1 /* sp.c
2  *
3  * Copyright (C) 2006-2021 wolfSSL Inc.
4  *
5  * This file is part of wolfSSL.
6  *
7  * wolfSSL is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * wolfSSL is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
20  */
21 
22 /* Implementation by Sean Parkinson. */
23 
24 #ifdef HAVE_CONFIG_H
25     #include <config.h>
26 #endif
27 
28 #include <wolfssl/wolfcrypt/settings.h>
29 
30 #if defined(WOLFSSL_HAVE_SP_RSA) || defined(WOLFSSL_HAVE_SP_DH) || \
31     defined(WOLFSSL_HAVE_SP_ECC)
32 
33 #include <wolfssl/wolfcrypt/error-crypt.h>
34 #include <wolfssl/wolfcrypt/cpuid.h>
35 #ifdef NO_INLINE
36     #include <wolfssl/wolfcrypt/misc.h>
37 #else
38     #define WOLFSSL_MISC_INCLUDED
39     #include <wolfcrypt/src/misc.c>
40 #endif
41 
42 #ifdef RSA_LOW_MEM
43 #ifndef SP_RSA_PRIVATE_EXP_D
44 #define SP_RSA_PRIVATE_EXP_D
45 #endif
46 
47 #ifndef WOLFSSL_SP_SMALL
48 #define WOLFSSL_SP_SMALL
49 #endif
50 #endif
51 
52 #include <wolfssl/wolfcrypt/sp.h>
53 
54 #ifndef WOLFSSL_SP_ASM
55 #if SP_WORD_SIZE == 64
56 #define SP_PRINT_NUM(var, name, total, words, bits)   \
57     do {                                              \
58         int ii;                                       \
59         byte n[bits / 8];                             \
60         sp_digit s[words];                            \
61         XMEMCPY(s, var, sizeof(s));                   \
62         sp_##total##_norm_##words(s);                 \
63         sp_##total##_to_bin_##words(s, n);            \
64         fprintf(stderr, name "=0x");                  \
65         for (ii=0; ii<bits/8; ii++)                   \
66             fprintf(stderr, "%02x", n[ii]);           \
67         fprintf(stderr, "\n");                       \
68     } while (0)
69 
70 #define SP_PRINT_VAL(var, name) \
71     fprintf(stderr, name "=0x" SP_PRINT_FMT "\n", var)
72 
73 #if (((!defined(WC_NO_CACHE_RESISTANT) && \
74       (defined(WOLFSSL_HAVE_SP_RSA) || defined(WOLFSSL_HAVE_SP_DH))) || \
75      (defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SP_FAST_MODEXP))) && \
76     !defined(WOLFSSL_RSA_PUBLIC_ONLY)) || (defined(WOLFSSL_SP_SMALL) && \
77     defined(WOLFSSL_HAVE_SP_ECC))
78 /* Mask for address to obfuscate which of the two address will be used. */
79 static const size_t addr_mask[2] = { 0, (size_t)-1 };
80 #endif
81 
82 #if defined(WOLFSSL_SP_NONBLOCK) && (!defined(WOLFSSL_SP_NO_MALLOC) ||                                      !defined(WOLFSSL_SP_SMALL))
83     #error SP non-blocking requires small and no-malloc (WOLFSSL_SP_SMALL and WOLFSSL_SP_NO_MALLOC)
84 #endif
85 
86 #if defined(WOLFSSL_HAVE_SP_RSA) || defined(WOLFSSL_HAVE_SP_DH)
87 #ifndef WOLFSSL_SP_NO_2048
88 #ifdef WOLFSSL_SP_SMALL
89 /* Read big endian unsigned byte array into r.
90  *
91  * r  A single precision integer.
92  * size  Maximum number of bytes to convert
93  * a  Byte array.
94  * n  Number of bytes in array to read.
95  */
sp_2048_from_bin(sp_digit * r,int size,const byte * a,int n)96 static void sp_2048_from_bin(sp_digit* r, int size, const byte* a, int n)
97 {
98     int i;
99     int j = 0;
100     word32 s = 0;
101 
102     r[0] = 0;
103     for (i = n-1; i >= 0; i--) {
104         r[j] |= (((sp_digit)a[i]) << s);
105         if (s >= 53U) {
106             r[j] &= 0x1fffffffffffffffL;
107             s = 61U - s;
108             if (j + 1 >= size) {
109                 break;
110             }
111             r[++j] = (sp_digit)a[i] >> s;
112             s = 8U - s;
113         }
114         else {
115             s += 8U;
116         }
117     }
118 
119     for (j++; j < size; j++) {
120         r[j] = 0;
121     }
122 }
123 
124 /* Convert an mp_int to an array of sp_digit.
125  *
126  * r  A single precision integer.
127  * size  Maximum number of bytes to convert
128  * a  A multi-precision integer.
129  */
sp_2048_from_mp(sp_digit * r,int size,const mp_int * a)130 static void sp_2048_from_mp(sp_digit* r, int size, const mp_int* a)
131 {
132 #if DIGIT_BIT == 61
133     int j;
134 
135     XMEMCPY(r, a->dp, sizeof(sp_digit) * a->used);
136 
137     for (j = a->used; j < size; j++) {
138         r[j] = 0;
139     }
140 #elif DIGIT_BIT > 61
141     int i;
142     int j = 0;
143     word32 s = 0;
144 
145     r[0] = 0;
146     for (i = 0; i < a->used && j < size; i++) {
147         r[j] |= ((sp_digit)a->dp[i] << s);
148         r[j] &= 0x1fffffffffffffffL;
149         s = 61U - s;
150         if (j + 1 >= size) {
151             break;
152         }
153         /* lint allow cast of mismatch word32 and mp_digit */
154         r[++j] = (sp_digit)(a->dp[i] >> s); /*lint !e9033*/
155         while ((s + 61U) <= (word32)DIGIT_BIT) {
156             s += 61U;
157             r[j] &= 0x1fffffffffffffffL;
158             if (j + 1 >= size) {
159                 break;
160             }
161             if (s < (word32)DIGIT_BIT) {
162                 /* lint allow cast of mismatch word32 and mp_digit */
163                 r[++j] = (sp_digit)(a->dp[i] >> s); /*lint !e9033*/
164             }
165             else {
166                 r[++j] = (sp_digit)0;
167             }
168         }
169         s = (word32)DIGIT_BIT - s;
170     }
171 
172     for (j++; j < size; j++) {
173         r[j] = 0;
174     }
175 #else
176     int i;
177     int j = 0;
178     int s = 0;
179 
180     r[0] = 0;
181     for (i = 0; i < a->used && j < size; i++) {
182         r[j] |= ((sp_digit)a->dp[i]) << s;
183         if (s + DIGIT_BIT >= 61) {
184             r[j] &= 0x1fffffffffffffffL;
185             if (j + 1 >= size) {
186                 break;
187             }
188             s = 61 - s;
189             if (s == DIGIT_BIT) {
190                 r[++j] = 0;
191                 s = 0;
192             }
193             else {
194                 r[++j] = a->dp[i] >> s;
195                 s = DIGIT_BIT - s;
196             }
197         }
198         else {
199             s += DIGIT_BIT;
200         }
201     }
202 
203     for (j++; j < size; j++) {
204         r[j] = 0;
205     }
206 #endif
207 }
208 
209 /* Write r as big endian to byte array.
210  * Fixed length number of bytes written: 256
211  *
212  * r  A single precision integer.
213  * a  Byte array.
214  */
sp_2048_to_bin_34(sp_digit * r,byte * a)215 static void sp_2048_to_bin_34(sp_digit* r, byte* a)
216 {
217     int i;
218     int j;
219     int s = 0;
220     int b;
221 
222     for (i=0; i<33; i++) {
223         r[i+1] += r[i] >> 61;
224         r[i] &= 0x1fffffffffffffffL;
225     }
226     j = 2048 / 8 - 1;
227     a[j] = 0;
228     for (i=0; i<34 && j>=0; i++) {
229         b = 0;
230         /* lint allow cast of mismatch sp_digit and int */
231         a[j--] |= (byte)(r[i] << s); /*lint !e9033*/
232         b += 8 - s;
233         if (j < 0) {
234             break;
235         }
236         while (b < 61) {
237             a[j--] = (byte)(r[i] >> b);
238             b += 8;
239             if (j < 0) {
240                 break;
241             }
242         }
243         s = 8 - (b - 61);
244         if (j >= 0) {
245             a[j] = 0;
246         }
247         if (s != 0) {
248             j++;
249         }
250     }
251 }
252 
253 #if (defined(WOLFSSL_HAVE_SP_RSA) && !defined(WOLFSSL_RSA_PUBLIC_ONLY)) || defined(WOLFSSL_HAVE_SP_DH)
254 /* Normalize the values in each word to 61 bits.
255  *
256  * a  Array of sp_digit to normalize.
257  */
sp_2048_norm_17(sp_digit * a)258 static void sp_2048_norm_17(sp_digit* a)
259 {
260     int i;
261     for (i = 0; i < 16; i++) {
262         a[i+1] += a[i] >> 61;
263         a[i] &= 0x1fffffffffffffffL;
264     }
265 }
266 
267 #endif /* (WOLFSSL_HAVE_SP_RSA && !WOLFSSL_RSA_PUBLIC_ONLY) || WOLFSSL_HAVE_SP_DH */
268 /* Normalize the values in each word to 61 bits.
269  *
270  * a  Array of sp_digit to normalize.
271  */
sp_2048_norm_34(sp_digit * a)272 static void sp_2048_norm_34(sp_digit* a)
273 {
274     int i;
275     for (i = 0; i < 33; i++) {
276         a[i+1] += a[i] >> 61;
277         a[i] &= 0x1fffffffffffffffL;
278     }
279 }
280 
281 /* Multiply a and b into r. (r = a * b)
282  *
283  * r  A single precision integer.
284  * a  A single precision integer.
285  * b  A single precision integer.
286  */
sp_2048_mul_34(sp_digit * r,const sp_digit * a,const sp_digit * b)287 SP_NOINLINE static void sp_2048_mul_34(sp_digit* r, const sp_digit* a,
288     const sp_digit* b)
289 {
290     int i;
291     int imax;
292     int k;
293     sp_uint128 c;
294     sp_uint128 lo;
295 
296     c = ((sp_uint128)a[33]) * b[33];
297     r[67] = (sp_digit)(c >> 61);
298     c &= 0x1fffffffffffffffL;
299     for (k = 65; k >= 0; k--) {
300         if (k >= 34) {
301             i = k - 33;
302             imax = 33;
303         }
304         else {
305             i = 0;
306             imax = k;
307         }
308         if (imax - i > 15) {
309             int imaxlo;
310             lo = 0;
311             for (imaxlo = i; imaxlo <= imax; imaxlo += 15) {
312                 for (; i <= imax && i < imaxlo + 15; i++) {
313                     lo += ((sp_uint128)a[i]) * b[k - i];
314                 }
315                 c += lo >> 61;
316                 lo &= 0x1fffffffffffffffL;
317             }
318             r[k + 2] += (sp_digit)(c >> 61);
319             r[k + 1]  = (sp_digit)(c & 0x1fffffffffffffffL);
320             c = lo & 0x1fffffffffffffffL;
321         }
322         else {
323             lo = 0;
324             for (; i <= imax; i++) {
325                 lo += ((sp_uint128)a[i]) * b[k - i];
326             }
327             c += lo >> 61;
328             r[k + 2] += (sp_digit)(c >> 61);
329             r[k + 1]  = (sp_digit)(c & 0x1fffffffffffffffL);
330             c = lo & 0x1fffffffffffffffL;
331         }
332     }
333     r[0] = (sp_digit)c;
334 }
335 
336 /* Square a and put result in r. (r = a * a)
337  *
338  * r  A single precision integer.
339  * a  A single precision integer.
340  */
sp_2048_sqr_34(sp_digit * r,const sp_digit * a)341 SP_NOINLINE static void sp_2048_sqr_34(sp_digit* r, const sp_digit* a)
342 {
343     int i;
344     int imax;
345     int k;
346     sp_uint128 c;
347     sp_uint128 t;
348 
349     c = ((sp_uint128)a[33]) * a[33];
350     r[67] = (sp_digit)(c >> 61);
351     c = (c & 0x1fffffffffffffffL) << 61;
352     for (k = 65; k >= 0; k--) {
353         i = (k + 1) / 2;
354         if ((k & 1) == 0) {
355            c += ((sp_uint128)a[i]) * a[i];
356            i++;
357         }
358         if (k < 33) {
359             imax = k;
360         }
361         else {
362             imax = 33;
363         }
364         if (imax - i >= 14) {
365             int imaxlo;
366             sp_uint128 hi;
367 
368             hi = c >> 61;
369             c &= 0x1fffffffffffffffL;
370             for (imaxlo = i; imaxlo <= imax; imaxlo += 14) {
371                 t = 0;
372                 for (; i <= imax && i < imaxlo + 14; i++) {
373                     t += ((sp_uint128)a[i]) * a[k - i];
374                 }
375                 c += t * 2;
376 
377                 hi += c >> 61;
378                 c &= 0x1fffffffffffffffL;
379             }
380             r[k + 2] += (sp_digit)(hi >> 61);
381             r[k + 1]  = (sp_digit)(hi & 0x1fffffffffffffffL);
382             c <<= 61;
383         }
384         else
385         {
386             t = 0;
387             for (; i <= imax; i++) {
388                 t += ((sp_uint128)a[i]) * a[k - i];
389             }
390             c += t * 2;
391 
392             r[k + 2] += (sp_digit) (c >> 122);
393             r[k + 1]  = (sp_digit)((c >> 61) & 0x1fffffffffffffffL);
394             c = (c & 0x1fffffffffffffffL) << 61;
395         }
396     }
397     r[0] = (sp_digit)(c >> 61);
398 }
399 
400 /* Caclulate the bottom digit of -1/a mod 2^n.
401  *
402  * a    A single precision number.
403  * rho  Bottom word of inverse.
404  */
sp_2048_mont_setup(const sp_digit * a,sp_digit * rho)405 static void sp_2048_mont_setup(const sp_digit* a, sp_digit* rho)
406 {
407     sp_digit x;
408     sp_digit b;
409 
410     b = a[0];
411     x = (((b + 2) & 4) << 1) + b; /* here x*a==1 mod 2**4 */
412     x *= 2 - b * x;               /* here x*a==1 mod 2**8 */
413     x *= 2 - b * x;               /* here x*a==1 mod 2**16 */
414     x *= 2 - b * x;               /* here x*a==1 mod 2**32 */
415     x *= 2 - b * x;               /* here x*a==1 mod 2**64 */
416     x &= 0x1fffffffffffffffL;
417 
418     /* rho = -1/m mod b */
419     *rho = ((sp_digit)1 << 61) - x;
420 }
421 
422 /* Multiply a by scalar b into r. (r = a * b)
423  *
424  * r  A single precision integer.
425  * a  A single precision integer.
426  * b  A scalar.
427  */
sp_2048_mul_d_34(sp_digit * r,const sp_digit * a,sp_digit b)428 SP_NOINLINE static void sp_2048_mul_d_34(sp_digit* r, const sp_digit* a,
429     sp_digit b)
430 {
431     sp_int128 tb = b;
432     sp_int128 t = 0;
433     int i;
434 
435     for (i = 0; i < 34; i++) {
436         t += tb * a[i];
437         r[i] = (sp_digit)(t & 0x1fffffffffffffffL);
438         t >>= 61;
439     }
440     r[34] = (sp_digit)t;
441 }
442 
443 #if (defined(WOLFSSL_HAVE_SP_RSA) && !defined(WOLFSSL_RSA_PUBLIC_ONLY)) || defined(WOLFSSL_HAVE_SP_DH)
444 /* Sub b from a into r. (r = a - b)
445  *
446  * r  A single precision integer.
447  * a  A single precision integer.
448  * b  A single precision integer.
449  */
sp_2048_sub_17(sp_digit * r,const sp_digit * a,const sp_digit * b)450 SP_NOINLINE static int sp_2048_sub_17(sp_digit* r, const sp_digit* a,
451         const sp_digit* b)
452 {
453     int i;
454 
455     for (i = 0; i < 17; i++) {
456         r[i] = a[i] - b[i];
457     }
458 
459     return 0;
460 }
461 
462 /* r = 2^n mod m where n is the number of bits to reduce by.
463  * Given m must be 2048 bits, just need to subtract.
464  *
465  * r  A single precision number.
466  * m  A single precision number.
467  */
sp_2048_mont_norm_17(sp_digit * r,const sp_digit * m)468 static void sp_2048_mont_norm_17(sp_digit* r, const sp_digit* m)
469 {
470     /* Set r = 2^n - 1. */
471     int i;
472 
473     for (i=0; i<16; i++) {
474         r[i] = 0x1fffffffffffffffL;
475     }
476     r[16] = 0xffffffffffffL;
477 
478     /* r = (2^n - 1) mod n */
479     (void)sp_2048_sub_17(r, r, m);
480 
481     /* Add one so r = 2^n mod m */
482     r[0] += 1;
483 }
484 
485 /* Compare a with b in constant time.
486  *
487  * a  A single precision integer.
488  * b  A single precision integer.
489  * return -ve, 0 or +ve if a is less than, equal to or greater than b
490  * respectively.
491  */
sp_2048_cmp_17(const sp_digit * a,const sp_digit * b)492 static sp_digit sp_2048_cmp_17(const sp_digit* a, const sp_digit* b)
493 {
494     sp_digit r = 0;
495     int i;
496 
497     for (i=16; i>=0; i--) {
498         r |= (a[i] - b[i]) & (0 - (sp_digit)((r == 0) ? 1 : 0));
499     }
500 
501     return r;
502 }
503 
504 /* Conditionally subtract b from a using the mask m.
505  * m is -1 to subtract and 0 when not.
506  *
507  * r  A single precision number representing condition subtract result.
508  * a  A single precision number to subtract from.
509  * b  A single precision number to subtract.
510  * m  Mask value to apply.
511  */
sp_2048_cond_sub_17(sp_digit * r,const sp_digit * a,const sp_digit * b,const sp_digit m)512 static void sp_2048_cond_sub_17(sp_digit* r, const sp_digit* a,
513         const sp_digit* b, const sp_digit m)
514 {
515     int i;
516 
517     for (i = 0; i < 17; i++) {
518         r[i] = a[i] - (b[i] & m);
519     }
520 }
521 
522 /* Mul a by scalar b and add into r. (r += a * b)
523  *
524  * r  A single precision integer.
525  * a  A single precision integer.
526  * b  A scalar.
527  */
sp_2048_mul_add_17(sp_digit * r,const sp_digit * a,const sp_digit b)528 SP_NOINLINE static void sp_2048_mul_add_17(sp_digit* r, const sp_digit* a,
529         const sp_digit b)
530 {
531     sp_int128 tb = b;
532     sp_int128 t[4];
533     int i;
534 
535     t[0] = 0;
536     for (i = 0; i < 16; i += 4) {
537         t[0] += (tb * a[i+0]) + r[i+0];
538         t[1]  = (tb * a[i+1]) + r[i+1];
539         t[2]  = (tb * a[i+2]) + r[i+2];
540         t[3]  = (tb * a[i+3]) + r[i+3];
541         r[i+0] = t[0] & 0x1fffffffffffffffL;
542         t[1] += t[0] >> 61;
543         r[i+1] = t[1] & 0x1fffffffffffffffL;
544         t[2] += t[1] >> 61;
545         r[i+2] = t[2] & 0x1fffffffffffffffL;
546         t[3] += t[2] >> 61;
547         r[i+3] = t[3] & 0x1fffffffffffffffL;
548         t[0]  = t[3] >> 61;
549     }
550     t[0] += (tb * a[16]) + r[16];
551     r[16] = t[0] & 0x1fffffffffffffffL;
552     r[17] +=  (sp_digit)(t[0] >> 61);
553 }
554 
555 /* Shift the result in the high 1024 bits down to the bottom.
556  *
557  * r  A single precision number.
558  * a  A single precision number.
559  */
sp_2048_mont_shift_17(sp_digit * r,const sp_digit * a)560 static void sp_2048_mont_shift_17(sp_digit* r, const sp_digit* a)
561 {
562     int i;
563     sp_int128 n = a[16] >> 48;
564     n += ((sp_int128)a[17]) << 13;
565 
566     for (i = 0; i < 16; i++) {
567         r[i] = n & 0x1fffffffffffffffL;
568         n >>= 61;
569         n += ((sp_int128)a[18 + i]) << 13;
570     }
571     r[16] = (sp_digit)n;
572     XMEMSET(&r[17], 0, sizeof(*r) * 17U);
573 }
574 
575 /* Reduce the number back to 2048 bits using Montgomery reduction.
576  *
577  * a   A single precision number to reduce in place.
578  * m   The single precision number representing the modulus.
579  * mp  The digit representing the negative inverse of m mod 2^n.
580  */
sp_2048_mont_reduce_17(sp_digit * a,const sp_digit * m,sp_digit mp)581 static void sp_2048_mont_reduce_17(sp_digit* a, const sp_digit* m, sp_digit mp)
582 {
583     int i;
584     sp_digit mu;
585 
586     sp_2048_norm_17(a + 17);
587 
588     for (i=0; i<16; i++) {
589         mu = (a[i] * mp) & 0x1fffffffffffffffL;
590         sp_2048_mul_add_17(a+i, m, mu);
591         a[i+1] += a[i] >> 61;
592     }
593     mu = (a[i] * mp) & 0xffffffffffffL;
594     sp_2048_mul_add_17(a+i, m, mu);
595     a[i+1] += a[i] >> 61;
596     a[i] &= 0x1fffffffffffffffL;
597     sp_2048_mont_shift_17(a, a);
598     sp_2048_cond_sub_17(a, a, m, 0 - (((a[16] - m[16]) > 0) ?
599             (sp_digit)1 : (sp_digit)0));
600     sp_2048_norm_17(a);
601 }
602 
603 /* Multiply a and b into r. (r = a * b)
604  *
605  * r  A single precision integer.
606  * a  A single precision integer.
607  * b  A single precision integer.
608  */
sp_2048_mul_17(sp_digit * r,const sp_digit * a,const sp_digit * b)609 SP_NOINLINE static void sp_2048_mul_17(sp_digit* r, const sp_digit* a,
610     const sp_digit* b)
611 {
612     int i;
613     int imax;
614     int k;
615     sp_uint128 c;
616     sp_uint128 lo;
617 
618     c = ((sp_uint128)a[16]) * b[16];
619     r[33] = (sp_digit)(c >> 61);
620     c &= 0x1fffffffffffffffL;
621     for (k = 31; k >= 0; k--) {
622         if (k >= 17) {
623             i = k - 16;
624             imax = 16;
625         }
626         else {
627             i = 0;
628             imax = k;
629         }
630         if (imax - i > 15) {
631             int imaxlo;
632             lo = 0;
633             for (imaxlo = i; imaxlo <= imax; imaxlo += 15) {
634                 for (; i <= imax && i < imaxlo + 15; i++) {
635                     lo += ((sp_uint128)a[i]) * b[k - i];
636                 }
637                 c += lo >> 61;
638                 lo &= 0x1fffffffffffffffL;
639             }
640             r[k + 2] += (sp_digit)(c >> 61);
641             r[k + 1]  = (sp_digit)(c & 0x1fffffffffffffffL);
642             c = lo & 0x1fffffffffffffffL;
643         }
644         else {
645             lo = 0;
646             for (; i <= imax; i++) {
647                 lo += ((sp_uint128)a[i]) * b[k - i];
648             }
649             c += lo >> 61;
650             r[k + 2] += (sp_digit)(c >> 61);
651             r[k + 1]  = (sp_digit)(c & 0x1fffffffffffffffL);
652             c = lo & 0x1fffffffffffffffL;
653         }
654     }
655     r[0] = (sp_digit)c;
656 }
657 
658 /* Multiply two Montgomery form numbers mod the modulus (prime).
659  * (r = a * b mod m)
660  *
661  * r   Result of multiplication.
662  * a   First number to multiply in Montgomery form.
663  * b   Second number to multiply in Montgomery form.
664  * m   Modulus (prime).
665  * mp  Montgomery mulitplier.
666  */
sp_2048_mont_mul_17(sp_digit * r,const sp_digit * a,const sp_digit * b,const sp_digit * m,sp_digit mp)667 static void sp_2048_mont_mul_17(sp_digit* r, const sp_digit* a,
668         const sp_digit* b, const sp_digit* m, sp_digit mp)
669 {
670     sp_2048_mul_17(r, a, b);
671     sp_2048_mont_reduce_17(r, m, mp);
672 }
673 
674 /* Square a and put result in r. (r = a * a)
675  *
676  * r  A single precision integer.
677  * a  A single precision integer.
678  */
sp_2048_sqr_17(sp_digit * r,const sp_digit * a)679 SP_NOINLINE static void sp_2048_sqr_17(sp_digit* r, const sp_digit* a)
680 {
681     int i;
682     int imax;
683     int k;
684     sp_uint128 c;
685     sp_uint128 t;
686 
687     c = ((sp_uint128)a[16]) * a[16];
688     r[33] = (sp_digit)(c >> 61);
689     c = (c & 0x1fffffffffffffffL) << 61;
690     for (k = 31; k >= 0; k--) {
691         i = (k + 1) / 2;
692         if ((k & 1) == 0) {
693            c += ((sp_uint128)a[i]) * a[i];
694            i++;
695         }
696         if (k < 16) {
697             imax = k;
698         }
699         else {
700             imax = 16;
701         }
702         if (imax - i >= 14) {
703             int imaxlo;
704             sp_uint128 hi;
705 
706             hi = c >> 61;
707             c &= 0x1fffffffffffffffL;
708             for (imaxlo = i; imaxlo <= imax; imaxlo += 14) {
709                 t = 0;
710                 for (; i <= imax && i < imaxlo + 14; i++) {
711                     t += ((sp_uint128)a[i]) * a[k - i];
712                 }
713                 c += t * 2;
714 
715                 hi += c >> 61;
716                 c &= 0x1fffffffffffffffL;
717             }
718             r[k + 2] += (sp_digit)(hi >> 61);
719             r[k + 1]  = (sp_digit)(hi & 0x1fffffffffffffffL);
720             c <<= 61;
721         }
722         else
723         {
724             t = 0;
725             for (; i <= imax; i++) {
726                 t += ((sp_uint128)a[i]) * a[k - i];
727             }
728             c += t * 2;
729 
730             r[k + 2] += (sp_digit) (c >> 122);
731             r[k + 1]  = (sp_digit)((c >> 61) & 0x1fffffffffffffffL);
732             c = (c & 0x1fffffffffffffffL) << 61;
733         }
734     }
735     r[0] = (sp_digit)(c >> 61);
736 }
737 
738 /* Square the Montgomery form number. (r = a * a mod m)
739  *
740  * r   Result of squaring.
741  * a   Number to square in Montgomery form.
742  * m   Modulus (prime).
743  * mp  Montgomery mulitplier.
744  */
sp_2048_mont_sqr_17(sp_digit * r,const sp_digit * a,const sp_digit * m,sp_digit mp)745 static void sp_2048_mont_sqr_17(sp_digit* r, const sp_digit* a,
746         const sp_digit* m, sp_digit mp)
747 {
748     sp_2048_sqr_17(r, a);
749     sp_2048_mont_reduce_17(r, m, mp);
750 }
751 
752 /* Multiply a by scalar b into r. (r = a * b)
753  *
754  * r  A single precision integer.
755  * a  A single precision integer.
756  * b  A scalar.
757  */
sp_2048_mul_d_17(sp_digit * r,const sp_digit * a,sp_digit b)758 SP_NOINLINE static void sp_2048_mul_d_17(sp_digit* r, const sp_digit* a,
759     sp_digit b)
760 {
761     sp_int128 tb = b;
762     sp_int128 t = 0;
763     int i;
764 
765     for (i = 0; i < 17; i++) {
766         t += tb * a[i];
767         r[i] = (sp_digit)(t & 0x1fffffffffffffffL);
768         t >>= 61;
769     }
770     r[17] = (sp_digit)t;
771 }
772 
773 /* Conditionally add a and b using the mask m.
774  * m is -1 to add and 0 when not.
775  *
776  * r  A single precision number representing conditional add result.
777  * a  A single precision number to add with.
778  * b  A single precision number to add.
779  * m  Mask value to apply.
780  */
sp_2048_cond_add_17(sp_digit * r,const sp_digit * a,const sp_digit * b,const sp_digit m)781 static void sp_2048_cond_add_17(sp_digit* r, const sp_digit* a,
782         const sp_digit* b, const sp_digit m)
783 {
784     int i;
785 
786     for (i = 0; i < 17; i++) {
787         r[i] = a[i] + (b[i] & m);
788     }
789 }
790 
791 /* Add b to a into r. (r = a + b)
792  *
793  * r  A single precision integer.
794  * a  A single precision integer.
795  * b  A single precision integer.
796  */
sp_2048_add_17(sp_digit * r,const sp_digit * a,const sp_digit * b)797 SP_NOINLINE static int sp_2048_add_17(sp_digit* r, const sp_digit* a,
798         const sp_digit* b)
799 {
800     int i;
801 
802     for (i = 0; i < 17; i++) {
803         r[i] = a[i] + b[i];
804     }
805 
806     return 0;
807 }
808 
sp_2048_rshift_17(sp_digit * r,const sp_digit * a,byte n)809 SP_NOINLINE static void sp_2048_rshift_17(sp_digit* r, const sp_digit* a,
810         byte n)
811 {
812     int i;
813 
814     for (i=0; i<16; i++) {
815         r[i] = ((a[i] >> n) | (a[i + 1] << (61 - n))) & 0x1fffffffffffffffL;
816     }
817     r[16] = a[16] >> n;
818 }
819 
820 #ifdef WOLFSSL_SP_DIV_64
sp_2048_div_word_17(sp_digit d1,sp_digit d0,sp_digit dv)821 static WC_INLINE sp_digit sp_2048_div_word_17(sp_digit d1, sp_digit d0,
822     sp_digit dv)
823 {
824     sp_digit d;
825     sp_digit r;
826     sp_digit t;
827 
828     /* All 61 bits from d1 and top 2 bits from d0. */
829     d = (d1 << 2) + (d0 >> 59);
830     r = d / dv;
831     d -= r * dv;
832     /* Up to 3 bits in r */
833     /* Next 2 bits from d0. */
834     r <<= 2;
835     d <<= 2;
836     d += (d0 >> 57) & ((1 << 2) - 1);
837     t = d / dv;
838     d -= t * dv;
839     r += t;
840     /* Up to 5 bits in r */
841     /* Next 2 bits from d0. */
842     r <<= 2;
843     d <<= 2;
844     d += (d0 >> 55) & ((1 << 2) - 1);
845     t = d / dv;
846     d -= t * dv;
847     r += t;
848     /* Up to 7 bits in r */
849     /* Next 2 bits from d0. */
850     r <<= 2;
851     d <<= 2;
852     d += (d0 >> 53) & ((1 << 2) - 1);
853     t = d / dv;
854     d -= t * dv;
855     r += t;
856     /* Up to 9 bits in r */
857     /* Next 2 bits from d0. */
858     r <<= 2;
859     d <<= 2;
860     d += (d0 >> 51) & ((1 << 2) - 1);
861     t = d / dv;
862     d -= t * dv;
863     r += t;
864     /* Up to 11 bits in r */
865     /* Next 2 bits from d0. */
866     r <<= 2;
867     d <<= 2;
868     d += (d0 >> 49) & ((1 << 2) - 1);
869     t = d / dv;
870     d -= t * dv;
871     r += t;
872     /* Up to 13 bits in r */
873     /* Next 2 bits from d0. */
874     r <<= 2;
875     d <<= 2;
876     d += (d0 >> 47) & ((1 << 2) - 1);
877     t = d / dv;
878     d -= t * dv;
879     r += t;
880     /* Up to 15 bits in r */
881     /* Next 2 bits from d0. */
882     r <<= 2;
883     d <<= 2;
884     d += (d0 >> 45) & ((1 << 2) - 1);
885     t = d / dv;
886     d -= t * dv;
887     r += t;
888     /* Up to 17 bits in r */
889     /* Next 2 bits from d0. */
890     r <<= 2;
891     d <<= 2;
892     d += (d0 >> 43) & ((1 << 2) - 1);
893     t = d / dv;
894     d -= t * dv;
895     r += t;
896     /* Up to 19 bits in r */
897     /* Next 2 bits from d0. */
898     r <<= 2;
899     d <<= 2;
900     d += (d0 >> 41) & ((1 << 2) - 1);
901     t = d / dv;
902     d -= t * dv;
903     r += t;
904     /* Up to 21 bits in r */
905     /* Next 2 bits from d0. */
906     r <<= 2;
907     d <<= 2;
908     d += (d0 >> 39) & ((1 << 2) - 1);
909     t = d / dv;
910     d -= t * dv;
911     r += t;
912     /* Up to 23 bits in r */
913     /* Next 2 bits from d0. */
914     r <<= 2;
915     d <<= 2;
916     d += (d0 >> 37) & ((1 << 2) - 1);
917     t = d / dv;
918     d -= t * dv;
919     r += t;
920     /* Up to 25 bits in r */
921     /* Next 2 bits from d0. */
922     r <<= 2;
923     d <<= 2;
924     d += (d0 >> 35) & ((1 << 2) - 1);
925     t = d / dv;
926     d -= t * dv;
927     r += t;
928     /* Up to 27 bits in r */
929     /* Next 2 bits from d0. */
930     r <<= 2;
931     d <<= 2;
932     d += (d0 >> 33) & ((1 << 2) - 1);
933     t = d / dv;
934     d -= t * dv;
935     r += t;
936     /* Up to 29 bits in r */
937     /* Next 2 bits from d0. */
938     r <<= 2;
939     d <<= 2;
940     d += (d0 >> 31) & ((1 << 2) - 1);
941     t = d / dv;
942     d -= t * dv;
943     r += t;
944     /* Up to 31 bits in r */
945     /* Next 2 bits from d0. */
946     r <<= 2;
947     d <<= 2;
948     d += (d0 >> 29) & ((1 << 2) - 1);
949     t = d / dv;
950     d -= t * dv;
951     r += t;
952     /* Up to 33 bits in r */
953     /* Next 2 bits from d0. */
954     r <<= 2;
955     d <<= 2;
956     d += (d0 >> 27) & ((1 << 2) - 1);
957     t = d / dv;
958     d -= t * dv;
959     r += t;
960     /* Up to 35 bits in r */
961     /* Next 2 bits from d0. */
962     r <<= 2;
963     d <<= 2;
964     d += (d0 >> 25) & ((1 << 2) - 1);
965     t = d / dv;
966     d -= t * dv;
967     r += t;
968     /* Up to 37 bits in r */
969     /* Next 2 bits from d0. */
970     r <<= 2;
971     d <<= 2;
972     d += (d0 >> 23) & ((1 << 2) - 1);
973     t = d / dv;
974     d -= t * dv;
975     r += t;
976     /* Up to 39 bits in r */
977     /* Next 2 bits from d0. */
978     r <<= 2;
979     d <<= 2;
980     d += (d0 >> 21) & ((1 << 2) - 1);
981     t = d / dv;
982     d -= t * dv;
983     r += t;
984     /* Up to 41 bits in r */
985     /* Next 2 bits from d0. */
986     r <<= 2;
987     d <<= 2;
988     d += (d0 >> 19) & ((1 << 2) - 1);
989     t = d / dv;
990     d -= t * dv;
991     r += t;
992     /* Up to 43 bits in r */
993     /* Next 2 bits from d0. */
994     r <<= 2;
995     d <<= 2;
996     d += (d0 >> 17) & ((1 << 2) - 1);
997     t = d / dv;
998     d -= t * dv;
999     r += t;
1000     /* Up to 45 bits in r */
1001     /* Next 2 bits from d0. */
1002     r <<= 2;
1003     d <<= 2;
1004     d += (d0 >> 15) & ((1 << 2) - 1);
1005     t = d / dv;
1006     d -= t * dv;
1007     r += t;
1008     /* Up to 47 bits in r */
1009     /* Next 2 bits from d0. */
1010     r <<= 2;
1011     d <<= 2;
1012     d += (d0 >> 13) & ((1 << 2) - 1);
1013     t = d / dv;
1014     d -= t * dv;
1015     r += t;
1016     /* Up to 49 bits in r */
1017     /* Next 2 bits from d0. */
1018     r <<= 2;
1019     d <<= 2;
1020     d += (d0 >> 11) & ((1 << 2) - 1);
1021     t = d / dv;
1022     d -= t * dv;
1023     r += t;
1024     /* Up to 51 bits in r */
1025     /* Next 2 bits from d0. */
1026     r <<= 2;
1027     d <<= 2;
1028     d += (d0 >> 9) & ((1 << 2) - 1);
1029     t = d / dv;
1030     d -= t * dv;
1031     r += t;
1032     /* Up to 53 bits in r */
1033     /* Next 2 bits from d0. */
1034     r <<= 2;
1035     d <<= 2;
1036     d += (d0 >> 7) & ((1 << 2) - 1);
1037     t = d / dv;
1038     d -= t * dv;
1039     r += t;
1040     /* Up to 55 bits in r */
1041     /* Next 2 bits from d0. */
1042     r <<= 2;
1043     d <<= 2;
1044     d += (d0 >> 5) & ((1 << 2) - 1);
1045     t = d / dv;
1046     d -= t * dv;
1047     r += t;
1048     /* Up to 57 bits in r */
1049     /* Next 2 bits from d0. */
1050     r <<= 2;
1051     d <<= 2;
1052     d += (d0 >> 3) & ((1 << 2) - 1);
1053     t = d / dv;
1054     d -= t * dv;
1055     r += t;
1056     /* Up to 59 bits in r */
1057     /* Next 2 bits from d0. */
1058     r <<= 2;
1059     d <<= 2;
1060     d += (d0 >> 1) & ((1 << 2) - 1);
1061     t = d / dv;
1062     d -= t * dv;
1063     r += t;
1064     /* Up to 61 bits in r */
1065     /* Remaining 1 bits from d0. */
1066     r <<= 1;
1067     d <<= 1;
1068     d += d0 & ((1 << 1) - 1);
1069     t = d / dv;
1070     r += t;
1071 
1072     /* All 61 bits from d1 and top 2 bits from d0. */
1073     return r;
1074 }
1075 #endif /* WOLFSSL_SP_DIV_64 */
1076 
1077 /* Divide d in a and put remainder into r (m*d + r = a)
1078  * m is not calculated as it is not needed at this time.
1079  *
1080  * Full implementation.
1081  *
1082  * a  Number to be divided.
1083  * d  Number to divide with.
1084  * m  Multiplier result.
1085  * r  Remainder from the division.
1086  * returns MEMORY_E when unable to allocate memory and MP_OKAY otherwise.
1087  */
sp_2048_div_17(const sp_digit * a,const sp_digit * d,const sp_digit * m,sp_digit * r)1088 static int sp_2048_div_17(const sp_digit* a, const sp_digit* d,
1089         const sp_digit* m, sp_digit* r)
1090 {
1091     int i;
1092 #ifndef WOLFSSL_SP_DIV_64
1093     sp_int128 d1;
1094 #endif
1095     sp_digit dv;
1096     sp_digit r1;
1097 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
1098     sp_digit* t1 = NULL;
1099 #else
1100     sp_digit t1[4 * 17 + 3];
1101 #endif
1102     sp_digit* t2 = NULL;
1103     sp_digit* sd = NULL;
1104     int err = MP_OKAY;
1105 
1106     (void)m;
1107 
1108 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
1109     t1 = (sp_digit*)XMALLOC(sizeof(sp_digit) * (4 * 17 + 3), NULL,
1110                                                        DYNAMIC_TYPE_TMP_BUFFER);
1111     if (t1 == NULL)
1112         err = MEMORY_E;
1113 #endif
1114 
1115     (void)m;
1116 
1117     if (err == MP_OKAY) {
1118         t2 = t1 + 34 + 1;
1119         sd = t2 + 17 + 1;
1120 
1121         sp_2048_mul_d_17(sd, d, (sp_digit)1 << 13);
1122         sp_2048_mul_d_34(t1, a, (sp_digit)1 << 13);
1123         dv = sd[16];
1124         t1[17 + 17] += t1[17 + 17 - 1] >> 61;
1125         t1[17 + 17 - 1] &= 0x1fffffffffffffffL;
1126         for (i=17; i>=0; i--) {
1127 #ifndef WOLFSSL_SP_DIV_64
1128             d1 = t1[17 + i];
1129             d1 <<= 61;
1130             d1 += t1[17 + i - 1];
1131             r1 = (sp_digit)(d1 / dv);
1132 #else
1133             r1 = sp_2048_div_word_17(t1[17 + i], t1[17 + i - 1], dv);
1134 #endif
1135 
1136             sp_2048_mul_d_17(t2, sd, r1);
1137             (void)sp_2048_sub_17(&t1[i], &t1[i], t2);
1138             sp_2048_norm_17(&t1[i]);
1139             t1[17 + i] -= t2[17];
1140             t1[17 + i] += t1[17 + i - 1] >> 61;
1141             t1[17 + i - 1] &= 0x1fffffffffffffffL;
1142 #ifndef WOLFSSL_SP_DIV_64
1143             d1 = -t1[17 + i];
1144             d1 <<= 61;
1145             d1 -= t1[17 + i - 1];
1146             r1 = (sp_digit)(d1 / dv);
1147 #else
1148             r1 = sp_2048_div_word_17(-t1[17 + i], -t1[17 + i - 1], dv);
1149 #endif
1150             r1 -= t1[17 + i];
1151             sp_2048_mul_d_17(t2, sd, r1);
1152             (void)sp_2048_add_17(&t1[i], &t1[i], t2);
1153             t1[17 + i] += t1[17 + i - 1] >> 61;
1154             t1[17 + i - 1] &= 0x1fffffffffffffffL;
1155         }
1156         t1[17 - 1] += t1[17 - 2] >> 61;
1157         t1[17 - 2] &= 0x1fffffffffffffffL;
1158         r1 = t1[17 - 1] / dv;
1159 
1160         sp_2048_mul_d_17(t2, sd, r1);
1161         sp_2048_sub_17(t1, t1, t2);
1162         XMEMCPY(r, t1, sizeof(*r) * 34U);
1163         for (i=0; i<16; i++) {
1164             r[i+1] += r[i] >> 61;
1165             r[i] &= 0x1fffffffffffffffL;
1166         }
1167         sp_2048_cond_add_17(r, r, sd, 0 - ((r[16] < 0) ?
1168                     (sp_digit)1 : (sp_digit)0));
1169 
1170         sp_2048_norm_17(r);
1171         sp_2048_rshift_17(r, r, 13);
1172     }
1173 
1174 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
1175     if (t1 != NULL)
1176         XFREE(t1, NULL, DYNAMIC_TYPE_TMP_BUFFER);
1177 #endif
1178 
1179     return err;
1180 }
1181 
1182 /* Reduce a modulo m into r. (r = a mod m)
1183  *
1184  * r  A single precision number that is the reduced result.
1185  * a  A single precision number that is to be reduced.
1186  * m  A single precision number that is the modulus to reduce with.
1187  * returns MEMORY_E when unable to allocate memory and MP_OKAY otherwise.
1188  */
sp_2048_mod_17(sp_digit * r,const sp_digit * a,const sp_digit * m)1189 static int sp_2048_mod_17(sp_digit* r, const sp_digit* a, const sp_digit* m)
1190 {
1191     return sp_2048_div_17(a, m, NULL, r);
1192 }
1193 
1194 /* Modular exponentiate a to the e mod m. (r = a^e mod m)
1195  *
1196  * r     A single precision number that is the result of the operation.
1197  * a     A single precision number being exponentiated.
1198  * e     A single precision number that is the exponent.
1199  * bits  The number of bits in the exponent.
1200  * m     A single precision number that is the modulus.
1201  * returns  0 on success.
1202  * returns  MEMORY_E on dynamic memory allocation failure.
1203  * returns  MP_VAL when base is even or exponent is 0.
1204  */
sp_2048_mod_exp_17(sp_digit * r,const sp_digit * a,const sp_digit * e,int bits,const sp_digit * m,int reduceA)1205 static int sp_2048_mod_exp_17(sp_digit* r, const sp_digit* a, const sp_digit* e,
1206     int bits, const sp_digit* m, int reduceA)
1207 {
1208 #if defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SP_FAST_MODEXP)
1209 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
1210     sp_digit* td = NULL;
1211 #else
1212     sp_digit td[3 * 34];
1213 #endif
1214     sp_digit* t[3] = {0, 0, 0};
1215     sp_digit* norm = NULL;
1216     sp_digit mp = 1;
1217     sp_digit n;
1218     int i;
1219     int c;
1220     byte y;
1221     int err = MP_OKAY;
1222 
1223     if ((m[0] & 1) == 0) {
1224         err = MP_VAL;
1225     }
1226     else if (bits == 0) {
1227         err = MP_VAL;
1228     }
1229 
1230 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
1231     if (err == MP_OKAY) {
1232         td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 3 * 17 * 2, NULL,
1233                                 DYNAMIC_TYPE_TMP_BUFFER);
1234         if (td == NULL)
1235             err = MEMORY_E;
1236     }
1237 #endif
1238 
1239     if (err == MP_OKAY) {
1240         norm = td;
1241         for (i=0; i<3; i++) {
1242             t[i] = td + (i * 17 * 2);
1243             XMEMSET(t[i], 0, sizeof(sp_digit) * 17U * 2U);
1244         }
1245 
1246         sp_2048_mont_setup(m, &mp);
1247         sp_2048_mont_norm_17(norm, m);
1248 
1249         if (reduceA != 0) {
1250             err = sp_2048_mod_17(t[1], a, m);
1251         }
1252         else {
1253             XMEMCPY(t[1], a, sizeof(sp_digit) * 17U);
1254         }
1255     }
1256     if (err == MP_OKAY) {
1257         sp_2048_mul_17(t[1], t[1], norm);
1258         err = sp_2048_mod_17(t[1], t[1], m);
1259     }
1260 
1261     if (err == MP_OKAY) {
1262         i = bits / 61;
1263         c = bits % 61;
1264         n = e[i--] << (61 - c);
1265         for (; ; c--) {
1266             if (c == 0) {
1267                 if (i == -1) {
1268                     break;
1269                 }
1270 
1271                 n = e[i--];
1272                 c = 61;
1273             }
1274 
1275             y = (int)((n >> 60) & 1);
1276             n <<= 1;
1277 
1278             sp_2048_mont_mul_17(t[y^1], t[0], t[1], m, mp);
1279 
1280             XMEMCPY(t[2], (void*)(((size_t)t[0] & addr_mask[y^1]) +
1281                                   ((size_t)t[1] & addr_mask[y])),
1282                                   sizeof(*t[2]) * 17 * 2);
1283             sp_2048_mont_sqr_17(t[2], t[2], m, mp);
1284             XMEMCPY((void*)(((size_t)t[0] & addr_mask[y^1]) +
1285                             ((size_t)t[1] & addr_mask[y])), t[2],
1286                             sizeof(*t[2]) * 17 * 2);
1287         }
1288 
1289         sp_2048_mont_reduce_17(t[0], m, mp);
1290         n = sp_2048_cmp_17(t[0], m);
1291         sp_2048_cond_sub_17(t[0], t[0], m, ((n < 0) ?
1292                     (sp_digit)1 : (sp_digit)0) - 1);
1293         XMEMCPY(r, t[0], sizeof(*r) * 17 * 2);
1294 
1295     }
1296 
1297 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
1298     if (td != NULL)
1299         XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);
1300 #endif
1301 
1302     return err;
1303 #elif !defined(WC_NO_CACHE_RESISTANT)
1304 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
1305     sp_digit* td = NULL;
1306 #else
1307     sp_digit td[3 * 34];
1308 #endif
1309     sp_digit* t[3] = {0, 0, 0};
1310     sp_digit* norm = NULL;
1311     sp_digit mp = 1;
1312     sp_digit n;
1313     int i;
1314     int c;
1315     byte y;
1316     int err = MP_OKAY;
1317 
1318     if ((m[0] & 1) == 0) {
1319         err = MP_VAL;
1320     }
1321     else if (bits == 0) {
1322         err = MP_VAL;
1323     }
1324 
1325 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
1326     if (err == MP_OKAY) {
1327         td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 3 * 17 * 2, NULL,
1328                                 DYNAMIC_TYPE_TMP_BUFFER);
1329         if (td == NULL)
1330             err = MEMORY_E;
1331     }
1332 #endif
1333 
1334     if (err == MP_OKAY) {
1335         norm = td;
1336         for (i=0; i<3; i++) {
1337             t[i] = td + (i * 17 * 2);
1338         }
1339 
1340         sp_2048_mont_setup(m, &mp);
1341         sp_2048_mont_norm_17(norm, m);
1342 
1343         if (reduceA != 0) {
1344             err = sp_2048_mod_17(t[1], a, m);
1345             if (err == MP_OKAY) {
1346                 sp_2048_mul_17(t[1], t[1], norm);
1347                 err = sp_2048_mod_17(t[1], t[1], m);
1348             }
1349         }
1350         else {
1351             sp_2048_mul_17(t[1], a, norm);
1352             err = sp_2048_mod_17(t[1], t[1], m);
1353         }
1354     }
1355 
1356     if (err == MP_OKAY) {
1357         i = bits / 61;
1358         c = bits % 61;
1359         n = e[i--] << (61 - c);
1360         for (; ; c--) {
1361             if (c == 0) {
1362                 if (i == -1) {
1363                     break;
1364                 }
1365 
1366                 n = e[i--];
1367                 c = 61;
1368             }
1369 
1370             y = (int)((n >> 60) & 1);
1371             n <<= 1;
1372 
1373             sp_2048_mont_mul_17(t[y^1], t[0], t[1], m, mp);
1374 
1375             XMEMCPY(t[2], (void*)(((size_t)t[0] & addr_mask[y^1]) +
1376                                   ((size_t)t[1] & addr_mask[y])),
1377                                   sizeof(*t[2]) * 17 * 2);
1378             sp_2048_mont_sqr_17(t[2], t[2], m, mp);
1379             XMEMCPY((void*)(((size_t)t[0] & addr_mask[y^1]) +
1380                             ((size_t)t[1] & addr_mask[y])), t[2],
1381                             sizeof(*t[2]) * 17 * 2);
1382         }
1383 
1384         sp_2048_mont_reduce_17(t[0], m, mp);
1385         n = sp_2048_cmp_17(t[0], m);
1386         sp_2048_cond_sub_17(t[0], t[0], m, ((n < 0) ?
1387                     (sp_digit)1 : (sp_digit)0) - 1);
1388         XMEMCPY(r, t[0], sizeof(*r) * 17 * 2);
1389     }
1390 
1391 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
1392     if (td != NULL)
1393         XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);
1394 #endif
1395 
1396     return err;
1397 #else
1398 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
1399     sp_digit* td = NULL;
1400 #else
1401     sp_digit td[(32 * 34) + 34];
1402 #endif
1403     sp_digit* t[32];
1404     sp_digit* rt = NULL;
1405     sp_digit* norm = NULL;
1406     sp_digit mp = 1;
1407     sp_digit n;
1408     int i;
1409     int c;
1410     byte y;
1411     int err = MP_OKAY;
1412 
1413     if ((m[0] & 1) == 0) {
1414         err = MP_VAL;
1415     }
1416     else if (bits == 0) {
1417         err = MP_VAL;
1418     }
1419 
1420 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
1421     if (err == MP_OKAY) {
1422         td = (sp_digit*)XMALLOC(sizeof(sp_digit) * ((32 * 34) + 34), NULL,
1423                                 DYNAMIC_TYPE_TMP_BUFFER);
1424         if (td == NULL)
1425             err = MEMORY_E;
1426     }
1427 #endif
1428 
1429     if (err == MP_OKAY) {
1430         norm = td;
1431         for (i=0; i<32; i++)
1432             t[i] = td + i * 34;
1433         rt = td + 1088;
1434 
1435         sp_2048_mont_setup(m, &mp);
1436         sp_2048_mont_norm_17(norm, m);
1437 
1438         if (reduceA != 0) {
1439             err = sp_2048_mod_17(t[1], a, m);
1440             if (err == MP_OKAY) {
1441                 sp_2048_mul_17(t[1], t[1], norm);
1442                 err = sp_2048_mod_17(t[1], t[1], m);
1443             }
1444         }
1445         else {
1446             sp_2048_mul_17(t[1], a, norm);
1447             err = sp_2048_mod_17(t[1], t[1], m);
1448         }
1449     }
1450 
1451     if (err == MP_OKAY) {
1452         sp_2048_mont_sqr_17(t[ 2], t[ 1], m, mp);
1453         sp_2048_mont_mul_17(t[ 3], t[ 2], t[ 1], m, mp);
1454         sp_2048_mont_sqr_17(t[ 4], t[ 2], m, mp);
1455         sp_2048_mont_mul_17(t[ 5], t[ 3], t[ 2], m, mp);
1456         sp_2048_mont_sqr_17(t[ 6], t[ 3], m, mp);
1457         sp_2048_mont_mul_17(t[ 7], t[ 4], t[ 3], m, mp);
1458         sp_2048_mont_sqr_17(t[ 8], t[ 4], m, mp);
1459         sp_2048_mont_mul_17(t[ 9], t[ 5], t[ 4], m, mp);
1460         sp_2048_mont_sqr_17(t[10], t[ 5], m, mp);
1461         sp_2048_mont_mul_17(t[11], t[ 6], t[ 5], m, mp);
1462         sp_2048_mont_sqr_17(t[12], t[ 6], m, mp);
1463         sp_2048_mont_mul_17(t[13], t[ 7], t[ 6], m, mp);
1464         sp_2048_mont_sqr_17(t[14], t[ 7], m, mp);
1465         sp_2048_mont_mul_17(t[15], t[ 8], t[ 7], m, mp);
1466         sp_2048_mont_sqr_17(t[16], t[ 8], m, mp);
1467         sp_2048_mont_mul_17(t[17], t[ 9], t[ 8], m, mp);
1468         sp_2048_mont_sqr_17(t[18], t[ 9], m, mp);
1469         sp_2048_mont_mul_17(t[19], t[10], t[ 9], m, mp);
1470         sp_2048_mont_sqr_17(t[20], t[10], m, mp);
1471         sp_2048_mont_mul_17(t[21], t[11], t[10], m, mp);
1472         sp_2048_mont_sqr_17(t[22], t[11], m, mp);
1473         sp_2048_mont_mul_17(t[23], t[12], t[11], m, mp);
1474         sp_2048_mont_sqr_17(t[24], t[12], m, mp);
1475         sp_2048_mont_mul_17(t[25], t[13], t[12], m, mp);
1476         sp_2048_mont_sqr_17(t[26], t[13], m, mp);
1477         sp_2048_mont_mul_17(t[27], t[14], t[13], m, mp);
1478         sp_2048_mont_sqr_17(t[28], t[14], m, mp);
1479         sp_2048_mont_mul_17(t[29], t[15], t[14], m, mp);
1480         sp_2048_mont_sqr_17(t[30], t[15], m, mp);
1481         sp_2048_mont_mul_17(t[31], t[16], t[15], m, mp);
1482 
1483         bits = ((bits + 4) / 5) * 5;
1484         i = ((bits + 60) / 61) - 1;
1485         c = bits % 61;
1486         if (c == 0) {
1487             c = 61;
1488         }
1489         if (i < 17) {
1490             n = e[i--] << (64 - c);
1491         }
1492         else {
1493             n = 0;
1494             i--;
1495         }
1496         if (c < 5) {
1497             n |= e[i--] << (3 - c);
1498             c += 61;
1499         }
1500         y = (int)((n >> 59) & 0x1f);
1501         n <<= 5;
1502         c -= 5;
1503         XMEMCPY(rt, t[y], sizeof(sp_digit) * 34);
1504         while ((i >= 0) || (c >= 5)) {
1505             if (c >= 5) {
1506                 y = (byte)((n >> 59) & 0x1f);
1507                 n <<= 5;
1508                 c -= 5;
1509             }
1510             else if (c == 0) {
1511                 n = e[i--] << 3;
1512                 y = (byte)((n >> 59) & 0x1f);
1513                 n <<= 5;
1514                 c = 56;
1515             }
1516             else {
1517                 y = (byte)((n >> 59) & 0x1f);
1518                 n = e[i--] << 3;
1519                 c = 5 - c;
1520                 y |= (byte)((n >> (64 - c)) & ((1 << c) - 1));
1521                 n <<= c;
1522                 c = 61 - c;
1523             }
1524 
1525             sp_2048_mont_sqr_17(rt, rt, m, mp);
1526             sp_2048_mont_sqr_17(rt, rt, m, mp);
1527             sp_2048_mont_sqr_17(rt, rt, m, mp);
1528             sp_2048_mont_sqr_17(rt, rt, m, mp);
1529             sp_2048_mont_sqr_17(rt, rt, m, mp);
1530 
1531             sp_2048_mont_mul_17(rt, rt, t[y], m, mp);
1532         }
1533 
1534         sp_2048_mont_reduce_17(rt, m, mp);
1535         n = sp_2048_cmp_17(rt, m);
1536         sp_2048_cond_sub_17(rt, rt, m, ((n < 0) ?
1537                    (sp_digit)1 : (sp_digit)0) - 1);
1538         XMEMCPY(r, rt, sizeof(sp_digit) * 34);
1539     }
1540 
1541 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
1542     if (td != NULL)
1543         XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);
1544 #endif
1545 
1546     return err;
1547 #endif
1548 }
1549 
1550 #endif /* (WOLFSSL_HAVE_SP_RSA & !WOLFSSL_RSA_PUBLIC_ONLY) | WOLFSSL_HAVE_SP_DH */
1551 
1552 /* Sub b from a into r. (r = a - b)
1553  *
1554  * r  A single precision integer.
1555  * a  A single precision integer.
1556  * b  A single precision integer.
1557  */
sp_2048_sub_34(sp_digit * r,const sp_digit * a,const sp_digit * b)1558 SP_NOINLINE static int sp_2048_sub_34(sp_digit* r, const sp_digit* a,
1559         const sp_digit* b)
1560 {
1561     int i;
1562 
1563     for (i = 0; i < 34; i++) {
1564         r[i] = a[i] - b[i];
1565     }
1566 
1567     return 0;
1568 }
1569 
1570 /* r = 2^n mod m where n is the number of bits to reduce by.
1571  * Given m must be 2048 bits, just need to subtract.
1572  *
1573  * r  A single precision number.
1574  * m  A single precision number.
1575  */
sp_2048_mont_norm_34(sp_digit * r,const sp_digit * m)1576 static void sp_2048_mont_norm_34(sp_digit* r, const sp_digit* m)
1577 {
1578     /* Set r = 2^n - 1. */
1579     int i;
1580 
1581     for (i=0; i<33; i++) {
1582         r[i] = 0x1fffffffffffffffL;
1583     }
1584     r[33] = 0x7ffffffffL;
1585 
1586     /* r = (2^n - 1) mod n */
1587     (void)sp_2048_sub_34(r, r, m);
1588 
1589     /* Add one so r = 2^n mod m */
1590     r[0] += 1;
1591 }
1592 
1593 /* Compare a with b in constant time.
1594  *
1595  * a  A single precision integer.
1596  * b  A single precision integer.
1597  * return -ve, 0 or +ve if a is less than, equal to or greater than b
1598  * respectively.
1599  */
sp_2048_cmp_34(const sp_digit * a,const sp_digit * b)1600 static sp_digit sp_2048_cmp_34(const sp_digit* a, const sp_digit* b)
1601 {
1602     sp_digit r = 0;
1603     int i;
1604 
1605     for (i=33; i>=0; i--) {
1606         r |= (a[i] - b[i]) & (0 - (sp_digit)((r == 0) ? 1 : 0));
1607     }
1608 
1609     return r;
1610 }
1611 
1612 /* Conditionally subtract b from a using the mask m.
1613  * m is -1 to subtract and 0 when not.
1614  *
1615  * r  A single precision number representing condition subtract result.
1616  * a  A single precision number to subtract from.
1617  * b  A single precision number to subtract.
1618  * m  Mask value to apply.
1619  */
sp_2048_cond_sub_34(sp_digit * r,const sp_digit * a,const sp_digit * b,const sp_digit m)1620 static void sp_2048_cond_sub_34(sp_digit* r, const sp_digit* a,
1621         const sp_digit* b, const sp_digit m)
1622 {
1623     int i;
1624 
1625     for (i = 0; i < 34; i++) {
1626         r[i] = a[i] - (b[i] & m);
1627     }
1628 }
1629 
1630 /* Mul a by scalar b and add into r. (r += a * b)
1631  *
1632  * r  A single precision integer.
1633  * a  A single precision integer.
1634  * b  A scalar.
1635  */
sp_2048_mul_add_34(sp_digit * r,const sp_digit * a,const sp_digit b)1636 SP_NOINLINE static void sp_2048_mul_add_34(sp_digit* r, const sp_digit* a,
1637         const sp_digit b)
1638 {
1639     sp_int128 tb = b;
1640     sp_int128 t[4];
1641     int i;
1642 
1643     t[0] = 0;
1644     for (i = 0; i < 32; i += 4) {
1645         t[0] += (tb * a[i+0]) + r[i+0];
1646         t[1]  = (tb * a[i+1]) + r[i+1];
1647         t[2]  = (tb * a[i+2]) + r[i+2];
1648         t[3]  = (tb * a[i+3]) + r[i+3];
1649         r[i+0] = t[0] & 0x1fffffffffffffffL;
1650         t[1] += t[0] >> 61;
1651         r[i+1] = t[1] & 0x1fffffffffffffffL;
1652         t[2] += t[1] >> 61;
1653         r[i+2] = t[2] & 0x1fffffffffffffffL;
1654         t[3] += t[2] >> 61;
1655         r[i+3] = t[3] & 0x1fffffffffffffffL;
1656         t[0]  = t[3] >> 61;
1657     }
1658     t[0] += (tb * a[32]) + r[32];
1659     t[1]  = (tb * a[33]) + r[33];
1660     r[32] = t[0] & 0x1fffffffffffffffL;
1661     t[1] += t[0] >> 61;
1662     r[33] = t[1] & 0x1fffffffffffffffL;
1663     r[34] +=  (sp_digit)(t[1] >> 61);
1664 }
1665 
1666 /* Shift the result in the high 2048 bits down to the bottom.
1667  *
1668  * r  A single precision number.
1669  * a  A single precision number.
1670  */
sp_2048_mont_shift_34(sp_digit * r,const sp_digit * a)1671 static void sp_2048_mont_shift_34(sp_digit* r, const sp_digit* a)
1672 {
1673     int i;
1674     sp_int128 n = a[33] >> 35;
1675     n += ((sp_int128)a[34]) << 26;
1676 
1677     for (i = 0; i < 33; i++) {
1678         r[i] = n & 0x1fffffffffffffffL;
1679         n >>= 61;
1680         n += ((sp_int128)a[35 + i]) << 26;
1681     }
1682     r[33] = (sp_digit)n;
1683     XMEMSET(&r[34], 0, sizeof(*r) * 34U);
1684 }
1685 
1686 /* Reduce the number back to 2048 bits using Montgomery reduction.
1687  *
1688  * a   A single precision number to reduce in place.
1689  * m   The single precision number representing the modulus.
1690  * mp  The digit representing the negative inverse of m mod 2^n.
1691  */
sp_2048_mont_reduce_34(sp_digit * a,const sp_digit * m,sp_digit mp)1692 static void sp_2048_mont_reduce_34(sp_digit* a, const sp_digit* m, sp_digit mp)
1693 {
1694     int i;
1695     sp_digit mu;
1696 
1697     sp_2048_norm_34(a + 34);
1698 
1699 #ifdef WOLFSSL_SP_DH
1700     if (mp != 1) {
1701         for (i=0; i<33; i++) {
1702             mu = (a[i] * mp) & 0x1fffffffffffffffL;
1703             sp_2048_mul_add_34(a+i, m, mu);
1704             a[i+1] += a[i] >> 61;
1705         }
1706         mu = (a[i] * mp) & 0x7ffffffffL;
1707         sp_2048_mul_add_34(a+i, m, mu);
1708         a[i+1] += a[i] >> 61;
1709         a[i] &= 0x1fffffffffffffffL;
1710     }
1711     else {
1712         for (i=0; i<33; i++) {
1713             mu = a[i] & 0x1fffffffffffffffL;
1714             sp_2048_mul_add_34(a+i, m, mu);
1715             a[i+1] += a[i] >> 61;
1716         }
1717         mu = a[i] & 0x7ffffffffL;
1718         sp_2048_mul_add_34(a+i, m, mu);
1719         a[i+1] += a[i] >> 61;
1720         a[i] &= 0x1fffffffffffffffL;
1721     }
1722 #else
1723     for (i=0; i<33; i++) {
1724         mu = (a[i] * mp) & 0x1fffffffffffffffL;
1725         sp_2048_mul_add_34(a+i, m, mu);
1726         a[i+1] += a[i] >> 61;
1727     }
1728     mu = (a[i] * mp) & 0x7ffffffffL;
1729     sp_2048_mul_add_34(a+i, m, mu);
1730     a[i+1] += a[i] >> 61;
1731     a[i] &= 0x1fffffffffffffffL;
1732 #endif
1733     sp_2048_mont_shift_34(a, a);
1734     sp_2048_cond_sub_34(a, a, m, 0 - (((a[33] - m[33]) > 0) ?
1735             (sp_digit)1 : (sp_digit)0));
1736     sp_2048_norm_34(a);
1737 }
1738 
1739 /* Multiply two Montgomery form numbers mod the modulus (prime).
1740  * (r = a * b mod m)
1741  *
1742  * r   Result of multiplication.
1743  * a   First number to multiply in Montgomery form.
1744  * b   Second number to multiply in Montgomery form.
1745  * m   Modulus (prime).
1746  * mp  Montgomery mulitplier.
1747  */
sp_2048_mont_mul_34(sp_digit * r,const sp_digit * a,const sp_digit * b,const sp_digit * m,sp_digit mp)1748 static void sp_2048_mont_mul_34(sp_digit* r, const sp_digit* a,
1749         const sp_digit* b, const sp_digit* m, sp_digit mp)
1750 {
1751     sp_2048_mul_34(r, a, b);
1752     sp_2048_mont_reduce_34(r, m, mp);
1753 }
1754 
1755 /* Square the Montgomery form number. (r = a * a mod m)
1756  *
1757  * r   Result of squaring.
1758  * a   Number to square in Montgomery form.
1759  * m   Modulus (prime).
1760  * mp  Montgomery mulitplier.
1761  */
sp_2048_mont_sqr_34(sp_digit * r,const sp_digit * a,const sp_digit * m,sp_digit mp)1762 static void sp_2048_mont_sqr_34(sp_digit* r, const sp_digit* a,
1763         const sp_digit* m, sp_digit mp)
1764 {
1765     sp_2048_sqr_34(r, a);
1766     sp_2048_mont_reduce_34(r, m, mp);
1767 }
1768 
1769 /* Multiply a by scalar b into r. (r = a * b)
1770  *
1771  * r  A single precision integer.
1772  * a  A single precision integer.
1773  * b  A scalar.
1774  */
sp_2048_mul_d_68(sp_digit * r,const sp_digit * a,sp_digit b)1775 SP_NOINLINE static void sp_2048_mul_d_68(sp_digit* r, const sp_digit* a,
1776     sp_digit b)
1777 {
1778     sp_int128 tb = b;
1779     sp_int128 t = 0;
1780     int i;
1781 
1782     for (i = 0; i < 68; i++) {
1783         t += tb * a[i];
1784         r[i] = (sp_digit)(t & 0x1fffffffffffffffL);
1785         t >>= 61;
1786     }
1787     r[68] = (sp_digit)t;
1788 }
1789 
1790 /* Conditionally add a and b using the mask m.
1791  * m is -1 to add and 0 when not.
1792  *
1793  * r  A single precision number representing conditional add result.
1794  * a  A single precision number to add with.
1795  * b  A single precision number to add.
1796  * m  Mask value to apply.
1797  */
sp_2048_cond_add_34(sp_digit * r,const sp_digit * a,const sp_digit * b,const sp_digit m)1798 static void sp_2048_cond_add_34(sp_digit* r, const sp_digit* a,
1799         const sp_digit* b, const sp_digit m)
1800 {
1801     int i;
1802 
1803     for (i = 0; i < 17; i++) {
1804         r[i] = a[i] + (b[i] & m);
1805     }
1806 }
1807 
1808 /* Add b to a into r. (r = a + b)
1809  *
1810  * r  A single precision integer.
1811  * a  A single precision integer.
1812  * b  A single precision integer.
1813  */
sp_2048_add_34(sp_digit * r,const sp_digit * a,const sp_digit * b)1814 SP_NOINLINE static int sp_2048_add_34(sp_digit* r, const sp_digit* a,
1815         const sp_digit* b)
1816 {
1817     int i;
1818 
1819     for (i = 0; i < 34; i++) {
1820         r[i] = a[i] + b[i];
1821     }
1822 
1823     return 0;
1824 }
1825 
sp_2048_rshift_34(sp_digit * r,const sp_digit * a,byte n)1826 SP_NOINLINE static void sp_2048_rshift_34(sp_digit* r, const sp_digit* a,
1827         byte n)
1828 {
1829     int i;
1830 
1831     for (i=0; i<33; i++) {
1832         r[i] = ((a[i] >> n) | (a[i + 1] << (61 - n))) & 0x1fffffffffffffffL;
1833     }
1834     r[33] = a[33] >> n;
1835 }
1836 
1837 #ifdef WOLFSSL_SP_DIV_64
sp_2048_div_word_34(sp_digit d1,sp_digit d0,sp_digit dv)1838 static WC_INLINE sp_digit sp_2048_div_word_34(sp_digit d1, sp_digit d0,
1839     sp_digit dv)
1840 {
1841     sp_digit d;
1842     sp_digit r;
1843     sp_digit t;
1844 
1845     /* All 61 bits from d1 and top 2 bits from d0. */
1846     d = (d1 << 2) + (d0 >> 59);
1847     r = d / dv;
1848     d -= r * dv;
1849     /* Up to 3 bits in r */
1850     /* Next 2 bits from d0. */
1851     r <<= 2;
1852     d <<= 2;
1853     d += (d0 >> 57) & ((1 << 2) - 1);
1854     t = d / dv;
1855     d -= t * dv;
1856     r += t;
1857     /* Up to 5 bits in r */
1858     /* Next 2 bits from d0. */
1859     r <<= 2;
1860     d <<= 2;
1861     d += (d0 >> 55) & ((1 << 2) - 1);
1862     t = d / dv;
1863     d -= t * dv;
1864     r += t;
1865     /* Up to 7 bits in r */
1866     /* Next 2 bits from d0. */
1867     r <<= 2;
1868     d <<= 2;
1869     d += (d0 >> 53) & ((1 << 2) - 1);
1870     t = d / dv;
1871     d -= t * dv;
1872     r += t;
1873     /* Up to 9 bits in r */
1874     /* Next 2 bits from d0. */
1875     r <<= 2;
1876     d <<= 2;
1877     d += (d0 >> 51) & ((1 << 2) - 1);
1878     t = d / dv;
1879     d -= t * dv;
1880     r += t;
1881     /* Up to 11 bits in r */
1882     /* Next 2 bits from d0. */
1883     r <<= 2;
1884     d <<= 2;
1885     d += (d0 >> 49) & ((1 << 2) - 1);
1886     t = d / dv;
1887     d -= t * dv;
1888     r += t;
1889     /* Up to 13 bits in r */
1890     /* Next 2 bits from d0. */
1891     r <<= 2;
1892     d <<= 2;
1893     d += (d0 >> 47) & ((1 << 2) - 1);
1894     t = d / dv;
1895     d -= t * dv;
1896     r += t;
1897     /* Up to 15 bits in r */
1898     /* Next 2 bits from d0. */
1899     r <<= 2;
1900     d <<= 2;
1901     d += (d0 >> 45) & ((1 << 2) - 1);
1902     t = d / dv;
1903     d -= t * dv;
1904     r += t;
1905     /* Up to 17 bits in r */
1906     /* Next 2 bits from d0. */
1907     r <<= 2;
1908     d <<= 2;
1909     d += (d0 >> 43) & ((1 << 2) - 1);
1910     t = d / dv;
1911     d -= t * dv;
1912     r += t;
1913     /* Up to 19 bits in r */
1914     /* Next 2 bits from d0. */
1915     r <<= 2;
1916     d <<= 2;
1917     d += (d0 >> 41) & ((1 << 2) - 1);
1918     t = d / dv;
1919     d -= t * dv;
1920     r += t;
1921     /* Up to 21 bits in r */
1922     /* Next 2 bits from d0. */
1923     r <<= 2;
1924     d <<= 2;
1925     d += (d0 >> 39) & ((1 << 2) - 1);
1926     t = d / dv;
1927     d -= t * dv;
1928     r += t;
1929     /* Up to 23 bits in r */
1930     /* Next 2 bits from d0. */
1931     r <<= 2;
1932     d <<= 2;
1933     d += (d0 >> 37) & ((1 << 2) - 1);
1934     t = d / dv;
1935     d -= t * dv;
1936     r += t;
1937     /* Up to 25 bits in r */
1938     /* Next 2 bits from d0. */
1939     r <<= 2;
1940     d <<= 2;
1941     d += (d0 >> 35) & ((1 << 2) - 1);
1942     t = d / dv;
1943     d -= t * dv;
1944     r += t;
1945     /* Up to 27 bits in r */
1946     /* Next 2 bits from d0. */
1947     r <<= 2;
1948     d <<= 2;
1949     d += (d0 >> 33) & ((1 << 2) - 1);
1950     t = d / dv;
1951     d -= t * dv;
1952     r += t;
1953     /* Up to 29 bits in r */
1954     /* Next 2 bits from d0. */
1955     r <<= 2;
1956     d <<= 2;
1957     d += (d0 >> 31) & ((1 << 2) - 1);
1958     t = d / dv;
1959     d -= t * dv;
1960     r += t;
1961     /* Up to 31 bits in r */
1962     /* Next 2 bits from d0. */
1963     r <<= 2;
1964     d <<= 2;
1965     d += (d0 >> 29) & ((1 << 2) - 1);
1966     t = d / dv;
1967     d -= t * dv;
1968     r += t;
1969     /* Up to 33 bits in r */
1970     /* Next 2 bits from d0. */
1971     r <<= 2;
1972     d <<= 2;
1973     d += (d0 >> 27) & ((1 << 2) - 1);
1974     t = d / dv;
1975     d -= t * dv;
1976     r += t;
1977     /* Up to 35 bits in r */
1978     /* Next 2 bits from d0. */
1979     r <<= 2;
1980     d <<= 2;
1981     d += (d0 >> 25) & ((1 << 2) - 1);
1982     t = d / dv;
1983     d -= t * dv;
1984     r += t;
1985     /* Up to 37 bits in r */
1986     /* Next 2 bits from d0. */
1987     r <<= 2;
1988     d <<= 2;
1989     d += (d0 >> 23) & ((1 << 2) - 1);
1990     t = d / dv;
1991     d -= t * dv;
1992     r += t;
1993     /* Up to 39 bits in r */
1994     /* Next 2 bits from d0. */
1995     r <<= 2;
1996     d <<= 2;
1997     d += (d0 >> 21) & ((1 << 2) - 1);
1998     t = d / dv;
1999     d -= t * dv;
2000     r += t;
2001     /* Up to 41 bits in r */
2002     /* Next 2 bits from d0. */
2003     r <<= 2;
2004     d <<= 2;
2005     d += (d0 >> 19) & ((1 << 2) - 1);
2006     t = d / dv;
2007     d -= t * dv;
2008     r += t;
2009     /* Up to 43 bits in r */
2010     /* Next 2 bits from d0. */
2011     r <<= 2;
2012     d <<= 2;
2013     d += (d0 >> 17) & ((1 << 2) - 1);
2014     t = d / dv;
2015     d -= t * dv;
2016     r += t;
2017     /* Up to 45 bits in r */
2018     /* Next 2 bits from d0. */
2019     r <<= 2;
2020     d <<= 2;
2021     d += (d0 >> 15) & ((1 << 2) - 1);
2022     t = d / dv;
2023     d -= t * dv;
2024     r += t;
2025     /* Up to 47 bits in r */
2026     /* Next 2 bits from d0. */
2027     r <<= 2;
2028     d <<= 2;
2029     d += (d0 >> 13) & ((1 << 2) - 1);
2030     t = d / dv;
2031     d -= t * dv;
2032     r += t;
2033     /* Up to 49 bits in r */
2034     /* Next 2 bits from d0. */
2035     r <<= 2;
2036     d <<= 2;
2037     d += (d0 >> 11) & ((1 << 2) - 1);
2038     t = d / dv;
2039     d -= t * dv;
2040     r += t;
2041     /* Up to 51 bits in r */
2042     /* Next 2 bits from d0. */
2043     r <<= 2;
2044     d <<= 2;
2045     d += (d0 >> 9) & ((1 << 2) - 1);
2046     t = d / dv;
2047     d -= t * dv;
2048     r += t;
2049     /* Up to 53 bits in r */
2050     /* Next 2 bits from d0. */
2051     r <<= 2;
2052     d <<= 2;
2053     d += (d0 >> 7) & ((1 << 2) - 1);
2054     t = d / dv;
2055     d -= t * dv;
2056     r += t;
2057     /* Up to 55 bits in r */
2058     /* Next 2 bits from d0. */
2059     r <<= 2;
2060     d <<= 2;
2061     d += (d0 >> 5) & ((1 << 2) - 1);
2062     t = d / dv;
2063     d -= t * dv;
2064     r += t;
2065     /* Up to 57 bits in r */
2066     /* Next 2 bits from d0. */
2067     r <<= 2;
2068     d <<= 2;
2069     d += (d0 >> 3) & ((1 << 2) - 1);
2070     t = d / dv;
2071     d -= t * dv;
2072     r += t;
2073     /* Up to 59 bits in r */
2074     /* Next 2 bits from d0. */
2075     r <<= 2;
2076     d <<= 2;
2077     d += (d0 >> 1) & ((1 << 2) - 1);
2078     t = d / dv;
2079     d -= t * dv;
2080     r += t;
2081     /* Up to 61 bits in r */
2082     /* Remaining 1 bits from d0. */
2083     r <<= 1;
2084     d <<= 1;
2085     d += d0 & ((1 << 1) - 1);
2086     t = d / dv;
2087     r += t;
2088 
2089     /* All 61 bits from d1 and top 2 bits from d0. */
2090     return r;
2091 }
2092 #endif /* WOLFSSL_SP_DIV_64 */
2093 
2094 /* Divide d in a and put remainder into r (m*d + r = a)
2095  * m is not calculated as it is not needed at this time.
2096  *
2097  * Full implementation.
2098  *
2099  * a  Number to be divided.
2100  * d  Number to divide with.
2101  * m  Multiplier result.
2102  * r  Remainder from the division.
2103  * returns MEMORY_E when unable to allocate memory and MP_OKAY otherwise.
2104  */
sp_2048_div_34(const sp_digit * a,const sp_digit * d,const sp_digit * m,sp_digit * r)2105 static int sp_2048_div_34(const sp_digit* a, const sp_digit* d,
2106         const sp_digit* m, sp_digit* r)
2107 {
2108     int i;
2109 #ifndef WOLFSSL_SP_DIV_64
2110     sp_int128 d1;
2111 #endif
2112     sp_digit dv;
2113     sp_digit r1;
2114 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
2115     sp_digit* t1 = NULL;
2116 #else
2117     sp_digit t1[4 * 34 + 3];
2118 #endif
2119     sp_digit* t2 = NULL;
2120     sp_digit* sd = NULL;
2121     int err = MP_OKAY;
2122 
2123     (void)m;
2124 
2125 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
2126     t1 = (sp_digit*)XMALLOC(sizeof(sp_digit) * (4 * 34 + 3), NULL,
2127                                                        DYNAMIC_TYPE_TMP_BUFFER);
2128     if (t1 == NULL)
2129         err = MEMORY_E;
2130 #endif
2131 
2132     (void)m;
2133 
2134     if (err == MP_OKAY) {
2135         t2 = t1 + 68 + 1;
2136         sd = t2 + 34 + 1;
2137 
2138         sp_2048_mul_d_34(sd, d, (sp_digit)1 << 26);
2139         sp_2048_mul_d_68(t1, a, (sp_digit)1 << 26);
2140         dv = sd[33];
2141         t1[34 + 34] += t1[34 + 34 - 1] >> 61;
2142         t1[34 + 34 - 1] &= 0x1fffffffffffffffL;
2143         for (i=34; i>=0; i--) {
2144 #ifndef WOLFSSL_SP_DIV_64
2145             d1 = t1[34 + i];
2146             d1 <<= 61;
2147             d1 += t1[34 + i - 1];
2148             r1 = (sp_digit)(d1 / dv);
2149 #else
2150             r1 = sp_2048_div_word_34(t1[34 + i], t1[34 + i - 1], dv);
2151 #endif
2152 
2153             sp_2048_mul_d_34(t2, sd, r1);
2154             (void)sp_2048_sub_34(&t1[i], &t1[i], t2);
2155             sp_2048_norm_34(&t1[i]);
2156             t1[34 + i] -= t2[34];
2157             t1[34 + i] += t1[34 + i - 1] >> 61;
2158             t1[34 + i - 1] &= 0x1fffffffffffffffL;
2159 #ifndef WOLFSSL_SP_DIV_64
2160             d1 = -t1[34 + i];
2161             d1 <<= 61;
2162             d1 -= t1[34 + i - 1];
2163             r1 = (sp_digit)(d1 / dv);
2164 #else
2165             r1 = sp_2048_div_word_34(-t1[34 + i], -t1[34 + i - 1], dv);
2166 #endif
2167             r1 -= t1[34 + i];
2168             sp_2048_mul_d_34(t2, sd, r1);
2169             (void)sp_2048_add_34(&t1[i], &t1[i], t2);
2170             t1[34 + i] += t1[34 + i - 1] >> 61;
2171             t1[34 + i - 1] &= 0x1fffffffffffffffL;
2172         }
2173         t1[34 - 1] += t1[34 - 2] >> 61;
2174         t1[34 - 2] &= 0x1fffffffffffffffL;
2175         r1 = t1[34 - 1] / dv;
2176 
2177         sp_2048_mul_d_34(t2, sd, r1);
2178         sp_2048_sub_34(t1, t1, t2);
2179         XMEMCPY(r, t1, sizeof(*r) * 68U);
2180         for (i=0; i<33; i++) {
2181             r[i+1] += r[i] >> 61;
2182             r[i] &= 0x1fffffffffffffffL;
2183         }
2184         sp_2048_cond_add_34(r, r, sd, 0 - ((r[33] < 0) ?
2185                     (sp_digit)1 : (sp_digit)0));
2186 
2187         sp_2048_norm_34(r);
2188         sp_2048_rshift_34(r, r, 26);
2189     }
2190 
2191 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
2192     if (t1 != NULL)
2193         XFREE(t1, NULL, DYNAMIC_TYPE_TMP_BUFFER);
2194 #endif
2195 
2196     return err;
2197 }
2198 
2199 /* Reduce a modulo m into r. (r = a mod m)
2200  *
2201  * r  A single precision number that is the reduced result.
2202  * a  A single precision number that is to be reduced.
2203  * m  A single precision number that is the modulus to reduce with.
2204  * returns MEMORY_E when unable to allocate memory and MP_OKAY otherwise.
2205  */
sp_2048_mod_34(sp_digit * r,const sp_digit * a,const sp_digit * m)2206 static int sp_2048_mod_34(sp_digit* r, const sp_digit* a, const sp_digit* m)
2207 {
2208     return sp_2048_div_34(a, m, NULL, r);
2209 }
2210 
2211 #if (defined(WOLFSSL_HAVE_SP_RSA) && !defined(WOLFSSL_RSA_PUBLIC_ONLY)) || defined(WOLFSSL_HAVE_SP_DH)
2212 /* Modular exponentiate a to the e mod m. (r = a^e mod m)
2213  *
2214  * r     A single precision number that is the result of the operation.
2215  * a     A single precision number being exponentiated.
2216  * e     A single precision number that is the exponent.
2217  * bits  The number of bits in the exponent.
2218  * m     A single precision number that is the modulus.
2219  * returns  0 on success.
2220  * returns  MEMORY_E on dynamic memory allocation failure.
2221  * returns  MP_VAL when base is even or exponent is 0.
2222  */
sp_2048_mod_exp_34(sp_digit * r,const sp_digit * a,const sp_digit * e,int bits,const sp_digit * m,int reduceA)2223 static int sp_2048_mod_exp_34(sp_digit* r, const sp_digit* a, const sp_digit* e,
2224     int bits, const sp_digit* m, int reduceA)
2225 {
2226 #if defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SP_FAST_MODEXP)
2227 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
2228     sp_digit* td = NULL;
2229 #else
2230     sp_digit td[3 * 68];
2231 #endif
2232     sp_digit* t[3] = {0, 0, 0};
2233     sp_digit* norm = NULL;
2234     sp_digit mp = 1;
2235     sp_digit n;
2236     int i;
2237     int c;
2238     byte y;
2239     int err = MP_OKAY;
2240 
2241     if ((m[0] & 1) == 0) {
2242         err = MP_VAL;
2243     }
2244     else if (bits == 0) {
2245         err = MP_VAL;
2246     }
2247 
2248 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
2249     if (err == MP_OKAY) {
2250         td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 3 * 34 * 2, NULL,
2251                                 DYNAMIC_TYPE_TMP_BUFFER);
2252         if (td == NULL)
2253             err = MEMORY_E;
2254     }
2255 #endif
2256 
2257     if (err == MP_OKAY) {
2258         norm = td;
2259         for (i=0; i<3; i++) {
2260             t[i] = td + (i * 34 * 2);
2261             XMEMSET(t[i], 0, sizeof(sp_digit) * 34U * 2U);
2262         }
2263 
2264         sp_2048_mont_setup(m, &mp);
2265         sp_2048_mont_norm_34(norm, m);
2266 
2267         if (reduceA != 0) {
2268             err = sp_2048_mod_34(t[1], a, m);
2269         }
2270         else {
2271             XMEMCPY(t[1], a, sizeof(sp_digit) * 34U);
2272         }
2273     }
2274     if (err == MP_OKAY) {
2275         sp_2048_mul_34(t[1], t[1], norm);
2276         err = sp_2048_mod_34(t[1], t[1], m);
2277     }
2278 
2279     if (err == MP_OKAY) {
2280         i = bits / 61;
2281         c = bits % 61;
2282         n = e[i--] << (61 - c);
2283         for (; ; c--) {
2284             if (c == 0) {
2285                 if (i == -1) {
2286                     break;
2287                 }
2288 
2289                 n = e[i--];
2290                 c = 61;
2291             }
2292 
2293             y = (int)((n >> 60) & 1);
2294             n <<= 1;
2295 
2296             sp_2048_mont_mul_34(t[y^1], t[0], t[1], m, mp);
2297 
2298             XMEMCPY(t[2], (void*)(((size_t)t[0] & addr_mask[y^1]) +
2299                                   ((size_t)t[1] & addr_mask[y])),
2300                                   sizeof(*t[2]) * 34 * 2);
2301             sp_2048_mont_sqr_34(t[2], t[2], m, mp);
2302             XMEMCPY((void*)(((size_t)t[0] & addr_mask[y^1]) +
2303                             ((size_t)t[1] & addr_mask[y])), t[2],
2304                             sizeof(*t[2]) * 34 * 2);
2305         }
2306 
2307         sp_2048_mont_reduce_34(t[0], m, mp);
2308         n = sp_2048_cmp_34(t[0], m);
2309         sp_2048_cond_sub_34(t[0], t[0], m, ((n < 0) ?
2310                     (sp_digit)1 : (sp_digit)0) - 1);
2311         XMEMCPY(r, t[0], sizeof(*r) * 34 * 2);
2312 
2313     }
2314 
2315 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
2316     if (td != NULL)
2317         XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);
2318 #endif
2319 
2320     return err;
2321 #elif !defined(WC_NO_CACHE_RESISTANT)
2322 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
2323     sp_digit* td = NULL;
2324 #else
2325     sp_digit td[3 * 68];
2326 #endif
2327     sp_digit* t[3] = {0, 0, 0};
2328     sp_digit* norm = NULL;
2329     sp_digit mp = 1;
2330     sp_digit n;
2331     int i;
2332     int c;
2333     byte y;
2334     int err = MP_OKAY;
2335 
2336     if ((m[0] & 1) == 0) {
2337         err = MP_VAL;
2338     }
2339     else if (bits == 0) {
2340         err = MP_VAL;
2341     }
2342 
2343 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
2344     if (err == MP_OKAY) {
2345         td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 3 * 34 * 2, NULL,
2346                                 DYNAMIC_TYPE_TMP_BUFFER);
2347         if (td == NULL)
2348             err = MEMORY_E;
2349     }
2350 #endif
2351 
2352     if (err == MP_OKAY) {
2353         norm = td;
2354         for (i=0; i<3; i++) {
2355             t[i] = td + (i * 34 * 2);
2356         }
2357 
2358         sp_2048_mont_setup(m, &mp);
2359         sp_2048_mont_norm_34(norm, m);
2360 
2361         if (reduceA != 0) {
2362             err = sp_2048_mod_34(t[1], a, m);
2363             if (err == MP_OKAY) {
2364                 sp_2048_mul_34(t[1], t[1], norm);
2365                 err = sp_2048_mod_34(t[1], t[1], m);
2366             }
2367         }
2368         else {
2369             sp_2048_mul_34(t[1], a, norm);
2370             err = sp_2048_mod_34(t[1], t[1], m);
2371         }
2372     }
2373 
2374     if (err == MP_OKAY) {
2375         i = bits / 61;
2376         c = bits % 61;
2377         n = e[i--] << (61 - c);
2378         for (; ; c--) {
2379             if (c == 0) {
2380                 if (i == -1) {
2381                     break;
2382                 }
2383 
2384                 n = e[i--];
2385                 c = 61;
2386             }
2387 
2388             y = (int)((n >> 60) & 1);
2389             n <<= 1;
2390 
2391             sp_2048_mont_mul_34(t[y^1], t[0], t[1], m, mp);
2392 
2393             XMEMCPY(t[2], (void*)(((size_t)t[0] & addr_mask[y^1]) +
2394                                   ((size_t)t[1] & addr_mask[y])),
2395                                   sizeof(*t[2]) * 34 * 2);
2396             sp_2048_mont_sqr_34(t[2], t[2], m, mp);
2397             XMEMCPY((void*)(((size_t)t[0] & addr_mask[y^1]) +
2398                             ((size_t)t[1] & addr_mask[y])), t[2],
2399                             sizeof(*t[2]) * 34 * 2);
2400         }
2401 
2402         sp_2048_mont_reduce_34(t[0], m, mp);
2403         n = sp_2048_cmp_34(t[0], m);
2404         sp_2048_cond_sub_34(t[0], t[0], m, ((n < 0) ?
2405                     (sp_digit)1 : (sp_digit)0) - 1);
2406         XMEMCPY(r, t[0], sizeof(*r) * 34 * 2);
2407     }
2408 
2409 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
2410     if (td != NULL)
2411         XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);
2412 #endif
2413 
2414     return err;
2415 #else
2416 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
2417     sp_digit* td = NULL;
2418 #else
2419     sp_digit td[(16 * 68) + 68];
2420 #endif
2421     sp_digit* t[16];
2422     sp_digit* rt = NULL;
2423     sp_digit* norm = NULL;
2424     sp_digit mp = 1;
2425     sp_digit n;
2426     int i;
2427     int c;
2428     byte y;
2429     int err = MP_OKAY;
2430 
2431     if ((m[0] & 1) == 0) {
2432         err = MP_VAL;
2433     }
2434     else if (bits == 0) {
2435         err = MP_VAL;
2436     }
2437 
2438 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
2439     if (err == MP_OKAY) {
2440         td = (sp_digit*)XMALLOC(sizeof(sp_digit) * ((16 * 68) + 68), NULL,
2441                                 DYNAMIC_TYPE_TMP_BUFFER);
2442         if (td == NULL)
2443             err = MEMORY_E;
2444     }
2445 #endif
2446 
2447     if (err == MP_OKAY) {
2448         norm = td;
2449         for (i=0; i<16; i++)
2450             t[i] = td + i * 68;
2451         rt = td + 1088;
2452 
2453         sp_2048_mont_setup(m, &mp);
2454         sp_2048_mont_norm_34(norm, m);
2455 
2456         if (reduceA != 0) {
2457             err = sp_2048_mod_34(t[1], a, m);
2458             if (err == MP_OKAY) {
2459                 sp_2048_mul_34(t[1], t[1], norm);
2460                 err = sp_2048_mod_34(t[1], t[1], m);
2461             }
2462         }
2463         else {
2464             sp_2048_mul_34(t[1], a, norm);
2465             err = sp_2048_mod_34(t[1], t[1], m);
2466         }
2467     }
2468 
2469     if (err == MP_OKAY) {
2470         sp_2048_mont_sqr_34(t[ 2], t[ 1], m, mp);
2471         sp_2048_mont_mul_34(t[ 3], t[ 2], t[ 1], m, mp);
2472         sp_2048_mont_sqr_34(t[ 4], t[ 2], m, mp);
2473         sp_2048_mont_mul_34(t[ 5], t[ 3], t[ 2], m, mp);
2474         sp_2048_mont_sqr_34(t[ 6], t[ 3], m, mp);
2475         sp_2048_mont_mul_34(t[ 7], t[ 4], t[ 3], m, mp);
2476         sp_2048_mont_sqr_34(t[ 8], t[ 4], m, mp);
2477         sp_2048_mont_mul_34(t[ 9], t[ 5], t[ 4], m, mp);
2478         sp_2048_mont_sqr_34(t[10], t[ 5], m, mp);
2479         sp_2048_mont_mul_34(t[11], t[ 6], t[ 5], m, mp);
2480         sp_2048_mont_sqr_34(t[12], t[ 6], m, mp);
2481         sp_2048_mont_mul_34(t[13], t[ 7], t[ 6], m, mp);
2482         sp_2048_mont_sqr_34(t[14], t[ 7], m, mp);
2483         sp_2048_mont_mul_34(t[15], t[ 8], t[ 7], m, mp);
2484 
2485         bits = ((bits + 3) / 4) * 4;
2486         i = ((bits + 60) / 61) - 1;
2487         c = bits % 61;
2488         if (c == 0) {
2489             c = 61;
2490         }
2491         if (i < 34) {
2492             n = e[i--] << (64 - c);
2493         }
2494         else {
2495             n = 0;
2496             i--;
2497         }
2498         if (c < 4) {
2499             n |= e[i--] << (3 - c);
2500             c += 61;
2501         }
2502         y = (int)((n >> 60) & 0xf);
2503         n <<= 4;
2504         c -= 4;
2505         XMEMCPY(rt, t[y], sizeof(sp_digit) * 68);
2506         while ((i >= 0) || (c >= 4)) {
2507             if (c >= 4) {
2508                 y = (byte)((n >> 60) & 0xf);
2509                 n <<= 4;
2510                 c -= 4;
2511             }
2512             else if (c == 0) {
2513                 n = e[i--] << 3;
2514                 y = (byte)((n >> 60) & 0xf);
2515                 n <<= 4;
2516                 c = 57;
2517             }
2518             else {
2519                 y = (byte)((n >> 60) & 0xf);
2520                 n = e[i--] << 3;
2521                 c = 4 - c;
2522                 y |= (byte)((n >> (64 - c)) & ((1 << c) - 1));
2523                 n <<= c;
2524                 c = 61 - c;
2525             }
2526 
2527             sp_2048_mont_sqr_34(rt, rt, m, mp);
2528             sp_2048_mont_sqr_34(rt, rt, m, mp);
2529             sp_2048_mont_sqr_34(rt, rt, m, mp);
2530             sp_2048_mont_sqr_34(rt, rt, m, mp);
2531 
2532             sp_2048_mont_mul_34(rt, rt, t[y], m, mp);
2533         }
2534 
2535         sp_2048_mont_reduce_34(rt, m, mp);
2536         n = sp_2048_cmp_34(rt, m);
2537         sp_2048_cond_sub_34(rt, rt, m, ((n < 0) ?
2538                    (sp_digit)1 : (sp_digit)0) - 1);
2539         XMEMCPY(r, rt, sizeof(sp_digit) * 68);
2540     }
2541 
2542 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
2543     if (td != NULL)
2544         XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);
2545 #endif
2546 
2547     return err;
2548 #endif
2549 }
2550 
2551 #endif /* (WOLFSSL_HAVE_SP_RSA && !WOLFSSL_RSA_PUBLIC_ONLY) || WOLFSSL_HAVE_SP_DH */
2552 #ifdef WOLFSSL_HAVE_SP_RSA
2553 /* RSA public key operation.
2554  *
2555  * in      Array of bytes representing the number to exponentiate, base.
2556  * inLen   Number of bytes in base.
2557  * em      Public exponent.
2558  * mm      Modulus.
2559  * out     Buffer to hold big-endian bytes of exponentiation result.
2560  *         Must be at least 256 bytes long.
2561  * outLen  Number of bytes in result.
2562  * returns 0 on success, MP_TO_E when the outLen is too small, MP_READ_E when
2563  * an array is too long and MEMORY_E when dynamic memory allocation fails.
2564  */
sp_RsaPublic_2048(const byte * in,word32 inLen,const mp_int * em,const mp_int * mm,byte * out,word32 * outLen)2565 int sp_RsaPublic_2048(const byte* in, word32 inLen, const mp_int* em,
2566     const mp_int* mm, byte* out, word32* outLen)
2567 {
2568 #ifdef WOLFSSL_SP_SMALL
2569 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
2570     sp_digit* a = NULL;
2571 #else
2572     sp_digit a[34 * 5];
2573 #endif
2574     sp_digit* m = NULL;
2575     sp_digit* r = NULL;
2576     sp_digit* norm = NULL;
2577     sp_digit e[1] = {0};
2578     sp_digit mp;
2579     int i;
2580     int err = MP_OKAY;
2581 
2582     if (*outLen < 256U) {
2583         err = MP_TO_E;
2584     }
2585 
2586     if (err == MP_OKAY) {
2587         if (mp_count_bits(em) > 61) {
2588             err = MP_READ_E;
2589         }
2590         else if (inLen > 256U) {
2591             err = MP_READ_E;
2592         }
2593         else if (mp_count_bits(mm) != 2048) {
2594             err = MP_READ_E;
2595         }
2596         else if (mp_iseven(mm)) {
2597             err = MP_VAL;
2598         }
2599     }
2600 
2601 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
2602     if (err == MP_OKAY) {
2603         a = (sp_digit*)XMALLOC(sizeof(sp_digit) * 34 * 5, NULL,
2604                                                               DYNAMIC_TYPE_RSA);
2605         if (a == NULL)
2606             err = MEMORY_E;
2607     }
2608 #endif
2609 
2610     if (err == MP_OKAY) {
2611         r = a + 34 * 2;
2612         m = r + 34 * 2;
2613         norm = r;
2614 
2615         sp_2048_from_bin(a, 34, in, inLen);
2616 #if DIGIT_BIT >= 61
2617         e[0] = (sp_digit)em->dp[0];
2618 #else
2619         e[0] = (sp_digit)em->dp[0];
2620         if (em->used > 1) {
2621             e[0] |= ((sp_digit)em->dp[1]) << DIGIT_BIT;
2622         }
2623 #endif
2624         if (e[0] == 0) {
2625             err = MP_EXPTMOD_E;
2626         }
2627     }
2628 
2629     if (err == MP_OKAY) {
2630         sp_2048_from_mp(m, 34, mm);
2631 
2632         sp_2048_mont_setup(m, &mp);
2633         sp_2048_mont_norm_34(norm, m);
2634     }
2635     if (err == MP_OKAY) {
2636         sp_2048_mul_34(a, a, norm);
2637         err = sp_2048_mod_34(a, a, m);
2638     }
2639     if (err == MP_OKAY) {
2640         for (i=60; i>=0; i--) {
2641             if ((e[0] >> i) != 0) {
2642                 break;
2643             }
2644         }
2645 
2646         XMEMCPY(r, a, sizeof(sp_digit) * 34 * 2);
2647         for (i--; i>=0; i--) {
2648             sp_2048_mont_sqr_34(r, r, m, mp);
2649 
2650             if (((e[0] >> i) & 1) == 1) {
2651                 sp_2048_mont_mul_34(r, r, a, m, mp);
2652             }
2653         }
2654         sp_2048_mont_reduce_34(r, m, mp);
2655         mp = sp_2048_cmp_34(r, m);
2656         sp_2048_cond_sub_34(r, r, m, ((mp < 0) ?
2657                     (sp_digit)1 : (sp_digit)0)- 1);
2658 
2659         sp_2048_to_bin_34(r, out);
2660         *outLen = 256;
2661     }
2662 
2663 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
2664     if (a != NULL)
2665         XFREE(a, NULL, DYNAMIC_TYPE_RSA);
2666 #endif
2667 
2668     return err;
2669 #else
2670 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
2671     sp_digit* d = NULL;
2672 #else
2673     sp_digit d[34 * 5];
2674 #endif
2675     sp_digit* a = NULL;
2676     sp_digit* m = NULL;
2677     sp_digit* r = NULL;
2678     sp_digit e[1] = {0};
2679     int err = MP_OKAY;
2680 
2681     if (*outLen < 256U) {
2682         err = MP_TO_E;
2683     }
2684     if (err == MP_OKAY) {
2685         if (mp_count_bits(em) > 61) {
2686             err = MP_READ_E;
2687         }
2688         else if (inLen > 256U) {
2689             err = MP_READ_E;
2690         }
2691         else if (mp_count_bits(mm) != 2048) {
2692             err = MP_READ_E;
2693         }
2694         else if (mp_iseven(mm)) {
2695             err = MP_VAL;
2696         }
2697     }
2698 
2699 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
2700     if (err == MP_OKAY) {
2701         d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 34 * 5, NULL,
2702                                                               DYNAMIC_TYPE_RSA);
2703         if (d == NULL)
2704             err = MEMORY_E;
2705     }
2706 #endif
2707 
2708     if (err == MP_OKAY) {
2709         a = d;
2710         r = a + 34 * 2;
2711         m = r + 34 * 2;
2712 
2713         sp_2048_from_bin(a, 34, in, inLen);
2714 #if DIGIT_BIT >= 61
2715         e[0] = (sp_digit)em->dp[0];
2716 #else
2717         e[0] = (sp_digit)em->dp[0];
2718         if (em->used > 1) {
2719             e[0] |= ((sp_digit)em->dp[1]) << DIGIT_BIT;
2720         }
2721 #endif
2722         if (e[0] == 0) {
2723             err = MP_EXPTMOD_E;
2724         }
2725     }
2726     if (err == MP_OKAY) {
2727         sp_2048_from_mp(m, 34, mm);
2728 
2729         if (e[0] == 0x3) {
2730             sp_2048_sqr_34(r, a);
2731             err = sp_2048_mod_34(r, r, m);
2732             if (err == MP_OKAY) {
2733                 sp_2048_mul_34(r, a, r);
2734                 err = sp_2048_mod_34(r, r, m);
2735             }
2736         }
2737         else {
2738             sp_digit* norm = r;
2739             int i;
2740             sp_digit mp;
2741 
2742             sp_2048_mont_setup(m, &mp);
2743             sp_2048_mont_norm_34(norm, m);
2744 
2745             sp_2048_mul_34(a, a, norm);
2746             err = sp_2048_mod_34(a, a, m);
2747 
2748             if (err == MP_OKAY) {
2749                 for (i=60; i>=0; i--) {
2750                     if ((e[0] >> i) != 0) {
2751                         break;
2752                     }
2753                 }
2754 
2755                 XMEMCPY(r, a, sizeof(sp_digit) * 68U);
2756                 for (i--; i>=0; i--) {
2757                     sp_2048_mont_sqr_34(r, r, m, mp);
2758 
2759                     if (((e[0] >> i) & 1) == 1) {
2760                         sp_2048_mont_mul_34(r, r, a, m, mp);
2761                     }
2762                 }
2763                 sp_2048_mont_reduce_34(r, m, mp);
2764                 mp = sp_2048_cmp_34(r, m);
2765                 sp_2048_cond_sub_34(r, r, m, ((mp < 0) ?
2766                            (sp_digit)1 : (sp_digit)0) - 1);
2767             }
2768         }
2769     }
2770 
2771     if (err == MP_OKAY) {
2772         sp_2048_to_bin_34(r, out);
2773         *outLen = 256;
2774     }
2775 
2776 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
2777     if (d != NULL)
2778         XFREE(d, NULL, DYNAMIC_TYPE_RSA);
2779 #endif
2780 
2781     return err;
2782 #endif /* WOLFSSL_SP_SMALL */
2783 }
2784 
2785 #ifndef WOLFSSL_RSA_PUBLIC_ONLY
2786 #if !defined(SP_RSA_PRIVATE_EXP_D) && !defined(RSA_LOW_MEM)
2787 #endif /* !SP_RSA_PRIVATE_EXP_D & !RSA_LOW_MEM */
2788 /* RSA private key operation.
2789  *
2790  * in      Array of bytes representing the number to exponentiate, base.
2791  * inLen   Number of bytes in base.
2792  * dm      Private exponent.
2793  * pm      First prime.
2794  * qm      Second prime.
2795  * dpm     First prime's CRT exponent.
2796  * dqm     Second prime's CRT exponent.
2797  * qim     Inverse of second prime mod p.
2798  * mm      Modulus.
2799  * out     Buffer to hold big-endian bytes of exponentiation result.
2800  *         Must be at least 256 bytes long.
2801  * outLen  Number of bytes in result.
2802  * returns 0 on success, MP_TO_E when the outLen is too small, MP_READ_E when
2803  * an array is too long and MEMORY_E when dynamic memory allocation fails.
2804  */
sp_RsaPrivate_2048(const byte * in,word32 inLen,const mp_int * dm,const mp_int * pm,const mp_int * qm,const mp_int * dpm,const mp_int * dqm,const mp_int * qim,const mp_int * mm,byte * out,word32 * outLen)2805 int sp_RsaPrivate_2048(const byte* in, word32 inLen, const mp_int* dm,
2806     const mp_int* pm, const mp_int* qm, const mp_int* dpm, const mp_int* dqm,
2807     const mp_int* qim, const mp_int* mm, byte* out, word32* outLen)
2808 {
2809 #if defined(SP_RSA_PRIVATE_EXP_D) || defined(RSA_LOW_MEM)
2810 #if defined(WOLFSSL_SP_SMALL)
2811 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
2812     sp_digit* d = NULL;
2813 #else
2814     sp_digit  d[34 * 4];
2815 #endif
2816     sp_digit* a = NULL;
2817     sp_digit* m = NULL;
2818     sp_digit* r = NULL;
2819     int err = MP_OKAY;
2820 
2821     (void)pm;
2822     (void)qm;
2823     (void)dpm;
2824     (void)dqm;
2825     (void)qim;
2826 
2827     if (*outLen < 256U) {
2828         err = MP_TO_E;
2829     }
2830     if (err == MP_OKAY) {
2831         if (mp_count_bits(dm) > 2048) {
2832            err = MP_READ_E;
2833         }
2834         else if (inLen > 256) {
2835             err = MP_READ_E;
2836         }
2837         else if (mp_count_bits(mm) != 2048) {
2838             err = MP_READ_E;
2839         }
2840         else if (mp_iseven(mm)) {
2841             err = MP_VAL;
2842         }
2843     }
2844 
2845 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
2846     if (err == MP_OKAY) {
2847         d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 34 * 4, NULL,
2848                                                               DYNAMIC_TYPE_RSA);
2849         if (d == NULL)
2850             err = MEMORY_E;
2851     }
2852 #endif
2853 
2854     if (err == MP_OKAY) {
2855         a = d + 34;
2856         m = a + 68;
2857         r = a;
2858 
2859         sp_2048_from_bin(a, 34, in, inLen);
2860         sp_2048_from_mp(d, 34, dm);
2861         sp_2048_from_mp(m, 34, mm);
2862         err = sp_2048_mod_exp_34(r, a, d, 2048, m, 0);
2863     }
2864 
2865     if (err == MP_OKAY) {
2866         sp_2048_to_bin_34(r, out);
2867         *outLen = 256;
2868     }
2869 
2870 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
2871     if (d != NULL)
2872 #endif
2873     {
2874         /* only "a" and "r" are sensitive and need zeroized (same pointer) */
2875         if (a != NULL)
2876             ForceZero(a, sizeof(sp_digit) * 34);
2877 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
2878         XFREE(d, NULL, DYNAMIC_TYPE_RSA);
2879 #endif
2880     }
2881 
2882     return err;
2883 #else
2884 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
2885     sp_digit* d = NULL;
2886 #else
2887     sp_digit d[34 * 4];
2888 #endif
2889     sp_digit* a = NULL;
2890     sp_digit* m = NULL;
2891     sp_digit* r = NULL;
2892     int err = MP_OKAY;
2893 
2894     (void)pm;
2895     (void)qm;
2896     (void)dpm;
2897     (void)dqm;
2898     (void)qim;
2899 
2900     if (*outLen < 256U) {
2901         err = MP_TO_E;
2902     }
2903     if (err == MP_OKAY) {
2904         if (mp_count_bits(dm) > 2048) {
2905             err = MP_READ_E;
2906         }
2907         else if (inLen > 256U) {
2908             err = MP_READ_E;
2909         }
2910         else if (mp_count_bits(mm) != 2048) {
2911             err = MP_READ_E;
2912         }
2913         else if (mp_iseven(mm)) {
2914             err = MP_VAL;
2915         }
2916     }
2917 
2918 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
2919     if (err == MP_OKAY) {
2920         d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 34 * 4, NULL,
2921                                                               DYNAMIC_TYPE_RSA);
2922         if (d == NULL)
2923             err = MEMORY_E;
2924     }
2925 #endif
2926 
2927     if (err == MP_OKAY) {
2928         a = d + 34;
2929         m = a + 68;
2930         r = a;
2931 
2932         sp_2048_from_bin(a, 34, in, inLen);
2933         sp_2048_from_mp(d, 34, dm);
2934         sp_2048_from_mp(m, 34, mm);
2935         err = sp_2048_mod_exp_34(r, a, d, 2048, m, 0);
2936     }
2937 
2938     if (err == MP_OKAY) {
2939         sp_2048_to_bin_34(r, out);
2940         *outLen = 256;
2941     }
2942 
2943 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
2944     if (d != NULL)
2945 #endif
2946     {
2947         /* only "a" and "r" are sensitive and need zeroized (same pointer) */
2948         if (a != NULL)
2949             ForceZero(a, sizeof(sp_digit) * 34);
2950 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
2951         XFREE(d, NULL, DYNAMIC_TYPE_RSA);
2952 #endif
2953     }
2954 
2955     return err;
2956 #endif /* WOLFSSL_SP_SMALL */
2957 #else
2958 #if defined(WOLFSSL_SP_SMALL)
2959 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
2960     sp_digit* a = NULL;
2961 #else
2962     sp_digit a[17 * 8];
2963 #endif
2964     sp_digit* p = NULL;
2965     sp_digit* dp = NULL;
2966     sp_digit* dq = NULL;
2967     sp_digit* qi = NULL;
2968     sp_digit* tmpa = NULL;
2969     sp_digit* tmpb = NULL;
2970     sp_digit* r = NULL;
2971     int err = MP_OKAY;
2972 
2973     (void)dm;
2974     (void)mm;
2975 
2976     if (*outLen < 256U) {
2977         err = MP_TO_E;
2978     }
2979     if (err == MP_OKAY) {
2980         if (inLen > 256) {
2981             err = MP_READ_E;
2982         }
2983         else if (mp_count_bits(mm) != 2048) {
2984             err = MP_READ_E;
2985         }
2986         else if (mp_iseven(mm)) {
2987             err = MP_VAL;
2988         }
2989     }
2990 
2991 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
2992     if (err == MP_OKAY) {
2993         a = (sp_digit*)XMALLOC(sizeof(sp_digit) * 17 * 8, NULL,
2994                                                               DYNAMIC_TYPE_RSA);
2995         if (a == NULL)
2996             err = MEMORY_E;
2997     }
2998 #endif
2999     if (err == MP_OKAY) {
3000         p = a + 34;
3001         qi = dq = dp = p + 17;
3002         tmpa = qi + 17;
3003         tmpb = tmpa + 34;
3004         r = a;
3005 
3006         sp_2048_from_bin(a, 34, in, inLen);
3007         sp_2048_from_mp(p, 17, pm);
3008         sp_2048_from_mp(dp, 17, dpm);
3009         err = sp_2048_mod_exp_17(tmpa, a, dp, 1024, p, 1);
3010     }
3011     if (err == MP_OKAY) {
3012         sp_2048_from_mp(p, 17, qm);
3013         sp_2048_from_mp(dq, 17, dqm);
3014         err = sp_2048_mod_exp_17(tmpb, a, dq, 1024, p, 1);
3015     }
3016     if (err == MP_OKAY) {
3017         sp_2048_from_mp(p, 17, pm);
3018         (void)sp_2048_sub_17(tmpa, tmpa, tmpb);
3019         sp_2048_norm_17(tmpa);
3020         sp_2048_cond_add_17(tmpa, tmpa, p, 0 - ((sp_int_digit)tmpa[16] >> 63));
3021         sp_2048_cond_add_17(tmpa, tmpa, p, 0 - ((sp_int_digit)tmpa[16] >> 63));
3022         sp_2048_norm_17(tmpa);
3023 
3024         sp_2048_from_mp(qi, 17, qim);
3025         sp_2048_mul_17(tmpa, tmpa, qi);
3026         err = sp_2048_mod_17(tmpa, tmpa, p);
3027     }
3028 
3029     if (err == MP_OKAY) {
3030         sp_2048_from_mp(p, 17, qm);
3031         sp_2048_mul_17(tmpa, p, tmpa);
3032         (void)sp_2048_add_34(r, tmpb, tmpa);
3033         sp_2048_norm_34(r);
3034 
3035         sp_2048_to_bin_34(r, out);
3036         *outLen = 256;
3037     }
3038 
3039 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
3040     if (a != NULL)
3041 #endif
3042     {
3043         ForceZero(a, sizeof(sp_digit) * 17 * 8);
3044 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
3045         XFREE(a, NULL, DYNAMIC_TYPE_RSA);
3046 #endif
3047     }
3048 
3049     return err;
3050 #else
3051 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
3052     sp_digit* a = NULL;
3053 #else
3054     sp_digit a[17 * 13];
3055 #endif
3056     sp_digit* p = NULL;
3057     sp_digit* q = NULL;
3058     sp_digit* dp = NULL;
3059     sp_digit* dq = NULL;
3060     sp_digit* qi = NULL;
3061     sp_digit* tmpa = NULL;
3062     sp_digit* tmpb = NULL;
3063     sp_digit* r = NULL;
3064     int err = MP_OKAY;
3065 
3066     (void)dm;
3067     (void)mm;
3068 
3069     if (*outLen < 256U) {
3070         err = MP_TO_E;
3071     }
3072     if (err == MP_OKAY) {
3073         if (inLen > 256U) {
3074             err = MP_READ_E;
3075         }
3076         else if (mp_count_bits(mm) != 2048) {
3077             err = MP_READ_E;
3078         }
3079         else if (mp_iseven(mm)) {
3080             err = MP_VAL;
3081         }
3082     }
3083 
3084 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
3085     if (err == MP_OKAY) {
3086         a = (sp_digit*)XMALLOC(sizeof(sp_digit) * 17 * 13, NULL,
3087                                                               DYNAMIC_TYPE_RSA);
3088         if (a == NULL)
3089             err = MEMORY_E;
3090     }
3091 #endif
3092 
3093     if (err == MP_OKAY) {
3094         p = a + 34 * 2;
3095         q = p + 17;
3096         dp = q + 17;
3097         dq = dp + 17;
3098         qi = dq + 17;
3099         tmpa = qi + 17;
3100         tmpb = tmpa + 34;
3101         r = a;
3102 
3103         sp_2048_from_bin(a, 34, in, inLen);
3104         sp_2048_from_mp(p, 17, pm);
3105         sp_2048_from_mp(q, 17, qm);
3106         sp_2048_from_mp(dp, 17, dpm);
3107         sp_2048_from_mp(dq, 17, dqm);
3108         sp_2048_from_mp(qi, 17, qim);
3109 
3110         err = sp_2048_mod_exp_17(tmpa, a, dp, 1024, p, 1);
3111     }
3112     if (err == MP_OKAY) {
3113         err = sp_2048_mod_exp_17(tmpb, a, dq, 1024, q, 1);
3114     }
3115 
3116     if (err == MP_OKAY) {
3117         (void)sp_2048_sub_17(tmpa, tmpa, tmpb);
3118         sp_2048_norm_17(tmpa);
3119         sp_2048_cond_add_17(tmpa, tmpa, p, 0 - ((sp_int_digit)tmpa[16] >> 63));
3120         sp_2048_cond_add_17(tmpa, tmpa, p, 0 - ((sp_int_digit)tmpa[16] >> 63));
3121         sp_2048_norm_17(tmpa);
3122         sp_2048_mul_17(tmpa, tmpa, qi);
3123         err = sp_2048_mod_17(tmpa, tmpa, p);
3124     }
3125 
3126     if (err == MP_OKAY) {
3127         sp_2048_mul_17(tmpa, tmpa, q);
3128         (void)sp_2048_add_34(r, tmpb, tmpa);
3129         sp_2048_norm_34(r);
3130 
3131         sp_2048_to_bin_34(r, out);
3132         *outLen = 256;
3133     }
3134 
3135 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
3136 if (a != NULL)
3137 #endif
3138     {
3139         ForceZero(a, sizeof(sp_digit) * 17 * 13);
3140     #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
3141         XFREE(a, NULL, DYNAMIC_TYPE_RSA);
3142     #endif
3143     }
3144 
3145     return err;
3146 #endif /* WOLFSSL_SP_SMALL */
3147 #endif /* SP_RSA_PRIVATE_EXP_D || RSA_LOW_MEM */
3148 }
3149 
3150 #endif /* !WOLFSSL_RSA_PUBLIC_ONLY */
3151 #endif /* WOLFSSL_HAVE_SP_RSA */
3152 #if defined(WOLFSSL_HAVE_SP_DH) || (defined(WOLFSSL_HAVE_SP_RSA) && \
3153                                               !defined(WOLFSSL_RSA_PUBLIC_ONLY))
3154 /* Convert an array of sp_digit to an mp_int.
3155  *
3156  * a  A single precision integer.
3157  * r  A multi-precision integer.
3158  */
sp_2048_to_mp(const sp_digit * a,mp_int * r)3159 static int sp_2048_to_mp(const sp_digit* a, mp_int* r)
3160 {
3161     int err;
3162 
3163     err = mp_grow(r, (2048 + DIGIT_BIT - 1) / DIGIT_BIT);
3164     if (err == MP_OKAY) { /*lint !e774 case where err is always MP_OKAY*/
3165 #if DIGIT_BIT == 61
3166         XMEMCPY(r->dp, a, sizeof(sp_digit) * 34);
3167         r->used = 34;
3168         mp_clamp(r);
3169 #elif DIGIT_BIT < 61
3170         int i;
3171         int j = 0;
3172         int s = 0;
3173 
3174         r->dp[0] = 0;
3175         for (i = 0; i < 34; i++) {
3176             r->dp[j] |= (mp_digit)(a[i] << s);
3177             r->dp[j] &= ((sp_digit)1 << DIGIT_BIT) - 1;
3178             s = DIGIT_BIT - s;
3179             r->dp[++j] = (mp_digit)(a[i] >> s);
3180             while (s + DIGIT_BIT <= 61) {
3181                 s += DIGIT_BIT;
3182                 r->dp[j++] &= ((sp_digit)1 << DIGIT_BIT) - 1;
3183                 if (s == SP_WORD_SIZE) {
3184                     r->dp[j] = 0;
3185                 }
3186                 else {
3187                     r->dp[j] = (mp_digit)(a[i] >> s);
3188                 }
3189             }
3190             s = 61 - s;
3191         }
3192         r->used = (2048 + DIGIT_BIT - 1) / DIGIT_BIT;
3193         mp_clamp(r);
3194 #else
3195         int i;
3196         int j = 0;
3197         int s = 0;
3198 
3199         r->dp[0] = 0;
3200         for (i = 0; i < 34; i++) {
3201             r->dp[j] |= ((mp_digit)a[i]) << s;
3202             if (s + 61 >= DIGIT_BIT) {
3203     #if DIGIT_BIT != 32 && DIGIT_BIT != 64
3204                 r->dp[j] &= ((sp_digit)1 << DIGIT_BIT) - 1;
3205     #endif
3206                 s = DIGIT_BIT - s;
3207                 r->dp[++j] = a[i] >> s;
3208                 s = 61 - s;
3209             }
3210             else {
3211                 s += 61;
3212             }
3213         }
3214         r->used = (2048 + DIGIT_BIT - 1) / DIGIT_BIT;
3215         mp_clamp(r);
3216 #endif
3217     }
3218 
3219     return err;
3220 }
3221 
3222 /* Perform the modular exponentiation for Diffie-Hellman.
3223  *
3224  * base  Base. MP integer.
3225  * exp   Exponent. MP integer.
3226  * mod   Modulus. MP integer.
3227  * res   Result. MP integer.
3228  * returns 0 on success, MP_READ_E if there are too many bytes in an array
3229  * and MEMORY_E if memory allocation fails.
3230  */
sp_ModExp_2048(const mp_int * base,const mp_int * exp,const mp_int * mod,mp_int * res)3231 int sp_ModExp_2048(const mp_int* base, const mp_int* exp, const mp_int* mod,
3232     mp_int* res)
3233 {
3234 #ifdef WOLFSSL_SP_SMALL
3235     int err = MP_OKAY;
3236 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
3237     sp_digit* b = NULL;
3238 #else
3239     sp_digit b[34 * 4];
3240 #endif
3241     sp_digit* e = NULL;
3242     sp_digit* m = NULL;
3243     sp_digit* r = NULL;
3244     int expBits = mp_count_bits(exp);
3245 
3246     if (mp_count_bits(base) > 2048) {
3247         err = MP_READ_E;
3248     }
3249     else if (expBits > 2048) {
3250         err = MP_READ_E;
3251     }
3252     else if (mp_count_bits(mod) != 2048) {
3253         err = MP_READ_E;
3254     }
3255     else if (mp_iseven(mod)) {
3256         err = MP_VAL;
3257     }
3258 
3259 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
3260     if (err == MP_OKAY) {
3261         b = (sp_digit*)XMALLOC(sizeof(sp_digit) * 34 * 4, NULL,
3262             DYNAMIC_TYPE_DH);
3263         if (b == NULL)
3264             err = MEMORY_E;
3265     }
3266 #endif
3267 
3268     if (err == MP_OKAY) {
3269         e = b + 34 * 2;
3270         m = e + 34;
3271         r = b;
3272 
3273         sp_2048_from_mp(b, 34, base);
3274         sp_2048_from_mp(e, 34, exp);
3275         sp_2048_from_mp(m, 34, mod);
3276 
3277         err = sp_2048_mod_exp_34(r, b, e, mp_count_bits(exp), m, 0);
3278     }
3279 
3280     if (err == MP_OKAY) {
3281         err = sp_2048_to_mp(r, res);
3282     }
3283 
3284 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
3285     if (b != NULL)
3286 #endif
3287     {
3288         /* only "e" is sensitive and needs zeroized */
3289         if (e != NULL)
3290             ForceZero(e, sizeof(sp_digit) * 34U);
3291     #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
3292         XFREE(b, NULL, DYNAMIC_TYPE_DH);
3293     #endif
3294     }
3295     return err;
3296 #else
3297 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
3298     sp_digit* b = NULL;
3299 #else
3300     sp_digit b[34 * 4];
3301 #endif
3302     sp_digit* e = NULL;
3303     sp_digit* m = NULL;
3304     sp_digit* r = NULL;
3305     int err = MP_OKAY;
3306     int expBits = mp_count_bits(exp);
3307 
3308     if (mp_count_bits(base) > 2048) {
3309         err = MP_READ_E;
3310     }
3311     else if (expBits > 2048) {
3312         err = MP_READ_E;
3313     }
3314     else if (mp_count_bits(mod) != 2048) {
3315         err = MP_READ_E;
3316     }
3317     else if (mp_iseven(mod)) {
3318         err = MP_VAL;
3319     }
3320 
3321 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
3322     if (err == MP_OKAY) {
3323         b = (sp_digit*)XMALLOC(sizeof(sp_digit) * 34 * 4, NULL, DYNAMIC_TYPE_DH);
3324         if (b == NULL)
3325             err = MEMORY_E;
3326     }
3327 #endif
3328 
3329     if (err == MP_OKAY) {
3330         e = b + 34 * 2;
3331         m = e + 34;
3332         r = b;
3333 
3334         sp_2048_from_mp(b, 34, base);
3335         sp_2048_from_mp(e, 34, exp);
3336         sp_2048_from_mp(m, 34, mod);
3337 
3338         err = sp_2048_mod_exp_34(r, b, e, expBits, m, 0);
3339     }
3340 
3341     if (err == MP_OKAY) {
3342         err = sp_2048_to_mp(r, res);
3343     }
3344 
3345 
3346 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
3347     if (b != NULL)
3348 #endif
3349     {
3350         /* only "e" is sensitive and needs zeroized */
3351         if (e != NULL)
3352             ForceZero(e, sizeof(sp_digit) * 34U);
3353     #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
3354         XFREE(b, NULL, DYNAMIC_TYPE_DH);
3355     #endif
3356     }
3357 
3358     return err;
3359 #endif
3360 }
3361 
3362 #ifdef WOLFSSL_HAVE_SP_DH
3363 
3364 #ifdef HAVE_FFDHE_2048
sp_2048_lshift_34(sp_digit * r,const sp_digit * a,byte n)3365 SP_NOINLINE static void sp_2048_lshift_34(sp_digit* r, const sp_digit* a,
3366         byte n)
3367 {
3368     int i;
3369 
3370     r[34] = a[33] >> (61 - n);
3371     for (i=33; i>0; i--) {
3372         r[i] = ((a[i] << n) | (a[i-1] >> (61 - n))) & 0x1fffffffffffffffL;
3373     }
3374     r[0] = (a[0] << n) & 0x1fffffffffffffffL;
3375 }
3376 
3377 /* Modular exponentiate 2 to the e mod m. (r = 2^e mod m)
3378  *
3379  * r     A single precision number that is the result of the operation.
3380  * e     A single precision number that is the exponent.
3381  * bits  The number of bits in the exponent.
3382  * m     A single precision number that is the modulus.
3383  * returns  0 on success.
3384  * returns  MEMORY_E on dynamic memory allocation failure.
3385  * returns  MP_VAL when base is even.
3386  */
sp_2048_mod_exp_2_34(sp_digit * r,const sp_digit * e,int bits,const sp_digit * m)3387 static int sp_2048_mod_exp_2_34(sp_digit* r, const sp_digit* e, int bits, const sp_digit* m)
3388 {
3389 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
3390     sp_digit* td = NULL;
3391 #else
3392     sp_digit td[103];
3393 #endif
3394     sp_digit* norm = NULL;
3395     sp_digit* tmp = NULL;
3396     sp_digit mp = 1;
3397     sp_digit n;
3398     sp_digit o;
3399     int i;
3400     int c;
3401     byte y;
3402     int err = MP_OKAY;
3403 
3404     if ((m[0] & 1) == 0) {
3405         err = MP_VAL;
3406     }
3407 
3408 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
3409     if (err == MP_OKAY) {
3410         td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 103, NULL,
3411                                 DYNAMIC_TYPE_TMP_BUFFER);
3412         if (td == NULL)
3413             err = MEMORY_E;
3414     }
3415 #endif
3416 
3417     if (err == MP_OKAY) {
3418         norm = td;
3419         tmp  = td + 68;
3420         XMEMSET(td, 0, sizeof(sp_digit) * 103);
3421 
3422         sp_2048_mont_setup(m, &mp);
3423         sp_2048_mont_norm_34(norm, m);
3424 
3425         bits = ((bits + 4) / 5) * 5;
3426         i = ((bits + 60) / 61) - 1;
3427         c = bits % 61;
3428         if (c == 0) {
3429             c = 61;
3430         }
3431         if (i < 34) {
3432             n = e[i--] << (64 - c);
3433         }
3434         else {
3435             n = 0;
3436             i--;
3437         }
3438         if (c < 5) {
3439             n |= e[i--] << (3 - c);
3440             c += 61;
3441         }
3442         y = (int)((n >> 59) & 0x1f);
3443         n <<= 5;
3444         c -= 5;
3445         sp_2048_lshift_34(r, norm, (byte)y);
3446         while ((i >= 0) || (c >= 5)) {
3447             if (c >= 5) {
3448                 y = (byte)((n >> 59) & 0x1f);
3449                 n <<= 5;
3450                 c -= 5;
3451             }
3452             else if (c == 0) {
3453                 n = e[i--] << 3;
3454                 y = (byte)((n >> 59) & 0x1f);
3455                 n <<= 5;
3456                 c = 56;
3457             }
3458             else {
3459                 y = (byte)((n >> 59) & 0x1f);
3460                 n = e[i--] << 3;
3461                 c = 5 - c;
3462                 y |= (byte)((n >> (64 - c)) & ((1 << c) - 1));
3463                 n <<= c;
3464                 c = 61 - c;
3465             }
3466 
3467             sp_2048_mont_sqr_34(r, r, m, mp);
3468             sp_2048_mont_sqr_34(r, r, m, mp);
3469             sp_2048_mont_sqr_34(r, r, m, mp);
3470             sp_2048_mont_sqr_34(r, r, m, mp);
3471             sp_2048_mont_sqr_34(r, r, m, mp);
3472 
3473             sp_2048_lshift_34(r, r, (byte)y);
3474             sp_2048_mul_d_34(tmp, norm, (r[34] << 26) + (r[33] >> 35));
3475             r[34] = 0;
3476             r[33] &= 0x7ffffffffL;
3477             (void)sp_2048_add_34(r, r, tmp);
3478             sp_2048_norm_34(r);
3479             o = sp_2048_cmp_34(r, m);
3480             sp_2048_cond_sub_34(r, r, m, ((o < 0) ?
3481                                           (sp_digit)1 : (sp_digit)0) - 1);
3482         }
3483 
3484         sp_2048_mont_reduce_34(r, m, mp);
3485         n = sp_2048_cmp_34(r, m);
3486         sp_2048_cond_sub_34(r, r, m, ((n < 0) ?
3487                                                 (sp_digit)1 : (sp_digit)0) - 1);
3488     }
3489 
3490 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
3491     if (td != NULL)
3492         XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);
3493 #endif
3494 
3495     return err;
3496 }
3497 
3498 #endif /* HAVE_FFDHE_2048 */
3499 
3500 /* Perform the modular exponentiation for Diffie-Hellman.
3501  *
3502  * base     Base.
3503  * exp      Array of bytes that is the exponent.
3504  * expLen   Length of data, in bytes, in exponent.
3505  * mod      Modulus.
3506  * out      Buffer to hold big-endian bytes of exponentiation result.
3507  *          Must be at least 256 bytes long.
3508  * outLen   Length, in bytes, of exponentiation result.
3509  * returns 0 on success, MP_READ_E if there are too many bytes in an array
3510  * and MEMORY_E if memory allocation fails.
3511  */
sp_DhExp_2048(const mp_int * base,const byte * exp,word32 expLen,const mp_int * mod,byte * out,word32 * outLen)3512 int sp_DhExp_2048(const mp_int* base, const byte* exp, word32 expLen,
3513     const mp_int* mod, byte* out, word32* outLen)
3514 {
3515 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
3516     sp_digit* b = NULL;
3517 #else
3518     sp_digit b[34 * 4];
3519 #endif
3520     sp_digit* e = NULL;
3521     sp_digit* m = NULL;
3522     sp_digit* r = NULL;
3523     word32 i;
3524     int err = MP_OKAY;
3525 
3526     if (mp_count_bits(base) > 2048) {
3527         err = MP_READ_E;
3528     }
3529     else if (expLen > 256U) {
3530         err = MP_READ_E;
3531     }
3532     else if (mp_count_bits(mod) != 2048) {
3533         err = MP_READ_E;
3534     }
3535     else if (mp_iseven(mod)) {
3536         err = MP_VAL;
3537     }
3538 
3539 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
3540     if (err == MP_OKAY) {
3541         b = (sp_digit*)XMALLOC(sizeof(sp_digit) * 34 * 4, NULL,
3542             DYNAMIC_TYPE_DH);
3543         if (b == NULL)
3544             err = MEMORY_E;
3545     }
3546 #endif
3547 
3548     if (err == MP_OKAY) {
3549         e = b + 34 * 2;
3550         m = e + 34;
3551         r = b;
3552 
3553         sp_2048_from_mp(b, 34, base);
3554         sp_2048_from_bin(e, 34, exp, expLen);
3555         sp_2048_from_mp(m, 34, mod);
3556 
3557     #ifdef HAVE_FFDHE_2048
3558         if (base->used == 1 && base->dp[0] == 2U &&
3559                 (m[33] >> 3) == 0xffffffffL) {
3560             err = sp_2048_mod_exp_2_34(r, e, expLen * 8U, m);
3561         }
3562         else {
3563     #endif
3564             err = sp_2048_mod_exp_34(r, b, e, expLen * 8U, m, 0);
3565     #ifdef HAVE_FFDHE_2048
3566         }
3567     #endif
3568     }
3569 
3570     if (err == MP_OKAY) {
3571         sp_2048_to_bin_34(r, out);
3572         *outLen = 256;
3573         for (i=0; i<256U && out[i] == 0U; i++) {
3574             /* Search for first non-zero. */
3575         }
3576         *outLen -= i;
3577         XMEMMOVE(out, out + i, *outLen);
3578     }
3579 
3580 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
3581     if (b != NULL)
3582 #endif
3583     {
3584         /* only "e" is sensitive and needs zeroized */
3585         if (e != NULL)
3586             ForceZero(e, sizeof(sp_digit) * 34U);
3587     #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
3588         XFREE(b, NULL, DYNAMIC_TYPE_DH);
3589     #endif
3590     }
3591 
3592     return err;
3593 }
3594 #endif /* WOLFSSL_HAVE_SP_DH */
3595 
3596 /* Perform the modular exponentiation for Diffie-Hellman.
3597  *
3598  * base  Base. MP integer.
3599  * exp   Exponent. MP integer.
3600  * mod   Modulus. MP integer.
3601  * res   Result. MP integer.
3602  * returns 0 on success, MP_READ_E if there are too many bytes in an array
3603  * and MEMORY_E if memory allocation fails.
3604  */
sp_ModExp_1024(const mp_int * base,const mp_int * exp,const mp_int * mod,mp_int * res)3605 int sp_ModExp_1024(const mp_int* base, const mp_int* exp, const mp_int* mod,
3606     mp_int* res)
3607 {
3608 #ifdef WOLFSSL_SP_SMALL
3609     int err = MP_OKAY;
3610 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
3611     sp_digit* b = NULL;
3612 #else
3613     sp_digit b[17 * 4];
3614 #endif
3615     sp_digit* e = NULL;
3616     sp_digit* m = NULL;
3617     sp_digit* r = NULL;
3618     int expBits = mp_count_bits(exp);
3619 
3620     if (mp_count_bits(base) > 1024) {
3621         err = MP_READ_E;
3622     }
3623     else if (expBits > 1024) {
3624         err = MP_READ_E;
3625     }
3626     else if (mp_count_bits(mod) != 1024) {
3627         err = MP_READ_E;
3628     }
3629     else if (mp_iseven(mod)) {
3630         err = MP_VAL;
3631     }
3632 
3633 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
3634     if (err == MP_OKAY) {
3635         b = (sp_digit*)XMALLOC(sizeof(sp_digit) * 17 * 4, NULL,
3636             DYNAMIC_TYPE_DH);
3637         if (b == NULL)
3638             err = MEMORY_E;
3639     }
3640 #endif
3641 
3642     if (err == MP_OKAY) {
3643         e = b + 17 * 2;
3644         m = e + 17;
3645         r = b;
3646 
3647         sp_2048_from_mp(b, 17, base);
3648         sp_2048_from_mp(e, 17, exp);
3649         sp_2048_from_mp(m, 17, mod);
3650 
3651         err = sp_2048_mod_exp_17(r, b, e, mp_count_bits(exp), m, 0);
3652     }
3653 
3654     if (err == MP_OKAY) {
3655         XMEMSET(r + 17, 0, sizeof(*r) * 17U);
3656         err = sp_2048_to_mp(r, res);
3657     }
3658 
3659 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
3660     if (b != NULL)
3661 #endif
3662     {
3663         /* only "e" is sensitive and needs zeroized */
3664         if (e != NULL)
3665             ForceZero(e, sizeof(sp_digit) * 34U);
3666     #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
3667         XFREE(b, NULL, DYNAMIC_TYPE_DH);
3668     #endif
3669     }
3670     return err;
3671 #else
3672 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
3673     sp_digit* b = NULL;
3674 #else
3675     sp_digit b[17 * 4];
3676 #endif
3677     sp_digit* e = NULL;
3678     sp_digit* m = NULL;
3679     sp_digit* r = NULL;
3680     int err = MP_OKAY;
3681     int expBits = mp_count_bits(exp);
3682 
3683     if (mp_count_bits(base) > 1024) {
3684         err = MP_READ_E;
3685     }
3686     else if (expBits > 1024) {
3687         err = MP_READ_E;
3688     }
3689     else if (mp_count_bits(mod) != 1024) {
3690         err = MP_READ_E;
3691     }
3692     else if (mp_iseven(mod)) {
3693         err = MP_VAL;
3694     }
3695 
3696 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
3697     if (err == MP_OKAY) {
3698         b = (sp_digit*)XMALLOC(sizeof(sp_digit) * 17 * 4, NULL, DYNAMIC_TYPE_DH);
3699         if (b == NULL)
3700             err = MEMORY_E;
3701     }
3702 #endif
3703 
3704     if (err == MP_OKAY) {
3705         e = b + 17 * 2;
3706         m = e + 17;
3707         r = b;
3708 
3709         sp_2048_from_mp(b, 17, base);
3710         sp_2048_from_mp(e, 17, exp);
3711         sp_2048_from_mp(m, 17, mod);
3712 
3713         err = sp_2048_mod_exp_17(r, b, e, expBits, m, 0);
3714     }
3715 
3716     if (err == MP_OKAY) {
3717         XMEMSET(r + 17, 0, sizeof(*r) * 17U);
3718         err = sp_2048_to_mp(r, res);
3719     }
3720 
3721 
3722 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
3723     if (b != NULL)
3724 #endif
3725     {
3726         /* only "e" is sensitive and needs zeroized */
3727         if (e != NULL)
3728             ForceZero(e, sizeof(sp_digit) * 34U);
3729     #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
3730         XFREE(b, NULL, DYNAMIC_TYPE_DH);
3731     #endif
3732     }
3733 
3734     return err;
3735 #endif
3736 }
3737 
3738 #endif /* WOLFSSL_HAVE_SP_DH | (WOLFSSL_HAVE_SP_RSA & !WOLFSSL_RSA_PUBLIC_ONLY) */
3739 
3740 #else
3741 /* Read big endian unsigned byte array into r.
3742  *
3743  * r  A single precision integer.
3744  * size  Maximum number of bytes to convert
3745  * a  Byte array.
3746  * n  Number of bytes in array to read.
3747  */
sp_2048_from_bin(sp_digit * r,int size,const byte * a,int n)3748 static void sp_2048_from_bin(sp_digit* r, int size, const byte* a, int n)
3749 {
3750     int i;
3751     int j = 0;
3752     word32 s = 0;
3753 
3754     r[0] = 0;
3755     for (i = n-1; i >= 0; i--) {
3756         r[j] |= (((sp_digit)a[i]) << s);
3757         if (s >= 49U) {
3758             r[j] &= 0x1ffffffffffffffL;
3759             s = 57U - s;
3760             if (j + 1 >= size) {
3761                 break;
3762             }
3763             r[++j] = (sp_digit)a[i] >> s;
3764             s = 8U - s;
3765         }
3766         else {
3767             s += 8U;
3768         }
3769     }
3770 
3771     for (j++; j < size; j++) {
3772         r[j] = 0;
3773     }
3774 }
3775 
3776 /* Convert an mp_int to an array of sp_digit.
3777  *
3778  * r  A single precision integer.
3779  * size  Maximum number of bytes to convert
3780  * a  A multi-precision integer.
3781  */
sp_2048_from_mp(sp_digit * r,int size,const mp_int * a)3782 static void sp_2048_from_mp(sp_digit* r, int size, const mp_int* a)
3783 {
3784 #if DIGIT_BIT == 57
3785     int j;
3786 
3787     XMEMCPY(r, a->dp, sizeof(sp_digit) * a->used);
3788 
3789     for (j = a->used; j < size; j++) {
3790         r[j] = 0;
3791     }
3792 #elif DIGIT_BIT > 57
3793     int i;
3794     int j = 0;
3795     word32 s = 0;
3796 
3797     r[0] = 0;
3798     for (i = 0; i < a->used && j < size; i++) {
3799         r[j] |= ((sp_digit)a->dp[i] << s);
3800         r[j] &= 0x1ffffffffffffffL;
3801         s = 57U - s;
3802         if (j + 1 >= size) {
3803             break;
3804         }
3805         /* lint allow cast of mismatch word32 and mp_digit */
3806         r[++j] = (sp_digit)(a->dp[i] >> s); /*lint !e9033*/
3807         while ((s + 57U) <= (word32)DIGIT_BIT) {
3808             s += 57U;
3809             r[j] &= 0x1ffffffffffffffL;
3810             if (j + 1 >= size) {
3811                 break;
3812             }
3813             if (s < (word32)DIGIT_BIT) {
3814                 /* lint allow cast of mismatch word32 and mp_digit */
3815                 r[++j] = (sp_digit)(a->dp[i] >> s); /*lint !e9033*/
3816             }
3817             else {
3818                 r[++j] = (sp_digit)0;
3819             }
3820         }
3821         s = (word32)DIGIT_BIT - s;
3822     }
3823 
3824     for (j++; j < size; j++) {
3825         r[j] = 0;
3826     }
3827 #else
3828     int i;
3829     int j = 0;
3830     int s = 0;
3831 
3832     r[0] = 0;
3833     for (i = 0; i < a->used && j < size; i++) {
3834         r[j] |= ((sp_digit)a->dp[i]) << s;
3835         if (s + DIGIT_BIT >= 57) {
3836             r[j] &= 0x1ffffffffffffffL;
3837             if (j + 1 >= size) {
3838                 break;
3839             }
3840             s = 57 - s;
3841             if (s == DIGIT_BIT) {
3842                 r[++j] = 0;
3843                 s = 0;
3844             }
3845             else {
3846                 r[++j] = a->dp[i] >> s;
3847                 s = DIGIT_BIT - s;
3848             }
3849         }
3850         else {
3851             s += DIGIT_BIT;
3852         }
3853     }
3854 
3855     for (j++; j < size; j++) {
3856         r[j] = 0;
3857     }
3858 #endif
3859 }
3860 
3861 /* Write r as big endian to byte array.
3862  * Fixed length number of bytes written: 256
3863  *
3864  * r  A single precision integer.
3865  * a  Byte array.
3866  */
sp_2048_to_bin_36(sp_digit * r,byte * a)3867 static void sp_2048_to_bin_36(sp_digit* r, byte* a)
3868 {
3869     int i;
3870     int j;
3871     int s = 0;
3872     int b;
3873 
3874     for (i=0; i<35; i++) {
3875         r[i+1] += r[i] >> 57;
3876         r[i] &= 0x1ffffffffffffffL;
3877     }
3878     j = 2048 / 8 - 1;
3879     a[j] = 0;
3880     for (i=0; i<36 && j>=0; i++) {
3881         b = 0;
3882         /* lint allow cast of mismatch sp_digit and int */
3883         a[j--] |= (byte)(r[i] << s); /*lint !e9033*/
3884         b += 8 - s;
3885         if (j < 0) {
3886             break;
3887         }
3888         while (b < 57) {
3889             a[j--] = (byte)(r[i] >> b);
3890             b += 8;
3891             if (j < 0) {
3892                 break;
3893             }
3894         }
3895         s = 8 - (b - 57);
3896         if (j >= 0) {
3897             a[j] = 0;
3898         }
3899         if (s != 0) {
3900             j++;
3901         }
3902     }
3903 }
3904 
3905 #if (defined(WOLFSSL_HAVE_SP_RSA) && !defined(WOLFSSL_RSA_PUBLIC_ONLY)) || defined(WOLFSSL_HAVE_SP_DH)
3906 /* Normalize the values in each word to 57 bits.
3907  *
3908  * a  Array of sp_digit to normalize.
3909  */
sp_2048_norm_18(sp_digit * a)3910 static void sp_2048_norm_18(sp_digit* a)
3911 {
3912     int i;
3913     for (i = 0; i < 16; i += 8) {
3914         a[i+1] += a[i+0] >> 57; a[i+0] &= 0x1ffffffffffffffL;
3915         a[i+2] += a[i+1] >> 57; a[i+1] &= 0x1ffffffffffffffL;
3916         a[i+3] += a[i+2] >> 57; a[i+2] &= 0x1ffffffffffffffL;
3917         a[i+4] += a[i+3] >> 57; a[i+3] &= 0x1ffffffffffffffL;
3918         a[i+5] += a[i+4] >> 57; a[i+4] &= 0x1ffffffffffffffL;
3919         a[i+6] += a[i+5] >> 57; a[i+5] &= 0x1ffffffffffffffL;
3920         a[i+7] += a[i+6] >> 57; a[i+6] &= 0x1ffffffffffffffL;
3921         a[i+8] += a[i+7] >> 57; a[i+7] &= 0x1ffffffffffffffL;
3922     }
3923     a[17] += a[16] >> 57; a[16] &= 0x1ffffffffffffffL;
3924 }
3925 
3926 #endif /* (WOLFSSL_HAVE_SP_RSA && !WOLFSSL_RSA_PUBLIC_ONLY) || WOLFSSL_HAVE_SP_DH */
3927 /* Normalize the values in each word to 57 bits.
3928  *
3929  * a  Array of sp_digit to normalize.
3930  */
sp_2048_norm_36(sp_digit * a)3931 static void sp_2048_norm_36(sp_digit* a)
3932 {
3933     int i;
3934     for (i = 0; i < 32; i += 8) {
3935         a[i+1] += a[i+0] >> 57; a[i+0] &= 0x1ffffffffffffffL;
3936         a[i+2] += a[i+1] >> 57; a[i+1] &= 0x1ffffffffffffffL;
3937         a[i+3] += a[i+2] >> 57; a[i+2] &= 0x1ffffffffffffffL;
3938         a[i+4] += a[i+3] >> 57; a[i+3] &= 0x1ffffffffffffffL;
3939         a[i+5] += a[i+4] >> 57; a[i+4] &= 0x1ffffffffffffffL;
3940         a[i+6] += a[i+5] >> 57; a[i+5] &= 0x1ffffffffffffffL;
3941         a[i+7] += a[i+6] >> 57; a[i+6] &= 0x1ffffffffffffffL;
3942         a[i+8] += a[i+7] >> 57; a[i+7] &= 0x1ffffffffffffffL;
3943     }
3944     a[33] += a[32] >> 57; a[32] &= 0x1ffffffffffffffL;
3945     a[34] += a[33] >> 57; a[33] &= 0x1ffffffffffffffL;
3946     a[35] += a[34] >> 57; a[34] &= 0x1ffffffffffffffL;
3947 }
3948 
3949 #ifndef WOLFSSL_SP_SMALL
3950 /* Multiply a and b into r. (r = a * b)
3951  *
3952  * r  A single precision integer.
3953  * a  A single precision integer.
3954  * b  A single precision integer.
3955  */
sp_2048_mul_9(sp_digit * r,const sp_digit * a,const sp_digit * b)3956 SP_NOINLINE static void sp_2048_mul_9(sp_digit* r, const sp_digit* a,
3957     const sp_digit* b)
3958 {
3959     sp_uint128 t0   = ((sp_uint128)a[ 0]) * b[ 0];
3960     sp_uint128 t1   = ((sp_uint128)a[ 0]) * b[ 1]
3961                  + ((sp_uint128)a[ 1]) * b[ 0];
3962     sp_uint128 t2   = ((sp_uint128)a[ 0]) * b[ 2]
3963                  + ((sp_uint128)a[ 1]) * b[ 1]
3964                  + ((sp_uint128)a[ 2]) * b[ 0];
3965     sp_uint128 t3   = ((sp_uint128)a[ 0]) * b[ 3]
3966                  + ((sp_uint128)a[ 1]) * b[ 2]
3967                  + ((sp_uint128)a[ 2]) * b[ 1]
3968                  + ((sp_uint128)a[ 3]) * b[ 0];
3969     sp_uint128 t4   = ((sp_uint128)a[ 0]) * b[ 4]
3970                  + ((sp_uint128)a[ 1]) * b[ 3]
3971                  + ((sp_uint128)a[ 2]) * b[ 2]
3972                  + ((sp_uint128)a[ 3]) * b[ 1]
3973                  + ((sp_uint128)a[ 4]) * b[ 0];
3974     sp_uint128 t5   = ((sp_uint128)a[ 0]) * b[ 5]
3975                  + ((sp_uint128)a[ 1]) * b[ 4]
3976                  + ((sp_uint128)a[ 2]) * b[ 3]
3977                  + ((sp_uint128)a[ 3]) * b[ 2]
3978                  + ((sp_uint128)a[ 4]) * b[ 1]
3979                  + ((sp_uint128)a[ 5]) * b[ 0];
3980     sp_uint128 t6   = ((sp_uint128)a[ 0]) * b[ 6]
3981                  + ((sp_uint128)a[ 1]) * b[ 5]
3982                  + ((sp_uint128)a[ 2]) * b[ 4]
3983                  + ((sp_uint128)a[ 3]) * b[ 3]
3984                  + ((sp_uint128)a[ 4]) * b[ 2]
3985                  + ((sp_uint128)a[ 5]) * b[ 1]
3986                  + ((sp_uint128)a[ 6]) * b[ 0];
3987     sp_uint128 t7   = ((sp_uint128)a[ 0]) * b[ 7]
3988                  + ((sp_uint128)a[ 1]) * b[ 6]
3989                  + ((sp_uint128)a[ 2]) * b[ 5]
3990                  + ((sp_uint128)a[ 3]) * b[ 4]
3991                  + ((sp_uint128)a[ 4]) * b[ 3]
3992                  + ((sp_uint128)a[ 5]) * b[ 2]
3993                  + ((sp_uint128)a[ 6]) * b[ 1]
3994                  + ((sp_uint128)a[ 7]) * b[ 0];
3995     sp_uint128 t8   = ((sp_uint128)a[ 0]) * b[ 8]
3996                  + ((sp_uint128)a[ 1]) * b[ 7]
3997                  + ((sp_uint128)a[ 2]) * b[ 6]
3998                  + ((sp_uint128)a[ 3]) * b[ 5]
3999                  + ((sp_uint128)a[ 4]) * b[ 4]
4000                  + ((sp_uint128)a[ 5]) * b[ 3]
4001                  + ((sp_uint128)a[ 6]) * b[ 2]
4002                  + ((sp_uint128)a[ 7]) * b[ 1]
4003                  + ((sp_uint128)a[ 8]) * b[ 0];
4004     sp_uint128 t9   = ((sp_uint128)a[ 1]) * b[ 8]
4005                  + ((sp_uint128)a[ 2]) * b[ 7]
4006                  + ((sp_uint128)a[ 3]) * b[ 6]
4007                  + ((sp_uint128)a[ 4]) * b[ 5]
4008                  + ((sp_uint128)a[ 5]) * b[ 4]
4009                  + ((sp_uint128)a[ 6]) * b[ 3]
4010                  + ((sp_uint128)a[ 7]) * b[ 2]
4011                  + ((sp_uint128)a[ 8]) * b[ 1];
4012     sp_uint128 t10  = ((sp_uint128)a[ 2]) * b[ 8]
4013                  + ((sp_uint128)a[ 3]) * b[ 7]
4014                  + ((sp_uint128)a[ 4]) * b[ 6]
4015                  + ((sp_uint128)a[ 5]) * b[ 5]
4016                  + ((sp_uint128)a[ 6]) * b[ 4]
4017                  + ((sp_uint128)a[ 7]) * b[ 3]
4018                  + ((sp_uint128)a[ 8]) * b[ 2];
4019     sp_uint128 t11  = ((sp_uint128)a[ 3]) * b[ 8]
4020                  + ((sp_uint128)a[ 4]) * b[ 7]
4021                  + ((sp_uint128)a[ 5]) * b[ 6]
4022                  + ((sp_uint128)a[ 6]) * b[ 5]
4023                  + ((sp_uint128)a[ 7]) * b[ 4]
4024                  + ((sp_uint128)a[ 8]) * b[ 3];
4025     sp_uint128 t12  = ((sp_uint128)a[ 4]) * b[ 8]
4026                  + ((sp_uint128)a[ 5]) * b[ 7]
4027                  + ((sp_uint128)a[ 6]) * b[ 6]
4028                  + ((sp_uint128)a[ 7]) * b[ 5]
4029                  + ((sp_uint128)a[ 8]) * b[ 4];
4030     sp_uint128 t13  = ((sp_uint128)a[ 5]) * b[ 8]
4031                  + ((sp_uint128)a[ 6]) * b[ 7]
4032                  + ((sp_uint128)a[ 7]) * b[ 6]
4033                  + ((sp_uint128)a[ 8]) * b[ 5];
4034     sp_uint128 t14  = ((sp_uint128)a[ 6]) * b[ 8]
4035                  + ((sp_uint128)a[ 7]) * b[ 7]
4036                  + ((sp_uint128)a[ 8]) * b[ 6];
4037     sp_uint128 t15  = ((sp_uint128)a[ 7]) * b[ 8]
4038                  + ((sp_uint128)a[ 8]) * b[ 7];
4039     sp_uint128 t16  = ((sp_uint128)a[ 8]) * b[ 8];
4040 
4041     t1   += t0  >> 57; r[ 0] = t0  & 0x1ffffffffffffffL;
4042     t2   += t1  >> 57; r[ 1] = t1  & 0x1ffffffffffffffL;
4043     t3   += t2  >> 57; r[ 2] = t2  & 0x1ffffffffffffffL;
4044     t4   += t3  >> 57; r[ 3] = t3  & 0x1ffffffffffffffL;
4045     t5   += t4  >> 57; r[ 4] = t4  & 0x1ffffffffffffffL;
4046     t6   += t5  >> 57; r[ 5] = t5  & 0x1ffffffffffffffL;
4047     t7   += t6  >> 57; r[ 6] = t6  & 0x1ffffffffffffffL;
4048     t8   += t7  >> 57; r[ 7] = t7  & 0x1ffffffffffffffL;
4049     t9   += t8  >> 57; r[ 8] = t8  & 0x1ffffffffffffffL;
4050     t10  += t9  >> 57; r[ 9] = t9  & 0x1ffffffffffffffL;
4051     t11  += t10 >> 57; r[10] = t10 & 0x1ffffffffffffffL;
4052     t12  += t11 >> 57; r[11] = t11 & 0x1ffffffffffffffL;
4053     t13  += t12 >> 57; r[12] = t12 & 0x1ffffffffffffffL;
4054     t14  += t13 >> 57; r[13] = t13 & 0x1ffffffffffffffL;
4055     t15  += t14 >> 57; r[14] = t14 & 0x1ffffffffffffffL;
4056     t16  += t15 >> 57; r[15] = t15 & 0x1ffffffffffffffL;
4057     r[17] = (sp_digit)(t16 >> 57);
4058                        r[16] = t16 & 0x1ffffffffffffffL;
4059 }
4060 
4061 /* Square a and put result in r. (r = a * a)
4062  *
4063  * r  A single precision integer.
4064  * a  A single precision integer.
4065  */
sp_2048_sqr_9(sp_digit * r,const sp_digit * a)4066 SP_NOINLINE static void sp_2048_sqr_9(sp_digit* r, const sp_digit* a)
4067 {
4068     sp_uint128 t0   =  ((sp_uint128)a[ 0]) * a[ 0];
4069     sp_uint128 t1   = (((sp_uint128)a[ 0]) * a[ 1]) * 2;
4070     sp_uint128 t2   = (((sp_uint128)a[ 0]) * a[ 2]) * 2
4071                  +  ((sp_uint128)a[ 1]) * a[ 1];
4072     sp_uint128 t3   = (((sp_uint128)a[ 0]) * a[ 3]
4073                  +  ((sp_uint128)a[ 1]) * a[ 2]) * 2;
4074     sp_uint128 t4   = (((sp_uint128)a[ 0]) * a[ 4]
4075                  +  ((sp_uint128)a[ 1]) * a[ 3]) * 2
4076                  +  ((sp_uint128)a[ 2]) * a[ 2];
4077     sp_uint128 t5   = (((sp_uint128)a[ 0]) * a[ 5]
4078                  +  ((sp_uint128)a[ 1]) * a[ 4]
4079                  +  ((sp_uint128)a[ 2]) * a[ 3]) * 2;
4080     sp_uint128 t6   = (((sp_uint128)a[ 0]) * a[ 6]
4081                  +  ((sp_uint128)a[ 1]) * a[ 5]
4082                  +  ((sp_uint128)a[ 2]) * a[ 4]) * 2
4083                  +  ((sp_uint128)a[ 3]) * a[ 3];
4084     sp_uint128 t7   = (((sp_uint128)a[ 0]) * a[ 7]
4085                  +  ((sp_uint128)a[ 1]) * a[ 6]
4086                  +  ((sp_uint128)a[ 2]) * a[ 5]
4087                  +  ((sp_uint128)a[ 3]) * a[ 4]) * 2;
4088     sp_uint128 t8   = (((sp_uint128)a[ 0]) * a[ 8]
4089                  +  ((sp_uint128)a[ 1]) * a[ 7]
4090                  +  ((sp_uint128)a[ 2]) * a[ 6]
4091                  +  ((sp_uint128)a[ 3]) * a[ 5]) * 2
4092                  +  ((sp_uint128)a[ 4]) * a[ 4];
4093     sp_uint128 t9   = (((sp_uint128)a[ 1]) * a[ 8]
4094                  +  ((sp_uint128)a[ 2]) * a[ 7]
4095                  +  ((sp_uint128)a[ 3]) * a[ 6]
4096                  +  ((sp_uint128)a[ 4]) * a[ 5]) * 2;
4097     sp_uint128 t10  = (((sp_uint128)a[ 2]) * a[ 8]
4098                  +  ((sp_uint128)a[ 3]) * a[ 7]
4099                  +  ((sp_uint128)a[ 4]) * a[ 6]) * 2
4100                  +  ((sp_uint128)a[ 5]) * a[ 5];
4101     sp_uint128 t11  = (((sp_uint128)a[ 3]) * a[ 8]
4102                  +  ((sp_uint128)a[ 4]) * a[ 7]
4103                  +  ((sp_uint128)a[ 5]) * a[ 6]) * 2;
4104     sp_uint128 t12  = (((sp_uint128)a[ 4]) * a[ 8]
4105                  +  ((sp_uint128)a[ 5]) * a[ 7]) * 2
4106                  +  ((sp_uint128)a[ 6]) * a[ 6];
4107     sp_uint128 t13  = (((sp_uint128)a[ 5]) * a[ 8]
4108                  +  ((sp_uint128)a[ 6]) * a[ 7]) * 2;
4109     sp_uint128 t14  = (((sp_uint128)a[ 6]) * a[ 8]) * 2
4110                  +  ((sp_uint128)a[ 7]) * a[ 7];
4111     sp_uint128 t15  = (((sp_uint128)a[ 7]) * a[ 8]) * 2;
4112     sp_uint128 t16  =  ((sp_uint128)a[ 8]) * a[ 8];
4113 
4114     t1   += t0  >> 57; r[ 0] = t0  & 0x1ffffffffffffffL;
4115     t2   += t1  >> 57; r[ 1] = t1  & 0x1ffffffffffffffL;
4116     t3   += t2  >> 57; r[ 2] = t2  & 0x1ffffffffffffffL;
4117     t4   += t3  >> 57; r[ 3] = t3  & 0x1ffffffffffffffL;
4118     t5   += t4  >> 57; r[ 4] = t4  & 0x1ffffffffffffffL;
4119     t6   += t5  >> 57; r[ 5] = t5  & 0x1ffffffffffffffL;
4120     t7   += t6  >> 57; r[ 6] = t6  & 0x1ffffffffffffffL;
4121     t8   += t7  >> 57; r[ 7] = t7  & 0x1ffffffffffffffL;
4122     t9   += t8  >> 57; r[ 8] = t8  & 0x1ffffffffffffffL;
4123     t10  += t9  >> 57; r[ 9] = t9  & 0x1ffffffffffffffL;
4124     t11  += t10 >> 57; r[10] = t10 & 0x1ffffffffffffffL;
4125     t12  += t11 >> 57; r[11] = t11 & 0x1ffffffffffffffL;
4126     t13  += t12 >> 57; r[12] = t12 & 0x1ffffffffffffffL;
4127     t14  += t13 >> 57; r[13] = t13 & 0x1ffffffffffffffL;
4128     t15  += t14 >> 57; r[14] = t14 & 0x1ffffffffffffffL;
4129     t16  += t15 >> 57; r[15] = t15 & 0x1ffffffffffffffL;
4130     r[17] = (sp_digit)(t16 >> 57);
4131                        r[16] = t16 & 0x1ffffffffffffffL;
4132 }
4133 
4134 /* Add b to a into r. (r = a + b)
4135  *
4136  * r  A single precision integer.
4137  * a  A single precision integer.
4138  * b  A single precision integer.
4139  */
sp_2048_add_9(sp_digit * r,const sp_digit * a,const sp_digit * b)4140 SP_NOINLINE static int sp_2048_add_9(sp_digit* r, const sp_digit* a,
4141         const sp_digit* b)
4142 {
4143     r[ 0] = a[ 0] + b[ 0];
4144     r[ 1] = a[ 1] + b[ 1];
4145     r[ 2] = a[ 2] + b[ 2];
4146     r[ 3] = a[ 3] + b[ 3];
4147     r[ 4] = a[ 4] + b[ 4];
4148     r[ 5] = a[ 5] + b[ 5];
4149     r[ 6] = a[ 6] + b[ 6];
4150     r[ 7] = a[ 7] + b[ 7];
4151     r[ 8] = a[ 8] + b[ 8];
4152 
4153     return 0;
4154 }
4155 
4156 /* Add b to a into r. (r = a + b)
4157  *
4158  * r  A single precision integer.
4159  * a  A single precision integer.
4160  * b  A single precision integer.
4161  */
sp_2048_add_18(sp_digit * r,const sp_digit * a,const sp_digit * b)4162 SP_NOINLINE static int sp_2048_add_18(sp_digit* r, const sp_digit* a,
4163         const sp_digit* b)
4164 {
4165     int i;
4166 
4167     for (i = 0; i < 16; i += 8) {
4168         r[i + 0] = a[i + 0] + b[i + 0];
4169         r[i + 1] = a[i + 1] + b[i + 1];
4170         r[i + 2] = a[i + 2] + b[i + 2];
4171         r[i + 3] = a[i + 3] + b[i + 3];
4172         r[i + 4] = a[i + 4] + b[i + 4];
4173         r[i + 5] = a[i + 5] + b[i + 5];
4174         r[i + 6] = a[i + 6] + b[i + 6];
4175         r[i + 7] = a[i + 7] + b[i + 7];
4176     }
4177     r[16] = a[16] + b[16];
4178     r[17] = a[17] + b[17];
4179 
4180     return 0;
4181 }
4182 
4183 /* Sub b from a into r. (r = a - b)
4184  *
4185  * r  A single precision integer.
4186  * a  A single precision integer.
4187  * b  A single precision integer.
4188  */
sp_2048_sub_18(sp_digit * r,const sp_digit * a,const sp_digit * b)4189 SP_NOINLINE static int sp_2048_sub_18(sp_digit* r, const sp_digit* a,
4190         const sp_digit* b)
4191 {
4192     int i;
4193 
4194     for (i = 0; i < 16; i += 8) {
4195         r[i + 0] = a[i + 0] - b[i + 0];
4196         r[i + 1] = a[i + 1] - b[i + 1];
4197         r[i + 2] = a[i + 2] - b[i + 2];
4198         r[i + 3] = a[i + 3] - b[i + 3];
4199         r[i + 4] = a[i + 4] - b[i + 4];
4200         r[i + 5] = a[i + 5] - b[i + 5];
4201         r[i + 6] = a[i + 6] - b[i + 6];
4202         r[i + 7] = a[i + 7] - b[i + 7];
4203     }
4204     r[16] = a[16] - b[16];
4205     r[17] = a[17] - b[17];
4206 
4207     return 0;
4208 }
4209 
4210 /* Multiply a and b into r. (r = a * b)
4211  *
4212  * r  A single precision integer.
4213  * a  A single precision integer.
4214  * b  A single precision integer.
4215  */
sp_2048_mul_18(sp_digit * r,const sp_digit * a,const sp_digit * b)4216 SP_NOINLINE static void sp_2048_mul_18(sp_digit* r, const sp_digit* a,
4217     const sp_digit* b)
4218 {
4219     sp_digit* z0 = r;
4220     sp_digit z1[18];
4221     sp_digit* a1 = z1;
4222     sp_digit b1[9];
4223     sp_digit* z2 = r + 18;
4224     (void)sp_2048_add_9(a1, a, &a[9]);
4225     (void)sp_2048_add_9(b1, b, &b[9]);
4226     sp_2048_mul_9(z2, &a[9], &b[9]);
4227     sp_2048_mul_9(z0, a, b);
4228     sp_2048_mul_9(z1, a1, b1);
4229     (void)sp_2048_sub_18(z1, z1, z2);
4230     (void)sp_2048_sub_18(z1, z1, z0);
4231     (void)sp_2048_add_18(r + 9, r + 9, z1);
4232 }
4233 
4234 /* Square a and put result in r. (r = a * a)
4235  *
4236  * r  A single precision integer.
4237  * a  A single precision integer.
4238  */
sp_2048_sqr_18(sp_digit * r,const sp_digit * a)4239 SP_NOINLINE static void sp_2048_sqr_18(sp_digit* r, const sp_digit* a)
4240 {
4241     sp_digit* z0 = r;
4242     sp_digit z1[18];
4243     sp_digit* a1 = z1;
4244     sp_digit* z2 = r + 18;
4245     (void)sp_2048_add_9(a1, a, &a[9]);
4246     sp_2048_sqr_9(z2, &a[9]);
4247     sp_2048_sqr_9(z0, a);
4248     sp_2048_sqr_9(z1, a1);
4249     (void)sp_2048_sub_18(z1, z1, z2);
4250     (void)sp_2048_sub_18(z1, z1, z0);
4251     (void)sp_2048_add_18(r + 9, r + 9, z1);
4252 }
4253 
4254 /* Add b to a into r. (r = a + b)
4255  *
4256  * r  A single precision integer.
4257  * a  A single precision integer.
4258  * b  A single precision integer.
4259  */
sp_2048_add_36(sp_digit * r,const sp_digit * a,const sp_digit * b)4260 SP_NOINLINE static int sp_2048_add_36(sp_digit* r, const sp_digit* a,
4261         const sp_digit* b)
4262 {
4263     int i;
4264 
4265     for (i = 0; i < 32; i += 8) {
4266         r[i + 0] = a[i + 0] + b[i + 0];
4267         r[i + 1] = a[i + 1] + b[i + 1];
4268         r[i + 2] = a[i + 2] + b[i + 2];
4269         r[i + 3] = a[i + 3] + b[i + 3];
4270         r[i + 4] = a[i + 4] + b[i + 4];
4271         r[i + 5] = a[i + 5] + b[i + 5];
4272         r[i + 6] = a[i + 6] + b[i + 6];
4273         r[i + 7] = a[i + 7] + b[i + 7];
4274     }
4275     r[32] = a[32] + b[32];
4276     r[33] = a[33] + b[33];
4277     r[34] = a[34] + b[34];
4278     r[35] = a[35] + b[35];
4279 
4280     return 0;
4281 }
4282 
4283 /* Sub b from a into r. (r = a - b)
4284  *
4285  * r  A single precision integer.
4286  * a  A single precision integer.
4287  * b  A single precision integer.
4288  */
sp_2048_sub_36(sp_digit * r,const sp_digit * a,const sp_digit * b)4289 SP_NOINLINE static int sp_2048_sub_36(sp_digit* r, const sp_digit* a,
4290         const sp_digit* b)
4291 {
4292     int i;
4293 
4294     for (i = 0; i < 32; i += 8) {
4295         r[i + 0] = a[i + 0] - b[i + 0];
4296         r[i + 1] = a[i + 1] - b[i + 1];
4297         r[i + 2] = a[i + 2] - b[i + 2];
4298         r[i + 3] = a[i + 3] - b[i + 3];
4299         r[i + 4] = a[i + 4] - b[i + 4];
4300         r[i + 5] = a[i + 5] - b[i + 5];
4301         r[i + 6] = a[i + 6] - b[i + 6];
4302         r[i + 7] = a[i + 7] - b[i + 7];
4303     }
4304     r[32] = a[32] - b[32];
4305     r[33] = a[33] - b[33];
4306     r[34] = a[34] - b[34];
4307     r[35] = a[35] - b[35];
4308 
4309     return 0;
4310 }
4311 
4312 /* Multiply a and b into r. (r = a * b)
4313  *
4314  * r  A single precision integer.
4315  * a  A single precision integer.
4316  * b  A single precision integer.
4317  */
sp_2048_mul_36(sp_digit * r,const sp_digit * a,const sp_digit * b)4318 SP_NOINLINE static void sp_2048_mul_36(sp_digit* r, const sp_digit* a,
4319     const sp_digit* b)
4320 {
4321     sp_digit* z0 = r;
4322     sp_digit z1[36];
4323     sp_digit* a1 = z1;
4324     sp_digit b1[18];
4325     sp_digit* z2 = r + 36;
4326     (void)sp_2048_add_18(a1, a, &a[18]);
4327     (void)sp_2048_add_18(b1, b, &b[18]);
4328     sp_2048_mul_18(z2, &a[18], &b[18]);
4329     sp_2048_mul_18(z0, a, b);
4330     sp_2048_mul_18(z1, a1, b1);
4331     (void)sp_2048_sub_36(z1, z1, z2);
4332     (void)sp_2048_sub_36(z1, z1, z0);
4333     (void)sp_2048_add_36(r + 18, r + 18, z1);
4334 }
4335 
4336 /* Square a and put result in r. (r = a * a)
4337  *
4338  * r  A single precision integer.
4339  * a  A single precision integer.
4340  */
sp_2048_sqr_36(sp_digit * r,const sp_digit * a)4341 SP_NOINLINE static void sp_2048_sqr_36(sp_digit* r, const sp_digit* a)
4342 {
4343     sp_digit* z0 = r;
4344     sp_digit z1[36];
4345     sp_digit* a1 = z1;
4346     sp_digit* z2 = r + 36;
4347     (void)sp_2048_add_18(a1, a, &a[18]);
4348     sp_2048_sqr_18(z2, &a[18]);
4349     sp_2048_sqr_18(z0, a);
4350     sp_2048_sqr_18(z1, a1);
4351     (void)sp_2048_sub_36(z1, z1, z2);
4352     (void)sp_2048_sub_36(z1, z1, z0);
4353     (void)sp_2048_add_36(r + 18, r + 18, z1);
4354 }
4355 
4356 #endif /* !WOLFSSL_SP_SMALL */
4357 /* Caclulate the bottom digit of -1/a mod 2^n.
4358  *
4359  * a    A single precision number.
4360  * rho  Bottom word of inverse.
4361  */
sp_2048_mont_setup(const sp_digit * a,sp_digit * rho)4362 static void sp_2048_mont_setup(const sp_digit* a, sp_digit* rho)
4363 {
4364     sp_digit x;
4365     sp_digit b;
4366 
4367     b = a[0];
4368     x = (((b + 2) & 4) << 1) + b; /* here x*a==1 mod 2**4 */
4369     x *= 2 - b * x;               /* here x*a==1 mod 2**8 */
4370     x *= 2 - b * x;               /* here x*a==1 mod 2**16 */
4371     x *= 2 - b * x;               /* here x*a==1 mod 2**32 */
4372     x *= 2 - b * x;               /* here x*a==1 mod 2**64 */
4373     x &= 0x1ffffffffffffffL;
4374 
4375     /* rho = -1/m mod b */
4376     *rho = ((sp_digit)1 << 57) - x;
4377 }
4378 
4379 /* Multiply a by scalar b into r. (r = a * b)
4380  *
4381  * r  A single precision integer.
4382  * a  A single precision integer.
4383  * b  A scalar.
4384  */
sp_2048_mul_d_36(sp_digit * r,const sp_digit * a,sp_digit b)4385 SP_NOINLINE static void sp_2048_mul_d_36(sp_digit* r, const sp_digit* a,
4386     sp_digit b)
4387 {
4388     sp_int128 tb = b;
4389     sp_int128 t = 0;
4390     sp_digit t2;
4391     sp_int128 p[4];
4392     int i;
4393 
4394     for (i = 0; i < 36; i += 4) {
4395         p[0] = tb * a[i + 0];
4396         p[1] = tb * a[i + 1];
4397         p[2] = tb * a[i + 2];
4398         p[3] = tb * a[i + 3];
4399         t += p[0];
4400         t2 = (sp_digit)(t & 0x1ffffffffffffffL);
4401         t >>= 57;
4402         r[i + 0] = (sp_digit)t2;
4403         t += p[1];
4404         t2 = (sp_digit)(t & 0x1ffffffffffffffL);
4405         t >>= 57;
4406         r[i + 1] = (sp_digit)t2;
4407         t += p[2];
4408         t2 = (sp_digit)(t & 0x1ffffffffffffffL);
4409         t >>= 57;
4410         r[i + 2] = (sp_digit)t2;
4411         t += p[3];
4412         t2 = (sp_digit)(t & 0x1ffffffffffffffL);
4413         t >>= 57;
4414         r[i + 3] = (sp_digit)t2;
4415     }
4416     r[36] = (sp_digit)(t & 0x1ffffffffffffffL);
4417 }
4418 
4419 #if (defined(WOLFSSL_HAVE_SP_RSA) && !defined(WOLFSSL_RSA_PUBLIC_ONLY)) || defined(WOLFSSL_HAVE_SP_DH)
4420 /* r = 2^n mod m where n is the number of bits to reduce by.
4421  * Given m must be 2048 bits, just need to subtract.
4422  *
4423  * r  A single precision number.
4424  * m  A single precision number.
4425  */
sp_2048_mont_norm_18(sp_digit * r,const sp_digit * m)4426 static void sp_2048_mont_norm_18(sp_digit* r, const sp_digit* m)
4427 {
4428     /* Set r = 2^n - 1. */
4429     int i;
4430 
4431     for (i = 0; i < 16; i += 8) {
4432         r[i + 0] = 0x1ffffffffffffffL;
4433         r[i + 1] = 0x1ffffffffffffffL;
4434         r[i + 2] = 0x1ffffffffffffffL;
4435         r[i + 3] = 0x1ffffffffffffffL;
4436         r[i + 4] = 0x1ffffffffffffffL;
4437         r[i + 5] = 0x1ffffffffffffffL;
4438         r[i + 6] = 0x1ffffffffffffffL;
4439         r[i + 7] = 0x1ffffffffffffffL;
4440     }
4441     r[16] = 0x1ffffffffffffffL;
4442     r[17] = 0x7fffffffffffffL;
4443 
4444     /* r = (2^n - 1) mod n */
4445     (void)sp_2048_sub_18(r, r, m);
4446 
4447     /* Add one so r = 2^n mod m */
4448     r[0] += 1;
4449 }
4450 
4451 /* Compare a with b in constant time.
4452  *
4453  * a  A single precision integer.
4454  * b  A single precision integer.
4455  * return -ve, 0 or +ve if a is less than, equal to or greater than b
4456  * respectively.
4457  */
sp_2048_cmp_18(const sp_digit * a,const sp_digit * b)4458 static sp_digit sp_2048_cmp_18(const sp_digit* a, const sp_digit* b)
4459 {
4460     sp_digit r = 0;
4461     int i;
4462 
4463     r |= (a[17] - b[17]) & (0 - (sp_digit)1);
4464     r |= (a[16] - b[16]) & (0 - (sp_digit)((r == 0) ? 1 : 0));
4465     for (i = 8; i >= 0; i -= 8) {
4466         r |= (a[i + 7] - b[i + 7]) & (0 - (sp_digit)((r == 0) ? 1 : 0));
4467         r |= (a[i + 6] - b[i + 6]) & (0 - (sp_digit)((r == 0) ? 1 : 0));
4468         r |= (a[i + 5] - b[i + 5]) & (0 - (sp_digit)((r == 0) ? 1 : 0));
4469         r |= (a[i + 4] - b[i + 4]) & (0 - (sp_digit)((r == 0) ? 1 : 0));
4470         r |= (a[i + 3] - b[i + 3]) & (0 - (sp_digit)((r == 0) ? 1 : 0));
4471         r |= (a[i + 2] - b[i + 2]) & (0 - (sp_digit)((r == 0) ? 1 : 0));
4472         r |= (a[i + 1] - b[i + 1]) & (0 - (sp_digit)((r == 0) ? 1 : 0));
4473         r |= (a[i + 0] - b[i + 0]) & (0 - (sp_digit)((r == 0) ? 1 : 0));
4474     }
4475 
4476     return r;
4477 }
4478 
4479 /* Conditionally subtract b from a using the mask m.
4480  * m is -1 to subtract and 0 when not.
4481  *
4482  * r  A single precision number representing condition subtract result.
4483  * a  A single precision number to subtract from.
4484  * b  A single precision number to subtract.
4485  * m  Mask value to apply.
4486  */
sp_2048_cond_sub_18(sp_digit * r,const sp_digit * a,const sp_digit * b,const sp_digit m)4487 static void sp_2048_cond_sub_18(sp_digit* r, const sp_digit* a,
4488         const sp_digit* b, const sp_digit m)
4489 {
4490     int i;
4491 
4492     for (i = 0; i < 16; i += 8) {
4493         r[i + 0] = a[i + 0] - (b[i + 0] & m);
4494         r[i + 1] = a[i + 1] - (b[i + 1] & m);
4495         r[i + 2] = a[i + 2] - (b[i + 2] & m);
4496         r[i + 3] = a[i + 3] - (b[i + 3] & m);
4497         r[i + 4] = a[i + 4] - (b[i + 4] & m);
4498         r[i + 5] = a[i + 5] - (b[i + 5] & m);
4499         r[i + 6] = a[i + 6] - (b[i + 6] & m);
4500         r[i + 7] = a[i + 7] - (b[i + 7] & m);
4501     }
4502     r[16] = a[16] - (b[16] & m);
4503     r[17] = a[17] - (b[17] & m);
4504 }
4505 
4506 /* Mul a by scalar b and add into r. (r += a * b)
4507  *
4508  * r  A single precision integer.
4509  * a  A single precision integer.
4510  * b  A scalar.
4511  */
sp_2048_mul_add_18(sp_digit * r,const sp_digit * a,const sp_digit b)4512 SP_NOINLINE static void sp_2048_mul_add_18(sp_digit* r, const sp_digit* a,
4513         const sp_digit b)
4514 {
4515     sp_int128 tb = b;
4516     sp_int128 t[8];
4517     int i;
4518 
4519     t[0] = tb * a[0]; r[0] += (sp_digit)(t[0] & 0x1ffffffffffffffL);
4520     for (i = 0; i < 16; i += 8) {
4521         t[1] = tb * a[i+1];
4522         r[i+1] += (sp_digit)((t[0] >> 57) + (t[1] & 0x1ffffffffffffffL));
4523         t[2] = tb * a[i+2];
4524         r[i+2] += (sp_digit)((t[1] >> 57) + (t[2] & 0x1ffffffffffffffL));
4525         t[3] = tb * a[i+3];
4526         r[i+3] += (sp_digit)((t[2] >> 57) + (t[3] & 0x1ffffffffffffffL));
4527         t[4] = tb * a[i+4];
4528         r[i+4] += (sp_digit)((t[3] >> 57) + (t[4] & 0x1ffffffffffffffL));
4529         t[5] = tb * a[i+5];
4530         r[i+5] += (sp_digit)((t[4] >> 57) + (t[5] & 0x1ffffffffffffffL));
4531         t[6] = tb * a[i+6];
4532         r[i+6] += (sp_digit)((t[5] >> 57) + (t[6] & 0x1ffffffffffffffL));
4533         t[7] = tb * a[i+7];
4534         r[i+7] += (sp_digit)((t[6] >> 57) + (t[7] & 0x1ffffffffffffffL));
4535         t[0] = tb * a[i+8];
4536         r[i+8] += (sp_digit)((t[7] >> 57) + (t[0] & 0x1ffffffffffffffL));
4537     }
4538     t[1] = tb * a[17];
4539     r[17] += (sp_digit)((t[0] >> 57) + (t[1] & 0x1ffffffffffffffL));
4540     r[18] +=  (sp_digit)(t[1] >> 57);
4541 }
4542 
4543 /* Shift the result in the high 1024 bits down to the bottom.
4544  *
4545  * r  A single precision number.
4546  * a  A single precision number.
4547  */
sp_2048_mont_shift_18(sp_digit * r,const sp_digit * a)4548 static void sp_2048_mont_shift_18(sp_digit* r, const sp_digit* a)
4549 {
4550     sp_uint64 n;
4551     int i;
4552 
4553     n  = (sp_uint64)a[17];
4554     n  = n >> 55U;
4555     for (i = 0; i < 16; i += 8) {
4556         n += (sp_uint64)a[i+18] << 2U; r[i+0] = n & 0x1ffffffffffffffUL; n >>= 57U;
4557         n += (sp_uint64)a[i+19] << 2U; r[i+1] = n & 0x1ffffffffffffffUL; n >>= 57U;
4558         n += (sp_uint64)a[i+20] << 2U; r[i+2] = n & 0x1ffffffffffffffUL; n >>= 57U;
4559         n += (sp_uint64)a[i+21] << 2U; r[i+3] = n & 0x1ffffffffffffffUL; n >>= 57U;
4560         n += (sp_uint64)a[i+22] << 2U; r[i+4] = n & 0x1ffffffffffffffUL; n >>= 57U;
4561         n += (sp_uint64)a[i+23] << 2U; r[i+5] = n & 0x1ffffffffffffffUL; n >>= 57U;
4562         n += (sp_uint64)a[i+24] << 2U; r[i+6] = n & 0x1ffffffffffffffUL; n >>= 57U;
4563         n += (sp_uint64)a[i+25] << 2U; r[i+7] = n & 0x1ffffffffffffffUL; n >>= 57U;
4564     }
4565     n += (sp_uint64)a[34] << 2U; r[16] = n & 0x1ffffffffffffffUL; n >>= 57U;
4566     n += (sp_uint64)a[35] << 2U; r[17] = n;
4567     XMEMSET(&r[18], 0, sizeof(*r) * 18U);
4568 }
4569 
4570 /* Reduce the number back to 2048 bits using Montgomery reduction.
4571  *
4572  * a   A single precision number to reduce in place.
4573  * m   The single precision number representing the modulus.
4574  * mp  The digit representing the negative inverse of m mod 2^n.
4575  */
sp_2048_mont_reduce_18(sp_digit * a,const sp_digit * m,sp_digit mp)4576 static void sp_2048_mont_reduce_18(sp_digit* a, const sp_digit* m, sp_digit mp)
4577 {
4578     int i;
4579     sp_digit mu;
4580 
4581     sp_2048_norm_18(a + 18);
4582 
4583     for (i=0; i<17; i++) {
4584         mu = (a[i] * mp) & 0x1ffffffffffffffL;
4585         sp_2048_mul_add_18(a+i, m, mu);
4586         a[i+1] += a[i] >> 57;
4587     }
4588     mu = (a[i] * mp) & 0x7fffffffffffffL;
4589     sp_2048_mul_add_18(a+i, m, mu);
4590     a[i+1] += a[i] >> 57;
4591     a[i] &= 0x1ffffffffffffffL;
4592     sp_2048_mont_shift_18(a, a);
4593     sp_2048_cond_sub_18(a, a, m, 0 - (((a[17] - m[17]) > 0) ?
4594             (sp_digit)1 : (sp_digit)0));
4595     sp_2048_norm_18(a);
4596 }
4597 
4598 /* Multiply two Montgomery form numbers mod the modulus (prime).
4599  * (r = a * b mod m)
4600  *
4601  * r   Result of multiplication.
4602  * a   First number to multiply in Montgomery form.
4603  * b   Second number to multiply in Montgomery form.
4604  * m   Modulus (prime).
4605  * mp  Montgomery mulitplier.
4606  */
sp_2048_mont_mul_18(sp_digit * r,const sp_digit * a,const sp_digit * b,const sp_digit * m,sp_digit mp)4607 static void sp_2048_mont_mul_18(sp_digit* r, const sp_digit* a,
4608         const sp_digit* b, const sp_digit* m, sp_digit mp)
4609 {
4610     sp_2048_mul_18(r, a, b);
4611     sp_2048_mont_reduce_18(r, m, mp);
4612 }
4613 
4614 /* Square the Montgomery form number. (r = a * a mod m)
4615  *
4616  * r   Result of squaring.
4617  * a   Number to square in Montgomery form.
4618  * m   Modulus (prime).
4619  * mp  Montgomery mulitplier.
4620  */
sp_2048_mont_sqr_18(sp_digit * r,const sp_digit * a,const sp_digit * m,sp_digit mp)4621 static void sp_2048_mont_sqr_18(sp_digit* r, const sp_digit* a,
4622         const sp_digit* m, sp_digit mp)
4623 {
4624     sp_2048_sqr_18(r, a);
4625     sp_2048_mont_reduce_18(r, m, mp);
4626 }
4627 
4628 /* Multiply a by scalar b into r. (r = a * b)
4629  *
4630  * r  A single precision integer.
4631  * a  A single precision integer.
4632  * b  A scalar.
4633  */
sp_2048_mul_d_18(sp_digit * r,const sp_digit * a,sp_digit b)4634 SP_NOINLINE static void sp_2048_mul_d_18(sp_digit* r, const sp_digit* a,
4635     sp_digit b)
4636 {
4637     sp_int128 tb = b;
4638     sp_int128 t = 0;
4639     sp_digit t2;
4640     sp_int128 p[4];
4641     int i;
4642 
4643     for (i = 0; i < 16; i += 4) {
4644         p[0] = tb * a[i + 0];
4645         p[1] = tb * a[i + 1];
4646         p[2] = tb * a[i + 2];
4647         p[3] = tb * a[i + 3];
4648         t += p[0];
4649         t2 = (sp_digit)(t & 0x1ffffffffffffffL);
4650         t >>= 57;
4651         r[i + 0] = (sp_digit)t2;
4652         t += p[1];
4653         t2 = (sp_digit)(t & 0x1ffffffffffffffL);
4654         t >>= 57;
4655         r[i + 1] = (sp_digit)t2;
4656         t += p[2];
4657         t2 = (sp_digit)(t & 0x1ffffffffffffffL);
4658         t >>= 57;
4659         r[i + 2] = (sp_digit)t2;
4660         t += p[3];
4661         t2 = (sp_digit)(t & 0x1ffffffffffffffL);
4662         t >>= 57;
4663         r[i + 3] = (sp_digit)t2;
4664     }
4665     t += tb * a[16];
4666     r[16] = (sp_digit)(t & 0x1ffffffffffffffL);
4667     t >>= 57;
4668     t += tb * a[17];
4669     r[17] = (sp_digit)(t & 0x1ffffffffffffffL);
4670     t >>= 57;
4671     r[18] = (sp_digit)(t & 0x1ffffffffffffffL);
4672 }
4673 
4674 /* Conditionally add a and b using the mask m.
4675  * m is -1 to add and 0 when not.
4676  *
4677  * r  A single precision number representing conditional add result.
4678  * a  A single precision number to add with.
4679  * b  A single precision number to add.
4680  * m  Mask value to apply.
4681  */
sp_2048_cond_add_18(sp_digit * r,const sp_digit * a,const sp_digit * b,const sp_digit m)4682 static void sp_2048_cond_add_18(sp_digit* r, const sp_digit* a,
4683         const sp_digit* b, const sp_digit m)
4684 {
4685     int i;
4686 
4687     for (i = 0; i < 16; i += 8) {
4688         r[i + 0] = a[i + 0] + (b[i + 0] & m);
4689         r[i + 1] = a[i + 1] + (b[i + 1] & m);
4690         r[i + 2] = a[i + 2] + (b[i + 2] & m);
4691         r[i + 3] = a[i + 3] + (b[i + 3] & m);
4692         r[i + 4] = a[i + 4] + (b[i + 4] & m);
4693         r[i + 5] = a[i + 5] + (b[i + 5] & m);
4694         r[i + 6] = a[i + 6] + (b[i + 6] & m);
4695         r[i + 7] = a[i + 7] + (b[i + 7] & m);
4696     }
4697     r[16] = a[16] + (b[16] & m);
4698     r[17] = a[17] + (b[17] & m);
4699 }
4700 
sp_2048_rshift_18(sp_digit * r,const sp_digit * a,byte n)4701 SP_NOINLINE static void sp_2048_rshift_18(sp_digit* r, const sp_digit* a,
4702         byte n)
4703 {
4704     int i;
4705 
4706     for (i=0; i<16; i += 8) {
4707         r[i+0] = (a[i+0] >> n) | ((a[i+1] << (57 - n)) & 0x1ffffffffffffffL);
4708         r[i+1] = (a[i+1] >> n) | ((a[i+2] << (57 - n)) & 0x1ffffffffffffffL);
4709         r[i+2] = (a[i+2] >> n) | ((a[i+3] << (57 - n)) & 0x1ffffffffffffffL);
4710         r[i+3] = (a[i+3] >> n) | ((a[i+4] << (57 - n)) & 0x1ffffffffffffffL);
4711         r[i+4] = (a[i+4] >> n) | ((a[i+5] << (57 - n)) & 0x1ffffffffffffffL);
4712         r[i+5] = (a[i+5] >> n) | ((a[i+6] << (57 - n)) & 0x1ffffffffffffffL);
4713         r[i+6] = (a[i+6] >> n) | ((a[i+7] << (57 - n)) & 0x1ffffffffffffffL);
4714         r[i+7] = (a[i+7] >> n) | ((a[i+8] << (57 - n)) & 0x1ffffffffffffffL);
4715     }
4716     r[16] = (a[16] >> n) | ((a[17] << (57 - n)) & 0x1ffffffffffffffL);
4717     r[17] = a[17] >> n;
4718 }
4719 
4720 #ifdef WOLFSSL_SP_DIV_64
sp_2048_div_word_18(sp_digit d1,sp_digit d0,sp_digit dv)4721 static WC_INLINE sp_digit sp_2048_div_word_18(sp_digit d1, sp_digit d0,
4722     sp_digit dv)
4723 {
4724     sp_digit d;
4725     sp_digit r;
4726     sp_digit t;
4727 
4728     /* All 57 bits from d1 and top 6 bits from d0. */
4729     d = (d1 << 6) + (d0 >> 51);
4730     r = d / dv;
4731     d -= r * dv;
4732     /* Up to 7 bits in r */
4733     /* Next 6 bits from d0. */
4734     r <<= 6;
4735     d <<= 6;
4736     d += (d0 >> 45) & ((1 << 6) - 1);
4737     t = d / dv;
4738     d -= t * dv;
4739     r += t;
4740     /* Up to 13 bits in r */
4741     /* Next 6 bits from d0. */
4742     r <<= 6;
4743     d <<= 6;
4744     d += (d0 >> 39) & ((1 << 6) - 1);
4745     t = d / dv;
4746     d -= t * dv;
4747     r += t;
4748     /* Up to 19 bits in r */
4749     /* Next 6 bits from d0. */
4750     r <<= 6;
4751     d <<= 6;
4752     d += (d0 >> 33) & ((1 << 6) - 1);
4753     t = d / dv;
4754     d -= t * dv;
4755     r += t;
4756     /* Up to 25 bits in r */
4757     /* Next 6 bits from d0. */
4758     r <<= 6;
4759     d <<= 6;
4760     d += (d0 >> 27) & ((1 << 6) - 1);
4761     t = d / dv;
4762     d -= t * dv;
4763     r += t;
4764     /* Up to 31 bits in r */
4765     /* Next 6 bits from d0. */
4766     r <<= 6;
4767     d <<= 6;
4768     d += (d0 >> 21) & ((1 << 6) - 1);
4769     t = d / dv;
4770     d -= t * dv;
4771     r += t;
4772     /* Up to 37 bits in r */
4773     /* Next 6 bits from d0. */
4774     r <<= 6;
4775     d <<= 6;
4776     d += (d0 >> 15) & ((1 << 6) - 1);
4777     t = d / dv;
4778     d -= t * dv;
4779     r += t;
4780     /* Up to 43 bits in r */
4781     /* Next 6 bits from d0. */
4782     r <<= 6;
4783     d <<= 6;
4784     d += (d0 >> 9) & ((1 << 6) - 1);
4785     t = d / dv;
4786     d -= t * dv;
4787     r += t;
4788     /* Up to 49 bits in r */
4789     /* Next 6 bits from d0. */
4790     r <<= 6;
4791     d <<= 6;
4792     d += (d0 >> 3) & ((1 << 6) - 1);
4793     t = d / dv;
4794     d -= t * dv;
4795     r += t;
4796     /* Up to 55 bits in r */
4797     /* Remaining 3 bits from d0. */
4798     r <<= 3;
4799     d <<= 3;
4800     d += d0 & ((1 << 3) - 1);
4801     t = d / dv;
4802     r += t;
4803 
4804     /* All 57 bits from d1 and top 6 bits from d0. */
4805     return r;
4806 }
4807 #endif /* WOLFSSL_SP_DIV_64 */
4808 
4809 /* Divide d in a and put remainder into r (m*d + r = a)
4810  * m is not calculated as it is not needed at this time.
4811  *
4812  * Full implementation.
4813  *
4814  * a  Number to be divided.
4815  * d  Number to divide with.
4816  * m  Multiplier result.
4817  * r  Remainder from the division.
4818  * returns MEMORY_E when unable to allocate memory and MP_OKAY otherwise.
4819  */
sp_2048_div_18(const sp_digit * a,const sp_digit * d,const sp_digit * m,sp_digit * r)4820 static int sp_2048_div_18(const sp_digit* a, const sp_digit* d,
4821         const sp_digit* m, sp_digit* r)
4822 {
4823     int i;
4824 #ifndef WOLFSSL_SP_DIV_64
4825     sp_int128 d1;
4826 #endif
4827     sp_digit dv;
4828     sp_digit r1;
4829 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
4830     sp_digit* t1 = NULL;
4831 #else
4832     sp_digit t1[4 * 18 + 3];
4833 #endif
4834     sp_digit* t2 = NULL;
4835     sp_digit* sd = NULL;
4836     int err = MP_OKAY;
4837 
4838     (void)m;
4839 
4840 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
4841     t1 = (sp_digit*)XMALLOC(sizeof(sp_digit) * (4 * 18 + 3), NULL,
4842                                                        DYNAMIC_TYPE_TMP_BUFFER);
4843     if (t1 == NULL)
4844         err = MEMORY_E;
4845 #endif
4846 
4847     (void)m;
4848 
4849     if (err == MP_OKAY) {
4850         t2 = t1 + 36 + 1;
4851         sd = t2 + 18 + 1;
4852 
4853         sp_2048_mul_d_18(sd, d, (sp_digit)1 << 2);
4854         sp_2048_mul_d_36(t1, a, (sp_digit)1 << 2);
4855         dv = sd[17];
4856         t1[18 + 18] += t1[18 + 18 - 1] >> 57;
4857         t1[18 + 18 - 1] &= 0x1ffffffffffffffL;
4858         for (i=18; i>=0; i--) {
4859 #ifndef WOLFSSL_SP_DIV_64
4860             d1 = t1[18 + i];
4861             d1 <<= 57;
4862             d1 += t1[18 + i - 1];
4863             r1 = (sp_digit)(d1 / dv);
4864 #else
4865             r1 = sp_2048_div_word_18(t1[18 + i], t1[18 + i - 1], dv);
4866 #endif
4867 
4868             sp_2048_mul_d_18(t2, sd, r1);
4869             (void)sp_2048_sub_18(&t1[i], &t1[i], t2);
4870             sp_2048_norm_18(&t1[i]);
4871             t1[18 + i] -= t2[18];
4872             t1[18 + i] += t1[18 + i - 1] >> 57;
4873             t1[18 + i - 1] &= 0x1ffffffffffffffL;
4874 #ifndef WOLFSSL_SP_DIV_64
4875             d1 = -t1[18 + i];
4876             d1 <<= 57;
4877             d1 -= t1[18 + i - 1];
4878             r1 = (sp_digit)(d1 / dv);
4879 #else
4880             r1 = sp_2048_div_word_18(-t1[18 + i], -t1[18 + i - 1], dv);
4881 #endif
4882             r1 -= t1[18 + i];
4883             sp_2048_mul_d_18(t2, sd, r1);
4884             (void)sp_2048_add_18(&t1[i], &t1[i], t2);
4885             t1[18 + i] += t1[18 + i - 1] >> 57;
4886             t1[18 + i - 1] &= 0x1ffffffffffffffL;
4887         }
4888         t1[18 - 1] += t1[18 - 2] >> 57;
4889         t1[18 - 2] &= 0x1ffffffffffffffL;
4890         r1 = t1[18 - 1] / dv;
4891 
4892         sp_2048_mul_d_18(t2, sd, r1);
4893         sp_2048_sub_18(t1, t1, t2);
4894         XMEMCPY(r, t1, sizeof(*r) * 36U);
4895         for (i=0; i<17; i++) {
4896             r[i+1] += r[i] >> 57;
4897             r[i] &= 0x1ffffffffffffffL;
4898         }
4899         sp_2048_cond_add_18(r, r, sd, 0 - ((r[17] < 0) ?
4900                     (sp_digit)1 : (sp_digit)0));
4901 
4902         sp_2048_norm_18(r);
4903         sp_2048_rshift_18(r, r, 2);
4904     }
4905 
4906 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
4907     if (t1 != NULL)
4908         XFREE(t1, NULL, DYNAMIC_TYPE_TMP_BUFFER);
4909 #endif
4910 
4911     return err;
4912 }
4913 
4914 /* Reduce a modulo m into r. (r = a mod m)
4915  *
4916  * r  A single precision number that is the reduced result.
4917  * a  A single precision number that is to be reduced.
4918  * m  A single precision number that is the modulus to reduce with.
4919  * returns MEMORY_E when unable to allocate memory and MP_OKAY otherwise.
4920  */
sp_2048_mod_18(sp_digit * r,const sp_digit * a,const sp_digit * m)4921 static int sp_2048_mod_18(sp_digit* r, const sp_digit* a, const sp_digit* m)
4922 {
4923     return sp_2048_div_18(a, m, NULL, r);
4924 }
4925 
4926 /* Modular exponentiate a to the e mod m. (r = a^e mod m)
4927  *
4928  * r     A single precision number that is the result of the operation.
4929  * a     A single precision number being exponentiated.
4930  * e     A single precision number that is the exponent.
4931  * bits  The number of bits in the exponent.
4932  * m     A single precision number that is the modulus.
4933  * returns  0 on success.
4934  * returns  MEMORY_E on dynamic memory allocation failure.
4935  * returns  MP_VAL when base is even or exponent is 0.
4936  */
sp_2048_mod_exp_18(sp_digit * r,const sp_digit * a,const sp_digit * e,int bits,const sp_digit * m,int reduceA)4937 static int sp_2048_mod_exp_18(sp_digit* r, const sp_digit* a, const sp_digit* e,
4938     int bits, const sp_digit* m, int reduceA)
4939 {
4940 #if defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SP_FAST_MODEXP)
4941 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
4942     sp_digit* td = NULL;
4943 #else
4944     sp_digit td[3 * 36];
4945 #endif
4946     sp_digit* t[3] = {0, 0, 0};
4947     sp_digit* norm = NULL;
4948     sp_digit mp = 1;
4949     sp_digit n;
4950     int i;
4951     int c;
4952     byte y;
4953     int err = MP_OKAY;
4954 
4955     if ((m[0] & 1) == 0) {
4956         err = MP_VAL;
4957     }
4958     else if (bits == 0) {
4959         err = MP_VAL;
4960     }
4961 
4962 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
4963     if (err == MP_OKAY) {
4964         td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 3 * 18 * 2, NULL,
4965                                 DYNAMIC_TYPE_TMP_BUFFER);
4966         if (td == NULL)
4967             err = MEMORY_E;
4968     }
4969 #endif
4970 
4971     if (err == MP_OKAY) {
4972         norm = td;
4973         for (i=0; i<3; i++) {
4974             t[i] = td + (i * 18 * 2);
4975             XMEMSET(t[i], 0, sizeof(sp_digit) * 18U * 2U);
4976         }
4977 
4978         sp_2048_mont_setup(m, &mp);
4979         sp_2048_mont_norm_18(norm, m);
4980 
4981         if (reduceA != 0) {
4982             err = sp_2048_mod_18(t[1], a, m);
4983         }
4984         else {
4985             XMEMCPY(t[1], a, sizeof(sp_digit) * 18U);
4986         }
4987     }
4988     if (err == MP_OKAY) {
4989         sp_2048_mul_18(t[1], t[1], norm);
4990         err = sp_2048_mod_18(t[1], t[1], m);
4991     }
4992 
4993     if (err == MP_OKAY) {
4994         i = bits / 57;
4995         c = bits % 57;
4996         n = e[i--] << (57 - c);
4997         for (; ; c--) {
4998             if (c == 0) {
4999                 if (i == -1) {
5000                     break;
5001                 }
5002 
5003                 n = e[i--];
5004                 c = 57;
5005             }
5006 
5007             y = (int)((n >> 56) & 1);
5008             n <<= 1;
5009 
5010             sp_2048_mont_mul_18(t[y^1], t[0], t[1], m, mp);
5011 
5012             XMEMCPY(t[2], (void*)(((size_t)t[0] & addr_mask[y^1]) +
5013                                   ((size_t)t[1] & addr_mask[y])),
5014                                   sizeof(*t[2]) * 18 * 2);
5015             sp_2048_mont_sqr_18(t[2], t[2], m, mp);
5016             XMEMCPY((void*)(((size_t)t[0] & addr_mask[y^1]) +
5017                             ((size_t)t[1] & addr_mask[y])), t[2],
5018                             sizeof(*t[2]) * 18 * 2);
5019         }
5020 
5021         sp_2048_mont_reduce_18(t[0], m, mp);
5022         n = sp_2048_cmp_18(t[0], m);
5023         sp_2048_cond_sub_18(t[0], t[0], m, ((n < 0) ?
5024                     (sp_digit)1 : (sp_digit)0) - 1);
5025         XMEMCPY(r, t[0], sizeof(*r) * 18 * 2);
5026 
5027     }
5028 
5029 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
5030     if (td != NULL)
5031         XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);
5032 #endif
5033 
5034     return err;
5035 #elif !defined(WC_NO_CACHE_RESISTANT)
5036 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
5037     sp_digit* td = NULL;
5038 #else
5039     sp_digit td[3 * 36];
5040 #endif
5041     sp_digit* t[3] = {0, 0, 0};
5042     sp_digit* norm = NULL;
5043     sp_digit mp = 1;
5044     sp_digit n;
5045     int i;
5046     int c;
5047     byte y;
5048     int err = MP_OKAY;
5049 
5050     if ((m[0] & 1) == 0) {
5051         err = MP_VAL;
5052     }
5053     else if (bits == 0) {
5054         err = MP_VAL;
5055     }
5056 
5057 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
5058     if (err == MP_OKAY) {
5059         td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 3 * 18 * 2, NULL,
5060                                 DYNAMIC_TYPE_TMP_BUFFER);
5061         if (td == NULL)
5062             err = MEMORY_E;
5063     }
5064 #endif
5065 
5066     if (err == MP_OKAY) {
5067         norm = td;
5068         for (i=0; i<3; i++) {
5069             t[i] = td + (i * 18 * 2);
5070         }
5071 
5072         sp_2048_mont_setup(m, &mp);
5073         sp_2048_mont_norm_18(norm, m);
5074 
5075         if (reduceA != 0) {
5076             err = sp_2048_mod_18(t[1], a, m);
5077             if (err == MP_OKAY) {
5078                 sp_2048_mul_18(t[1], t[1], norm);
5079                 err = sp_2048_mod_18(t[1], t[1], m);
5080             }
5081         }
5082         else {
5083             sp_2048_mul_18(t[1], a, norm);
5084             err = sp_2048_mod_18(t[1], t[1], m);
5085         }
5086     }
5087 
5088     if (err == MP_OKAY) {
5089         i = bits / 57;
5090         c = bits % 57;
5091         n = e[i--] << (57 - c);
5092         for (; ; c--) {
5093             if (c == 0) {
5094                 if (i == -1) {
5095                     break;
5096                 }
5097 
5098                 n = e[i--];
5099                 c = 57;
5100             }
5101 
5102             y = (int)((n >> 56) & 1);
5103             n <<= 1;
5104 
5105             sp_2048_mont_mul_18(t[y^1], t[0], t[1], m, mp);
5106 
5107             XMEMCPY(t[2], (void*)(((size_t)t[0] & addr_mask[y^1]) +
5108                                   ((size_t)t[1] & addr_mask[y])),
5109                                   sizeof(*t[2]) * 18 * 2);
5110             sp_2048_mont_sqr_18(t[2], t[2], m, mp);
5111             XMEMCPY((void*)(((size_t)t[0] & addr_mask[y^1]) +
5112                             ((size_t)t[1] & addr_mask[y])), t[2],
5113                             sizeof(*t[2]) * 18 * 2);
5114         }
5115 
5116         sp_2048_mont_reduce_18(t[0], m, mp);
5117         n = sp_2048_cmp_18(t[0], m);
5118         sp_2048_cond_sub_18(t[0], t[0], m, ((n < 0) ?
5119                     (sp_digit)1 : (sp_digit)0) - 1);
5120         XMEMCPY(r, t[0], sizeof(*r) * 18 * 2);
5121     }
5122 
5123 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
5124     if (td != NULL)
5125         XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);
5126 #endif
5127 
5128     return err;
5129 #else
5130 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
5131     sp_digit* td = NULL;
5132 #else
5133     sp_digit td[(32 * 36) + 36];
5134 #endif
5135     sp_digit* t[32];
5136     sp_digit* rt = NULL;
5137     sp_digit* norm = NULL;
5138     sp_digit mp = 1;
5139     sp_digit n;
5140     int i;
5141     int c;
5142     byte y;
5143     int err = MP_OKAY;
5144 
5145     if ((m[0] & 1) == 0) {
5146         err = MP_VAL;
5147     }
5148     else if (bits == 0) {
5149         err = MP_VAL;
5150     }
5151 
5152 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
5153     if (err == MP_OKAY) {
5154         td = (sp_digit*)XMALLOC(sizeof(sp_digit) * ((32 * 36) + 36), NULL,
5155                                 DYNAMIC_TYPE_TMP_BUFFER);
5156         if (td == NULL)
5157             err = MEMORY_E;
5158     }
5159 #endif
5160 
5161     if (err == MP_OKAY) {
5162         norm = td;
5163         for (i=0; i<32; i++)
5164             t[i] = td + i * 36;
5165         rt = td + 1152;
5166 
5167         sp_2048_mont_setup(m, &mp);
5168         sp_2048_mont_norm_18(norm, m);
5169 
5170         if (reduceA != 0) {
5171             err = sp_2048_mod_18(t[1], a, m);
5172             if (err == MP_OKAY) {
5173                 sp_2048_mul_18(t[1], t[1], norm);
5174                 err = sp_2048_mod_18(t[1], t[1], m);
5175             }
5176         }
5177         else {
5178             sp_2048_mul_18(t[1], a, norm);
5179             err = sp_2048_mod_18(t[1], t[1], m);
5180         }
5181     }
5182 
5183     if (err == MP_OKAY) {
5184         sp_2048_mont_sqr_18(t[ 2], t[ 1], m, mp);
5185         sp_2048_mont_mul_18(t[ 3], t[ 2], t[ 1], m, mp);
5186         sp_2048_mont_sqr_18(t[ 4], t[ 2], m, mp);
5187         sp_2048_mont_mul_18(t[ 5], t[ 3], t[ 2], m, mp);
5188         sp_2048_mont_sqr_18(t[ 6], t[ 3], m, mp);
5189         sp_2048_mont_mul_18(t[ 7], t[ 4], t[ 3], m, mp);
5190         sp_2048_mont_sqr_18(t[ 8], t[ 4], m, mp);
5191         sp_2048_mont_mul_18(t[ 9], t[ 5], t[ 4], m, mp);
5192         sp_2048_mont_sqr_18(t[10], t[ 5], m, mp);
5193         sp_2048_mont_mul_18(t[11], t[ 6], t[ 5], m, mp);
5194         sp_2048_mont_sqr_18(t[12], t[ 6], m, mp);
5195         sp_2048_mont_mul_18(t[13], t[ 7], t[ 6], m, mp);
5196         sp_2048_mont_sqr_18(t[14], t[ 7], m, mp);
5197         sp_2048_mont_mul_18(t[15], t[ 8], t[ 7], m, mp);
5198         sp_2048_mont_sqr_18(t[16], t[ 8], m, mp);
5199         sp_2048_mont_mul_18(t[17], t[ 9], t[ 8], m, mp);
5200         sp_2048_mont_sqr_18(t[18], t[ 9], m, mp);
5201         sp_2048_mont_mul_18(t[19], t[10], t[ 9], m, mp);
5202         sp_2048_mont_sqr_18(t[20], t[10], m, mp);
5203         sp_2048_mont_mul_18(t[21], t[11], t[10], m, mp);
5204         sp_2048_mont_sqr_18(t[22], t[11], m, mp);
5205         sp_2048_mont_mul_18(t[23], t[12], t[11], m, mp);
5206         sp_2048_mont_sqr_18(t[24], t[12], m, mp);
5207         sp_2048_mont_mul_18(t[25], t[13], t[12], m, mp);
5208         sp_2048_mont_sqr_18(t[26], t[13], m, mp);
5209         sp_2048_mont_mul_18(t[27], t[14], t[13], m, mp);
5210         sp_2048_mont_sqr_18(t[28], t[14], m, mp);
5211         sp_2048_mont_mul_18(t[29], t[15], t[14], m, mp);
5212         sp_2048_mont_sqr_18(t[30], t[15], m, mp);
5213         sp_2048_mont_mul_18(t[31], t[16], t[15], m, mp);
5214 
5215         bits = ((bits + 4) / 5) * 5;
5216         i = ((bits + 56) / 57) - 1;
5217         c = bits % 57;
5218         if (c == 0) {
5219             c = 57;
5220         }
5221         if (i < 18) {
5222             n = e[i--] << (64 - c);
5223         }
5224         else {
5225             n = 0;
5226             i--;
5227         }
5228         if (c < 5) {
5229             n |= e[i--] << (7 - c);
5230             c += 57;
5231         }
5232         y = (int)((n >> 59) & 0x1f);
5233         n <<= 5;
5234         c -= 5;
5235         XMEMCPY(rt, t[y], sizeof(sp_digit) * 36);
5236         while ((i >= 0) || (c >= 5)) {
5237             if (c >= 5) {
5238                 y = (byte)((n >> 59) & 0x1f);
5239                 n <<= 5;
5240                 c -= 5;
5241             }
5242             else if (c == 0) {
5243                 n = e[i--] << 7;
5244                 y = (byte)((n >> 59) & 0x1f);
5245                 n <<= 5;
5246                 c = 52;
5247             }
5248             else {
5249                 y = (byte)((n >> 59) & 0x1f);
5250                 n = e[i--] << 7;
5251                 c = 5 - c;
5252                 y |= (byte)((n >> (64 - c)) & ((1 << c) - 1));
5253                 n <<= c;
5254                 c = 57 - c;
5255             }
5256 
5257             sp_2048_mont_sqr_18(rt, rt, m, mp);
5258             sp_2048_mont_sqr_18(rt, rt, m, mp);
5259             sp_2048_mont_sqr_18(rt, rt, m, mp);
5260             sp_2048_mont_sqr_18(rt, rt, m, mp);
5261             sp_2048_mont_sqr_18(rt, rt, m, mp);
5262 
5263             sp_2048_mont_mul_18(rt, rt, t[y], m, mp);
5264         }
5265 
5266         sp_2048_mont_reduce_18(rt, m, mp);
5267         n = sp_2048_cmp_18(rt, m);
5268         sp_2048_cond_sub_18(rt, rt, m, ((n < 0) ?
5269                    (sp_digit)1 : (sp_digit)0) - 1);
5270         XMEMCPY(r, rt, sizeof(sp_digit) * 36);
5271     }
5272 
5273 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
5274     if (td != NULL)
5275         XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);
5276 #endif
5277 
5278     return err;
5279 #endif
5280 }
5281 
5282 #endif /* (WOLFSSL_HAVE_SP_RSA & !WOLFSSL_RSA_PUBLIC_ONLY) | WOLFSSL_HAVE_SP_DH */
5283 
5284 /* r = 2^n mod m where n is the number of bits to reduce by.
5285  * Given m must be 2048 bits, just need to subtract.
5286  *
5287  * r  A single precision number.
5288  * m  A single precision number.
5289  */
sp_2048_mont_norm_36(sp_digit * r,const sp_digit * m)5290 static void sp_2048_mont_norm_36(sp_digit* r, const sp_digit* m)
5291 {
5292     /* Set r = 2^n - 1. */
5293     int i;
5294 
5295     for (i = 0; i < 32; i += 8) {
5296         r[i + 0] = 0x1ffffffffffffffL;
5297         r[i + 1] = 0x1ffffffffffffffL;
5298         r[i + 2] = 0x1ffffffffffffffL;
5299         r[i + 3] = 0x1ffffffffffffffL;
5300         r[i + 4] = 0x1ffffffffffffffL;
5301         r[i + 5] = 0x1ffffffffffffffL;
5302         r[i + 6] = 0x1ffffffffffffffL;
5303         r[i + 7] = 0x1ffffffffffffffL;
5304     }
5305     r[32] = 0x1ffffffffffffffL;
5306     r[33] = 0x1ffffffffffffffL;
5307     r[34] = 0x1ffffffffffffffL;
5308     r[35] = 0x1fffffffffffffL;
5309 
5310     /* r = (2^n - 1) mod n */
5311     (void)sp_2048_sub_36(r, r, m);
5312 
5313     /* Add one so r = 2^n mod m */
5314     r[0] += 1;
5315 }
5316 
5317 /* Compare a with b in constant time.
5318  *
5319  * a  A single precision integer.
5320  * b  A single precision integer.
5321  * return -ve, 0 or +ve if a is less than, equal to or greater than b
5322  * respectively.
5323  */
sp_2048_cmp_36(const sp_digit * a,const sp_digit * b)5324 static sp_digit sp_2048_cmp_36(const sp_digit* a, const sp_digit* b)
5325 {
5326     sp_digit r = 0;
5327     int i;
5328 
5329     r |= (a[35] - b[35]) & (0 - (sp_digit)1);
5330     r |= (a[34] - b[34]) & (0 - (sp_digit)((r == 0) ? 1 : 0));
5331     r |= (a[33] - b[33]) & (0 - (sp_digit)((r == 0) ? 1 : 0));
5332     r |= (a[32] - b[32]) & (0 - (sp_digit)((r == 0) ? 1 : 0));
5333     for (i = 24; i >= 0; i -= 8) {
5334         r |= (a[i + 7] - b[i + 7]) & (0 - (sp_digit)((r == 0) ? 1 : 0));
5335         r |= (a[i + 6] - b[i + 6]) & (0 - (sp_digit)((r == 0) ? 1 : 0));
5336         r |= (a[i + 5] - b[i + 5]) & (0 - (sp_digit)((r == 0) ? 1 : 0));
5337         r |= (a[i + 4] - b[i + 4]) & (0 - (sp_digit)((r == 0) ? 1 : 0));
5338         r |= (a[i + 3] - b[i + 3]) & (0 - (sp_digit)((r == 0) ? 1 : 0));
5339         r |= (a[i + 2] - b[i + 2]) & (0 - (sp_digit)((r == 0) ? 1 : 0));
5340         r |= (a[i + 1] - b[i + 1]) & (0 - (sp_digit)((r == 0) ? 1 : 0));
5341         r |= (a[i + 0] - b[i + 0]) & (0 - (sp_digit)((r == 0) ? 1 : 0));
5342     }
5343 
5344     return r;
5345 }
5346 
5347 /* Conditionally subtract b from a using the mask m.
5348  * m is -1 to subtract and 0 when not.
5349  *
5350  * r  A single precision number representing condition subtract result.
5351  * a  A single precision number to subtract from.
5352  * b  A single precision number to subtract.
5353  * m  Mask value to apply.
5354  */
sp_2048_cond_sub_36(sp_digit * r,const sp_digit * a,const sp_digit * b,const sp_digit m)5355 static void sp_2048_cond_sub_36(sp_digit* r, const sp_digit* a,
5356         const sp_digit* b, const sp_digit m)
5357 {
5358     int i;
5359 
5360     for (i = 0; i < 32; i += 8) {
5361         r[i + 0] = a[i + 0] - (b[i + 0] & m);
5362         r[i + 1] = a[i + 1] - (b[i + 1] & m);
5363         r[i + 2] = a[i + 2] - (b[i + 2] & m);
5364         r[i + 3] = a[i + 3] - (b[i + 3] & m);
5365         r[i + 4] = a[i + 4] - (b[i + 4] & m);
5366         r[i + 5] = a[i + 5] - (b[i + 5] & m);
5367         r[i + 6] = a[i + 6] - (b[i + 6] & m);
5368         r[i + 7] = a[i + 7] - (b[i + 7] & m);
5369     }
5370     r[32] = a[32] - (b[32] & m);
5371     r[33] = a[33] - (b[33] & m);
5372     r[34] = a[34] - (b[34] & m);
5373     r[35] = a[35] - (b[35] & m);
5374 }
5375 
5376 /* Mul a by scalar b and add into r. (r += a * b)
5377  *
5378  * r  A single precision integer.
5379  * a  A single precision integer.
5380  * b  A scalar.
5381  */
sp_2048_mul_add_36(sp_digit * r,const sp_digit * a,const sp_digit b)5382 SP_NOINLINE static void sp_2048_mul_add_36(sp_digit* r, const sp_digit* a,
5383         const sp_digit b)
5384 {
5385     sp_int128 tb = b;
5386     sp_int128 t[8];
5387     int i;
5388 
5389     t[0] = tb * a[0]; r[0] += (sp_digit)(t[0] & 0x1ffffffffffffffL);
5390     for (i = 0; i < 32; i += 8) {
5391         t[1] = tb * a[i+1];
5392         r[i+1] += (sp_digit)((t[0] >> 57) + (t[1] & 0x1ffffffffffffffL));
5393         t[2] = tb * a[i+2];
5394         r[i+2] += (sp_digit)((t[1] >> 57) + (t[2] & 0x1ffffffffffffffL));
5395         t[3] = tb * a[i+3];
5396         r[i+3] += (sp_digit)((t[2] >> 57) + (t[3] & 0x1ffffffffffffffL));
5397         t[4] = tb * a[i+4];
5398         r[i+4] += (sp_digit)((t[3] >> 57) + (t[4] & 0x1ffffffffffffffL));
5399         t[5] = tb * a[i+5];
5400         r[i+5] += (sp_digit)((t[4] >> 57) + (t[5] & 0x1ffffffffffffffL));
5401         t[6] = tb * a[i+6];
5402         r[i+6] += (sp_digit)((t[5] >> 57) + (t[6] & 0x1ffffffffffffffL));
5403         t[7] = tb * a[i+7];
5404         r[i+7] += (sp_digit)((t[6] >> 57) + (t[7] & 0x1ffffffffffffffL));
5405         t[0] = tb * a[i+8];
5406         r[i+8] += (sp_digit)((t[7] >> 57) + (t[0] & 0x1ffffffffffffffL));
5407     }
5408     t[1] = tb * a[33];
5409     r[33] += (sp_digit)((t[0] >> 57) + (t[1] & 0x1ffffffffffffffL));
5410     t[2] = tb * a[34];
5411     r[34] += (sp_digit)((t[1] >> 57) + (t[2] & 0x1ffffffffffffffL));
5412     t[3] = tb * a[35];
5413     r[35] += (sp_digit)((t[2] >> 57) + (t[3] & 0x1ffffffffffffffL));
5414     r[36] +=  (sp_digit)(t[3] >> 57);
5415 }
5416 
5417 /* Shift the result in the high 2048 bits down to the bottom.
5418  *
5419  * r  A single precision number.
5420  * a  A single precision number.
5421  */
sp_2048_mont_shift_36(sp_digit * r,const sp_digit * a)5422 static void sp_2048_mont_shift_36(sp_digit* r, const sp_digit* a)
5423 {
5424     sp_digit n;
5425     sp_digit s;
5426     int i;
5427 
5428     s = a[36]; n = a[35] >> 53;
5429     for (i = 0; i < 32; i += 8) {
5430         n += (s & 0x1ffffffffffffffL) << 4; r[i+0] = n & 0x1ffffffffffffffL;
5431         n >>= 57; s = a[i+37] + (s >> 57);
5432         n += (s & 0x1ffffffffffffffL) << 4; r[i+1] = n & 0x1ffffffffffffffL;
5433         n >>= 57; s = a[i+38] + (s >> 57);
5434         n += (s & 0x1ffffffffffffffL) << 4; r[i+2] = n & 0x1ffffffffffffffL;
5435         n >>= 57; s = a[i+39] + (s >> 57);
5436         n += (s & 0x1ffffffffffffffL) << 4; r[i+3] = n & 0x1ffffffffffffffL;
5437         n >>= 57; s = a[i+40] + (s >> 57);
5438         n += (s & 0x1ffffffffffffffL) << 4; r[i+4] = n & 0x1ffffffffffffffL;
5439         n >>= 57; s = a[i+41] + (s >> 57);
5440         n += (s & 0x1ffffffffffffffL) << 4; r[i+5] = n & 0x1ffffffffffffffL;
5441         n >>= 57; s = a[i+42] + (s >> 57);
5442         n += (s & 0x1ffffffffffffffL) << 4; r[i+6] = n & 0x1ffffffffffffffL;
5443         n >>= 57; s = a[i+43] + (s >> 57);
5444         n += (s & 0x1ffffffffffffffL) << 4; r[i+7] = n & 0x1ffffffffffffffL;
5445         n >>= 57; s = a[i+44] + (s >> 57);
5446     }
5447     n += (s & 0x1ffffffffffffffL) << 4; r[32] = n & 0x1ffffffffffffffL;
5448     n >>= 57; s = a[69] + (s >> 57);
5449     n += (s & 0x1ffffffffffffffL) << 4; r[33] = n & 0x1ffffffffffffffL;
5450     n >>= 57; s = a[70] + (s >> 57);
5451     n += (s & 0x1ffffffffffffffL) << 4; r[34] = n & 0x1ffffffffffffffL;
5452     n >>= 57; s = a[71] + (s >> 57);
5453     n += s << 4;              r[35] = n;
5454     XMEMSET(&r[36], 0, sizeof(*r) * 36U);
5455 }
5456 
5457 /* Reduce the number back to 2048 bits using Montgomery reduction.
5458  *
5459  * a   A single precision number to reduce in place.
5460  * m   The single precision number representing the modulus.
5461  * mp  The digit representing the negative inverse of m mod 2^n.
5462  */
sp_2048_mont_reduce_36(sp_digit * a,const sp_digit * m,sp_digit mp)5463 static void sp_2048_mont_reduce_36(sp_digit* a, const sp_digit* m, sp_digit mp)
5464 {
5465     int i;
5466     sp_digit mu;
5467 
5468     sp_2048_norm_36(a + 36);
5469 
5470 #ifdef WOLFSSL_SP_DH
5471     if (mp != 1) {
5472         for (i=0; i<35; i++) {
5473             mu = (a[i] * mp) & 0x1ffffffffffffffL;
5474             sp_2048_mul_add_36(a+i, m, mu);
5475             a[i+1] += a[i] >> 57;
5476         }
5477         mu = (a[i] * mp) & 0x1fffffffffffffL;
5478         sp_2048_mul_add_36(a+i, m, mu);
5479         a[i+1] += a[i] >> 57;
5480         a[i] &= 0x1ffffffffffffffL;
5481     }
5482     else {
5483         for (i=0; i<35; i++) {
5484             mu = a[i] & 0x1ffffffffffffffL;
5485             sp_2048_mul_add_36(a+i, m, mu);
5486             a[i+1] += a[i] >> 57;
5487         }
5488         mu = a[i] & 0x1fffffffffffffL;
5489         sp_2048_mul_add_36(a+i, m, mu);
5490         a[i+1] += a[i] >> 57;
5491         a[i] &= 0x1ffffffffffffffL;
5492     }
5493 #else
5494     for (i=0; i<35; i++) {
5495         mu = (a[i] * mp) & 0x1ffffffffffffffL;
5496         sp_2048_mul_add_36(a+i, m, mu);
5497         a[i+1] += a[i] >> 57;
5498     }
5499     mu = (a[i] * mp) & 0x1fffffffffffffL;
5500     sp_2048_mul_add_36(a+i, m, mu);
5501     a[i+1] += a[i] >> 57;
5502     a[i] &= 0x1ffffffffffffffL;
5503 #endif
5504     sp_2048_mont_shift_36(a, a);
5505     sp_2048_cond_sub_36(a, a, m, 0 - (((a[35] - m[35]) > 0) ?
5506             (sp_digit)1 : (sp_digit)0));
5507     sp_2048_norm_36(a);
5508 }
5509 
5510 /* Multiply two Montgomery form numbers mod the modulus (prime).
5511  * (r = a * b mod m)
5512  *
5513  * r   Result of multiplication.
5514  * a   First number to multiply in Montgomery form.
5515  * b   Second number to multiply in Montgomery form.
5516  * m   Modulus (prime).
5517  * mp  Montgomery mulitplier.
5518  */
sp_2048_mont_mul_36(sp_digit * r,const sp_digit * a,const sp_digit * b,const sp_digit * m,sp_digit mp)5519 static void sp_2048_mont_mul_36(sp_digit* r, const sp_digit* a,
5520         const sp_digit* b, const sp_digit* m, sp_digit mp)
5521 {
5522     sp_2048_mul_36(r, a, b);
5523     sp_2048_mont_reduce_36(r, m, mp);
5524 }
5525 
5526 /* Square the Montgomery form number. (r = a * a mod m)
5527  *
5528  * r   Result of squaring.
5529  * a   Number to square in Montgomery form.
5530  * m   Modulus (prime).
5531  * mp  Montgomery mulitplier.
5532  */
sp_2048_mont_sqr_36(sp_digit * r,const sp_digit * a,const sp_digit * m,sp_digit mp)5533 static void sp_2048_mont_sqr_36(sp_digit* r, const sp_digit* a,
5534         const sp_digit* m, sp_digit mp)
5535 {
5536     sp_2048_sqr_36(r, a);
5537     sp_2048_mont_reduce_36(r, m, mp);
5538 }
5539 
5540 /* Multiply a by scalar b into r. (r = a * b)
5541  *
5542  * r  A single precision integer.
5543  * a  A single precision integer.
5544  * b  A scalar.
5545  */
sp_2048_mul_d_72(sp_digit * r,const sp_digit * a,sp_digit b)5546 SP_NOINLINE static void sp_2048_mul_d_72(sp_digit* r, const sp_digit* a,
5547     sp_digit b)
5548 {
5549     sp_int128 tb = b;
5550     sp_int128 t = 0;
5551     sp_digit t2;
5552     sp_int128 p[4];
5553     int i;
5554 
5555     for (i = 0; i < 72; i += 4) {
5556         p[0] = tb * a[i + 0];
5557         p[1] = tb * a[i + 1];
5558         p[2] = tb * a[i + 2];
5559         p[3] = tb * a[i + 3];
5560         t += p[0];
5561         t2 = (sp_digit)(t & 0x1ffffffffffffffL);
5562         t >>= 57;
5563         r[i + 0] = (sp_digit)t2;
5564         t += p[1];
5565         t2 = (sp_digit)(t & 0x1ffffffffffffffL);
5566         t >>= 57;
5567         r[i + 1] = (sp_digit)t2;
5568         t += p[2];
5569         t2 = (sp_digit)(t & 0x1ffffffffffffffL);
5570         t >>= 57;
5571         r[i + 2] = (sp_digit)t2;
5572         t += p[3];
5573         t2 = (sp_digit)(t & 0x1ffffffffffffffL);
5574         t >>= 57;
5575         r[i + 3] = (sp_digit)t2;
5576     }
5577     r[72] = (sp_digit)(t & 0x1ffffffffffffffL);
5578 }
5579 
5580 /* Conditionally add a and b using the mask m.
5581  * m is -1 to add and 0 when not.
5582  *
5583  * r  A single precision number representing conditional add result.
5584  * a  A single precision number to add with.
5585  * b  A single precision number to add.
5586  * m  Mask value to apply.
5587  */
sp_2048_cond_add_36(sp_digit * r,const sp_digit * a,const sp_digit * b,const sp_digit m)5588 static void sp_2048_cond_add_36(sp_digit* r, const sp_digit* a,
5589         const sp_digit* b, const sp_digit m)
5590 {
5591     int i;
5592 
5593     for (i = 0; i < 32; i += 8) {
5594         r[i + 0] = a[i + 0] + (b[i + 0] & m);
5595         r[i + 1] = a[i + 1] + (b[i + 1] & m);
5596         r[i + 2] = a[i + 2] + (b[i + 2] & m);
5597         r[i + 3] = a[i + 3] + (b[i + 3] & m);
5598         r[i + 4] = a[i + 4] + (b[i + 4] & m);
5599         r[i + 5] = a[i + 5] + (b[i + 5] & m);
5600         r[i + 6] = a[i + 6] + (b[i + 6] & m);
5601         r[i + 7] = a[i + 7] + (b[i + 7] & m);
5602     }
5603     r[32] = a[32] + (b[32] & m);
5604     r[33] = a[33] + (b[33] & m);
5605     r[34] = a[34] + (b[34] & m);
5606     r[35] = a[35] + (b[35] & m);
5607 }
5608 
sp_2048_rshift_36(sp_digit * r,const sp_digit * a,byte n)5609 SP_NOINLINE static void sp_2048_rshift_36(sp_digit* r, const sp_digit* a,
5610         byte n)
5611 {
5612     int i;
5613 
5614     for (i=0; i<32; i += 8) {
5615         r[i+0] = (a[i+0] >> n) | ((a[i+1] << (57 - n)) & 0x1ffffffffffffffL);
5616         r[i+1] = (a[i+1] >> n) | ((a[i+2] << (57 - n)) & 0x1ffffffffffffffL);
5617         r[i+2] = (a[i+2] >> n) | ((a[i+3] << (57 - n)) & 0x1ffffffffffffffL);
5618         r[i+3] = (a[i+3] >> n) | ((a[i+4] << (57 - n)) & 0x1ffffffffffffffL);
5619         r[i+4] = (a[i+4] >> n) | ((a[i+5] << (57 - n)) & 0x1ffffffffffffffL);
5620         r[i+5] = (a[i+5] >> n) | ((a[i+6] << (57 - n)) & 0x1ffffffffffffffL);
5621         r[i+6] = (a[i+6] >> n) | ((a[i+7] << (57 - n)) & 0x1ffffffffffffffL);
5622         r[i+7] = (a[i+7] >> n) | ((a[i+8] << (57 - n)) & 0x1ffffffffffffffL);
5623     }
5624     r[32] = (a[32] >> n) | ((a[33] << (57 - n)) & 0x1ffffffffffffffL);
5625     r[33] = (a[33] >> n) | ((a[34] << (57 - n)) & 0x1ffffffffffffffL);
5626     r[34] = (a[34] >> n) | ((a[35] << (57 - n)) & 0x1ffffffffffffffL);
5627     r[35] = a[35] >> n;
5628 }
5629 
5630 #ifdef WOLFSSL_SP_DIV_64
sp_2048_div_word_36(sp_digit d1,sp_digit d0,sp_digit dv)5631 static WC_INLINE sp_digit sp_2048_div_word_36(sp_digit d1, sp_digit d0,
5632     sp_digit dv)
5633 {
5634     sp_digit d;
5635     sp_digit r;
5636     sp_digit t;
5637 
5638     /* All 57 bits from d1 and top 6 bits from d0. */
5639     d = (d1 << 6) + (d0 >> 51);
5640     r = d / dv;
5641     d -= r * dv;
5642     /* Up to 7 bits in r */
5643     /* Next 6 bits from d0. */
5644     r <<= 6;
5645     d <<= 6;
5646     d += (d0 >> 45) & ((1 << 6) - 1);
5647     t = d / dv;
5648     d -= t * dv;
5649     r += t;
5650     /* Up to 13 bits in r */
5651     /* Next 6 bits from d0. */
5652     r <<= 6;
5653     d <<= 6;
5654     d += (d0 >> 39) & ((1 << 6) - 1);
5655     t = d / dv;
5656     d -= t * dv;
5657     r += t;
5658     /* Up to 19 bits in r */
5659     /* Next 6 bits from d0. */
5660     r <<= 6;
5661     d <<= 6;
5662     d += (d0 >> 33) & ((1 << 6) - 1);
5663     t = d / dv;
5664     d -= t * dv;
5665     r += t;
5666     /* Up to 25 bits in r */
5667     /* Next 6 bits from d0. */
5668     r <<= 6;
5669     d <<= 6;
5670     d += (d0 >> 27) & ((1 << 6) - 1);
5671     t = d / dv;
5672     d -= t * dv;
5673     r += t;
5674     /* Up to 31 bits in r */
5675     /* Next 6 bits from d0. */
5676     r <<= 6;
5677     d <<= 6;
5678     d += (d0 >> 21) & ((1 << 6) - 1);
5679     t = d / dv;
5680     d -= t * dv;
5681     r += t;
5682     /* Up to 37 bits in r */
5683     /* Next 6 bits from d0. */
5684     r <<= 6;
5685     d <<= 6;
5686     d += (d0 >> 15) & ((1 << 6) - 1);
5687     t = d / dv;
5688     d -= t * dv;
5689     r += t;
5690     /* Up to 43 bits in r */
5691     /* Next 6 bits from d0. */
5692     r <<= 6;
5693     d <<= 6;
5694     d += (d0 >> 9) & ((1 << 6) - 1);
5695     t = d / dv;
5696     d -= t * dv;
5697     r += t;
5698     /* Up to 49 bits in r */
5699     /* Next 6 bits from d0. */
5700     r <<= 6;
5701     d <<= 6;
5702     d += (d0 >> 3) & ((1 << 6) - 1);
5703     t = d / dv;
5704     d -= t * dv;
5705     r += t;
5706     /* Up to 55 bits in r */
5707     /* Remaining 3 bits from d0. */
5708     r <<= 3;
5709     d <<= 3;
5710     d += d0 & ((1 << 3) - 1);
5711     t = d / dv;
5712     r += t;
5713 
5714     /* All 57 bits from d1 and top 6 bits from d0. */
5715     return r;
5716 }
5717 #endif /* WOLFSSL_SP_DIV_64 */
5718 
5719 /* Divide d in a and put remainder into r (m*d + r = a)
5720  * m is not calculated as it is not needed at this time.
5721  *
5722  * Full implementation.
5723  *
5724  * a  Number to be divided.
5725  * d  Number to divide with.
5726  * m  Multiplier result.
5727  * r  Remainder from the division.
5728  * returns MEMORY_E when unable to allocate memory and MP_OKAY otherwise.
5729  */
sp_2048_div_36(const sp_digit * a,const sp_digit * d,const sp_digit * m,sp_digit * r)5730 static int sp_2048_div_36(const sp_digit* a, const sp_digit* d,
5731         const sp_digit* m, sp_digit* r)
5732 {
5733     int i;
5734 #ifndef WOLFSSL_SP_DIV_64
5735     sp_int128 d1;
5736 #endif
5737     sp_digit dv;
5738     sp_digit r1;
5739 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
5740     sp_digit* t1 = NULL;
5741 #else
5742     sp_digit t1[4 * 36 + 3];
5743 #endif
5744     sp_digit* t2 = NULL;
5745     sp_digit* sd = NULL;
5746     int err = MP_OKAY;
5747 
5748     (void)m;
5749 
5750 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
5751     t1 = (sp_digit*)XMALLOC(sizeof(sp_digit) * (4 * 36 + 3), NULL,
5752                                                        DYNAMIC_TYPE_TMP_BUFFER);
5753     if (t1 == NULL)
5754         err = MEMORY_E;
5755 #endif
5756 
5757     (void)m;
5758 
5759     if (err == MP_OKAY) {
5760         t2 = t1 + 72 + 1;
5761         sd = t2 + 36 + 1;
5762 
5763         sp_2048_mul_d_36(sd, d, (sp_digit)1 << 4);
5764         sp_2048_mul_d_72(t1, a, (sp_digit)1 << 4);
5765         dv = sd[35];
5766         t1[36 + 36] += t1[36 + 36 - 1] >> 57;
5767         t1[36 + 36 - 1] &= 0x1ffffffffffffffL;
5768         for (i=36; i>=0; i--) {
5769 #ifndef WOLFSSL_SP_DIV_64
5770             d1 = t1[36 + i];
5771             d1 <<= 57;
5772             d1 += t1[36 + i - 1];
5773             r1 = (sp_digit)(d1 / dv);
5774 #else
5775             r1 = sp_2048_div_word_36(t1[36 + i], t1[36 + i - 1], dv);
5776 #endif
5777 
5778             sp_2048_mul_d_36(t2, sd, r1);
5779             (void)sp_2048_sub_36(&t1[i], &t1[i], t2);
5780             sp_2048_norm_36(&t1[i]);
5781             t1[36 + i] -= t2[36];
5782             t1[36 + i] += t1[36 + i - 1] >> 57;
5783             t1[36 + i - 1] &= 0x1ffffffffffffffL;
5784 #ifndef WOLFSSL_SP_DIV_64
5785             d1 = -t1[36 + i];
5786             d1 <<= 57;
5787             d1 -= t1[36 + i - 1];
5788             r1 = (sp_digit)(d1 / dv);
5789 #else
5790             r1 = sp_2048_div_word_36(-t1[36 + i], -t1[36 + i - 1], dv);
5791 #endif
5792             r1 -= t1[36 + i];
5793             sp_2048_mul_d_36(t2, sd, r1);
5794             (void)sp_2048_add_36(&t1[i], &t1[i], t2);
5795             t1[36 + i] += t1[36 + i - 1] >> 57;
5796             t1[36 + i - 1] &= 0x1ffffffffffffffL;
5797         }
5798         t1[36 - 1] += t1[36 - 2] >> 57;
5799         t1[36 - 2] &= 0x1ffffffffffffffL;
5800         r1 = t1[36 - 1] / dv;
5801 
5802         sp_2048_mul_d_36(t2, sd, r1);
5803         sp_2048_sub_36(t1, t1, t2);
5804         XMEMCPY(r, t1, sizeof(*r) * 72U);
5805         for (i=0; i<35; i++) {
5806             r[i+1] += r[i] >> 57;
5807             r[i] &= 0x1ffffffffffffffL;
5808         }
5809         sp_2048_cond_add_36(r, r, sd, 0 - ((r[35] < 0) ?
5810                     (sp_digit)1 : (sp_digit)0));
5811 
5812         sp_2048_norm_36(r);
5813         sp_2048_rshift_36(r, r, 4);
5814     }
5815 
5816 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
5817     if (t1 != NULL)
5818         XFREE(t1, NULL, DYNAMIC_TYPE_TMP_BUFFER);
5819 #endif
5820 
5821     return err;
5822 }
5823 
5824 /* Reduce a modulo m into r. (r = a mod m)
5825  *
5826  * r  A single precision number that is the reduced result.
5827  * a  A single precision number that is to be reduced.
5828  * m  A single precision number that is the modulus to reduce with.
5829  * returns MEMORY_E when unable to allocate memory and MP_OKAY otherwise.
5830  */
sp_2048_mod_36(sp_digit * r,const sp_digit * a,const sp_digit * m)5831 static int sp_2048_mod_36(sp_digit* r, const sp_digit* a, const sp_digit* m)
5832 {
5833     return sp_2048_div_36(a, m, NULL, r);
5834 }
5835 
5836 #if (defined(WOLFSSL_HAVE_SP_RSA) && !defined(WOLFSSL_RSA_PUBLIC_ONLY)) || defined(WOLFSSL_HAVE_SP_DH)
5837 #if (defined(WOLFSSL_HAVE_SP_RSA) && !defined(WOLFSSL_RSA_PUBLIC_ONLY)) || \
5838                                                      defined(WOLFSSL_HAVE_SP_DH)
5839 /* Modular exponentiate a to the e mod m. (r = a^e mod m)
5840  *
5841  * r     A single precision number that is the result of the operation.
5842  * a     A single precision number being exponentiated.
5843  * e     A single precision number that is the exponent.
5844  * bits  The number of bits in the exponent.
5845  * m     A single precision number that is the modulus.
5846  * returns  0 on success.
5847  * returns  MEMORY_E on dynamic memory allocation failure.
5848  * returns  MP_VAL when base is even or exponent is 0.
5849  */
sp_2048_mod_exp_36(sp_digit * r,const sp_digit * a,const sp_digit * e,int bits,const sp_digit * m,int reduceA)5850 static int sp_2048_mod_exp_36(sp_digit* r, const sp_digit* a, const sp_digit* e,
5851     int bits, const sp_digit* m, int reduceA)
5852 {
5853 #if defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SP_FAST_MODEXP)
5854 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
5855     sp_digit* td = NULL;
5856 #else
5857     sp_digit td[3 * 72];
5858 #endif
5859     sp_digit* t[3] = {0, 0, 0};
5860     sp_digit* norm = NULL;
5861     sp_digit mp = 1;
5862     sp_digit n;
5863     int i;
5864     int c;
5865     byte y;
5866     int err = MP_OKAY;
5867 
5868     if ((m[0] & 1) == 0) {
5869         err = MP_VAL;
5870     }
5871     else if (bits == 0) {
5872         err = MP_VAL;
5873     }
5874 
5875 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
5876     if (err == MP_OKAY) {
5877         td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 3 * 36 * 2, NULL,
5878                                 DYNAMIC_TYPE_TMP_BUFFER);
5879         if (td == NULL)
5880             err = MEMORY_E;
5881     }
5882 #endif
5883 
5884     if (err == MP_OKAY) {
5885         norm = td;
5886         for (i=0; i<3; i++) {
5887             t[i] = td + (i * 36 * 2);
5888             XMEMSET(t[i], 0, sizeof(sp_digit) * 36U * 2U);
5889         }
5890 
5891         sp_2048_mont_setup(m, &mp);
5892         sp_2048_mont_norm_36(norm, m);
5893 
5894         if (reduceA != 0) {
5895             err = sp_2048_mod_36(t[1], a, m);
5896         }
5897         else {
5898             XMEMCPY(t[1], a, sizeof(sp_digit) * 36U);
5899         }
5900     }
5901     if (err == MP_OKAY) {
5902         sp_2048_mul_36(t[1], t[1], norm);
5903         err = sp_2048_mod_36(t[1], t[1], m);
5904     }
5905 
5906     if (err == MP_OKAY) {
5907         i = bits / 57;
5908         c = bits % 57;
5909         n = e[i--] << (57 - c);
5910         for (; ; c--) {
5911             if (c == 0) {
5912                 if (i == -1) {
5913                     break;
5914                 }
5915 
5916                 n = e[i--];
5917                 c = 57;
5918             }
5919 
5920             y = (int)((n >> 56) & 1);
5921             n <<= 1;
5922 
5923             sp_2048_mont_mul_36(t[y^1], t[0], t[1], m, mp);
5924 
5925             XMEMCPY(t[2], (void*)(((size_t)t[0] & addr_mask[y^1]) +
5926                                   ((size_t)t[1] & addr_mask[y])),
5927                                   sizeof(*t[2]) * 36 * 2);
5928             sp_2048_mont_sqr_36(t[2], t[2], m, mp);
5929             XMEMCPY((void*)(((size_t)t[0] & addr_mask[y^1]) +
5930                             ((size_t)t[1] & addr_mask[y])), t[2],
5931                             sizeof(*t[2]) * 36 * 2);
5932         }
5933 
5934         sp_2048_mont_reduce_36(t[0], m, mp);
5935         n = sp_2048_cmp_36(t[0], m);
5936         sp_2048_cond_sub_36(t[0], t[0], m, ((n < 0) ?
5937                     (sp_digit)1 : (sp_digit)0) - 1);
5938         XMEMCPY(r, t[0], sizeof(*r) * 36 * 2);
5939 
5940     }
5941 
5942 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
5943     if (td != NULL)
5944         XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);
5945 #endif
5946 
5947     return err;
5948 #elif !defined(WC_NO_CACHE_RESISTANT)
5949 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
5950     sp_digit* td = NULL;
5951 #else
5952     sp_digit td[3 * 72];
5953 #endif
5954     sp_digit* t[3] = {0, 0, 0};
5955     sp_digit* norm = NULL;
5956     sp_digit mp = 1;
5957     sp_digit n;
5958     int i;
5959     int c;
5960     byte y;
5961     int err = MP_OKAY;
5962 
5963     if ((m[0] & 1) == 0) {
5964         err = MP_VAL;
5965     }
5966     else if (bits == 0) {
5967         err = MP_VAL;
5968     }
5969 
5970 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
5971     if (err == MP_OKAY) {
5972         td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 3 * 36 * 2, NULL,
5973                                 DYNAMIC_TYPE_TMP_BUFFER);
5974         if (td == NULL)
5975             err = MEMORY_E;
5976     }
5977 #endif
5978 
5979     if (err == MP_OKAY) {
5980         norm = td;
5981         for (i=0; i<3; i++) {
5982             t[i] = td + (i * 36 * 2);
5983         }
5984 
5985         sp_2048_mont_setup(m, &mp);
5986         sp_2048_mont_norm_36(norm, m);
5987 
5988         if (reduceA != 0) {
5989             err = sp_2048_mod_36(t[1], a, m);
5990             if (err == MP_OKAY) {
5991                 sp_2048_mul_36(t[1], t[1], norm);
5992                 err = sp_2048_mod_36(t[1], t[1], m);
5993             }
5994         }
5995         else {
5996             sp_2048_mul_36(t[1], a, norm);
5997             err = sp_2048_mod_36(t[1], t[1], m);
5998         }
5999     }
6000 
6001     if (err == MP_OKAY) {
6002         i = bits / 57;
6003         c = bits % 57;
6004         n = e[i--] << (57 - c);
6005         for (; ; c--) {
6006             if (c == 0) {
6007                 if (i == -1) {
6008                     break;
6009                 }
6010 
6011                 n = e[i--];
6012                 c = 57;
6013             }
6014 
6015             y = (int)((n >> 56) & 1);
6016             n <<= 1;
6017 
6018             sp_2048_mont_mul_36(t[y^1], t[0], t[1], m, mp);
6019 
6020             XMEMCPY(t[2], (void*)(((size_t)t[0] & addr_mask[y^1]) +
6021                                   ((size_t)t[1] & addr_mask[y])),
6022                                   sizeof(*t[2]) * 36 * 2);
6023             sp_2048_mont_sqr_36(t[2], t[2], m, mp);
6024             XMEMCPY((void*)(((size_t)t[0] & addr_mask[y^1]) +
6025                             ((size_t)t[1] & addr_mask[y])), t[2],
6026                             sizeof(*t[2]) * 36 * 2);
6027         }
6028 
6029         sp_2048_mont_reduce_36(t[0], m, mp);
6030         n = sp_2048_cmp_36(t[0], m);
6031         sp_2048_cond_sub_36(t[0], t[0], m, ((n < 0) ?
6032                     (sp_digit)1 : (sp_digit)0) - 1);
6033         XMEMCPY(r, t[0], sizeof(*r) * 36 * 2);
6034     }
6035 
6036 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
6037     if (td != NULL)
6038         XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);
6039 #endif
6040 
6041     return err;
6042 #else
6043 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
6044     sp_digit* td = NULL;
6045 #else
6046     sp_digit td[(16 * 72) + 72];
6047 #endif
6048     sp_digit* t[16];
6049     sp_digit* rt = NULL;
6050     sp_digit* norm = NULL;
6051     sp_digit mp = 1;
6052     sp_digit n;
6053     int i;
6054     int c;
6055     byte y;
6056     int err = MP_OKAY;
6057 
6058     if ((m[0] & 1) == 0) {
6059         err = MP_VAL;
6060     }
6061     else if (bits == 0) {
6062         err = MP_VAL;
6063     }
6064 
6065 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
6066     if (err == MP_OKAY) {
6067         td = (sp_digit*)XMALLOC(sizeof(sp_digit) * ((16 * 72) + 72), NULL,
6068                                 DYNAMIC_TYPE_TMP_BUFFER);
6069         if (td == NULL)
6070             err = MEMORY_E;
6071     }
6072 #endif
6073 
6074     if (err == MP_OKAY) {
6075         norm = td;
6076         for (i=0; i<16; i++)
6077             t[i] = td + i * 72;
6078         rt = td + 1152;
6079 
6080         sp_2048_mont_setup(m, &mp);
6081         sp_2048_mont_norm_36(norm, m);
6082 
6083         if (reduceA != 0) {
6084             err = sp_2048_mod_36(t[1], a, m);
6085             if (err == MP_OKAY) {
6086                 sp_2048_mul_36(t[1], t[1], norm);
6087                 err = sp_2048_mod_36(t[1], t[1], m);
6088             }
6089         }
6090         else {
6091             sp_2048_mul_36(t[1], a, norm);
6092             err = sp_2048_mod_36(t[1], t[1], m);
6093         }
6094     }
6095 
6096     if (err == MP_OKAY) {
6097         sp_2048_mont_sqr_36(t[ 2], t[ 1], m, mp);
6098         sp_2048_mont_mul_36(t[ 3], t[ 2], t[ 1], m, mp);
6099         sp_2048_mont_sqr_36(t[ 4], t[ 2], m, mp);
6100         sp_2048_mont_mul_36(t[ 5], t[ 3], t[ 2], m, mp);
6101         sp_2048_mont_sqr_36(t[ 6], t[ 3], m, mp);
6102         sp_2048_mont_mul_36(t[ 7], t[ 4], t[ 3], m, mp);
6103         sp_2048_mont_sqr_36(t[ 8], t[ 4], m, mp);
6104         sp_2048_mont_mul_36(t[ 9], t[ 5], t[ 4], m, mp);
6105         sp_2048_mont_sqr_36(t[10], t[ 5], m, mp);
6106         sp_2048_mont_mul_36(t[11], t[ 6], t[ 5], m, mp);
6107         sp_2048_mont_sqr_36(t[12], t[ 6], m, mp);
6108         sp_2048_mont_mul_36(t[13], t[ 7], t[ 6], m, mp);
6109         sp_2048_mont_sqr_36(t[14], t[ 7], m, mp);
6110         sp_2048_mont_mul_36(t[15], t[ 8], t[ 7], m, mp);
6111 
6112         bits = ((bits + 3) / 4) * 4;
6113         i = ((bits + 56) / 57) - 1;
6114         c = bits % 57;
6115         if (c == 0) {
6116             c = 57;
6117         }
6118         if (i < 36) {
6119             n = e[i--] << (64 - c);
6120         }
6121         else {
6122             n = 0;
6123             i--;
6124         }
6125         if (c < 4) {
6126             n |= e[i--] << (7 - c);
6127             c += 57;
6128         }
6129         y = (int)((n >> 60) & 0xf);
6130         n <<= 4;
6131         c -= 4;
6132         XMEMCPY(rt, t[y], sizeof(sp_digit) * 72);
6133         while ((i >= 0) || (c >= 4)) {
6134             if (c >= 4) {
6135                 y = (byte)((n >> 60) & 0xf);
6136                 n <<= 4;
6137                 c -= 4;
6138             }
6139             else if (c == 0) {
6140                 n = e[i--] << 7;
6141                 y = (byte)((n >> 60) & 0xf);
6142                 n <<= 4;
6143                 c = 53;
6144             }
6145             else {
6146                 y = (byte)((n >> 60) & 0xf);
6147                 n = e[i--] << 7;
6148                 c = 4 - c;
6149                 y |= (byte)((n >> (64 - c)) & ((1 << c) - 1));
6150                 n <<= c;
6151                 c = 57 - c;
6152             }
6153 
6154             sp_2048_mont_sqr_36(rt, rt, m, mp);
6155             sp_2048_mont_sqr_36(rt, rt, m, mp);
6156             sp_2048_mont_sqr_36(rt, rt, m, mp);
6157             sp_2048_mont_sqr_36(rt, rt, m, mp);
6158 
6159             sp_2048_mont_mul_36(rt, rt, t[y], m, mp);
6160         }
6161 
6162         sp_2048_mont_reduce_36(rt, m, mp);
6163         n = sp_2048_cmp_36(rt, m);
6164         sp_2048_cond_sub_36(rt, rt, m, ((n < 0) ?
6165                    (sp_digit)1 : (sp_digit)0) - 1);
6166         XMEMCPY(r, rt, sizeof(sp_digit) * 72);
6167     }
6168 
6169 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
6170     if (td != NULL)
6171         XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);
6172 #endif
6173 
6174     return err;
6175 #endif
6176 }
6177 #endif /* (WOLFSSL_HAVE_SP_RSA & !WOLFSSL_RSA_PUBLIC_ONLY) || */
6178        /* WOLFSSL_HAVE_SP_DH */
6179 
6180 #endif /* (WOLFSSL_HAVE_SP_RSA && !WOLFSSL_RSA_PUBLIC_ONLY) || WOLFSSL_HAVE_SP_DH */
6181 #ifdef WOLFSSL_HAVE_SP_RSA
6182 /* RSA public key operation.
6183  *
6184  * in      Array of bytes representing the number to exponentiate, base.
6185  * inLen   Number of bytes in base.
6186  * em      Public exponent.
6187  * mm      Modulus.
6188  * out     Buffer to hold big-endian bytes of exponentiation result.
6189  *         Must be at least 256 bytes long.
6190  * outLen  Number of bytes in result.
6191  * returns 0 on success, MP_TO_E when the outLen is too small, MP_READ_E when
6192  * an array is too long and MEMORY_E when dynamic memory allocation fails.
6193  */
sp_RsaPublic_2048(const byte * in,word32 inLen,const mp_int * em,const mp_int * mm,byte * out,word32 * outLen)6194 int sp_RsaPublic_2048(const byte* in, word32 inLen, const mp_int* em,
6195     const mp_int* mm, byte* out, word32* outLen)
6196 {
6197 #ifdef WOLFSSL_SP_SMALL
6198 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
6199     sp_digit* a = NULL;
6200 #else
6201     sp_digit a[36 * 5];
6202 #endif
6203     sp_digit* m = NULL;
6204     sp_digit* r = NULL;
6205     sp_digit* norm = NULL;
6206     sp_digit e[1] = {0};
6207     sp_digit mp;
6208     int i;
6209     int err = MP_OKAY;
6210 
6211     if (*outLen < 256U) {
6212         err = MP_TO_E;
6213     }
6214 
6215     if (err == MP_OKAY) {
6216         if (mp_count_bits(em) > 57) {
6217             err = MP_READ_E;
6218         }
6219         else if (inLen > 256U) {
6220             err = MP_READ_E;
6221         }
6222         else if (mp_count_bits(mm) != 2048) {
6223             err = MP_READ_E;
6224         }
6225         else if (mp_iseven(mm)) {
6226             err = MP_VAL;
6227         }
6228     }
6229 
6230 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
6231     if (err == MP_OKAY) {
6232         a = (sp_digit*)XMALLOC(sizeof(sp_digit) * 36 * 5, NULL,
6233                                                               DYNAMIC_TYPE_RSA);
6234         if (a == NULL)
6235             err = MEMORY_E;
6236     }
6237 #endif
6238 
6239     if (err == MP_OKAY) {
6240         r = a + 36 * 2;
6241         m = r + 36 * 2;
6242         norm = r;
6243 
6244         sp_2048_from_bin(a, 36, in, inLen);
6245 #if DIGIT_BIT >= 57
6246         e[0] = (sp_digit)em->dp[0];
6247 #else
6248         e[0] = (sp_digit)em->dp[0];
6249         if (em->used > 1) {
6250             e[0] |= ((sp_digit)em->dp[1]) << DIGIT_BIT;
6251         }
6252 #endif
6253         if (e[0] == 0) {
6254             err = MP_EXPTMOD_E;
6255         }
6256     }
6257 
6258     if (err == MP_OKAY) {
6259         sp_2048_from_mp(m, 36, mm);
6260 
6261         sp_2048_mont_setup(m, &mp);
6262         sp_2048_mont_norm_36(norm, m);
6263     }
6264     if (err == MP_OKAY) {
6265         sp_2048_mul_36(a, a, norm);
6266         err = sp_2048_mod_36(a, a, m);
6267     }
6268     if (err == MP_OKAY) {
6269         for (i=56; i>=0; i--) {
6270             if ((e[0] >> i) != 0) {
6271                 break;
6272             }
6273         }
6274 
6275         XMEMCPY(r, a, sizeof(sp_digit) * 36 * 2);
6276         for (i--; i>=0; i--) {
6277             sp_2048_mont_sqr_36(r, r, m, mp);
6278 
6279             if (((e[0] >> i) & 1) == 1) {
6280                 sp_2048_mont_mul_36(r, r, a, m, mp);
6281             }
6282         }
6283         sp_2048_mont_reduce_36(r, m, mp);
6284         mp = sp_2048_cmp_36(r, m);
6285         sp_2048_cond_sub_36(r, r, m, ((mp < 0) ?
6286                     (sp_digit)1 : (sp_digit)0)- 1);
6287 
6288         sp_2048_to_bin_36(r, out);
6289         *outLen = 256;
6290     }
6291 
6292 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
6293     if (a != NULL)
6294         XFREE(a, NULL, DYNAMIC_TYPE_RSA);
6295 #endif
6296 
6297     return err;
6298 #else
6299 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
6300     sp_digit* d = NULL;
6301 #else
6302     sp_digit d[36 * 5];
6303 #endif
6304     sp_digit* a = NULL;
6305     sp_digit* m = NULL;
6306     sp_digit* r = NULL;
6307     sp_digit e[1] = {0};
6308     int err = MP_OKAY;
6309 
6310     if (*outLen < 256U) {
6311         err = MP_TO_E;
6312     }
6313     if (err == MP_OKAY) {
6314         if (mp_count_bits(em) > 57) {
6315             err = MP_READ_E;
6316         }
6317         else if (inLen > 256U) {
6318             err = MP_READ_E;
6319         }
6320         else if (mp_count_bits(mm) != 2048) {
6321             err = MP_READ_E;
6322         }
6323         else if (mp_iseven(mm)) {
6324             err = MP_VAL;
6325         }
6326     }
6327 
6328 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
6329     if (err == MP_OKAY) {
6330         d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 36 * 5, NULL,
6331                                                               DYNAMIC_TYPE_RSA);
6332         if (d == NULL)
6333             err = MEMORY_E;
6334     }
6335 #endif
6336 
6337     if (err == MP_OKAY) {
6338         a = d;
6339         r = a + 36 * 2;
6340         m = r + 36 * 2;
6341 
6342         sp_2048_from_bin(a, 36, in, inLen);
6343 #if DIGIT_BIT >= 57
6344         e[0] = (sp_digit)em->dp[0];
6345 #else
6346         e[0] = (sp_digit)em->dp[0];
6347         if (em->used > 1) {
6348             e[0] |= ((sp_digit)em->dp[1]) << DIGIT_BIT;
6349         }
6350 #endif
6351         if (e[0] == 0) {
6352             err = MP_EXPTMOD_E;
6353         }
6354     }
6355     if (err == MP_OKAY) {
6356         sp_2048_from_mp(m, 36, mm);
6357 
6358         if (e[0] == 0x3) {
6359             sp_2048_sqr_36(r, a);
6360             err = sp_2048_mod_36(r, r, m);
6361             if (err == MP_OKAY) {
6362                 sp_2048_mul_36(r, a, r);
6363                 err = sp_2048_mod_36(r, r, m);
6364             }
6365         }
6366         else {
6367             sp_digit* norm = r;
6368             int i;
6369             sp_digit mp;
6370 
6371             sp_2048_mont_setup(m, &mp);
6372             sp_2048_mont_norm_36(norm, m);
6373 
6374             sp_2048_mul_36(a, a, norm);
6375             err = sp_2048_mod_36(a, a, m);
6376 
6377             if (err == MP_OKAY) {
6378                 for (i=56; i>=0; i--) {
6379                     if ((e[0] >> i) != 0) {
6380                         break;
6381                     }
6382                 }
6383 
6384                 XMEMCPY(r, a, sizeof(sp_digit) * 72U);
6385                 for (i--; i>=0; i--) {
6386                     sp_2048_mont_sqr_36(r, r, m, mp);
6387 
6388                     if (((e[0] >> i) & 1) == 1) {
6389                         sp_2048_mont_mul_36(r, r, a, m, mp);
6390                     }
6391                 }
6392                 sp_2048_mont_reduce_36(r, m, mp);
6393                 mp = sp_2048_cmp_36(r, m);
6394                 sp_2048_cond_sub_36(r, r, m, ((mp < 0) ?
6395                            (sp_digit)1 : (sp_digit)0) - 1);
6396             }
6397         }
6398     }
6399 
6400     if (err == MP_OKAY) {
6401         sp_2048_to_bin_36(r, out);
6402         *outLen = 256;
6403     }
6404 
6405 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
6406     if (d != NULL)
6407         XFREE(d, NULL, DYNAMIC_TYPE_RSA);
6408 #endif
6409 
6410     return err;
6411 #endif /* WOLFSSL_SP_SMALL */
6412 }
6413 
6414 #ifndef WOLFSSL_RSA_PUBLIC_ONLY
6415 #if !defined(SP_RSA_PRIVATE_EXP_D) && !defined(RSA_LOW_MEM)
6416 #endif /* !SP_RSA_PRIVATE_EXP_D & !RSA_LOW_MEM */
6417 /* RSA private key operation.
6418  *
6419  * in      Array of bytes representing the number to exponentiate, base.
6420  * inLen   Number of bytes in base.
6421  * dm      Private exponent.
6422  * pm      First prime.
6423  * qm      Second prime.
6424  * dpm     First prime's CRT exponent.
6425  * dqm     Second prime's CRT exponent.
6426  * qim     Inverse of second prime mod p.
6427  * mm      Modulus.
6428  * out     Buffer to hold big-endian bytes of exponentiation result.
6429  *         Must be at least 256 bytes long.
6430  * outLen  Number of bytes in result.
6431  * returns 0 on success, MP_TO_E when the outLen is too small, MP_READ_E when
6432  * an array is too long and MEMORY_E when dynamic memory allocation fails.
6433  */
sp_RsaPrivate_2048(const byte * in,word32 inLen,const mp_int * dm,const mp_int * pm,const mp_int * qm,const mp_int * dpm,const mp_int * dqm,const mp_int * qim,const mp_int * mm,byte * out,word32 * outLen)6434 int sp_RsaPrivate_2048(const byte* in, word32 inLen, const mp_int* dm,
6435     const mp_int* pm, const mp_int* qm, const mp_int* dpm, const mp_int* dqm,
6436     const mp_int* qim, const mp_int* mm, byte* out, word32* outLen)
6437 {
6438 #if defined(SP_RSA_PRIVATE_EXP_D) || defined(RSA_LOW_MEM)
6439 #if defined(WOLFSSL_SP_SMALL)
6440 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
6441     sp_digit* d = NULL;
6442 #else
6443     sp_digit  d[36 * 4];
6444 #endif
6445     sp_digit* a = NULL;
6446     sp_digit* m = NULL;
6447     sp_digit* r = NULL;
6448     int err = MP_OKAY;
6449 
6450     (void)pm;
6451     (void)qm;
6452     (void)dpm;
6453     (void)dqm;
6454     (void)qim;
6455 
6456     if (*outLen < 256U) {
6457         err = MP_TO_E;
6458     }
6459     if (err == MP_OKAY) {
6460         if (mp_count_bits(dm) > 2048) {
6461            err = MP_READ_E;
6462         }
6463         else if (inLen > 256) {
6464             err = MP_READ_E;
6465         }
6466         else if (mp_count_bits(mm) != 2048) {
6467             err = MP_READ_E;
6468         }
6469         else if (mp_iseven(mm)) {
6470             err = MP_VAL;
6471         }
6472     }
6473 
6474 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
6475     if (err == MP_OKAY) {
6476         d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 36 * 4, NULL,
6477                                                               DYNAMIC_TYPE_RSA);
6478         if (d == NULL)
6479             err = MEMORY_E;
6480     }
6481 #endif
6482 
6483     if (err == MP_OKAY) {
6484         a = d + 36;
6485         m = a + 72;
6486         r = a;
6487 
6488         sp_2048_from_bin(a, 36, in, inLen);
6489         sp_2048_from_mp(d, 36, dm);
6490         sp_2048_from_mp(m, 36, mm);
6491         err = sp_2048_mod_exp_36(r, a, d, 2048, m, 0);
6492     }
6493 
6494     if (err == MP_OKAY) {
6495         sp_2048_to_bin_36(r, out);
6496         *outLen = 256;
6497     }
6498 
6499 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
6500     if (d != NULL)
6501 #endif
6502     {
6503         /* only "a" and "r" are sensitive and need zeroized (same pointer) */
6504         if (a != NULL)
6505             ForceZero(a, sizeof(sp_digit) * 36);
6506 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
6507         XFREE(d, NULL, DYNAMIC_TYPE_RSA);
6508 #endif
6509     }
6510 
6511     return err;
6512 #else
6513 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
6514     sp_digit* d = NULL;
6515 #else
6516     sp_digit d[36 * 4];
6517 #endif
6518     sp_digit* a = NULL;
6519     sp_digit* m = NULL;
6520     sp_digit* r = NULL;
6521     int err = MP_OKAY;
6522 
6523     (void)pm;
6524     (void)qm;
6525     (void)dpm;
6526     (void)dqm;
6527     (void)qim;
6528 
6529     if (*outLen < 256U) {
6530         err = MP_TO_E;
6531     }
6532     if (err == MP_OKAY) {
6533         if (mp_count_bits(dm) > 2048) {
6534             err = MP_READ_E;
6535         }
6536         else if (inLen > 256U) {
6537             err = MP_READ_E;
6538         }
6539         else if (mp_count_bits(mm) != 2048) {
6540             err = MP_READ_E;
6541         }
6542         else if (mp_iseven(mm)) {
6543             err = MP_VAL;
6544         }
6545     }
6546 
6547 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
6548     if (err == MP_OKAY) {
6549         d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 36 * 4, NULL,
6550                                                               DYNAMIC_TYPE_RSA);
6551         if (d == NULL)
6552             err = MEMORY_E;
6553     }
6554 #endif
6555 
6556     if (err == MP_OKAY) {
6557         a = d + 36;
6558         m = a + 72;
6559         r = a;
6560 
6561         sp_2048_from_bin(a, 36, in, inLen);
6562         sp_2048_from_mp(d, 36, dm);
6563         sp_2048_from_mp(m, 36, mm);
6564         err = sp_2048_mod_exp_36(r, a, d, 2048, m, 0);
6565     }
6566 
6567     if (err == MP_OKAY) {
6568         sp_2048_to_bin_36(r, out);
6569         *outLen = 256;
6570     }
6571 
6572 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
6573     if (d != NULL)
6574 #endif
6575     {
6576         /* only "a" and "r" are sensitive and need zeroized (same pointer) */
6577         if (a != NULL)
6578             ForceZero(a, sizeof(sp_digit) * 36);
6579 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
6580         XFREE(d, NULL, DYNAMIC_TYPE_RSA);
6581 #endif
6582     }
6583 
6584     return err;
6585 #endif /* WOLFSSL_SP_SMALL */
6586 #else
6587 #if defined(WOLFSSL_SP_SMALL)
6588 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
6589     sp_digit* a = NULL;
6590 #else
6591     sp_digit a[18 * 8];
6592 #endif
6593     sp_digit* p = NULL;
6594     sp_digit* dp = NULL;
6595     sp_digit* dq = NULL;
6596     sp_digit* qi = NULL;
6597     sp_digit* tmpa = NULL;
6598     sp_digit* tmpb = NULL;
6599     sp_digit* r = NULL;
6600     int err = MP_OKAY;
6601 
6602     (void)dm;
6603     (void)mm;
6604 
6605     if (*outLen < 256U) {
6606         err = MP_TO_E;
6607     }
6608     if (err == MP_OKAY) {
6609         if (inLen > 256) {
6610             err = MP_READ_E;
6611         }
6612         else if (mp_count_bits(mm) != 2048) {
6613             err = MP_READ_E;
6614         }
6615         else if (mp_iseven(mm)) {
6616             err = MP_VAL;
6617         }
6618     }
6619 
6620 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
6621     if (err == MP_OKAY) {
6622         a = (sp_digit*)XMALLOC(sizeof(sp_digit) * 18 * 8, NULL,
6623                                                               DYNAMIC_TYPE_RSA);
6624         if (a == NULL)
6625             err = MEMORY_E;
6626     }
6627 #endif
6628     if (err == MP_OKAY) {
6629         p = a + 36;
6630         qi = dq = dp = p + 18;
6631         tmpa = qi + 18;
6632         tmpb = tmpa + 36;
6633         r = a;
6634 
6635         sp_2048_from_bin(a, 36, in, inLen);
6636         sp_2048_from_mp(p, 18, pm);
6637         sp_2048_from_mp(dp, 18, dpm);
6638         err = sp_2048_mod_exp_18(tmpa, a, dp, 1024, p, 1);
6639     }
6640     if (err == MP_OKAY) {
6641         sp_2048_from_mp(p, 18, qm);
6642         sp_2048_from_mp(dq, 18, dqm);
6643         err = sp_2048_mod_exp_18(tmpb, a, dq, 1024, p, 1);
6644     }
6645     if (err == MP_OKAY) {
6646         sp_2048_from_mp(p, 18, pm);
6647         (void)sp_2048_sub_18(tmpa, tmpa, tmpb);
6648         sp_2048_norm_18(tmpa);
6649         sp_2048_cond_add_18(tmpa, tmpa, p, 0 - ((sp_int_digit)tmpa[17] >> 63));
6650         sp_2048_cond_add_18(tmpa, tmpa, p, 0 - ((sp_int_digit)tmpa[17] >> 63));
6651         sp_2048_norm_18(tmpa);
6652 
6653         sp_2048_from_mp(qi, 18, qim);
6654         sp_2048_mul_18(tmpa, tmpa, qi);
6655         err = sp_2048_mod_18(tmpa, tmpa, p);
6656     }
6657 
6658     if (err == MP_OKAY) {
6659         sp_2048_from_mp(p, 18, qm);
6660         sp_2048_mul_18(tmpa, p, tmpa);
6661         (void)sp_2048_add_36(r, tmpb, tmpa);
6662         sp_2048_norm_36(r);
6663 
6664         sp_2048_to_bin_36(r, out);
6665         *outLen = 256;
6666     }
6667 
6668 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
6669     if (a != NULL)
6670 #endif
6671     {
6672         ForceZero(a, sizeof(sp_digit) * 18 * 8);
6673 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
6674         XFREE(a, NULL, DYNAMIC_TYPE_RSA);
6675 #endif
6676     }
6677 
6678     return err;
6679 #else
6680 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
6681     sp_digit* a = NULL;
6682 #else
6683     sp_digit a[18 * 13];
6684 #endif
6685     sp_digit* p = NULL;
6686     sp_digit* q = NULL;
6687     sp_digit* dp = NULL;
6688     sp_digit* dq = NULL;
6689     sp_digit* qi = NULL;
6690     sp_digit* tmpa = NULL;
6691     sp_digit* tmpb = NULL;
6692     sp_digit* r = NULL;
6693     int err = MP_OKAY;
6694 
6695     (void)dm;
6696     (void)mm;
6697 
6698     if (*outLen < 256U) {
6699         err = MP_TO_E;
6700     }
6701     if (err == MP_OKAY) {
6702         if (inLen > 256U) {
6703             err = MP_READ_E;
6704         }
6705         else if (mp_count_bits(mm) != 2048) {
6706             err = MP_READ_E;
6707         }
6708         else if (mp_iseven(mm)) {
6709             err = MP_VAL;
6710         }
6711     }
6712 
6713 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
6714     if (err == MP_OKAY) {
6715         a = (sp_digit*)XMALLOC(sizeof(sp_digit) * 18 * 13, NULL,
6716                                                               DYNAMIC_TYPE_RSA);
6717         if (a == NULL)
6718             err = MEMORY_E;
6719     }
6720 #endif
6721 
6722     if (err == MP_OKAY) {
6723         p = a + 36 * 2;
6724         q = p + 18;
6725         dp = q + 18;
6726         dq = dp + 18;
6727         qi = dq + 18;
6728         tmpa = qi + 18;
6729         tmpb = tmpa + 36;
6730         r = a;
6731 
6732         sp_2048_from_bin(a, 36, in, inLen);
6733         sp_2048_from_mp(p, 18, pm);
6734         sp_2048_from_mp(q, 18, qm);
6735         sp_2048_from_mp(dp, 18, dpm);
6736         sp_2048_from_mp(dq, 18, dqm);
6737         sp_2048_from_mp(qi, 18, qim);
6738 
6739         err = sp_2048_mod_exp_18(tmpa, a, dp, 1024, p, 1);
6740     }
6741     if (err == MP_OKAY) {
6742         err = sp_2048_mod_exp_18(tmpb, a, dq, 1024, q, 1);
6743     }
6744 
6745     if (err == MP_OKAY) {
6746         (void)sp_2048_sub_18(tmpa, tmpa, tmpb);
6747         sp_2048_norm_18(tmpa);
6748         sp_2048_cond_add_18(tmpa, tmpa, p, 0 - ((sp_int_digit)tmpa[17] >> 63));
6749         sp_2048_cond_add_18(tmpa, tmpa, p, 0 - ((sp_int_digit)tmpa[17] >> 63));
6750         sp_2048_norm_18(tmpa);
6751         sp_2048_mul_18(tmpa, tmpa, qi);
6752         err = sp_2048_mod_18(tmpa, tmpa, p);
6753     }
6754 
6755     if (err == MP_OKAY) {
6756         sp_2048_mul_18(tmpa, tmpa, q);
6757         (void)sp_2048_add_36(r, tmpb, tmpa);
6758         sp_2048_norm_36(r);
6759 
6760         sp_2048_to_bin_36(r, out);
6761         *outLen = 256;
6762     }
6763 
6764 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
6765 if (a != NULL)
6766 #endif
6767     {
6768         ForceZero(a, sizeof(sp_digit) * 18 * 13);
6769     #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
6770         XFREE(a, NULL, DYNAMIC_TYPE_RSA);
6771     #endif
6772     }
6773 
6774     return err;
6775 #endif /* WOLFSSL_SP_SMALL */
6776 #endif /* SP_RSA_PRIVATE_EXP_D || RSA_LOW_MEM */
6777 }
6778 
6779 #endif /* !WOLFSSL_RSA_PUBLIC_ONLY */
6780 #endif /* WOLFSSL_HAVE_SP_RSA */
6781 #if defined(WOLFSSL_HAVE_SP_DH) || (defined(WOLFSSL_HAVE_SP_RSA) && \
6782                                               !defined(WOLFSSL_RSA_PUBLIC_ONLY))
6783 /* Convert an array of sp_digit to an mp_int.
6784  *
6785  * a  A single precision integer.
6786  * r  A multi-precision integer.
6787  */
sp_2048_to_mp(const sp_digit * a,mp_int * r)6788 static int sp_2048_to_mp(const sp_digit* a, mp_int* r)
6789 {
6790     int err;
6791 
6792     err = mp_grow(r, (2048 + DIGIT_BIT - 1) / DIGIT_BIT);
6793     if (err == MP_OKAY) { /*lint !e774 case where err is always MP_OKAY*/
6794 #if DIGIT_BIT == 57
6795         XMEMCPY(r->dp, a, sizeof(sp_digit) * 36);
6796         r->used = 36;
6797         mp_clamp(r);
6798 #elif DIGIT_BIT < 57
6799         int i;
6800         int j = 0;
6801         int s = 0;
6802 
6803         r->dp[0] = 0;
6804         for (i = 0; i < 36; i++) {
6805             r->dp[j] |= (mp_digit)(a[i] << s);
6806             r->dp[j] &= ((sp_digit)1 << DIGIT_BIT) - 1;
6807             s = DIGIT_BIT - s;
6808             r->dp[++j] = (mp_digit)(a[i] >> s);
6809             while (s + DIGIT_BIT <= 57) {
6810                 s += DIGIT_BIT;
6811                 r->dp[j++] &= ((sp_digit)1 << DIGIT_BIT) - 1;
6812                 if (s == SP_WORD_SIZE) {
6813                     r->dp[j] = 0;
6814                 }
6815                 else {
6816                     r->dp[j] = (mp_digit)(a[i] >> s);
6817                 }
6818             }
6819             s = 57 - s;
6820         }
6821         r->used = (2048 + DIGIT_BIT - 1) / DIGIT_BIT;
6822         mp_clamp(r);
6823 #else
6824         int i;
6825         int j = 0;
6826         int s = 0;
6827 
6828         r->dp[0] = 0;
6829         for (i = 0; i < 36; i++) {
6830             r->dp[j] |= ((mp_digit)a[i]) << s;
6831             if (s + 57 >= DIGIT_BIT) {
6832     #if DIGIT_BIT != 32 && DIGIT_BIT != 64
6833                 r->dp[j] &= ((sp_digit)1 << DIGIT_BIT) - 1;
6834     #endif
6835                 s = DIGIT_BIT - s;
6836                 r->dp[++j] = a[i] >> s;
6837                 s = 57 - s;
6838             }
6839             else {
6840                 s += 57;
6841             }
6842         }
6843         r->used = (2048 + DIGIT_BIT - 1) / DIGIT_BIT;
6844         mp_clamp(r);
6845 #endif
6846     }
6847 
6848     return err;
6849 }
6850 
6851 /* Perform the modular exponentiation for Diffie-Hellman.
6852  *
6853  * base  Base. MP integer.
6854  * exp   Exponent. MP integer.
6855  * mod   Modulus. MP integer.
6856  * res   Result. MP integer.
6857  * returns 0 on success, MP_READ_E if there are too many bytes in an array
6858  * and MEMORY_E if memory allocation fails.
6859  */
sp_ModExp_2048(const mp_int * base,const mp_int * exp,const mp_int * mod,mp_int * res)6860 int sp_ModExp_2048(const mp_int* base, const mp_int* exp, const mp_int* mod,
6861     mp_int* res)
6862 {
6863 #ifdef WOLFSSL_SP_SMALL
6864     int err = MP_OKAY;
6865 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
6866     sp_digit* b = NULL;
6867 #else
6868     sp_digit b[36 * 4];
6869 #endif
6870     sp_digit* e = NULL;
6871     sp_digit* m = NULL;
6872     sp_digit* r = NULL;
6873     int expBits = mp_count_bits(exp);
6874 
6875     if (mp_count_bits(base) > 2048) {
6876         err = MP_READ_E;
6877     }
6878     else if (expBits > 2048) {
6879         err = MP_READ_E;
6880     }
6881     else if (mp_count_bits(mod) != 2048) {
6882         err = MP_READ_E;
6883     }
6884     else if (mp_iseven(mod)) {
6885         err = MP_VAL;
6886     }
6887 
6888 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
6889     if (err == MP_OKAY) {
6890         b = (sp_digit*)XMALLOC(sizeof(sp_digit) * 36 * 4, NULL,
6891             DYNAMIC_TYPE_DH);
6892         if (b == NULL)
6893             err = MEMORY_E;
6894     }
6895 #endif
6896 
6897     if (err == MP_OKAY) {
6898         e = b + 36 * 2;
6899         m = e + 36;
6900         r = b;
6901 
6902         sp_2048_from_mp(b, 36, base);
6903         sp_2048_from_mp(e, 36, exp);
6904         sp_2048_from_mp(m, 36, mod);
6905 
6906         err = sp_2048_mod_exp_36(r, b, e, mp_count_bits(exp), m, 0);
6907     }
6908 
6909     if (err == MP_OKAY) {
6910         err = sp_2048_to_mp(r, res);
6911     }
6912 
6913 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
6914     if (b != NULL)
6915 #endif
6916     {
6917         /* only "e" is sensitive and needs zeroized */
6918         if (e != NULL)
6919             ForceZero(e, sizeof(sp_digit) * 36U);
6920     #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
6921         XFREE(b, NULL, DYNAMIC_TYPE_DH);
6922     #endif
6923     }
6924     return err;
6925 #else
6926 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
6927     sp_digit* b = NULL;
6928 #else
6929     sp_digit b[36 * 4];
6930 #endif
6931     sp_digit* e = NULL;
6932     sp_digit* m = NULL;
6933     sp_digit* r = NULL;
6934     int err = MP_OKAY;
6935     int expBits = mp_count_bits(exp);
6936 
6937     if (mp_count_bits(base) > 2048) {
6938         err = MP_READ_E;
6939     }
6940     else if (expBits > 2048) {
6941         err = MP_READ_E;
6942     }
6943     else if (mp_count_bits(mod) != 2048) {
6944         err = MP_READ_E;
6945     }
6946     else if (mp_iseven(mod)) {
6947         err = MP_VAL;
6948     }
6949 
6950 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
6951     if (err == MP_OKAY) {
6952         b = (sp_digit*)XMALLOC(sizeof(sp_digit) * 36 * 4, NULL, DYNAMIC_TYPE_DH);
6953         if (b == NULL)
6954             err = MEMORY_E;
6955     }
6956 #endif
6957 
6958     if (err == MP_OKAY) {
6959         e = b + 36 * 2;
6960         m = e + 36;
6961         r = b;
6962 
6963         sp_2048_from_mp(b, 36, base);
6964         sp_2048_from_mp(e, 36, exp);
6965         sp_2048_from_mp(m, 36, mod);
6966 
6967         err = sp_2048_mod_exp_36(r, b, e, expBits, m, 0);
6968     }
6969 
6970     if (err == MP_OKAY) {
6971         err = sp_2048_to_mp(r, res);
6972     }
6973 
6974 
6975 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
6976     if (b != NULL)
6977 #endif
6978     {
6979         /* only "e" is sensitive and needs zeroized */
6980         if (e != NULL)
6981             ForceZero(e, sizeof(sp_digit) * 36U);
6982     #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
6983         XFREE(b, NULL, DYNAMIC_TYPE_DH);
6984     #endif
6985     }
6986 
6987     return err;
6988 #endif
6989 }
6990 
6991 #ifdef WOLFSSL_HAVE_SP_DH
6992 
6993 #ifdef HAVE_FFDHE_2048
sp_2048_lshift_36(sp_digit * r,const sp_digit * a,byte n)6994 SP_NOINLINE static void sp_2048_lshift_36(sp_digit* r, const sp_digit* a,
6995         byte n)
6996 {
6997     sp_int_digit s;
6998     sp_int_digit t;
6999 
7000     s = (sp_int_digit)a[35];
7001     r[36] = s >> (57U - n);
7002     s = (sp_int_digit)(a[35]); t = (sp_int_digit)(a[34]);
7003     r[35] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;
7004     s = (sp_int_digit)(a[34]); t = (sp_int_digit)(a[33]);
7005     r[34] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;
7006     s = (sp_int_digit)(a[33]); t = (sp_int_digit)(a[32]);
7007     r[33] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;
7008     s = (sp_int_digit)(a[32]); t = (sp_int_digit)(a[31]);
7009     r[32] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;
7010     s = (sp_int_digit)(a[31]); t = (sp_int_digit)(a[30]);
7011     r[31] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;
7012     s = (sp_int_digit)(a[30]); t = (sp_int_digit)(a[29]);
7013     r[30] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;
7014     s = (sp_int_digit)(a[29]); t = (sp_int_digit)(a[28]);
7015     r[29] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;
7016     s = (sp_int_digit)(a[28]); t = (sp_int_digit)(a[27]);
7017     r[28] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;
7018     s = (sp_int_digit)(a[27]); t = (sp_int_digit)(a[26]);
7019     r[27] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;
7020     s = (sp_int_digit)(a[26]); t = (sp_int_digit)(a[25]);
7021     r[26] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;
7022     s = (sp_int_digit)(a[25]); t = (sp_int_digit)(a[24]);
7023     r[25] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;
7024     s = (sp_int_digit)(a[24]); t = (sp_int_digit)(a[23]);
7025     r[24] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;
7026     s = (sp_int_digit)(a[23]); t = (sp_int_digit)(a[22]);
7027     r[23] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;
7028     s = (sp_int_digit)(a[22]); t = (sp_int_digit)(a[21]);
7029     r[22] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;
7030     s = (sp_int_digit)(a[21]); t = (sp_int_digit)(a[20]);
7031     r[21] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;
7032     s = (sp_int_digit)(a[20]); t = (sp_int_digit)(a[19]);
7033     r[20] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;
7034     s = (sp_int_digit)(a[19]); t = (sp_int_digit)(a[18]);
7035     r[19] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;
7036     s = (sp_int_digit)(a[18]); t = (sp_int_digit)(a[17]);
7037     r[18] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;
7038     s = (sp_int_digit)(a[17]); t = (sp_int_digit)(a[16]);
7039     r[17] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;
7040     s = (sp_int_digit)(a[16]); t = (sp_int_digit)(a[15]);
7041     r[16] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;
7042     s = (sp_int_digit)(a[15]); t = (sp_int_digit)(a[14]);
7043     r[15] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;
7044     s = (sp_int_digit)(a[14]); t = (sp_int_digit)(a[13]);
7045     r[14] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;
7046     s = (sp_int_digit)(a[13]); t = (sp_int_digit)(a[12]);
7047     r[13] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;
7048     s = (sp_int_digit)(a[12]); t = (sp_int_digit)(a[11]);
7049     r[12] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;
7050     s = (sp_int_digit)(a[11]); t = (sp_int_digit)(a[10]);
7051     r[11] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;
7052     s = (sp_int_digit)(a[10]); t = (sp_int_digit)(a[9]);
7053     r[10] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;
7054     s = (sp_int_digit)(a[9]); t = (sp_int_digit)(a[8]);
7055     r[9] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;
7056     s = (sp_int_digit)(a[8]); t = (sp_int_digit)(a[7]);
7057     r[8] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;
7058     s = (sp_int_digit)(a[7]); t = (sp_int_digit)(a[6]);
7059     r[7] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;
7060     s = (sp_int_digit)(a[6]); t = (sp_int_digit)(a[5]);
7061     r[6] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;
7062     s = (sp_int_digit)(a[5]); t = (sp_int_digit)(a[4]);
7063     r[5] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;
7064     s = (sp_int_digit)(a[4]); t = (sp_int_digit)(a[3]);
7065     r[4] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;
7066     s = (sp_int_digit)(a[3]); t = (sp_int_digit)(a[2]);
7067     r[3] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;
7068     s = (sp_int_digit)(a[2]); t = (sp_int_digit)(a[1]);
7069     r[2] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;
7070     s = (sp_int_digit)(a[1]); t = (sp_int_digit)(a[0]);
7071     r[1] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;
7072     r[0] = (a[0] << n) & 0x1ffffffffffffffL;
7073 }
7074 
7075 /* Modular exponentiate 2 to the e mod m. (r = 2^e mod m)
7076  *
7077  * r     A single precision number that is the result of the operation.
7078  * e     A single precision number that is the exponent.
7079  * bits  The number of bits in the exponent.
7080  * m     A single precision number that is the modulus.
7081  * returns  0 on success.
7082  * returns  MEMORY_E on dynamic memory allocation failure.
7083  * returns  MP_VAL when base is even.
7084  */
sp_2048_mod_exp_2_36(sp_digit * r,const sp_digit * e,int bits,const sp_digit * m)7085 static int sp_2048_mod_exp_2_36(sp_digit* r, const sp_digit* e, int bits, const sp_digit* m)
7086 {
7087 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
7088     sp_digit* td = NULL;
7089 #else
7090     sp_digit td[109];
7091 #endif
7092     sp_digit* norm = NULL;
7093     sp_digit* tmp = NULL;
7094     sp_digit mp = 1;
7095     sp_digit n;
7096     sp_digit o;
7097     int i;
7098     int c;
7099     byte y;
7100     int err = MP_OKAY;
7101 
7102     if ((m[0] & 1) == 0) {
7103         err = MP_VAL;
7104     }
7105 
7106 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
7107     if (err == MP_OKAY) {
7108         td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 109, NULL,
7109                                 DYNAMIC_TYPE_TMP_BUFFER);
7110         if (td == NULL)
7111             err = MEMORY_E;
7112     }
7113 #endif
7114 
7115     if (err == MP_OKAY) {
7116         norm = td;
7117         tmp  = td + 72;
7118         XMEMSET(td, 0, sizeof(sp_digit) * 109);
7119 
7120         sp_2048_mont_setup(m, &mp);
7121         sp_2048_mont_norm_36(norm, m);
7122 
7123         bits = ((bits + 4) / 5) * 5;
7124         i = ((bits + 56) / 57) - 1;
7125         c = bits % 57;
7126         if (c == 0) {
7127             c = 57;
7128         }
7129         if (i < 36) {
7130             n = e[i--] << (64 - c);
7131         }
7132         else {
7133             n = 0;
7134             i--;
7135         }
7136         if (c < 5) {
7137             n |= e[i--] << (7 - c);
7138             c += 57;
7139         }
7140         y = (int)((n >> 59) & 0x1f);
7141         n <<= 5;
7142         c -= 5;
7143         sp_2048_lshift_36(r, norm, (byte)y);
7144         while ((i >= 0) || (c >= 5)) {
7145             if (c >= 5) {
7146                 y = (byte)((n >> 59) & 0x1f);
7147                 n <<= 5;
7148                 c -= 5;
7149             }
7150             else if (c == 0) {
7151                 n = e[i--] << 7;
7152                 y = (byte)((n >> 59) & 0x1f);
7153                 n <<= 5;
7154                 c = 52;
7155             }
7156             else {
7157                 y = (byte)((n >> 59) & 0x1f);
7158                 n = e[i--] << 7;
7159                 c = 5 - c;
7160                 y |= (byte)((n >> (64 - c)) & ((1 << c) - 1));
7161                 n <<= c;
7162                 c = 57 - c;
7163             }
7164 
7165             sp_2048_mont_sqr_36(r, r, m, mp);
7166             sp_2048_mont_sqr_36(r, r, m, mp);
7167             sp_2048_mont_sqr_36(r, r, m, mp);
7168             sp_2048_mont_sqr_36(r, r, m, mp);
7169             sp_2048_mont_sqr_36(r, r, m, mp);
7170 
7171             sp_2048_lshift_36(r, r, (byte)y);
7172             sp_2048_mul_d_36(tmp, norm, (r[36] << 4) + (r[35] >> 53));
7173             r[36] = 0;
7174             r[35] &= 0x1fffffffffffffL;
7175             (void)sp_2048_add_36(r, r, tmp);
7176             sp_2048_norm_36(r);
7177             o = sp_2048_cmp_36(r, m);
7178             sp_2048_cond_sub_36(r, r, m, ((o < 0) ?
7179                                           (sp_digit)1 : (sp_digit)0) - 1);
7180         }
7181 
7182         sp_2048_mont_reduce_36(r, m, mp);
7183         n = sp_2048_cmp_36(r, m);
7184         sp_2048_cond_sub_36(r, r, m, ((n < 0) ?
7185                                                 (sp_digit)1 : (sp_digit)0) - 1);
7186     }
7187 
7188 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
7189     if (td != NULL)
7190         XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);
7191 #endif
7192 
7193     return err;
7194 }
7195 
7196 #endif /* HAVE_FFDHE_2048 */
7197 
7198 /* Perform the modular exponentiation for Diffie-Hellman.
7199  *
7200  * base     Base.
7201  * exp      Array of bytes that is the exponent.
7202  * expLen   Length of data, in bytes, in exponent.
7203  * mod      Modulus.
7204  * out      Buffer to hold big-endian bytes of exponentiation result.
7205  *          Must be at least 256 bytes long.
7206  * outLen   Length, in bytes, of exponentiation result.
7207  * returns 0 on success, MP_READ_E if there are too many bytes in an array
7208  * and MEMORY_E if memory allocation fails.
7209  */
sp_DhExp_2048(const mp_int * base,const byte * exp,word32 expLen,const mp_int * mod,byte * out,word32 * outLen)7210 int sp_DhExp_2048(const mp_int* base, const byte* exp, word32 expLen,
7211     const mp_int* mod, byte* out, word32* outLen)
7212 {
7213 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
7214     sp_digit* b = NULL;
7215 #else
7216     sp_digit b[36 * 4];
7217 #endif
7218     sp_digit* e = NULL;
7219     sp_digit* m = NULL;
7220     sp_digit* r = NULL;
7221     word32 i;
7222     int err = MP_OKAY;
7223 
7224     if (mp_count_bits(base) > 2048) {
7225         err = MP_READ_E;
7226     }
7227     else if (expLen > 256U) {
7228         err = MP_READ_E;
7229     }
7230     else if (mp_count_bits(mod) != 2048) {
7231         err = MP_READ_E;
7232     }
7233     else if (mp_iseven(mod)) {
7234         err = MP_VAL;
7235     }
7236 
7237 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
7238     if (err == MP_OKAY) {
7239         b = (sp_digit*)XMALLOC(sizeof(sp_digit) * 36 * 4, NULL,
7240             DYNAMIC_TYPE_DH);
7241         if (b == NULL)
7242             err = MEMORY_E;
7243     }
7244 #endif
7245 
7246     if (err == MP_OKAY) {
7247         e = b + 36 * 2;
7248         m = e + 36;
7249         r = b;
7250 
7251         sp_2048_from_mp(b, 36, base);
7252         sp_2048_from_bin(e, 36, exp, expLen);
7253         sp_2048_from_mp(m, 36, mod);
7254 
7255     #ifdef HAVE_FFDHE_2048
7256         if (base->used == 1 && base->dp[0] == 2U &&
7257                 (m[35] >> 21) == 0xffffffffL) {
7258             err = sp_2048_mod_exp_2_36(r, e, expLen * 8U, m);
7259         }
7260         else {
7261     #endif
7262             err = sp_2048_mod_exp_36(r, b, e, expLen * 8U, m, 0);
7263     #ifdef HAVE_FFDHE_2048
7264         }
7265     #endif
7266     }
7267 
7268     if (err == MP_OKAY) {
7269         sp_2048_to_bin_36(r, out);
7270         *outLen = 256;
7271         for (i=0; i<256U && out[i] == 0U; i++) {
7272             /* Search for first non-zero. */
7273         }
7274         *outLen -= i;
7275         XMEMMOVE(out, out + i, *outLen);
7276     }
7277 
7278 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
7279     if (b != NULL)
7280 #endif
7281     {
7282         /* only "e" is sensitive and needs zeroized */
7283         if (e != NULL)
7284             ForceZero(e, sizeof(sp_digit) * 36U);
7285     #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
7286         XFREE(b, NULL, DYNAMIC_TYPE_DH);
7287     #endif
7288     }
7289 
7290     return err;
7291 }
7292 #endif /* WOLFSSL_HAVE_SP_DH */
7293 
7294 /* Perform the modular exponentiation for Diffie-Hellman.
7295  *
7296  * base  Base. MP integer.
7297  * exp   Exponent. MP integer.
7298  * mod   Modulus. MP integer.
7299  * res   Result. MP integer.
7300  * returns 0 on success, MP_READ_E if there are too many bytes in an array
7301  * and MEMORY_E if memory allocation fails.
7302  */
sp_ModExp_1024(const mp_int * base,const mp_int * exp,const mp_int * mod,mp_int * res)7303 int sp_ModExp_1024(const mp_int* base, const mp_int* exp, const mp_int* mod,
7304     mp_int* res)
7305 {
7306 #ifdef WOLFSSL_SP_SMALL
7307     int err = MP_OKAY;
7308 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
7309     sp_digit* b = NULL;
7310 #else
7311     sp_digit b[18 * 4];
7312 #endif
7313     sp_digit* e = NULL;
7314     sp_digit* m = NULL;
7315     sp_digit* r = NULL;
7316     int expBits = mp_count_bits(exp);
7317 
7318     if (mp_count_bits(base) > 1024) {
7319         err = MP_READ_E;
7320     }
7321     else if (expBits > 1024) {
7322         err = MP_READ_E;
7323     }
7324     else if (mp_count_bits(mod) != 1024) {
7325         err = MP_READ_E;
7326     }
7327     else if (mp_iseven(mod)) {
7328         err = MP_VAL;
7329     }
7330 
7331 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
7332     if (err == MP_OKAY) {
7333         b = (sp_digit*)XMALLOC(sizeof(sp_digit) * 18 * 4, NULL,
7334             DYNAMIC_TYPE_DH);
7335         if (b == NULL)
7336             err = MEMORY_E;
7337     }
7338 #endif
7339 
7340     if (err == MP_OKAY) {
7341         e = b + 18 * 2;
7342         m = e + 18;
7343         r = b;
7344 
7345         sp_2048_from_mp(b, 18, base);
7346         sp_2048_from_mp(e, 18, exp);
7347         sp_2048_from_mp(m, 18, mod);
7348 
7349         err = sp_2048_mod_exp_18(r, b, e, mp_count_bits(exp), m, 0);
7350     }
7351 
7352     if (err == MP_OKAY) {
7353         XMEMSET(r + 18, 0, sizeof(*r) * 18U);
7354         err = sp_2048_to_mp(r, res);
7355     }
7356 
7357 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
7358     if (b != NULL)
7359 #endif
7360     {
7361         /* only "e" is sensitive and needs zeroized */
7362         if (e != NULL)
7363             ForceZero(e, sizeof(sp_digit) * 36U);
7364     #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
7365         XFREE(b, NULL, DYNAMIC_TYPE_DH);
7366     #endif
7367     }
7368     return err;
7369 #else
7370 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
7371     sp_digit* b = NULL;
7372 #else
7373     sp_digit b[18 * 4];
7374 #endif
7375     sp_digit* e = NULL;
7376     sp_digit* m = NULL;
7377     sp_digit* r = NULL;
7378     int err = MP_OKAY;
7379     int expBits = mp_count_bits(exp);
7380 
7381     if (mp_count_bits(base) > 1024) {
7382         err = MP_READ_E;
7383     }
7384     else if (expBits > 1024) {
7385         err = MP_READ_E;
7386     }
7387     else if (mp_count_bits(mod) != 1024) {
7388         err = MP_READ_E;
7389     }
7390     else if (mp_iseven(mod)) {
7391         err = MP_VAL;
7392     }
7393 
7394 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
7395     if (err == MP_OKAY) {
7396         b = (sp_digit*)XMALLOC(sizeof(sp_digit) * 18 * 4, NULL, DYNAMIC_TYPE_DH);
7397         if (b == NULL)
7398             err = MEMORY_E;
7399     }
7400 #endif
7401 
7402     if (err == MP_OKAY) {
7403         e = b + 18 * 2;
7404         m = e + 18;
7405         r = b;
7406 
7407         sp_2048_from_mp(b, 18, base);
7408         sp_2048_from_mp(e, 18, exp);
7409         sp_2048_from_mp(m, 18, mod);
7410 
7411         err = sp_2048_mod_exp_18(r, b, e, expBits, m, 0);
7412     }
7413 
7414     if (err == MP_OKAY) {
7415         XMEMSET(r + 18, 0, sizeof(*r) * 18U);
7416         err = sp_2048_to_mp(r, res);
7417     }
7418 
7419 
7420 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
7421     if (b != NULL)
7422 #endif
7423     {
7424         /* only "e" is sensitive and needs zeroized */
7425         if (e != NULL)
7426             ForceZero(e, sizeof(sp_digit) * 36U);
7427     #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
7428         XFREE(b, NULL, DYNAMIC_TYPE_DH);
7429     #endif
7430     }
7431 
7432     return err;
7433 #endif
7434 }
7435 
7436 #endif /* WOLFSSL_HAVE_SP_DH | (WOLFSSL_HAVE_SP_RSA & !WOLFSSL_RSA_PUBLIC_ONLY) */
7437 
7438 #endif /* WOLFSSL_SP_SMALL */
7439 #endif /* !WOLFSSL_SP_NO_2048 */
7440 
7441 #ifndef WOLFSSL_SP_NO_3072
7442 #ifdef WOLFSSL_SP_SMALL
7443 /* Read big endian unsigned byte array into r.
7444  *
7445  * r  A single precision integer.
7446  * size  Maximum number of bytes to convert
7447  * a  Byte array.
7448  * n  Number of bytes in array to read.
7449  */
sp_3072_from_bin(sp_digit * r,int size,const byte * a,int n)7450 static void sp_3072_from_bin(sp_digit* r, int size, const byte* a, int n)
7451 {
7452     int i;
7453     int j = 0;
7454     word32 s = 0;
7455 
7456     r[0] = 0;
7457     for (i = n-1; i >= 0; i--) {
7458         r[j] |= (((sp_digit)a[i]) << s);
7459         if (s >= 52U) {
7460             r[j] &= 0xfffffffffffffffL;
7461             s = 60U - s;
7462             if (j + 1 >= size) {
7463                 break;
7464             }
7465             r[++j] = (sp_digit)a[i] >> s;
7466             s = 8U - s;
7467         }
7468         else {
7469             s += 8U;
7470         }
7471     }
7472 
7473     for (j++; j < size; j++) {
7474         r[j] = 0;
7475     }
7476 }
7477 
7478 /* Convert an mp_int to an array of sp_digit.
7479  *
7480  * r  A single precision integer.
7481  * size  Maximum number of bytes to convert
7482  * a  A multi-precision integer.
7483  */
sp_3072_from_mp(sp_digit * r,int size,const mp_int * a)7484 static void sp_3072_from_mp(sp_digit* r, int size, const mp_int* a)
7485 {
7486 #if DIGIT_BIT == 60
7487     int j;
7488 
7489     XMEMCPY(r, a->dp, sizeof(sp_digit) * a->used);
7490 
7491     for (j = a->used; j < size; j++) {
7492         r[j] = 0;
7493     }
7494 #elif DIGIT_BIT > 60
7495     int i;
7496     int j = 0;
7497     word32 s = 0;
7498 
7499     r[0] = 0;
7500     for (i = 0; i < a->used && j < size; i++) {
7501         r[j] |= ((sp_digit)a->dp[i] << s);
7502         r[j] &= 0xfffffffffffffffL;
7503         s = 60U - s;
7504         if (j + 1 >= size) {
7505             break;
7506         }
7507         /* lint allow cast of mismatch word32 and mp_digit */
7508         r[++j] = (sp_digit)(a->dp[i] >> s); /*lint !e9033*/
7509         while ((s + 60U) <= (word32)DIGIT_BIT) {
7510             s += 60U;
7511             r[j] &= 0xfffffffffffffffL;
7512             if (j + 1 >= size) {
7513                 break;
7514             }
7515             if (s < (word32)DIGIT_BIT) {
7516                 /* lint allow cast of mismatch word32 and mp_digit */
7517                 r[++j] = (sp_digit)(a->dp[i] >> s); /*lint !e9033*/
7518             }
7519             else {
7520                 r[++j] = (sp_digit)0;
7521             }
7522         }
7523         s = (word32)DIGIT_BIT - s;
7524     }
7525 
7526     for (j++; j < size; j++) {
7527         r[j] = 0;
7528     }
7529 #else
7530     int i;
7531     int j = 0;
7532     int s = 0;
7533 
7534     r[0] = 0;
7535     for (i = 0; i < a->used && j < size; i++) {
7536         r[j] |= ((sp_digit)a->dp[i]) << s;
7537         if (s + DIGIT_BIT >= 60) {
7538             r[j] &= 0xfffffffffffffffL;
7539             if (j + 1 >= size) {
7540                 break;
7541             }
7542             s = 60 - s;
7543             if (s == DIGIT_BIT) {
7544                 r[++j] = 0;
7545                 s = 0;
7546             }
7547             else {
7548                 r[++j] = a->dp[i] >> s;
7549                 s = DIGIT_BIT - s;
7550             }
7551         }
7552         else {
7553             s += DIGIT_BIT;
7554         }
7555     }
7556 
7557     for (j++; j < size; j++) {
7558         r[j] = 0;
7559     }
7560 #endif
7561 }
7562 
7563 /* Write r as big endian to byte array.
7564  * Fixed length number of bytes written: 384
7565  *
7566  * r  A single precision integer.
7567  * a  Byte array.
7568  */
sp_3072_to_bin_52(sp_digit * r,byte * a)7569 static void sp_3072_to_bin_52(sp_digit* r, byte* a)
7570 {
7571     int i;
7572     int j;
7573     int s = 0;
7574     int b;
7575 
7576     for (i=0; i<51; i++) {
7577         r[i+1] += r[i] >> 60;
7578         r[i] &= 0xfffffffffffffffL;
7579     }
7580     j = 3072 / 8 - 1;
7581     a[j] = 0;
7582     for (i=0; i<52 && j>=0; i++) {
7583         b = 0;
7584         /* lint allow cast of mismatch sp_digit and int */
7585         a[j--] |= (byte)(r[i] << s); /*lint !e9033*/
7586         b += 8 - s;
7587         if (j < 0) {
7588             break;
7589         }
7590         while (b < 60) {
7591             a[j--] = (byte)(r[i] >> b);
7592             b += 8;
7593             if (j < 0) {
7594                 break;
7595             }
7596         }
7597         s = 8 - (b - 60);
7598         if (j >= 0) {
7599             a[j] = 0;
7600         }
7601         if (s != 0) {
7602             j++;
7603         }
7604     }
7605 }
7606 
7607 #if (defined(WOLFSSL_HAVE_SP_RSA) && !defined(WOLFSSL_RSA_PUBLIC_ONLY)) || defined(WOLFSSL_HAVE_SP_DH)
7608 /* Normalize the values in each word to 60 bits.
7609  *
7610  * a  Array of sp_digit to normalize.
7611  */
sp_3072_norm_26(sp_digit * a)7612 static void sp_3072_norm_26(sp_digit* a)
7613 {
7614     int i;
7615     for (i = 0; i < 25; i++) {
7616         a[i+1] += a[i] >> 60;
7617         a[i] &= 0xfffffffffffffffL;
7618     }
7619 }
7620 
7621 #endif /* (WOLFSSL_HAVE_SP_RSA && !WOLFSSL_RSA_PUBLIC_ONLY) || WOLFSSL_HAVE_SP_DH */
7622 /* Normalize the values in each word to 60 bits.
7623  *
7624  * a  Array of sp_digit to normalize.
7625  */
sp_3072_norm_52(sp_digit * a)7626 static void sp_3072_norm_52(sp_digit* a)
7627 {
7628     int i;
7629     for (i = 0; i < 51; i++) {
7630         a[i+1] += a[i] >> 60;
7631         a[i] &= 0xfffffffffffffffL;
7632     }
7633 }
7634 
7635 /* Multiply a and b into r. (r = a * b)
7636  *
7637  * r  A single precision integer.
7638  * a  A single precision integer.
7639  * b  A single precision integer.
7640  */
sp_3072_mul_52(sp_digit * r,const sp_digit * a,const sp_digit * b)7641 SP_NOINLINE static void sp_3072_mul_52(sp_digit* r, const sp_digit* a,
7642     const sp_digit* b)
7643 {
7644     int i;
7645     int imax;
7646     int k;
7647     sp_uint128 c;
7648     sp_uint128 lo;
7649 
7650     c = ((sp_uint128)a[51]) * b[51];
7651     r[103] = (sp_digit)(c >> 60);
7652     c &= 0xfffffffffffffffL;
7653     for (k = 101; k >= 0; k--) {
7654         if (k >= 52) {
7655             i = k - 51;
7656             imax = 51;
7657         }
7658         else {
7659             i = 0;
7660             imax = k;
7661         }
7662         lo = 0;
7663         for (; i <= imax; i++) {
7664             lo += ((sp_uint128)a[i]) * b[k - i];
7665         }
7666         c += lo >> 60;
7667         r[k + 2] += (sp_digit)(c >> 60);
7668         r[k + 1]  = (sp_digit)(c & 0xfffffffffffffffL);
7669         c = lo & 0xfffffffffffffffL;
7670     }
7671     r[0] = (sp_digit)c;
7672 }
7673 
7674 /* Square a and put result in r. (r = a * a)
7675  *
7676  * r  A single precision integer.
7677  * a  A single precision integer.
7678  */
sp_3072_sqr_52(sp_digit * r,const sp_digit * a)7679 SP_NOINLINE static void sp_3072_sqr_52(sp_digit* r, const sp_digit* a)
7680 {
7681     int i;
7682     int imax;
7683     int k;
7684     sp_uint128 c;
7685     sp_uint128 t;
7686 
7687     c = ((sp_uint128)a[51]) * a[51];
7688     r[103] = (sp_digit)(c >> 60);
7689     c = (c & 0xfffffffffffffffL) << 60;
7690     for (k = 101; k >= 0; k--) {
7691         i = (k + 1) / 2;
7692         if ((k & 1) == 0) {
7693            c += ((sp_uint128)a[i]) * a[i];
7694            i++;
7695         }
7696         if (k < 51) {
7697             imax = k;
7698         }
7699         else {
7700             imax = 51;
7701         }
7702         t = 0;
7703         for (; i <= imax; i++) {
7704             t += ((sp_uint128)a[i]) * a[k - i];
7705         }
7706         c += t * 2;
7707 
7708         r[k + 2] += (sp_digit) (c >> 120);
7709         r[k + 1]  = (sp_digit)((c >> 60) & 0xfffffffffffffffL);
7710         c = (c & 0xfffffffffffffffL) << 60;
7711     }
7712     r[0] = (sp_digit)(c >> 60);
7713 }
7714 
7715 /* Caclulate the bottom digit of -1/a mod 2^n.
7716  *
7717  * a    A single precision number.
7718  * rho  Bottom word of inverse.
7719  */
sp_3072_mont_setup(const sp_digit * a,sp_digit * rho)7720 static void sp_3072_mont_setup(const sp_digit* a, sp_digit* rho)
7721 {
7722     sp_digit x;
7723     sp_digit b;
7724 
7725     b = a[0];
7726     x = (((b + 2) & 4) << 1) + b; /* here x*a==1 mod 2**4 */
7727     x *= 2 - b * x;               /* here x*a==1 mod 2**8 */
7728     x *= 2 - b * x;               /* here x*a==1 mod 2**16 */
7729     x *= 2 - b * x;               /* here x*a==1 mod 2**32 */
7730     x *= 2 - b * x;               /* here x*a==1 mod 2**64 */
7731     x &= 0xfffffffffffffffL;
7732 
7733     /* rho = -1/m mod b */
7734     *rho = ((sp_digit)1 << 60) - x;
7735 }
7736 
7737 /* Multiply a by scalar b into r. (r = a * b)
7738  *
7739  * r  A single precision integer.
7740  * a  A single precision integer.
7741  * b  A scalar.
7742  */
sp_3072_mul_d_52(sp_digit * r,const sp_digit * a,sp_digit b)7743 SP_NOINLINE static void sp_3072_mul_d_52(sp_digit* r, const sp_digit* a,
7744     sp_digit b)
7745 {
7746     sp_int128 tb = b;
7747     sp_int128 t = 0;
7748     int i;
7749 
7750     for (i = 0; i < 52; i++) {
7751         t += tb * a[i];
7752         r[i] = (sp_digit)(t & 0xfffffffffffffffL);
7753         t >>= 60;
7754     }
7755     r[52] = (sp_digit)t;
7756 }
7757 
7758 #if (defined(WOLFSSL_HAVE_SP_RSA) && !defined(WOLFSSL_RSA_PUBLIC_ONLY)) || defined(WOLFSSL_HAVE_SP_DH)
7759 /* Sub b from a into r. (r = a - b)
7760  *
7761  * r  A single precision integer.
7762  * a  A single precision integer.
7763  * b  A single precision integer.
7764  */
sp_3072_sub_26(sp_digit * r,const sp_digit * a,const sp_digit * b)7765 SP_NOINLINE static int sp_3072_sub_26(sp_digit* r, const sp_digit* a,
7766         const sp_digit* b)
7767 {
7768     int i;
7769 
7770     for (i = 0; i < 26; i++) {
7771         r[i] = a[i] - b[i];
7772     }
7773 
7774     return 0;
7775 }
7776 
7777 /* r = 2^n mod m where n is the number of bits to reduce by.
7778  * Given m must be 3072 bits, just need to subtract.
7779  *
7780  * r  A single precision number.
7781  * m  A single precision number.
7782  */
sp_3072_mont_norm_26(sp_digit * r,const sp_digit * m)7783 static void sp_3072_mont_norm_26(sp_digit* r, const sp_digit* m)
7784 {
7785     /* Set r = 2^n - 1. */
7786     int i;
7787 
7788     for (i=0; i<25; i++) {
7789         r[i] = 0xfffffffffffffffL;
7790     }
7791     r[25] = 0xfffffffffL;
7792 
7793     /* r = (2^n - 1) mod n */
7794     (void)sp_3072_sub_26(r, r, m);
7795 
7796     /* Add one so r = 2^n mod m */
7797     r[0] += 1;
7798 }
7799 
7800 /* Compare a with b in constant time.
7801  *
7802  * a  A single precision integer.
7803  * b  A single precision integer.
7804  * return -ve, 0 or +ve if a is less than, equal to or greater than b
7805  * respectively.
7806  */
sp_3072_cmp_26(const sp_digit * a,const sp_digit * b)7807 static sp_digit sp_3072_cmp_26(const sp_digit* a, const sp_digit* b)
7808 {
7809     sp_digit r = 0;
7810     int i;
7811 
7812     for (i=25; i>=0; i--) {
7813         r |= (a[i] - b[i]) & (0 - (sp_digit)((r == 0) ? 1 : 0));
7814     }
7815 
7816     return r;
7817 }
7818 
7819 /* Conditionally subtract b from a using the mask m.
7820  * m is -1 to subtract and 0 when not.
7821  *
7822  * r  A single precision number representing condition subtract result.
7823  * a  A single precision number to subtract from.
7824  * b  A single precision number to subtract.
7825  * m  Mask value to apply.
7826  */
sp_3072_cond_sub_26(sp_digit * r,const sp_digit * a,const sp_digit * b,const sp_digit m)7827 static void sp_3072_cond_sub_26(sp_digit* r, const sp_digit* a,
7828         const sp_digit* b, const sp_digit m)
7829 {
7830     int i;
7831 
7832     for (i = 0; i < 26; i++) {
7833         r[i] = a[i] - (b[i] & m);
7834     }
7835 }
7836 
7837 /* Mul a by scalar b and add into r. (r += a * b)
7838  *
7839  * r  A single precision integer.
7840  * a  A single precision integer.
7841  * b  A scalar.
7842  */
sp_3072_mul_add_26(sp_digit * r,const sp_digit * a,const sp_digit b)7843 SP_NOINLINE static void sp_3072_mul_add_26(sp_digit* r, const sp_digit* a,
7844         const sp_digit b)
7845 {
7846     sp_int128 tb = b;
7847     sp_int128 t[4];
7848     int i;
7849 
7850     t[0] = 0;
7851     for (i = 0; i < 24; i += 4) {
7852         t[0] += (tb * a[i+0]) + r[i+0];
7853         t[1]  = (tb * a[i+1]) + r[i+1];
7854         t[2]  = (tb * a[i+2]) + r[i+2];
7855         t[3]  = (tb * a[i+3]) + r[i+3];
7856         r[i+0] = t[0] & 0xfffffffffffffffL;
7857         t[1] += t[0] >> 60;
7858         r[i+1] = t[1] & 0xfffffffffffffffL;
7859         t[2] += t[1] >> 60;
7860         r[i+2] = t[2] & 0xfffffffffffffffL;
7861         t[3] += t[2] >> 60;
7862         r[i+3] = t[3] & 0xfffffffffffffffL;
7863         t[0]  = t[3] >> 60;
7864     }
7865     t[0] += (tb * a[24]) + r[24];
7866     t[1]  = (tb * a[25]) + r[25];
7867     r[24] = t[0] & 0xfffffffffffffffL;
7868     t[1] += t[0] >> 60;
7869     r[25] = t[1] & 0xfffffffffffffffL;
7870     r[26] +=  (sp_digit)(t[1] >> 60);
7871 }
7872 
7873 /* Shift the result in the high 1536 bits down to the bottom.
7874  *
7875  * r  A single precision number.
7876  * a  A single precision number.
7877  */
sp_3072_mont_shift_26(sp_digit * r,const sp_digit * a)7878 static void sp_3072_mont_shift_26(sp_digit* r, const sp_digit* a)
7879 {
7880     int i;
7881     sp_int128 n = a[25] >> 36;
7882     n += ((sp_int128)a[26]) << 24;
7883 
7884     for (i = 0; i < 25; i++) {
7885         r[i] = n & 0xfffffffffffffffL;
7886         n >>= 60;
7887         n += ((sp_int128)a[27 + i]) << 24;
7888     }
7889     r[25] = (sp_digit)n;
7890     XMEMSET(&r[26], 0, sizeof(*r) * 26U);
7891 }
7892 
7893 /* Reduce the number back to 3072 bits using Montgomery reduction.
7894  *
7895  * a   A single precision number to reduce in place.
7896  * m   The single precision number representing the modulus.
7897  * mp  The digit representing the negative inverse of m mod 2^n.
7898  */
sp_3072_mont_reduce_26(sp_digit * a,const sp_digit * m,sp_digit mp)7899 static void sp_3072_mont_reduce_26(sp_digit* a, const sp_digit* m, sp_digit mp)
7900 {
7901     int i;
7902     sp_digit mu;
7903 
7904     sp_3072_norm_26(a + 26);
7905 
7906     for (i=0; i<25; i++) {
7907         mu = (a[i] * mp) & 0xfffffffffffffffL;
7908         sp_3072_mul_add_26(a+i, m, mu);
7909         a[i+1] += a[i] >> 60;
7910     }
7911     mu = (a[i] * mp) & 0xfffffffffL;
7912     sp_3072_mul_add_26(a+i, m, mu);
7913     a[i+1] += a[i] >> 60;
7914     a[i] &= 0xfffffffffffffffL;
7915     sp_3072_mont_shift_26(a, a);
7916     sp_3072_cond_sub_26(a, a, m, 0 - (((a[25] - m[25]) > 0) ?
7917             (sp_digit)1 : (sp_digit)0));
7918     sp_3072_norm_26(a);
7919 }
7920 
7921 /* Multiply a and b into r. (r = a * b)
7922  *
7923  * r  A single precision integer.
7924  * a  A single precision integer.
7925  * b  A single precision integer.
7926  */
sp_3072_mul_26(sp_digit * r,const sp_digit * a,const sp_digit * b)7927 SP_NOINLINE static void sp_3072_mul_26(sp_digit* r, const sp_digit* a,
7928     const sp_digit* b)
7929 {
7930     int i;
7931     int imax;
7932     int k;
7933     sp_uint128 c;
7934     sp_uint128 lo;
7935 
7936     c = ((sp_uint128)a[25]) * b[25];
7937     r[51] = (sp_digit)(c >> 60);
7938     c &= 0xfffffffffffffffL;
7939     for (k = 49; k >= 0; k--) {
7940         if (k >= 26) {
7941             i = k - 25;
7942             imax = 25;
7943         }
7944         else {
7945             i = 0;
7946             imax = k;
7947         }
7948         lo = 0;
7949         for (; i <= imax; i++) {
7950             lo += ((sp_uint128)a[i]) * b[k - i];
7951         }
7952         c += lo >> 60;
7953         r[k + 2] += (sp_digit)(c >> 60);
7954         r[k + 1]  = (sp_digit)(c & 0xfffffffffffffffL);
7955         c = lo & 0xfffffffffffffffL;
7956     }
7957     r[0] = (sp_digit)c;
7958 }
7959 
7960 /* Multiply two Montgomery form numbers mod the modulus (prime).
7961  * (r = a * b mod m)
7962  *
7963  * r   Result of multiplication.
7964  * a   First number to multiply in Montgomery form.
7965  * b   Second number to multiply in Montgomery form.
7966  * m   Modulus (prime).
7967  * mp  Montgomery mulitplier.
7968  */
sp_3072_mont_mul_26(sp_digit * r,const sp_digit * a,const sp_digit * b,const sp_digit * m,sp_digit mp)7969 static void sp_3072_mont_mul_26(sp_digit* r, const sp_digit* a,
7970         const sp_digit* b, const sp_digit* m, sp_digit mp)
7971 {
7972     sp_3072_mul_26(r, a, b);
7973     sp_3072_mont_reduce_26(r, m, mp);
7974 }
7975 
7976 /* Square a and put result in r. (r = a * a)
7977  *
7978  * r  A single precision integer.
7979  * a  A single precision integer.
7980  */
sp_3072_sqr_26(sp_digit * r,const sp_digit * a)7981 SP_NOINLINE static void sp_3072_sqr_26(sp_digit* r, const sp_digit* a)
7982 {
7983     int i;
7984     int imax;
7985     int k;
7986     sp_uint128 c;
7987     sp_uint128 t;
7988 
7989     c = ((sp_uint128)a[25]) * a[25];
7990     r[51] = (sp_digit)(c >> 60);
7991     c = (c & 0xfffffffffffffffL) << 60;
7992     for (k = 49; k >= 0; k--) {
7993         i = (k + 1) / 2;
7994         if ((k & 1) == 0) {
7995            c += ((sp_uint128)a[i]) * a[i];
7996            i++;
7997         }
7998         if (k < 25) {
7999             imax = k;
8000         }
8001         else {
8002             imax = 25;
8003         }
8004         t = 0;
8005         for (; i <= imax; i++) {
8006             t += ((sp_uint128)a[i]) * a[k - i];
8007         }
8008         c += t * 2;
8009 
8010         r[k + 2] += (sp_digit) (c >> 120);
8011         r[k + 1]  = (sp_digit)((c >> 60) & 0xfffffffffffffffL);
8012         c = (c & 0xfffffffffffffffL) << 60;
8013     }
8014     r[0] = (sp_digit)(c >> 60);
8015 }
8016 
8017 /* Square the Montgomery form number. (r = a * a mod m)
8018  *
8019  * r   Result of squaring.
8020  * a   Number to square in Montgomery form.
8021  * m   Modulus (prime).
8022  * mp  Montgomery mulitplier.
8023  */
sp_3072_mont_sqr_26(sp_digit * r,const sp_digit * a,const sp_digit * m,sp_digit mp)8024 static void sp_3072_mont_sqr_26(sp_digit* r, const sp_digit* a,
8025         const sp_digit* m, sp_digit mp)
8026 {
8027     sp_3072_sqr_26(r, a);
8028     sp_3072_mont_reduce_26(r, m, mp);
8029 }
8030 
8031 /* Multiply a by scalar b into r. (r = a * b)
8032  *
8033  * r  A single precision integer.
8034  * a  A single precision integer.
8035  * b  A scalar.
8036  */
sp_3072_mul_d_26(sp_digit * r,const sp_digit * a,sp_digit b)8037 SP_NOINLINE static void sp_3072_mul_d_26(sp_digit* r, const sp_digit* a,
8038     sp_digit b)
8039 {
8040     sp_int128 tb = b;
8041     sp_int128 t = 0;
8042     int i;
8043 
8044     for (i = 0; i < 26; i++) {
8045         t += tb * a[i];
8046         r[i] = (sp_digit)(t & 0xfffffffffffffffL);
8047         t >>= 60;
8048     }
8049     r[26] = (sp_digit)t;
8050 }
8051 
8052 /* Conditionally add a and b using the mask m.
8053  * m is -1 to add and 0 when not.
8054  *
8055  * r  A single precision number representing conditional add result.
8056  * a  A single precision number to add with.
8057  * b  A single precision number to add.
8058  * m  Mask value to apply.
8059  */
sp_3072_cond_add_26(sp_digit * r,const sp_digit * a,const sp_digit * b,const sp_digit m)8060 static void sp_3072_cond_add_26(sp_digit* r, const sp_digit* a,
8061         const sp_digit* b, const sp_digit m)
8062 {
8063     int i;
8064 
8065     for (i = 0; i < 26; i++) {
8066         r[i] = a[i] + (b[i] & m);
8067     }
8068 }
8069 
8070 /* Add b to a into r. (r = a + b)
8071  *
8072  * r  A single precision integer.
8073  * a  A single precision integer.
8074  * b  A single precision integer.
8075  */
sp_3072_add_26(sp_digit * r,const sp_digit * a,const sp_digit * b)8076 SP_NOINLINE static int sp_3072_add_26(sp_digit* r, const sp_digit* a,
8077         const sp_digit* b)
8078 {
8079     int i;
8080 
8081     for (i = 0; i < 26; i++) {
8082         r[i] = a[i] + b[i];
8083     }
8084 
8085     return 0;
8086 }
8087 
sp_3072_rshift_26(sp_digit * r,const sp_digit * a,byte n)8088 SP_NOINLINE static void sp_3072_rshift_26(sp_digit* r, const sp_digit* a,
8089         byte n)
8090 {
8091     int i;
8092 
8093     for (i=0; i<25; i++) {
8094         r[i] = ((a[i] >> n) | (a[i + 1] << (60 - n))) & 0xfffffffffffffffL;
8095     }
8096     r[25] = a[25] >> n;
8097 }
8098 
8099 #ifdef WOLFSSL_SP_DIV_64
sp_3072_div_word_26(sp_digit d1,sp_digit d0,sp_digit dv)8100 static WC_INLINE sp_digit sp_3072_div_word_26(sp_digit d1, sp_digit d0,
8101     sp_digit dv)
8102 {
8103     sp_digit d;
8104     sp_digit r;
8105     sp_digit t;
8106 
8107     /* All 60 bits from d1 and top 3 bits from d0. */
8108     d = (d1 << 3) + (d0 >> 57);
8109     r = d / dv;
8110     d -= r * dv;
8111     /* Up to 4 bits in r */
8112     /* Next 3 bits from d0. */
8113     r <<= 3;
8114     d <<= 3;
8115     d += (d0 >> 54) & ((1 << 3) - 1);
8116     t = d / dv;
8117     d -= t * dv;
8118     r += t;
8119     /* Up to 7 bits in r */
8120     /* Next 3 bits from d0. */
8121     r <<= 3;
8122     d <<= 3;
8123     d += (d0 >> 51) & ((1 << 3) - 1);
8124     t = d / dv;
8125     d -= t * dv;
8126     r += t;
8127     /* Up to 10 bits in r */
8128     /* Next 3 bits from d0. */
8129     r <<= 3;
8130     d <<= 3;
8131     d += (d0 >> 48) & ((1 << 3) - 1);
8132     t = d / dv;
8133     d -= t * dv;
8134     r += t;
8135     /* Up to 13 bits in r */
8136     /* Next 3 bits from d0. */
8137     r <<= 3;
8138     d <<= 3;
8139     d += (d0 >> 45) & ((1 << 3) - 1);
8140     t = d / dv;
8141     d -= t * dv;
8142     r += t;
8143     /* Up to 16 bits in r */
8144     /* Next 3 bits from d0. */
8145     r <<= 3;
8146     d <<= 3;
8147     d += (d0 >> 42) & ((1 << 3) - 1);
8148     t = d / dv;
8149     d -= t * dv;
8150     r += t;
8151     /* Up to 19 bits in r */
8152     /* Next 3 bits from d0. */
8153     r <<= 3;
8154     d <<= 3;
8155     d += (d0 >> 39) & ((1 << 3) - 1);
8156     t = d / dv;
8157     d -= t * dv;
8158     r += t;
8159     /* Up to 22 bits in r */
8160     /* Next 3 bits from d0. */
8161     r <<= 3;
8162     d <<= 3;
8163     d += (d0 >> 36) & ((1 << 3) - 1);
8164     t = d / dv;
8165     d -= t * dv;
8166     r += t;
8167     /* Up to 25 bits in r */
8168     /* Next 3 bits from d0. */
8169     r <<= 3;
8170     d <<= 3;
8171     d += (d0 >> 33) & ((1 << 3) - 1);
8172     t = d / dv;
8173     d -= t * dv;
8174     r += t;
8175     /* Up to 28 bits in r */
8176     /* Next 3 bits from d0. */
8177     r <<= 3;
8178     d <<= 3;
8179     d += (d0 >> 30) & ((1 << 3) - 1);
8180     t = d / dv;
8181     d -= t * dv;
8182     r += t;
8183     /* Up to 31 bits in r */
8184     /* Next 3 bits from d0. */
8185     r <<= 3;
8186     d <<= 3;
8187     d += (d0 >> 27) & ((1 << 3) - 1);
8188     t = d / dv;
8189     d -= t * dv;
8190     r += t;
8191     /* Up to 34 bits in r */
8192     /* Next 3 bits from d0. */
8193     r <<= 3;
8194     d <<= 3;
8195     d += (d0 >> 24) & ((1 << 3) - 1);
8196     t = d / dv;
8197     d -= t * dv;
8198     r += t;
8199     /* Up to 37 bits in r */
8200     /* Next 3 bits from d0. */
8201     r <<= 3;
8202     d <<= 3;
8203     d += (d0 >> 21) & ((1 << 3) - 1);
8204     t = d / dv;
8205     d -= t * dv;
8206     r += t;
8207     /* Up to 40 bits in r */
8208     /* Next 3 bits from d0. */
8209     r <<= 3;
8210     d <<= 3;
8211     d += (d0 >> 18) & ((1 << 3) - 1);
8212     t = d / dv;
8213     d -= t * dv;
8214     r += t;
8215     /* Up to 43 bits in r */
8216     /* Next 3 bits from d0. */
8217     r <<= 3;
8218     d <<= 3;
8219     d += (d0 >> 15) & ((1 << 3) - 1);
8220     t = d / dv;
8221     d -= t * dv;
8222     r += t;
8223     /* Up to 46 bits in r */
8224     /* Next 3 bits from d0. */
8225     r <<= 3;
8226     d <<= 3;
8227     d += (d0 >> 12) & ((1 << 3) - 1);
8228     t = d / dv;
8229     d -= t * dv;
8230     r += t;
8231     /* Up to 49 bits in r */
8232     /* Next 3 bits from d0. */
8233     r <<= 3;
8234     d <<= 3;
8235     d += (d0 >> 9) & ((1 << 3) - 1);
8236     t = d / dv;
8237     d -= t * dv;
8238     r += t;
8239     /* Up to 52 bits in r */
8240     /* Next 3 bits from d0. */
8241     r <<= 3;
8242     d <<= 3;
8243     d += (d0 >> 6) & ((1 << 3) - 1);
8244     t = d / dv;
8245     d -= t * dv;
8246     r += t;
8247     /* Up to 55 bits in r */
8248     /* Next 3 bits from d0. */
8249     r <<= 3;
8250     d <<= 3;
8251     d += (d0 >> 3) & ((1 << 3) - 1);
8252     t = d / dv;
8253     d -= t * dv;
8254     r += t;
8255     /* Up to 58 bits in r */
8256     /* Remaining 3 bits from d0. */
8257     r <<= 3;
8258     d <<= 3;
8259     d += d0 & ((1 << 3) - 1);
8260     t = d / dv;
8261     r += t;
8262 
8263     /* All 60 bits from d1 and top 3 bits from d0. */
8264     return r;
8265 }
8266 #endif /* WOLFSSL_SP_DIV_64 */
8267 
8268 /* Divide d in a and put remainder into r (m*d + r = a)
8269  * m is not calculated as it is not needed at this time.
8270  *
8271  * Full implementation.
8272  *
8273  * a  Number to be divided.
8274  * d  Number to divide with.
8275  * m  Multiplier result.
8276  * r  Remainder from the division.
8277  * returns MEMORY_E when unable to allocate memory and MP_OKAY otherwise.
8278  */
sp_3072_div_26(const sp_digit * a,const sp_digit * d,const sp_digit * m,sp_digit * r)8279 static int sp_3072_div_26(const sp_digit* a, const sp_digit* d,
8280         const sp_digit* m, sp_digit* r)
8281 {
8282     int i;
8283 #ifndef WOLFSSL_SP_DIV_64
8284     sp_int128 d1;
8285 #endif
8286     sp_digit dv;
8287     sp_digit r1;
8288 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
8289     sp_digit* t1 = NULL;
8290 #else
8291     sp_digit t1[4 * 26 + 3];
8292 #endif
8293     sp_digit* t2 = NULL;
8294     sp_digit* sd = NULL;
8295     int err = MP_OKAY;
8296 
8297     (void)m;
8298 
8299 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
8300     t1 = (sp_digit*)XMALLOC(sizeof(sp_digit) * (4 * 26 + 3), NULL,
8301                                                        DYNAMIC_TYPE_TMP_BUFFER);
8302     if (t1 == NULL)
8303         err = MEMORY_E;
8304 #endif
8305 
8306     (void)m;
8307 
8308     if (err == MP_OKAY) {
8309         t2 = t1 + 52 + 1;
8310         sd = t2 + 26 + 1;
8311 
8312         sp_3072_mul_d_26(sd, d, (sp_digit)1 << 24);
8313         sp_3072_mul_d_52(t1, a, (sp_digit)1 << 24);
8314         dv = sd[25];
8315         t1[26 + 26] += t1[26 + 26 - 1] >> 60;
8316         t1[26 + 26 - 1] &= 0xfffffffffffffffL;
8317         for (i=26; i>=0; i--) {
8318 #ifndef WOLFSSL_SP_DIV_64
8319             d1 = t1[26 + i];
8320             d1 <<= 60;
8321             d1 += t1[26 + i - 1];
8322             r1 = (sp_digit)(d1 / dv);
8323 #else
8324             r1 = sp_3072_div_word_26(t1[26 + i], t1[26 + i - 1], dv);
8325 #endif
8326 
8327             sp_3072_mul_d_26(t2, sd, r1);
8328             (void)sp_3072_sub_26(&t1[i], &t1[i], t2);
8329             sp_3072_norm_26(&t1[i]);
8330             t1[26 + i] -= t2[26];
8331             t1[26 + i] += t1[26 + i - 1] >> 60;
8332             t1[26 + i - 1] &= 0xfffffffffffffffL;
8333 #ifndef WOLFSSL_SP_DIV_64
8334             d1 = -t1[26 + i];
8335             d1 <<= 60;
8336             d1 -= t1[26 + i - 1];
8337             r1 = (sp_digit)(d1 / dv);
8338 #else
8339             r1 = sp_3072_div_word_26(-t1[26 + i], -t1[26 + i - 1], dv);
8340 #endif
8341             r1 -= t1[26 + i];
8342             sp_3072_mul_d_26(t2, sd, r1);
8343             (void)sp_3072_add_26(&t1[i], &t1[i], t2);
8344             t1[26 + i] += t1[26 + i - 1] >> 60;
8345             t1[26 + i - 1] &= 0xfffffffffffffffL;
8346         }
8347         t1[26 - 1] += t1[26 - 2] >> 60;
8348         t1[26 - 2] &= 0xfffffffffffffffL;
8349         r1 = t1[26 - 1] / dv;
8350 
8351         sp_3072_mul_d_26(t2, sd, r1);
8352         sp_3072_sub_26(t1, t1, t2);
8353         XMEMCPY(r, t1, sizeof(*r) * 52U);
8354         for (i=0; i<25; i++) {
8355             r[i+1] += r[i] >> 60;
8356             r[i] &= 0xfffffffffffffffL;
8357         }
8358         sp_3072_cond_add_26(r, r, sd, 0 - ((r[25] < 0) ?
8359                     (sp_digit)1 : (sp_digit)0));
8360 
8361         sp_3072_norm_26(r);
8362         sp_3072_rshift_26(r, r, 24);
8363     }
8364 
8365 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
8366     if (t1 != NULL)
8367         XFREE(t1, NULL, DYNAMIC_TYPE_TMP_BUFFER);
8368 #endif
8369 
8370     return err;
8371 }
8372 
8373 /* Reduce a modulo m into r. (r = a mod m)
8374  *
8375  * r  A single precision number that is the reduced result.
8376  * a  A single precision number that is to be reduced.
8377  * m  A single precision number that is the modulus to reduce with.
8378  * returns MEMORY_E when unable to allocate memory and MP_OKAY otherwise.
8379  */
sp_3072_mod_26(sp_digit * r,const sp_digit * a,const sp_digit * m)8380 static int sp_3072_mod_26(sp_digit* r, const sp_digit* a, const sp_digit* m)
8381 {
8382     return sp_3072_div_26(a, m, NULL, r);
8383 }
8384 
8385 /* Modular exponentiate a to the e mod m. (r = a^e mod m)
8386  *
8387  * r     A single precision number that is the result of the operation.
8388  * a     A single precision number being exponentiated.
8389  * e     A single precision number that is the exponent.
8390  * bits  The number of bits in the exponent.
8391  * m     A single precision number that is the modulus.
8392  * returns  0 on success.
8393  * returns  MEMORY_E on dynamic memory allocation failure.
8394  * returns  MP_VAL when base is even or exponent is 0.
8395  */
sp_3072_mod_exp_26(sp_digit * r,const sp_digit * a,const sp_digit * e,int bits,const sp_digit * m,int reduceA)8396 static int sp_3072_mod_exp_26(sp_digit* r, const sp_digit* a, const sp_digit* e,
8397     int bits, const sp_digit* m, int reduceA)
8398 {
8399 #if defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SP_FAST_MODEXP)
8400 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
8401     sp_digit* td = NULL;
8402 #else
8403     sp_digit td[3 * 52];
8404 #endif
8405     sp_digit* t[3] = {0, 0, 0};
8406     sp_digit* norm = NULL;
8407     sp_digit mp = 1;
8408     sp_digit n;
8409     int i;
8410     int c;
8411     byte y;
8412     int err = MP_OKAY;
8413 
8414     if ((m[0] & 1) == 0) {
8415         err = MP_VAL;
8416     }
8417     else if (bits == 0) {
8418         err = MP_VAL;
8419     }
8420 
8421 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
8422     if (err == MP_OKAY) {
8423         td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 3 * 26 * 2, NULL,
8424                                 DYNAMIC_TYPE_TMP_BUFFER);
8425         if (td == NULL)
8426             err = MEMORY_E;
8427     }
8428 #endif
8429 
8430     if (err == MP_OKAY) {
8431         norm = td;
8432         for (i=0; i<3; i++) {
8433             t[i] = td + (i * 26 * 2);
8434             XMEMSET(t[i], 0, sizeof(sp_digit) * 26U * 2U);
8435         }
8436 
8437         sp_3072_mont_setup(m, &mp);
8438         sp_3072_mont_norm_26(norm, m);
8439 
8440         if (reduceA != 0) {
8441             err = sp_3072_mod_26(t[1], a, m);
8442         }
8443         else {
8444             XMEMCPY(t[1], a, sizeof(sp_digit) * 26U);
8445         }
8446     }
8447     if (err == MP_OKAY) {
8448         sp_3072_mul_26(t[1], t[1], norm);
8449         err = sp_3072_mod_26(t[1], t[1], m);
8450     }
8451 
8452     if (err == MP_OKAY) {
8453         i = bits / 60;
8454         c = bits % 60;
8455         n = e[i--] << (60 - c);
8456         for (; ; c--) {
8457             if (c == 0) {
8458                 if (i == -1) {
8459                     break;
8460                 }
8461 
8462                 n = e[i--];
8463                 c = 60;
8464             }
8465 
8466             y = (int)((n >> 59) & 1);
8467             n <<= 1;
8468 
8469             sp_3072_mont_mul_26(t[y^1], t[0], t[1], m, mp);
8470 
8471             XMEMCPY(t[2], (void*)(((size_t)t[0] & addr_mask[y^1]) +
8472                                   ((size_t)t[1] & addr_mask[y])),
8473                                   sizeof(*t[2]) * 26 * 2);
8474             sp_3072_mont_sqr_26(t[2], t[2], m, mp);
8475             XMEMCPY((void*)(((size_t)t[0] & addr_mask[y^1]) +
8476                             ((size_t)t[1] & addr_mask[y])), t[2],
8477                             sizeof(*t[2]) * 26 * 2);
8478         }
8479 
8480         sp_3072_mont_reduce_26(t[0], m, mp);
8481         n = sp_3072_cmp_26(t[0], m);
8482         sp_3072_cond_sub_26(t[0], t[0], m, ((n < 0) ?
8483                     (sp_digit)1 : (sp_digit)0) - 1);
8484         XMEMCPY(r, t[0], sizeof(*r) * 26 * 2);
8485 
8486     }
8487 
8488 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
8489     if (td != NULL)
8490         XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);
8491 #endif
8492 
8493     return err;
8494 #elif !defined(WC_NO_CACHE_RESISTANT)
8495 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
8496     sp_digit* td = NULL;
8497 #else
8498     sp_digit td[3 * 52];
8499 #endif
8500     sp_digit* t[3] = {0, 0, 0};
8501     sp_digit* norm = NULL;
8502     sp_digit mp = 1;
8503     sp_digit n;
8504     int i;
8505     int c;
8506     byte y;
8507     int err = MP_OKAY;
8508 
8509     if ((m[0] & 1) == 0) {
8510         err = MP_VAL;
8511     }
8512     else if (bits == 0) {
8513         err = MP_VAL;
8514     }
8515 
8516 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
8517     if (err == MP_OKAY) {
8518         td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 3 * 26 * 2, NULL,
8519                                 DYNAMIC_TYPE_TMP_BUFFER);
8520         if (td == NULL)
8521             err = MEMORY_E;
8522     }
8523 #endif
8524 
8525     if (err == MP_OKAY) {
8526         norm = td;
8527         for (i=0; i<3; i++) {
8528             t[i] = td + (i * 26 * 2);
8529         }
8530 
8531         sp_3072_mont_setup(m, &mp);
8532         sp_3072_mont_norm_26(norm, m);
8533 
8534         if (reduceA != 0) {
8535             err = sp_3072_mod_26(t[1], a, m);
8536             if (err == MP_OKAY) {
8537                 sp_3072_mul_26(t[1], t[1], norm);
8538                 err = sp_3072_mod_26(t[1], t[1], m);
8539             }
8540         }
8541         else {
8542             sp_3072_mul_26(t[1], a, norm);
8543             err = sp_3072_mod_26(t[1], t[1], m);
8544         }
8545     }
8546 
8547     if (err == MP_OKAY) {
8548         i = bits / 60;
8549         c = bits % 60;
8550         n = e[i--] << (60 - c);
8551         for (; ; c--) {
8552             if (c == 0) {
8553                 if (i == -1) {
8554                     break;
8555                 }
8556 
8557                 n = e[i--];
8558                 c = 60;
8559             }
8560 
8561             y = (int)((n >> 59) & 1);
8562             n <<= 1;
8563 
8564             sp_3072_mont_mul_26(t[y^1], t[0], t[1], m, mp);
8565 
8566             XMEMCPY(t[2], (void*)(((size_t)t[0] & addr_mask[y^1]) +
8567                                   ((size_t)t[1] & addr_mask[y])),
8568                                   sizeof(*t[2]) * 26 * 2);
8569             sp_3072_mont_sqr_26(t[2], t[2], m, mp);
8570             XMEMCPY((void*)(((size_t)t[0] & addr_mask[y^1]) +
8571                             ((size_t)t[1] & addr_mask[y])), t[2],
8572                             sizeof(*t[2]) * 26 * 2);
8573         }
8574 
8575         sp_3072_mont_reduce_26(t[0], m, mp);
8576         n = sp_3072_cmp_26(t[0], m);
8577         sp_3072_cond_sub_26(t[0], t[0], m, ((n < 0) ?
8578                     (sp_digit)1 : (sp_digit)0) - 1);
8579         XMEMCPY(r, t[0], sizeof(*r) * 26 * 2);
8580     }
8581 
8582 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
8583     if (td != NULL)
8584         XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);
8585 #endif
8586 
8587     return err;
8588 #else
8589 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
8590     sp_digit* td = NULL;
8591 #else
8592     sp_digit td[(32 * 52) + 52];
8593 #endif
8594     sp_digit* t[32];
8595     sp_digit* rt = NULL;
8596     sp_digit* norm = NULL;
8597     sp_digit mp = 1;
8598     sp_digit n;
8599     int i;
8600     int c;
8601     byte y;
8602     int err = MP_OKAY;
8603 
8604     if ((m[0] & 1) == 0) {
8605         err = MP_VAL;
8606     }
8607     else if (bits == 0) {
8608         err = MP_VAL;
8609     }
8610 
8611 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
8612     if (err == MP_OKAY) {
8613         td = (sp_digit*)XMALLOC(sizeof(sp_digit) * ((32 * 52) + 52), NULL,
8614                                 DYNAMIC_TYPE_TMP_BUFFER);
8615         if (td == NULL)
8616             err = MEMORY_E;
8617     }
8618 #endif
8619 
8620     if (err == MP_OKAY) {
8621         norm = td;
8622         for (i=0; i<32; i++)
8623             t[i] = td + i * 52;
8624         rt = td + 1664;
8625 
8626         sp_3072_mont_setup(m, &mp);
8627         sp_3072_mont_norm_26(norm, m);
8628 
8629         if (reduceA != 0) {
8630             err = sp_3072_mod_26(t[1], a, m);
8631             if (err == MP_OKAY) {
8632                 sp_3072_mul_26(t[1], t[1], norm);
8633                 err = sp_3072_mod_26(t[1], t[1], m);
8634             }
8635         }
8636         else {
8637             sp_3072_mul_26(t[1], a, norm);
8638             err = sp_3072_mod_26(t[1], t[1], m);
8639         }
8640     }
8641 
8642     if (err == MP_OKAY) {
8643         sp_3072_mont_sqr_26(t[ 2], t[ 1], m, mp);
8644         sp_3072_mont_mul_26(t[ 3], t[ 2], t[ 1], m, mp);
8645         sp_3072_mont_sqr_26(t[ 4], t[ 2], m, mp);
8646         sp_3072_mont_mul_26(t[ 5], t[ 3], t[ 2], m, mp);
8647         sp_3072_mont_sqr_26(t[ 6], t[ 3], m, mp);
8648         sp_3072_mont_mul_26(t[ 7], t[ 4], t[ 3], m, mp);
8649         sp_3072_mont_sqr_26(t[ 8], t[ 4], m, mp);
8650         sp_3072_mont_mul_26(t[ 9], t[ 5], t[ 4], m, mp);
8651         sp_3072_mont_sqr_26(t[10], t[ 5], m, mp);
8652         sp_3072_mont_mul_26(t[11], t[ 6], t[ 5], m, mp);
8653         sp_3072_mont_sqr_26(t[12], t[ 6], m, mp);
8654         sp_3072_mont_mul_26(t[13], t[ 7], t[ 6], m, mp);
8655         sp_3072_mont_sqr_26(t[14], t[ 7], m, mp);
8656         sp_3072_mont_mul_26(t[15], t[ 8], t[ 7], m, mp);
8657         sp_3072_mont_sqr_26(t[16], t[ 8], m, mp);
8658         sp_3072_mont_mul_26(t[17], t[ 9], t[ 8], m, mp);
8659         sp_3072_mont_sqr_26(t[18], t[ 9], m, mp);
8660         sp_3072_mont_mul_26(t[19], t[10], t[ 9], m, mp);
8661         sp_3072_mont_sqr_26(t[20], t[10], m, mp);
8662         sp_3072_mont_mul_26(t[21], t[11], t[10], m, mp);
8663         sp_3072_mont_sqr_26(t[22], t[11], m, mp);
8664         sp_3072_mont_mul_26(t[23], t[12], t[11], m, mp);
8665         sp_3072_mont_sqr_26(t[24], t[12], m, mp);
8666         sp_3072_mont_mul_26(t[25], t[13], t[12], m, mp);
8667         sp_3072_mont_sqr_26(t[26], t[13], m, mp);
8668         sp_3072_mont_mul_26(t[27], t[14], t[13], m, mp);
8669         sp_3072_mont_sqr_26(t[28], t[14], m, mp);
8670         sp_3072_mont_mul_26(t[29], t[15], t[14], m, mp);
8671         sp_3072_mont_sqr_26(t[30], t[15], m, mp);
8672         sp_3072_mont_mul_26(t[31], t[16], t[15], m, mp);
8673 
8674         bits = ((bits + 4) / 5) * 5;
8675         i = ((bits + 59) / 60) - 1;
8676         c = bits % 60;
8677         if (c == 0) {
8678             c = 60;
8679         }
8680         if (i < 26) {
8681             n = e[i--] << (64 - c);
8682         }
8683         else {
8684             n = 0;
8685             i--;
8686         }
8687         if (c < 5) {
8688             n |= e[i--] << (4 - c);
8689             c += 60;
8690         }
8691         y = (int)((n >> 59) & 0x1f);
8692         n <<= 5;
8693         c -= 5;
8694         XMEMCPY(rt, t[y], sizeof(sp_digit) * 52);
8695         while ((i >= 0) || (c >= 5)) {
8696             if (c >= 5) {
8697                 y = (byte)((n >> 59) & 0x1f);
8698                 n <<= 5;
8699                 c -= 5;
8700             }
8701             else if (c == 0) {
8702                 n = e[i--] << 4;
8703                 y = (byte)((n >> 59) & 0x1f);
8704                 n <<= 5;
8705                 c = 55;
8706             }
8707             else {
8708                 y = (byte)((n >> 59) & 0x1f);
8709                 n = e[i--] << 4;
8710                 c = 5 - c;
8711                 y |= (byte)((n >> (64 - c)) & ((1 << c) - 1));
8712                 n <<= c;
8713                 c = 60 - c;
8714             }
8715 
8716             sp_3072_mont_sqr_26(rt, rt, m, mp);
8717             sp_3072_mont_sqr_26(rt, rt, m, mp);
8718             sp_3072_mont_sqr_26(rt, rt, m, mp);
8719             sp_3072_mont_sqr_26(rt, rt, m, mp);
8720             sp_3072_mont_sqr_26(rt, rt, m, mp);
8721 
8722             sp_3072_mont_mul_26(rt, rt, t[y], m, mp);
8723         }
8724 
8725         sp_3072_mont_reduce_26(rt, m, mp);
8726         n = sp_3072_cmp_26(rt, m);
8727         sp_3072_cond_sub_26(rt, rt, m, ((n < 0) ?
8728                    (sp_digit)1 : (sp_digit)0) - 1);
8729         XMEMCPY(r, rt, sizeof(sp_digit) * 52);
8730     }
8731 
8732 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
8733     if (td != NULL)
8734         XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);
8735 #endif
8736 
8737     return err;
8738 #endif
8739 }
8740 
8741 #endif /* (WOLFSSL_HAVE_SP_RSA & !WOLFSSL_RSA_PUBLIC_ONLY) | WOLFSSL_HAVE_SP_DH */
8742 
8743 /* Sub b from a into r. (r = a - b)
8744  *
8745  * r  A single precision integer.
8746  * a  A single precision integer.
8747  * b  A single precision integer.
8748  */
sp_3072_sub_52(sp_digit * r,const sp_digit * a,const sp_digit * b)8749 SP_NOINLINE static int sp_3072_sub_52(sp_digit* r, const sp_digit* a,
8750         const sp_digit* b)
8751 {
8752     int i;
8753 
8754     for (i = 0; i < 52; i++) {
8755         r[i] = a[i] - b[i];
8756     }
8757 
8758     return 0;
8759 }
8760 
8761 /* r = 2^n mod m where n is the number of bits to reduce by.
8762  * Given m must be 3072 bits, just need to subtract.
8763  *
8764  * r  A single precision number.
8765  * m  A single precision number.
8766  */
sp_3072_mont_norm_52(sp_digit * r,const sp_digit * m)8767 static void sp_3072_mont_norm_52(sp_digit* r, const sp_digit* m)
8768 {
8769     /* Set r = 2^n - 1. */
8770     int i;
8771 
8772     for (i=0; i<51; i++) {
8773         r[i] = 0xfffffffffffffffL;
8774     }
8775     r[51] = 0xfffL;
8776 
8777     /* r = (2^n - 1) mod n */
8778     (void)sp_3072_sub_52(r, r, m);
8779 
8780     /* Add one so r = 2^n mod m */
8781     r[0] += 1;
8782 }
8783 
8784 /* Compare a with b in constant time.
8785  *
8786  * a  A single precision integer.
8787  * b  A single precision integer.
8788  * return -ve, 0 or +ve if a is less than, equal to or greater than b
8789  * respectively.
8790  */
sp_3072_cmp_52(const sp_digit * a,const sp_digit * b)8791 static sp_digit sp_3072_cmp_52(const sp_digit* a, const sp_digit* b)
8792 {
8793     sp_digit r = 0;
8794     int i;
8795 
8796     for (i=51; i>=0; i--) {
8797         r |= (a[i] - b[i]) & (0 - (sp_digit)((r == 0) ? 1 : 0));
8798     }
8799 
8800     return r;
8801 }
8802 
8803 /* Conditionally subtract b from a using the mask m.
8804  * m is -1 to subtract and 0 when not.
8805  *
8806  * r  A single precision number representing condition subtract result.
8807  * a  A single precision number to subtract from.
8808  * b  A single precision number to subtract.
8809  * m  Mask value to apply.
8810  */
sp_3072_cond_sub_52(sp_digit * r,const sp_digit * a,const sp_digit * b,const sp_digit m)8811 static void sp_3072_cond_sub_52(sp_digit* r, const sp_digit* a,
8812         const sp_digit* b, const sp_digit m)
8813 {
8814     int i;
8815 
8816     for (i = 0; i < 52; i++) {
8817         r[i] = a[i] - (b[i] & m);
8818     }
8819 }
8820 
8821 /* Mul a by scalar b and add into r. (r += a * b)
8822  *
8823  * r  A single precision integer.
8824  * a  A single precision integer.
8825  * b  A scalar.
8826  */
sp_3072_mul_add_52(sp_digit * r,const sp_digit * a,const sp_digit b)8827 SP_NOINLINE static void sp_3072_mul_add_52(sp_digit* r, const sp_digit* a,
8828         const sp_digit b)
8829 {
8830     sp_int128 tb = b;
8831     sp_int128 t[4];
8832     int i;
8833 
8834     t[0] = 0;
8835     for (i = 0; i < 48; i += 4) {
8836         t[0] += (tb * a[i+0]) + r[i+0];
8837         t[1]  = (tb * a[i+1]) + r[i+1];
8838         t[2]  = (tb * a[i+2]) + r[i+2];
8839         t[3]  = (tb * a[i+3]) + r[i+3];
8840         r[i+0] = t[0] & 0xfffffffffffffffL;
8841         t[1] += t[0] >> 60;
8842         r[i+1] = t[1] & 0xfffffffffffffffL;
8843         t[2] += t[1] >> 60;
8844         r[i+2] = t[2] & 0xfffffffffffffffL;
8845         t[3] += t[2] >> 60;
8846         r[i+3] = t[3] & 0xfffffffffffffffL;
8847         t[0]  = t[3] >> 60;
8848     }
8849     t[0] += (tb * a[48]) + r[48];
8850     t[1]  = (tb * a[49]) + r[49];
8851     t[2]  = (tb * a[50]) + r[50];
8852     t[3]  = (tb * a[51]) + r[51];
8853     r[48] = t[0] & 0xfffffffffffffffL;
8854     t[1] += t[0] >> 60;
8855     r[49] = t[1] & 0xfffffffffffffffL;
8856     t[2] += t[1] >> 60;
8857     r[50] = t[2] & 0xfffffffffffffffL;
8858     t[3] += t[2] >> 60;
8859     r[51] = t[3] & 0xfffffffffffffffL;
8860     r[52] +=  (sp_digit)(t[3] >> 60);
8861 }
8862 
8863 /* Shift the result in the high 3072 bits down to the bottom.
8864  *
8865  * r  A single precision number.
8866  * a  A single precision number.
8867  */
sp_3072_mont_shift_52(sp_digit * r,const sp_digit * a)8868 static void sp_3072_mont_shift_52(sp_digit* r, const sp_digit* a)
8869 {
8870     int i;
8871     sp_int128 n = a[51] >> 12;
8872     n += ((sp_int128)a[52]) << 48;
8873 
8874     for (i = 0; i < 51; i++) {
8875         r[i] = n & 0xfffffffffffffffL;
8876         n >>= 60;
8877         n += ((sp_int128)a[53 + i]) << 48;
8878     }
8879     r[51] = (sp_digit)n;
8880     XMEMSET(&r[52], 0, sizeof(*r) * 52U);
8881 }
8882 
8883 /* Reduce the number back to 3072 bits using Montgomery reduction.
8884  *
8885  * a   A single precision number to reduce in place.
8886  * m   The single precision number representing the modulus.
8887  * mp  The digit representing the negative inverse of m mod 2^n.
8888  */
sp_3072_mont_reduce_52(sp_digit * a,const sp_digit * m,sp_digit mp)8889 static void sp_3072_mont_reduce_52(sp_digit* a, const sp_digit* m, sp_digit mp)
8890 {
8891     int i;
8892     sp_digit mu;
8893 
8894     sp_3072_norm_52(a + 52);
8895 
8896 #ifdef WOLFSSL_SP_DH
8897     if (mp != 1) {
8898         for (i=0; i<51; i++) {
8899             mu = (a[i] * mp) & 0xfffffffffffffffL;
8900             sp_3072_mul_add_52(a+i, m, mu);
8901             a[i+1] += a[i] >> 60;
8902         }
8903         mu = (a[i] * mp) & 0xfffL;
8904         sp_3072_mul_add_52(a+i, m, mu);
8905         a[i+1] += a[i] >> 60;
8906         a[i] &= 0xfffffffffffffffL;
8907     }
8908     else {
8909         for (i=0; i<51; i++) {
8910             mu = a[i] & 0xfffffffffffffffL;
8911             sp_3072_mul_add_52(a+i, m, mu);
8912             a[i+1] += a[i] >> 60;
8913         }
8914         mu = a[i] & 0xfffL;
8915         sp_3072_mul_add_52(a+i, m, mu);
8916         a[i+1] += a[i] >> 60;
8917         a[i] &= 0xfffffffffffffffL;
8918     }
8919 #else
8920     for (i=0; i<51; i++) {
8921         mu = (a[i] * mp) & 0xfffffffffffffffL;
8922         sp_3072_mul_add_52(a+i, m, mu);
8923         a[i+1] += a[i] >> 60;
8924     }
8925     mu = (a[i] * mp) & 0xfffL;
8926     sp_3072_mul_add_52(a+i, m, mu);
8927     a[i+1] += a[i] >> 60;
8928     a[i] &= 0xfffffffffffffffL;
8929 #endif
8930     sp_3072_mont_shift_52(a, a);
8931     sp_3072_cond_sub_52(a, a, m, 0 - (((a[51] - m[51]) > 0) ?
8932             (sp_digit)1 : (sp_digit)0));
8933     sp_3072_norm_52(a);
8934 }
8935 
8936 /* Multiply two Montgomery form numbers mod the modulus (prime).
8937  * (r = a * b mod m)
8938  *
8939  * r   Result of multiplication.
8940  * a   First number to multiply in Montgomery form.
8941  * b   Second number to multiply in Montgomery form.
8942  * m   Modulus (prime).
8943  * mp  Montgomery mulitplier.
8944  */
sp_3072_mont_mul_52(sp_digit * r,const sp_digit * a,const sp_digit * b,const sp_digit * m,sp_digit mp)8945 static void sp_3072_mont_mul_52(sp_digit* r, const sp_digit* a,
8946         const sp_digit* b, const sp_digit* m, sp_digit mp)
8947 {
8948     sp_3072_mul_52(r, a, b);
8949     sp_3072_mont_reduce_52(r, m, mp);
8950 }
8951 
8952 /* Square the Montgomery form number. (r = a * a mod m)
8953  *
8954  * r   Result of squaring.
8955  * a   Number to square in Montgomery form.
8956  * m   Modulus (prime).
8957  * mp  Montgomery mulitplier.
8958  */
sp_3072_mont_sqr_52(sp_digit * r,const sp_digit * a,const sp_digit * m,sp_digit mp)8959 static void sp_3072_mont_sqr_52(sp_digit* r, const sp_digit* a,
8960         const sp_digit* m, sp_digit mp)
8961 {
8962     sp_3072_sqr_52(r, a);
8963     sp_3072_mont_reduce_52(r, m, mp);
8964 }
8965 
8966 /* Multiply a by scalar b into r. (r = a * b)
8967  *
8968  * r  A single precision integer.
8969  * a  A single precision integer.
8970  * b  A scalar.
8971  */
sp_3072_mul_d_104(sp_digit * r,const sp_digit * a,sp_digit b)8972 SP_NOINLINE static void sp_3072_mul_d_104(sp_digit* r, const sp_digit* a,
8973     sp_digit b)
8974 {
8975     sp_int128 tb = b;
8976     sp_int128 t = 0;
8977     int i;
8978 
8979     for (i = 0; i < 104; i++) {
8980         t += tb * a[i];
8981         r[i] = (sp_digit)(t & 0xfffffffffffffffL);
8982         t >>= 60;
8983     }
8984     r[104] = (sp_digit)t;
8985 }
8986 
8987 /* Conditionally add a and b using the mask m.
8988  * m is -1 to add and 0 when not.
8989  *
8990  * r  A single precision number representing conditional add result.
8991  * a  A single precision number to add with.
8992  * b  A single precision number to add.
8993  * m  Mask value to apply.
8994  */
sp_3072_cond_add_52(sp_digit * r,const sp_digit * a,const sp_digit * b,const sp_digit m)8995 static void sp_3072_cond_add_52(sp_digit* r, const sp_digit* a,
8996         const sp_digit* b, const sp_digit m)
8997 {
8998     int i;
8999 
9000     for (i = 0; i < 26; i++) {
9001         r[i] = a[i] + (b[i] & m);
9002     }
9003 }
9004 
9005 /* Add b to a into r. (r = a + b)
9006  *
9007  * r  A single precision integer.
9008  * a  A single precision integer.
9009  * b  A single precision integer.
9010  */
sp_3072_add_52(sp_digit * r,const sp_digit * a,const sp_digit * b)9011 SP_NOINLINE static int sp_3072_add_52(sp_digit* r, const sp_digit* a,
9012         const sp_digit* b)
9013 {
9014     int i;
9015 
9016     for (i = 0; i < 52; i++) {
9017         r[i] = a[i] + b[i];
9018     }
9019 
9020     return 0;
9021 }
9022 
sp_3072_rshift_52(sp_digit * r,const sp_digit * a,byte n)9023 SP_NOINLINE static void sp_3072_rshift_52(sp_digit* r, const sp_digit* a,
9024         byte n)
9025 {
9026     int i;
9027 
9028     for (i=0; i<51; i++) {
9029         r[i] = ((a[i] >> n) | (a[i + 1] << (60 - n))) & 0xfffffffffffffffL;
9030     }
9031     r[51] = a[51] >> n;
9032 }
9033 
9034 #ifdef WOLFSSL_SP_DIV_64
sp_3072_div_word_52(sp_digit d1,sp_digit d0,sp_digit dv)9035 static WC_INLINE sp_digit sp_3072_div_word_52(sp_digit d1, sp_digit d0,
9036     sp_digit dv)
9037 {
9038     sp_digit d;
9039     sp_digit r;
9040     sp_digit t;
9041 
9042     /* All 60 bits from d1 and top 3 bits from d0. */
9043     d = (d1 << 3) + (d0 >> 57);
9044     r = d / dv;
9045     d -= r * dv;
9046     /* Up to 4 bits in r */
9047     /* Next 3 bits from d0. */
9048     r <<= 3;
9049     d <<= 3;
9050     d += (d0 >> 54) & ((1 << 3) - 1);
9051     t = d / dv;
9052     d -= t * dv;
9053     r += t;
9054     /* Up to 7 bits in r */
9055     /* Next 3 bits from d0. */
9056     r <<= 3;
9057     d <<= 3;
9058     d += (d0 >> 51) & ((1 << 3) - 1);
9059     t = d / dv;
9060     d -= t * dv;
9061     r += t;
9062     /* Up to 10 bits in r */
9063     /* Next 3 bits from d0. */
9064     r <<= 3;
9065     d <<= 3;
9066     d += (d0 >> 48) & ((1 << 3) - 1);
9067     t = d / dv;
9068     d -= t * dv;
9069     r += t;
9070     /* Up to 13 bits in r */
9071     /* Next 3 bits from d0. */
9072     r <<= 3;
9073     d <<= 3;
9074     d += (d0 >> 45) & ((1 << 3) - 1);
9075     t = d / dv;
9076     d -= t * dv;
9077     r += t;
9078     /* Up to 16 bits in r */
9079     /* Next 3 bits from d0. */
9080     r <<= 3;
9081     d <<= 3;
9082     d += (d0 >> 42) & ((1 << 3) - 1);
9083     t = d / dv;
9084     d -= t * dv;
9085     r += t;
9086     /* Up to 19 bits in r */
9087     /* Next 3 bits from d0. */
9088     r <<= 3;
9089     d <<= 3;
9090     d += (d0 >> 39) & ((1 << 3) - 1);
9091     t = d / dv;
9092     d -= t * dv;
9093     r += t;
9094     /* Up to 22 bits in r */
9095     /* Next 3 bits from d0. */
9096     r <<= 3;
9097     d <<= 3;
9098     d += (d0 >> 36) & ((1 << 3) - 1);
9099     t = d / dv;
9100     d -= t * dv;
9101     r += t;
9102     /* Up to 25 bits in r */
9103     /* Next 3 bits from d0. */
9104     r <<= 3;
9105     d <<= 3;
9106     d += (d0 >> 33) & ((1 << 3) - 1);
9107     t = d / dv;
9108     d -= t * dv;
9109     r += t;
9110     /* Up to 28 bits in r */
9111     /* Next 3 bits from d0. */
9112     r <<= 3;
9113     d <<= 3;
9114     d += (d0 >> 30) & ((1 << 3) - 1);
9115     t = d / dv;
9116     d -= t * dv;
9117     r += t;
9118     /* Up to 31 bits in r */
9119     /* Next 3 bits from d0. */
9120     r <<= 3;
9121     d <<= 3;
9122     d += (d0 >> 27) & ((1 << 3) - 1);
9123     t = d / dv;
9124     d -= t * dv;
9125     r += t;
9126     /* Up to 34 bits in r */
9127     /* Next 3 bits from d0. */
9128     r <<= 3;
9129     d <<= 3;
9130     d += (d0 >> 24) & ((1 << 3) - 1);
9131     t = d / dv;
9132     d -= t * dv;
9133     r += t;
9134     /* Up to 37 bits in r */
9135     /* Next 3 bits from d0. */
9136     r <<= 3;
9137     d <<= 3;
9138     d += (d0 >> 21) & ((1 << 3) - 1);
9139     t = d / dv;
9140     d -= t * dv;
9141     r += t;
9142     /* Up to 40 bits in r */
9143     /* Next 3 bits from d0. */
9144     r <<= 3;
9145     d <<= 3;
9146     d += (d0 >> 18) & ((1 << 3) - 1);
9147     t = d / dv;
9148     d -= t * dv;
9149     r += t;
9150     /* Up to 43 bits in r */
9151     /* Next 3 bits from d0. */
9152     r <<= 3;
9153     d <<= 3;
9154     d += (d0 >> 15) & ((1 << 3) - 1);
9155     t = d / dv;
9156     d -= t * dv;
9157     r += t;
9158     /* Up to 46 bits in r */
9159     /* Next 3 bits from d0. */
9160     r <<= 3;
9161     d <<= 3;
9162     d += (d0 >> 12) & ((1 << 3) - 1);
9163     t = d / dv;
9164     d -= t * dv;
9165     r += t;
9166     /* Up to 49 bits in r */
9167     /* Next 3 bits from d0. */
9168     r <<= 3;
9169     d <<= 3;
9170     d += (d0 >> 9) & ((1 << 3) - 1);
9171     t = d / dv;
9172     d -= t * dv;
9173     r += t;
9174     /* Up to 52 bits in r */
9175     /* Next 3 bits from d0. */
9176     r <<= 3;
9177     d <<= 3;
9178     d += (d0 >> 6) & ((1 << 3) - 1);
9179     t = d / dv;
9180     d -= t * dv;
9181     r += t;
9182     /* Up to 55 bits in r */
9183     /* Next 3 bits from d0. */
9184     r <<= 3;
9185     d <<= 3;
9186     d += (d0 >> 3) & ((1 << 3) - 1);
9187     t = d / dv;
9188     d -= t * dv;
9189     r += t;
9190     /* Up to 58 bits in r */
9191     /* Remaining 3 bits from d0. */
9192     r <<= 3;
9193     d <<= 3;
9194     d += d0 & ((1 << 3) - 1);
9195     t = d / dv;
9196     r += t;
9197 
9198     /* All 60 bits from d1 and top 3 bits from d0. */
9199     return r;
9200 }
9201 #endif /* WOLFSSL_SP_DIV_64 */
9202 
9203 /* Divide d in a and put remainder into r (m*d + r = a)
9204  * m is not calculated as it is not needed at this time.
9205  *
9206  * Full implementation.
9207  *
9208  * a  Number to be divided.
9209  * d  Number to divide with.
9210  * m  Multiplier result.
9211  * r  Remainder from the division.
9212  * returns MEMORY_E when unable to allocate memory and MP_OKAY otherwise.
9213  */
sp_3072_div_52(const sp_digit * a,const sp_digit * d,const sp_digit * m,sp_digit * r)9214 static int sp_3072_div_52(const sp_digit* a, const sp_digit* d,
9215         const sp_digit* m, sp_digit* r)
9216 {
9217     int i;
9218 #ifndef WOLFSSL_SP_DIV_64
9219     sp_int128 d1;
9220 #endif
9221     sp_digit dv;
9222     sp_digit r1;
9223 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
9224     sp_digit* t1 = NULL;
9225 #else
9226     sp_digit t1[4 * 52 + 3];
9227 #endif
9228     sp_digit* t2 = NULL;
9229     sp_digit* sd = NULL;
9230     int err = MP_OKAY;
9231 
9232     (void)m;
9233 
9234 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
9235     t1 = (sp_digit*)XMALLOC(sizeof(sp_digit) * (4 * 52 + 3), NULL,
9236                                                        DYNAMIC_TYPE_TMP_BUFFER);
9237     if (t1 == NULL)
9238         err = MEMORY_E;
9239 #endif
9240 
9241     (void)m;
9242 
9243     if (err == MP_OKAY) {
9244         t2 = t1 + 104 + 1;
9245         sd = t2 + 52 + 1;
9246 
9247         sp_3072_mul_d_52(sd, d, (sp_digit)1 << 48);
9248         sp_3072_mul_d_104(t1, a, (sp_digit)1 << 48);
9249         dv = sd[51];
9250         t1[52 + 52] += t1[52 + 52 - 1] >> 60;
9251         t1[52 + 52 - 1] &= 0xfffffffffffffffL;
9252         for (i=52; i>=0; i--) {
9253 #ifndef WOLFSSL_SP_DIV_64
9254             d1 = t1[52 + i];
9255             d1 <<= 60;
9256             d1 += t1[52 + i - 1];
9257             r1 = (sp_digit)(d1 / dv);
9258 #else
9259             r1 = sp_3072_div_word_52(t1[52 + i], t1[52 + i - 1], dv);
9260 #endif
9261 
9262             sp_3072_mul_d_52(t2, sd, r1);
9263             (void)sp_3072_sub_52(&t1[i], &t1[i], t2);
9264             sp_3072_norm_52(&t1[i]);
9265             t1[52 + i] -= t2[52];
9266             t1[52 + i] += t1[52 + i - 1] >> 60;
9267             t1[52 + i - 1] &= 0xfffffffffffffffL;
9268 #ifndef WOLFSSL_SP_DIV_64
9269             d1 = -t1[52 + i];
9270             d1 <<= 60;
9271             d1 -= t1[52 + i - 1];
9272             r1 = (sp_digit)(d1 / dv);
9273 #else
9274             r1 = sp_3072_div_word_52(-t1[52 + i], -t1[52 + i - 1], dv);
9275 #endif
9276             r1 -= t1[52 + i];
9277             sp_3072_mul_d_52(t2, sd, r1);
9278             (void)sp_3072_add_52(&t1[i], &t1[i], t2);
9279             t1[52 + i] += t1[52 + i - 1] >> 60;
9280             t1[52 + i - 1] &= 0xfffffffffffffffL;
9281         }
9282         t1[52 - 1] += t1[52 - 2] >> 60;
9283         t1[52 - 2] &= 0xfffffffffffffffL;
9284         r1 = t1[52 - 1] / dv;
9285 
9286         sp_3072_mul_d_52(t2, sd, r1);
9287         sp_3072_sub_52(t1, t1, t2);
9288         XMEMCPY(r, t1, sizeof(*r) * 104U);
9289         for (i=0; i<51; i++) {
9290             r[i+1] += r[i] >> 60;
9291             r[i] &= 0xfffffffffffffffL;
9292         }
9293         sp_3072_cond_add_52(r, r, sd, 0 - ((r[51] < 0) ?
9294                     (sp_digit)1 : (sp_digit)0));
9295 
9296         sp_3072_norm_52(r);
9297         sp_3072_rshift_52(r, r, 48);
9298     }
9299 
9300 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
9301     if (t1 != NULL)
9302         XFREE(t1, NULL, DYNAMIC_TYPE_TMP_BUFFER);
9303 #endif
9304 
9305     return err;
9306 }
9307 
9308 /* Reduce a modulo m into r. (r = a mod m)
9309  *
9310  * r  A single precision number that is the reduced result.
9311  * a  A single precision number that is to be reduced.
9312  * m  A single precision number that is the modulus to reduce with.
9313  * returns MEMORY_E when unable to allocate memory and MP_OKAY otherwise.
9314  */
sp_3072_mod_52(sp_digit * r,const sp_digit * a,const sp_digit * m)9315 static int sp_3072_mod_52(sp_digit* r, const sp_digit* a, const sp_digit* m)
9316 {
9317     return sp_3072_div_52(a, m, NULL, r);
9318 }
9319 
9320 #if (defined(WOLFSSL_HAVE_SP_RSA) && !defined(WOLFSSL_RSA_PUBLIC_ONLY)) || defined(WOLFSSL_HAVE_SP_DH)
9321 /* Modular exponentiate a to the e mod m. (r = a^e mod m)
9322  *
9323  * r     A single precision number that is the result of the operation.
9324  * a     A single precision number being exponentiated.
9325  * e     A single precision number that is the exponent.
9326  * bits  The number of bits in the exponent.
9327  * m     A single precision number that is the modulus.
9328  * returns  0 on success.
9329  * returns  MEMORY_E on dynamic memory allocation failure.
9330  * returns  MP_VAL when base is even or exponent is 0.
9331  */
sp_3072_mod_exp_52(sp_digit * r,const sp_digit * a,const sp_digit * e,int bits,const sp_digit * m,int reduceA)9332 static int sp_3072_mod_exp_52(sp_digit* r, const sp_digit* a, const sp_digit* e,
9333     int bits, const sp_digit* m, int reduceA)
9334 {
9335 #if defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SP_FAST_MODEXP)
9336 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
9337     sp_digit* td = NULL;
9338 #else
9339     sp_digit td[3 * 104];
9340 #endif
9341     sp_digit* t[3] = {0, 0, 0};
9342     sp_digit* norm = NULL;
9343     sp_digit mp = 1;
9344     sp_digit n;
9345     int i;
9346     int c;
9347     byte y;
9348     int err = MP_OKAY;
9349 
9350     if ((m[0] & 1) == 0) {
9351         err = MP_VAL;
9352     }
9353     else if (bits == 0) {
9354         err = MP_VAL;
9355     }
9356 
9357 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
9358     if (err == MP_OKAY) {
9359         td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 3 * 52 * 2, NULL,
9360                                 DYNAMIC_TYPE_TMP_BUFFER);
9361         if (td == NULL)
9362             err = MEMORY_E;
9363     }
9364 #endif
9365 
9366     if (err == MP_OKAY) {
9367         norm = td;
9368         for (i=0; i<3; i++) {
9369             t[i] = td + (i * 52 * 2);
9370             XMEMSET(t[i], 0, sizeof(sp_digit) * 52U * 2U);
9371         }
9372 
9373         sp_3072_mont_setup(m, &mp);
9374         sp_3072_mont_norm_52(norm, m);
9375 
9376         if (reduceA != 0) {
9377             err = sp_3072_mod_52(t[1], a, m);
9378         }
9379         else {
9380             XMEMCPY(t[1], a, sizeof(sp_digit) * 52U);
9381         }
9382     }
9383     if (err == MP_OKAY) {
9384         sp_3072_mul_52(t[1], t[1], norm);
9385         err = sp_3072_mod_52(t[1], t[1], m);
9386     }
9387 
9388     if (err == MP_OKAY) {
9389         i = bits / 60;
9390         c = bits % 60;
9391         n = e[i--] << (60 - c);
9392         for (; ; c--) {
9393             if (c == 0) {
9394                 if (i == -1) {
9395                     break;
9396                 }
9397 
9398                 n = e[i--];
9399                 c = 60;
9400             }
9401 
9402             y = (int)((n >> 59) & 1);
9403             n <<= 1;
9404 
9405             sp_3072_mont_mul_52(t[y^1], t[0], t[1], m, mp);
9406 
9407             XMEMCPY(t[2], (void*)(((size_t)t[0] & addr_mask[y^1]) +
9408                                   ((size_t)t[1] & addr_mask[y])),
9409                                   sizeof(*t[2]) * 52 * 2);
9410             sp_3072_mont_sqr_52(t[2], t[2], m, mp);
9411             XMEMCPY((void*)(((size_t)t[0] & addr_mask[y^1]) +
9412                             ((size_t)t[1] & addr_mask[y])), t[2],
9413                             sizeof(*t[2]) * 52 * 2);
9414         }
9415 
9416         sp_3072_mont_reduce_52(t[0], m, mp);
9417         n = sp_3072_cmp_52(t[0], m);
9418         sp_3072_cond_sub_52(t[0], t[0], m, ((n < 0) ?
9419                     (sp_digit)1 : (sp_digit)0) - 1);
9420         XMEMCPY(r, t[0], sizeof(*r) * 52 * 2);
9421 
9422     }
9423 
9424 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
9425     if (td != NULL)
9426         XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);
9427 #endif
9428 
9429     return err;
9430 #elif !defined(WC_NO_CACHE_RESISTANT)
9431 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
9432     sp_digit* td = NULL;
9433 #else
9434     sp_digit td[3 * 104];
9435 #endif
9436     sp_digit* t[3] = {0, 0, 0};
9437     sp_digit* norm = NULL;
9438     sp_digit mp = 1;
9439     sp_digit n;
9440     int i;
9441     int c;
9442     byte y;
9443     int err = MP_OKAY;
9444 
9445     if ((m[0] & 1) == 0) {
9446         err = MP_VAL;
9447     }
9448     else if (bits == 0) {
9449         err = MP_VAL;
9450     }
9451 
9452 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
9453     if (err == MP_OKAY) {
9454         td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 3 * 52 * 2, NULL,
9455                                 DYNAMIC_TYPE_TMP_BUFFER);
9456         if (td == NULL)
9457             err = MEMORY_E;
9458     }
9459 #endif
9460 
9461     if (err == MP_OKAY) {
9462         norm = td;
9463         for (i=0; i<3; i++) {
9464             t[i] = td + (i * 52 * 2);
9465         }
9466 
9467         sp_3072_mont_setup(m, &mp);
9468         sp_3072_mont_norm_52(norm, m);
9469 
9470         if (reduceA != 0) {
9471             err = sp_3072_mod_52(t[1], a, m);
9472             if (err == MP_OKAY) {
9473                 sp_3072_mul_52(t[1], t[1], norm);
9474                 err = sp_3072_mod_52(t[1], t[1], m);
9475             }
9476         }
9477         else {
9478             sp_3072_mul_52(t[1], a, norm);
9479             err = sp_3072_mod_52(t[1], t[1], m);
9480         }
9481     }
9482 
9483     if (err == MP_OKAY) {
9484         i = bits / 60;
9485         c = bits % 60;
9486         n = e[i--] << (60 - c);
9487         for (; ; c--) {
9488             if (c == 0) {
9489                 if (i == -1) {
9490                     break;
9491                 }
9492 
9493                 n = e[i--];
9494                 c = 60;
9495             }
9496 
9497             y = (int)((n >> 59) & 1);
9498             n <<= 1;
9499 
9500             sp_3072_mont_mul_52(t[y^1], t[0], t[1], m, mp);
9501 
9502             XMEMCPY(t[2], (void*)(((size_t)t[0] & addr_mask[y^1]) +
9503                                   ((size_t)t[1] & addr_mask[y])),
9504                                   sizeof(*t[2]) * 52 * 2);
9505             sp_3072_mont_sqr_52(t[2], t[2], m, mp);
9506             XMEMCPY((void*)(((size_t)t[0] & addr_mask[y^1]) +
9507                             ((size_t)t[1] & addr_mask[y])), t[2],
9508                             sizeof(*t[2]) * 52 * 2);
9509         }
9510 
9511         sp_3072_mont_reduce_52(t[0], m, mp);
9512         n = sp_3072_cmp_52(t[0], m);
9513         sp_3072_cond_sub_52(t[0], t[0], m, ((n < 0) ?
9514                     (sp_digit)1 : (sp_digit)0) - 1);
9515         XMEMCPY(r, t[0], sizeof(*r) * 52 * 2);
9516     }
9517 
9518 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
9519     if (td != NULL)
9520         XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);
9521 #endif
9522 
9523     return err;
9524 #else
9525 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
9526     sp_digit* td = NULL;
9527 #else
9528     sp_digit td[(16 * 104) + 104];
9529 #endif
9530     sp_digit* t[16];
9531     sp_digit* rt = NULL;
9532     sp_digit* norm = NULL;
9533     sp_digit mp = 1;
9534     sp_digit n;
9535     int i;
9536     int c;
9537     byte y;
9538     int err = MP_OKAY;
9539 
9540     if ((m[0] & 1) == 0) {
9541         err = MP_VAL;
9542     }
9543     else if (bits == 0) {
9544         err = MP_VAL;
9545     }
9546 
9547 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
9548     if (err == MP_OKAY) {
9549         td = (sp_digit*)XMALLOC(sizeof(sp_digit) * ((16 * 104) + 104), NULL,
9550                                 DYNAMIC_TYPE_TMP_BUFFER);
9551         if (td == NULL)
9552             err = MEMORY_E;
9553     }
9554 #endif
9555 
9556     if (err == MP_OKAY) {
9557         norm = td;
9558         for (i=0; i<16; i++)
9559             t[i] = td + i * 104;
9560         rt = td + 1664;
9561 
9562         sp_3072_mont_setup(m, &mp);
9563         sp_3072_mont_norm_52(norm, m);
9564 
9565         if (reduceA != 0) {
9566             err = sp_3072_mod_52(t[1], a, m);
9567             if (err == MP_OKAY) {
9568                 sp_3072_mul_52(t[1], t[1], norm);
9569                 err = sp_3072_mod_52(t[1], t[1], m);
9570             }
9571         }
9572         else {
9573             sp_3072_mul_52(t[1], a, norm);
9574             err = sp_3072_mod_52(t[1], t[1], m);
9575         }
9576     }
9577 
9578     if (err == MP_OKAY) {
9579         sp_3072_mont_sqr_52(t[ 2], t[ 1], m, mp);
9580         sp_3072_mont_mul_52(t[ 3], t[ 2], t[ 1], m, mp);
9581         sp_3072_mont_sqr_52(t[ 4], t[ 2], m, mp);
9582         sp_3072_mont_mul_52(t[ 5], t[ 3], t[ 2], m, mp);
9583         sp_3072_mont_sqr_52(t[ 6], t[ 3], m, mp);
9584         sp_3072_mont_mul_52(t[ 7], t[ 4], t[ 3], m, mp);
9585         sp_3072_mont_sqr_52(t[ 8], t[ 4], m, mp);
9586         sp_3072_mont_mul_52(t[ 9], t[ 5], t[ 4], m, mp);
9587         sp_3072_mont_sqr_52(t[10], t[ 5], m, mp);
9588         sp_3072_mont_mul_52(t[11], t[ 6], t[ 5], m, mp);
9589         sp_3072_mont_sqr_52(t[12], t[ 6], m, mp);
9590         sp_3072_mont_mul_52(t[13], t[ 7], t[ 6], m, mp);
9591         sp_3072_mont_sqr_52(t[14], t[ 7], m, mp);
9592         sp_3072_mont_mul_52(t[15], t[ 8], t[ 7], m, mp);
9593 
9594         bits = ((bits + 3) / 4) * 4;
9595         i = ((bits + 59) / 60) - 1;
9596         c = bits % 60;
9597         if (c == 0) {
9598             c = 60;
9599         }
9600         if (i < 52) {
9601             n = e[i--] << (64 - c);
9602         }
9603         else {
9604             n = 0;
9605             i--;
9606         }
9607         if (c < 4) {
9608             n |= e[i--] << (4 - c);
9609             c += 60;
9610         }
9611         y = (int)((n >> 60) & 0xf);
9612         n <<= 4;
9613         c -= 4;
9614         XMEMCPY(rt, t[y], sizeof(sp_digit) * 104);
9615         while ((i >= 0) || (c >= 4)) {
9616             if (c >= 4) {
9617                 y = (byte)((n >> 60) & 0xf);
9618                 n <<= 4;
9619                 c -= 4;
9620             }
9621             else if (c == 0) {
9622                 n = e[i--] << 4;
9623                 y = (byte)((n >> 60) & 0xf);
9624                 n <<= 4;
9625                 c = 56;
9626             }
9627             else {
9628                 y = (byte)((n >> 60) & 0xf);
9629                 n = e[i--] << 4;
9630                 c = 4 - c;
9631                 y |= (byte)((n >> (64 - c)) & ((1 << c) - 1));
9632                 n <<= c;
9633                 c = 60 - c;
9634             }
9635 
9636             sp_3072_mont_sqr_52(rt, rt, m, mp);
9637             sp_3072_mont_sqr_52(rt, rt, m, mp);
9638             sp_3072_mont_sqr_52(rt, rt, m, mp);
9639             sp_3072_mont_sqr_52(rt, rt, m, mp);
9640 
9641             sp_3072_mont_mul_52(rt, rt, t[y], m, mp);
9642         }
9643 
9644         sp_3072_mont_reduce_52(rt, m, mp);
9645         n = sp_3072_cmp_52(rt, m);
9646         sp_3072_cond_sub_52(rt, rt, m, ((n < 0) ?
9647                    (sp_digit)1 : (sp_digit)0) - 1);
9648         XMEMCPY(r, rt, sizeof(sp_digit) * 104);
9649     }
9650 
9651 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
9652     if (td != NULL)
9653         XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);
9654 #endif
9655 
9656     return err;
9657 #endif
9658 }
9659 
9660 #endif /* (WOLFSSL_HAVE_SP_RSA && !WOLFSSL_RSA_PUBLIC_ONLY) || WOLFSSL_HAVE_SP_DH */
9661 #ifdef WOLFSSL_HAVE_SP_RSA
9662 /* RSA public key operation.
9663  *
9664  * in      Array of bytes representing the number to exponentiate, base.
9665  * inLen   Number of bytes in base.
9666  * em      Public exponent.
9667  * mm      Modulus.
9668  * out     Buffer to hold big-endian bytes of exponentiation result.
9669  *         Must be at least 384 bytes long.
9670  * outLen  Number of bytes in result.
9671  * returns 0 on success, MP_TO_E when the outLen is too small, MP_READ_E when
9672  * an array is too long and MEMORY_E when dynamic memory allocation fails.
9673  */
sp_RsaPublic_3072(const byte * in,word32 inLen,const mp_int * em,const mp_int * mm,byte * out,word32 * outLen)9674 int sp_RsaPublic_3072(const byte* in, word32 inLen, const mp_int* em,
9675     const mp_int* mm, byte* out, word32* outLen)
9676 {
9677 #ifdef WOLFSSL_SP_SMALL
9678 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
9679     sp_digit* a = NULL;
9680 #else
9681     sp_digit a[52 * 5];
9682 #endif
9683     sp_digit* m = NULL;
9684     sp_digit* r = NULL;
9685     sp_digit* norm = NULL;
9686     sp_digit e[1] = {0};
9687     sp_digit mp;
9688     int i;
9689     int err = MP_OKAY;
9690 
9691     if (*outLen < 384U) {
9692         err = MP_TO_E;
9693     }
9694 
9695     if (err == MP_OKAY) {
9696         if (mp_count_bits(em) > 60) {
9697             err = MP_READ_E;
9698         }
9699         else if (inLen > 384U) {
9700             err = MP_READ_E;
9701         }
9702         else if (mp_count_bits(mm) != 3072) {
9703             err = MP_READ_E;
9704         }
9705         else if (mp_iseven(mm)) {
9706             err = MP_VAL;
9707         }
9708     }
9709 
9710 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
9711     if (err == MP_OKAY) {
9712         a = (sp_digit*)XMALLOC(sizeof(sp_digit) * 52 * 5, NULL,
9713                                                               DYNAMIC_TYPE_RSA);
9714         if (a == NULL)
9715             err = MEMORY_E;
9716     }
9717 #endif
9718 
9719     if (err == MP_OKAY) {
9720         r = a + 52 * 2;
9721         m = r + 52 * 2;
9722         norm = r;
9723 
9724         sp_3072_from_bin(a, 52, in, inLen);
9725 #if DIGIT_BIT >= 60
9726         e[0] = (sp_digit)em->dp[0];
9727 #else
9728         e[0] = (sp_digit)em->dp[0];
9729         if (em->used > 1) {
9730             e[0] |= ((sp_digit)em->dp[1]) << DIGIT_BIT;
9731         }
9732 #endif
9733         if (e[0] == 0) {
9734             err = MP_EXPTMOD_E;
9735         }
9736     }
9737 
9738     if (err == MP_OKAY) {
9739         sp_3072_from_mp(m, 52, mm);
9740 
9741         sp_3072_mont_setup(m, &mp);
9742         sp_3072_mont_norm_52(norm, m);
9743     }
9744     if (err == MP_OKAY) {
9745         sp_3072_mul_52(a, a, norm);
9746         err = sp_3072_mod_52(a, a, m);
9747     }
9748     if (err == MP_OKAY) {
9749         for (i=59; i>=0; i--) {
9750             if ((e[0] >> i) != 0) {
9751                 break;
9752             }
9753         }
9754 
9755         XMEMCPY(r, a, sizeof(sp_digit) * 52 * 2);
9756         for (i--; i>=0; i--) {
9757             sp_3072_mont_sqr_52(r, r, m, mp);
9758 
9759             if (((e[0] >> i) & 1) == 1) {
9760                 sp_3072_mont_mul_52(r, r, a, m, mp);
9761             }
9762         }
9763         sp_3072_mont_reduce_52(r, m, mp);
9764         mp = sp_3072_cmp_52(r, m);
9765         sp_3072_cond_sub_52(r, r, m, ((mp < 0) ?
9766                     (sp_digit)1 : (sp_digit)0)- 1);
9767 
9768         sp_3072_to_bin_52(r, out);
9769         *outLen = 384;
9770     }
9771 
9772 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
9773     if (a != NULL)
9774         XFREE(a, NULL, DYNAMIC_TYPE_RSA);
9775 #endif
9776 
9777     return err;
9778 #else
9779 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
9780     sp_digit* d = NULL;
9781 #else
9782     sp_digit d[52 * 5];
9783 #endif
9784     sp_digit* a = NULL;
9785     sp_digit* m = NULL;
9786     sp_digit* r = NULL;
9787     sp_digit e[1] = {0};
9788     int err = MP_OKAY;
9789 
9790     if (*outLen < 384U) {
9791         err = MP_TO_E;
9792     }
9793     if (err == MP_OKAY) {
9794         if (mp_count_bits(em) > 60) {
9795             err = MP_READ_E;
9796         }
9797         else if (inLen > 384U) {
9798             err = MP_READ_E;
9799         }
9800         else if (mp_count_bits(mm) != 3072) {
9801             err = MP_READ_E;
9802         }
9803         else if (mp_iseven(mm)) {
9804             err = MP_VAL;
9805         }
9806     }
9807 
9808 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
9809     if (err == MP_OKAY) {
9810         d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 52 * 5, NULL,
9811                                                               DYNAMIC_TYPE_RSA);
9812         if (d == NULL)
9813             err = MEMORY_E;
9814     }
9815 #endif
9816 
9817     if (err == MP_OKAY) {
9818         a = d;
9819         r = a + 52 * 2;
9820         m = r + 52 * 2;
9821 
9822         sp_3072_from_bin(a, 52, in, inLen);
9823 #if DIGIT_BIT >= 60
9824         e[0] = (sp_digit)em->dp[0];
9825 #else
9826         e[0] = (sp_digit)em->dp[0];
9827         if (em->used > 1) {
9828             e[0] |= ((sp_digit)em->dp[1]) << DIGIT_BIT;
9829         }
9830 #endif
9831         if (e[0] == 0) {
9832             err = MP_EXPTMOD_E;
9833         }
9834     }
9835     if (err == MP_OKAY) {
9836         sp_3072_from_mp(m, 52, mm);
9837 
9838         if (e[0] == 0x3) {
9839             sp_3072_sqr_52(r, a);
9840             err = sp_3072_mod_52(r, r, m);
9841             if (err == MP_OKAY) {
9842                 sp_3072_mul_52(r, a, r);
9843                 err = sp_3072_mod_52(r, r, m);
9844             }
9845         }
9846         else {
9847             sp_digit* norm = r;
9848             int i;
9849             sp_digit mp;
9850 
9851             sp_3072_mont_setup(m, &mp);
9852             sp_3072_mont_norm_52(norm, m);
9853 
9854             sp_3072_mul_52(a, a, norm);
9855             err = sp_3072_mod_52(a, a, m);
9856 
9857             if (err == MP_OKAY) {
9858                 for (i=59; i>=0; i--) {
9859                     if ((e[0] >> i) != 0) {
9860                         break;
9861                     }
9862                 }
9863 
9864                 XMEMCPY(r, a, sizeof(sp_digit) * 104U);
9865                 for (i--; i>=0; i--) {
9866                     sp_3072_mont_sqr_52(r, r, m, mp);
9867 
9868                     if (((e[0] >> i) & 1) == 1) {
9869                         sp_3072_mont_mul_52(r, r, a, m, mp);
9870                     }
9871                 }
9872                 sp_3072_mont_reduce_52(r, m, mp);
9873                 mp = sp_3072_cmp_52(r, m);
9874                 sp_3072_cond_sub_52(r, r, m, ((mp < 0) ?
9875                            (sp_digit)1 : (sp_digit)0) - 1);
9876             }
9877         }
9878     }
9879 
9880     if (err == MP_OKAY) {
9881         sp_3072_to_bin_52(r, out);
9882         *outLen = 384;
9883     }
9884 
9885 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
9886     if (d != NULL)
9887         XFREE(d, NULL, DYNAMIC_TYPE_RSA);
9888 #endif
9889 
9890     return err;
9891 #endif /* WOLFSSL_SP_SMALL */
9892 }
9893 
9894 #ifndef WOLFSSL_RSA_PUBLIC_ONLY
9895 #if !defined(SP_RSA_PRIVATE_EXP_D) && !defined(RSA_LOW_MEM)
9896 #endif /* !SP_RSA_PRIVATE_EXP_D & !RSA_LOW_MEM */
9897 /* RSA private key operation.
9898  *
9899  * in      Array of bytes representing the number to exponentiate, base.
9900  * inLen   Number of bytes in base.
9901  * dm      Private exponent.
9902  * pm      First prime.
9903  * qm      Second prime.
9904  * dpm     First prime's CRT exponent.
9905  * dqm     Second prime's CRT exponent.
9906  * qim     Inverse of second prime mod p.
9907  * mm      Modulus.
9908  * out     Buffer to hold big-endian bytes of exponentiation result.
9909  *         Must be at least 384 bytes long.
9910  * outLen  Number of bytes in result.
9911  * returns 0 on success, MP_TO_E when the outLen is too small, MP_READ_E when
9912  * an array is too long and MEMORY_E when dynamic memory allocation fails.
9913  */
sp_RsaPrivate_3072(const byte * in,word32 inLen,const mp_int * dm,const mp_int * pm,const mp_int * qm,const mp_int * dpm,const mp_int * dqm,const mp_int * qim,const mp_int * mm,byte * out,word32 * outLen)9914 int sp_RsaPrivate_3072(const byte* in, word32 inLen, const mp_int* dm,
9915     const mp_int* pm, const mp_int* qm, const mp_int* dpm, const mp_int* dqm,
9916     const mp_int* qim, const mp_int* mm, byte* out, word32* outLen)
9917 {
9918 #if defined(SP_RSA_PRIVATE_EXP_D) || defined(RSA_LOW_MEM)
9919 #if defined(WOLFSSL_SP_SMALL)
9920 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
9921     sp_digit* d = NULL;
9922 #else
9923     sp_digit  d[52 * 4];
9924 #endif
9925     sp_digit* a = NULL;
9926     sp_digit* m = NULL;
9927     sp_digit* r = NULL;
9928     int err = MP_OKAY;
9929 
9930     (void)pm;
9931     (void)qm;
9932     (void)dpm;
9933     (void)dqm;
9934     (void)qim;
9935 
9936     if (*outLen < 384U) {
9937         err = MP_TO_E;
9938     }
9939     if (err == MP_OKAY) {
9940         if (mp_count_bits(dm) > 3072) {
9941            err = MP_READ_E;
9942         }
9943         else if (inLen > 384) {
9944             err = MP_READ_E;
9945         }
9946         else if (mp_count_bits(mm) != 3072) {
9947             err = MP_READ_E;
9948         }
9949         else if (mp_iseven(mm)) {
9950             err = MP_VAL;
9951         }
9952     }
9953 
9954 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
9955     if (err == MP_OKAY) {
9956         d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 52 * 4, NULL,
9957                                                               DYNAMIC_TYPE_RSA);
9958         if (d == NULL)
9959             err = MEMORY_E;
9960     }
9961 #endif
9962 
9963     if (err == MP_OKAY) {
9964         a = d + 52;
9965         m = a + 104;
9966         r = a;
9967 
9968         sp_3072_from_bin(a, 52, in, inLen);
9969         sp_3072_from_mp(d, 52, dm);
9970         sp_3072_from_mp(m, 52, mm);
9971         err = sp_3072_mod_exp_52(r, a, d, 3072, m, 0);
9972     }
9973 
9974     if (err == MP_OKAY) {
9975         sp_3072_to_bin_52(r, out);
9976         *outLen = 384;
9977     }
9978 
9979 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
9980     if (d != NULL)
9981 #endif
9982     {
9983         /* only "a" and "r" are sensitive and need zeroized (same pointer) */
9984         if (a != NULL)
9985             ForceZero(a, sizeof(sp_digit) * 52);
9986 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
9987         XFREE(d, NULL, DYNAMIC_TYPE_RSA);
9988 #endif
9989     }
9990 
9991     return err;
9992 #else
9993 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
9994     sp_digit* d = NULL;
9995 #else
9996     sp_digit d[52 * 4];
9997 #endif
9998     sp_digit* a = NULL;
9999     sp_digit* m = NULL;
10000     sp_digit* r = NULL;
10001     int err = MP_OKAY;
10002 
10003     (void)pm;
10004     (void)qm;
10005     (void)dpm;
10006     (void)dqm;
10007     (void)qim;
10008 
10009     if (*outLen < 384U) {
10010         err = MP_TO_E;
10011     }
10012     if (err == MP_OKAY) {
10013         if (mp_count_bits(dm) > 3072) {
10014             err = MP_READ_E;
10015         }
10016         else if (inLen > 384U) {
10017             err = MP_READ_E;
10018         }
10019         else if (mp_count_bits(mm) != 3072) {
10020             err = MP_READ_E;
10021         }
10022         else if (mp_iseven(mm)) {
10023             err = MP_VAL;
10024         }
10025     }
10026 
10027 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
10028     if (err == MP_OKAY) {
10029         d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 52 * 4, NULL,
10030                                                               DYNAMIC_TYPE_RSA);
10031         if (d == NULL)
10032             err = MEMORY_E;
10033     }
10034 #endif
10035 
10036     if (err == MP_OKAY) {
10037         a = d + 52;
10038         m = a + 104;
10039         r = a;
10040 
10041         sp_3072_from_bin(a, 52, in, inLen);
10042         sp_3072_from_mp(d, 52, dm);
10043         sp_3072_from_mp(m, 52, mm);
10044         err = sp_3072_mod_exp_52(r, a, d, 3072, m, 0);
10045     }
10046 
10047     if (err == MP_OKAY) {
10048         sp_3072_to_bin_52(r, out);
10049         *outLen = 384;
10050     }
10051 
10052 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
10053     if (d != NULL)
10054 #endif
10055     {
10056         /* only "a" and "r" are sensitive and need zeroized (same pointer) */
10057         if (a != NULL)
10058             ForceZero(a, sizeof(sp_digit) * 52);
10059 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
10060         XFREE(d, NULL, DYNAMIC_TYPE_RSA);
10061 #endif
10062     }
10063 
10064     return err;
10065 #endif /* WOLFSSL_SP_SMALL */
10066 #else
10067 #if defined(WOLFSSL_SP_SMALL)
10068 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
10069     sp_digit* a = NULL;
10070 #else
10071     sp_digit a[26 * 8];
10072 #endif
10073     sp_digit* p = NULL;
10074     sp_digit* dp = NULL;
10075     sp_digit* dq = NULL;
10076     sp_digit* qi = NULL;
10077     sp_digit* tmpa = NULL;
10078     sp_digit* tmpb = NULL;
10079     sp_digit* r = NULL;
10080     int err = MP_OKAY;
10081 
10082     (void)dm;
10083     (void)mm;
10084 
10085     if (*outLen < 384U) {
10086         err = MP_TO_E;
10087     }
10088     if (err == MP_OKAY) {
10089         if (inLen > 384) {
10090             err = MP_READ_E;
10091         }
10092         else if (mp_count_bits(mm) != 3072) {
10093             err = MP_READ_E;
10094         }
10095         else if (mp_iseven(mm)) {
10096             err = MP_VAL;
10097         }
10098     }
10099 
10100 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
10101     if (err == MP_OKAY) {
10102         a = (sp_digit*)XMALLOC(sizeof(sp_digit) * 26 * 8, NULL,
10103                                                               DYNAMIC_TYPE_RSA);
10104         if (a == NULL)
10105             err = MEMORY_E;
10106     }
10107 #endif
10108     if (err == MP_OKAY) {
10109         p = a + 52;
10110         qi = dq = dp = p + 26;
10111         tmpa = qi + 26;
10112         tmpb = tmpa + 52;
10113         r = a;
10114 
10115         sp_3072_from_bin(a, 52, in, inLen);
10116         sp_3072_from_mp(p, 26, pm);
10117         sp_3072_from_mp(dp, 26, dpm);
10118         err = sp_3072_mod_exp_26(tmpa, a, dp, 1536, p, 1);
10119     }
10120     if (err == MP_OKAY) {
10121         sp_3072_from_mp(p, 26, qm);
10122         sp_3072_from_mp(dq, 26, dqm);
10123         err = sp_3072_mod_exp_26(tmpb, a, dq, 1536, p, 1);
10124     }
10125     if (err == MP_OKAY) {
10126         sp_3072_from_mp(p, 26, pm);
10127         (void)sp_3072_sub_26(tmpa, tmpa, tmpb);
10128         sp_3072_norm_26(tmpa);
10129         sp_3072_cond_add_26(tmpa, tmpa, p, 0 - ((sp_int_digit)tmpa[25] >> 63));
10130         sp_3072_cond_add_26(tmpa, tmpa, p, 0 - ((sp_int_digit)tmpa[25] >> 63));
10131         sp_3072_norm_26(tmpa);
10132 
10133         sp_3072_from_mp(qi, 26, qim);
10134         sp_3072_mul_26(tmpa, tmpa, qi);
10135         err = sp_3072_mod_26(tmpa, tmpa, p);
10136     }
10137 
10138     if (err == MP_OKAY) {
10139         sp_3072_from_mp(p, 26, qm);
10140         sp_3072_mul_26(tmpa, p, tmpa);
10141         (void)sp_3072_add_52(r, tmpb, tmpa);
10142         sp_3072_norm_52(r);
10143 
10144         sp_3072_to_bin_52(r, out);
10145         *outLen = 384;
10146     }
10147 
10148 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
10149     if (a != NULL)
10150 #endif
10151     {
10152         ForceZero(a, sizeof(sp_digit) * 26 * 8);
10153 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
10154         XFREE(a, NULL, DYNAMIC_TYPE_RSA);
10155 #endif
10156     }
10157 
10158     return err;
10159 #else
10160 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
10161     sp_digit* a = NULL;
10162 #else
10163     sp_digit a[26 * 13];
10164 #endif
10165     sp_digit* p = NULL;
10166     sp_digit* q = NULL;
10167     sp_digit* dp = NULL;
10168     sp_digit* dq = NULL;
10169     sp_digit* qi = NULL;
10170     sp_digit* tmpa = NULL;
10171     sp_digit* tmpb = NULL;
10172     sp_digit* r = NULL;
10173     int err = MP_OKAY;
10174 
10175     (void)dm;
10176     (void)mm;
10177 
10178     if (*outLen < 384U) {
10179         err = MP_TO_E;
10180     }
10181     if (err == MP_OKAY) {
10182         if (inLen > 384U) {
10183             err = MP_READ_E;
10184         }
10185         else if (mp_count_bits(mm) != 3072) {
10186             err = MP_READ_E;
10187         }
10188         else if (mp_iseven(mm)) {
10189             err = MP_VAL;
10190         }
10191     }
10192 
10193 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
10194     if (err == MP_OKAY) {
10195         a = (sp_digit*)XMALLOC(sizeof(sp_digit) * 26 * 13, NULL,
10196                                                               DYNAMIC_TYPE_RSA);
10197         if (a == NULL)
10198             err = MEMORY_E;
10199     }
10200 #endif
10201 
10202     if (err == MP_OKAY) {
10203         p = a + 52 * 2;
10204         q = p + 26;
10205         dp = q + 26;
10206         dq = dp + 26;
10207         qi = dq + 26;
10208         tmpa = qi + 26;
10209         tmpb = tmpa + 52;
10210         r = a;
10211 
10212         sp_3072_from_bin(a, 52, in, inLen);
10213         sp_3072_from_mp(p, 26, pm);
10214         sp_3072_from_mp(q, 26, qm);
10215         sp_3072_from_mp(dp, 26, dpm);
10216         sp_3072_from_mp(dq, 26, dqm);
10217         sp_3072_from_mp(qi, 26, qim);
10218 
10219         err = sp_3072_mod_exp_26(tmpa, a, dp, 1536, p, 1);
10220     }
10221     if (err == MP_OKAY) {
10222         err = sp_3072_mod_exp_26(tmpb, a, dq, 1536, q, 1);
10223     }
10224 
10225     if (err == MP_OKAY) {
10226         (void)sp_3072_sub_26(tmpa, tmpa, tmpb);
10227         sp_3072_norm_26(tmpa);
10228         sp_3072_cond_add_26(tmpa, tmpa, p, 0 - ((sp_int_digit)tmpa[25] >> 63));
10229         sp_3072_cond_add_26(tmpa, tmpa, p, 0 - ((sp_int_digit)tmpa[25] >> 63));
10230         sp_3072_norm_26(tmpa);
10231         sp_3072_mul_26(tmpa, tmpa, qi);
10232         err = sp_3072_mod_26(tmpa, tmpa, p);
10233     }
10234 
10235     if (err == MP_OKAY) {
10236         sp_3072_mul_26(tmpa, tmpa, q);
10237         (void)sp_3072_add_52(r, tmpb, tmpa);
10238         sp_3072_norm_52(r);
10239 
10240         sp_3072_to_bin_52(r, out);
10241         *outLen = 384;
10242     }
10243 
10244 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
10245 if (a != NULL)
10246 #endif
10247     {
10248         ForceZero(a, sizeof(sp_digit) * 26 * 13);
10249     #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
10250         XFREE(a, NULL, DYNAMIC_TYPE_RSA);
10251     #endif
10252     }
10253 
10254     return err;
10255 #endif /* WOLFSSL_SP_SMALL */
10256 #endif /* SP_RSA_PRIVATE_EXP_D || RSA_LOW_MEM */
10257 }
10258 
10259 #endif /* !WOLFSSL_RSA_PUBLIC_ONLY */
10260 #endif /* WOLFSSL_HAVE_SP_RSA */
10261 #if defined(WOLFSSL_HAVE_SP_DH) || (defined(WOLFSSL_HAVE_SP_RSA) && \
10262                                               !defined(WOLFSSL_RSA_PUBLIC_ONLY))
10263 /* Convert an array of sp_digit to an mp_int.
10264  *
10265  * a  A single precision integer.
10266  * r  A multi-precision integer.
10267  */
sp_3072_to_mp(const sp_digit * a,mp_int * r)10268 static int sp_3072_to_mp(const sp_digit* a, mp_int* r)
10269 {
10270     int err;
10271 
10272     err = mp_grow(r, (3072 + DIGIT_BIT - 1) / DIGIT_BIT);
10273     if (err == MP_OKAY) { /*lint !e774 case where err is always MP_OKAY*/
10274 #if DIGIT_BIT == 60
10275         XMEMCPY(r->dp, a, sizeof(sp_digit) * 52);
10276         r->used = 52;
10277         mp_clamp(r);
10278 #elif DIGIT_BIT < 60
10279         int i;
10280         int j = 0;
10281         int s = 0;
10282 
10283         r->dp[0] = 0;
10284         for (i = 0; i < 52; i++) {
10285             r->dp[j] |= (mp_digit)(a[i] << s);
10286             r->dp[j] &= ((sp_digit)1 << DIGIT_BIT) - 1;
10287             s = DIGIT_BIT - s;
10288             r->dp[++j] = (mp_digit)(a[i] >> s);
10289             while (s + DIGIT_BIT <= 60) {
10290                 s += DIGIT_BIT;
10291                 r->dp[j++] &= ((sp_digit)1 << DIGIT_BIT) - 1;
10292                 if (s == SP_WORD_SIZE) {
10293                     r->dp[j] = 0;
10294                 }
10295                 else {
10296                     r->dp[j] = (mp_digit)(a[i] >> s);
10297                 }
10298             }
10299             s = 60 - s;
10300         }
10301         r->used = (3072 + DIGIT_BIT - 1) / DIGIT_BIT;
10302         mp_clamp(r);
10303 #else
10304         int i;
10305         int j = 0;
10306         int s = 0;
10307 
10308         r->dp[0] = 0;
10309         for (i = 0; i < 52; i++) {
10310             r->dp[j] |= ((mp_digit)a[i]) << s;
10311             if (s + 60 >= DIGIT_BIT) {
10312     #if DIGIT_BIT != 32 && DIGIT_BIT != 64
10313                 r->dp[j] &= ((sp_digit)1 << DIGIT_BIT) - 1;
10314     #endif
10315                 s = DIGIT_BIT - s;
10316                 r->dp[++j] = a[i] >> s;
10317                 s = 60 - s;
10318             }
10319             else {
10320                 s += 60;
10321             }
10322         }
10323         r->used = (3072 + DIGIT_BIT - 1) / DIGIT_BIT;
10324         mp_clamp(r);
10325 #endif
10326     }
10327 
10328     return err;
10329 }
10330 
10331 /* Perform the modular exponentiation for Diffie-Hellman.
10332  *
10333  * base  Base. MP integer.
10334  * exp   Exponent. MP integer.
10335  * mod   Modulus. MP integer.
10336  * res   Result. MP integer.
10337  * returns 0 on success, MP_READ_E if there are too many bytes in an array
10338  * and MEMORY_E if memory allocation fails.
10339  */
sp_ModExp_3072(const mp_int * base,const mp_int * exp,const mp_int * mod,mp_int * res)10340 int sp_ModExp_3072(const mp_int* base, const mp_int* exp, const mp_int* mod,
10341     mp_int* res)
10342 {
10343 #ifdef WOLFSSL_SP_SMALL
10344     int err = MP_OKAY;
10345 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
10346     sp_digit* b = NULL;
10347 #else
10348     sp_digit b[52 * 4];
10349 #endif
10350     sp_digit* e = NULL;
10351     sp_digit* m = NULL;
10352     sp_digit* r = NULL;
10353     int expBits = mp_count_bits(exp);
10354 
10355     if (mp_count_bits(base) > 3072) {
10356         err = MP_READ_E;
10357     }
10358     else if (expBits > 3072) {
10359         err = MP_READ_E;
10360     }
10361     else if (mp_count_bits(mod) != 3072) {
10362         err = MP_READ_E;
10363     }
10364     else if (mp_iseven(mod)) {
10365         err = MP_VAL;
10366     }
10367 
10368 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
10369     if (err == MP_OKAY) {
10370         b = (sp_digit*)XMALLOC(sizeof(sp_digit) * 52 * 4, NULL,
10371             DYNAMIC_TYPE_DH);
10372         if (b == NULL)
10373             err = MEMORY_E;
10374     }
10375 #endif
10376 
10377     if (err == MP_OKAY) {
10378         e = b + 52 * 2;
10379         m = e + 52;
10380         r = b;
10381 
10382         sp_3072_from_mp(b, 52, base);
10383         sp_3072_from_mp(e, 52, exp);
10384         sp_3072_from_mp(m, 52, mod);
10385 
10386         err = sp_3072_mod_exp_52(r, b, e, mp_count_bits(exp), m, 0);
10387     }
10388 
10389     if (err == MP_OKAY) {
10390         err = sp_3072_to_mp(r, res);
10391     }
10392 
10393 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
10394     if (b != NULL)
10395 #endif
10396     {
10397         /* only "e" is sensitive and needs zeroized */
10398         if (e != NULL)
10399             ForceZero(e, sizeof(sp_digit) * 52U);
10400     #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
10401         XFREE(b, NULL, DYNAMIC_TYPE_DH);
10402     #endif
10403     }
10404     return err;
10405 #else
10406 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
10407     sp_digit* b = NULL;
10408 #else
10409     sp_digit b[52 * 4];
10410 #endif
10411     sp_digit* e = NULL;
10412     sp_digit* m = NULL;
10413     sp_digit* r = NULL;
10414     int err = MP_OKAY;
10415     int expBits = mp_count_bits(exp);
10416 
10417     if (mp_count_bits(base) > 3072) {
10418         err = MP_READ_E;
10419     }
10420     else if (expBits > 3072) {
10421         err = MP_READ_E;
10422     }
10423     else if (mp_count_bits(mod) != 3072) {
10424         err = MP_READ_E;
10425     }
10426     else if (mp_iseven(mod)) {
10427         err = MP_VAL;
10428     }
10429 
10430 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
10431     if (err == MP_OKAY) {
10432         b = (sp_digit*)XMALLOC(sizeof(sp_digit) * 52 * 4, NULL, DYNAMIC_TYPE_DH);
10433         if (b == NULL)
10434             err = MEMORY_E;
10435     }
10436 #endif
10437 
10438     if (err == MP_OKAY) {
10439         e = b + 52 * 2;
10440         m = e + 52;
10441         r = b;
10442 
10443         sp_3072_from_mp(b, 52, base);
10444         sp_3072_from_mp(e, 52, exp);
10445         sp_3072_from_mp(m, 52, mod);
10446 
10447         err = sp_3072_mod_exp_52(r, b, e, expBits, m, 0);
10448     }
10449 
10450     if (err == MP_OKAY) {
10451         err = sp_3072_to_mp(r, res);
10452     }
10453 
10454 
10455 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
10456     if (b != NULL)
10457 #endif
10458     {
10459         /* only "e" is sensitive and needs zeroized */
10460         if (e != NULL)
10461             ForceZero(e, sizeof(sp_digit) * 52U);
10462     #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
10463         XFREE(b, NULL, DYNAMIC_TYPE_DH);
10464     #endif
10465     }
10466 
10467     return err;
10468 #endif
10469 }
10470 
10471 #ifdef WOLFSSL_HAVE_SP_DH
10472 
10473 #ifdef HAVE_FFDHE_3072
sp_3072_lshift_52(sp_digit * r,const sp_digit * a,byte n)10474 SP_NOINLINE static void sp_3072_lshift_52(sp_digit* r, const sp_digit* a,
10475         byte n)
10476 {
10477     int i;
10478 
10479     r[52] = a[51] >> (60 - n);
10480     for (i=51; i>0; i--) {
10481         r[i] = ((a[i] << n) | (a[i-1] >> (60 - n))) & 0xfffffffffffffffL;
10482     }
10483     r[0] = (a[0] << n) & 0xfffffffffffffffL;
10484 }
10485 
10486 /* Modular exponentiate 2 to the e mod m. (r = 2^e mod m)
10487  *
10488  * r     A single precision number that is the result of the operation.
10489  * e     A single precision number that is the exponent.
10490  * bits  The number of bits in the exponent.
10491  * m     A single precision number that is the modulus.
10492  * returns  0 on success.
10493  * returns  MEMORY_E on dynamic memory allocation failure.
10494  * returns  MP_VAL when base is even.
10495  */
sp_3072_mod_exp_2_52(sp_digit * r,const sp_digit * e,int bits,const sp_digit * m)10496 static int sp_3072_mod_exp_2_52(sp_digit* r, const sp_digit* e, int bits, const sp_digit* m)
10497 {
10498 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
10499     sp_digit* td = NULL;
10500 #else
10501     sp_digit td[157];
10502 #endif
10503     sp_digit* norm = NULL;
10504     sp_digit* tmp = NULL;
10505     sp_digit mp = 1;
10506     sp_digit n;
10507     sp_digit o;
10508     int i;
10509     int c;
10510     byte y;
10511     int err = MP_OKAY;
10512 
10513     if ((m[0] & 1) == 0) {
10514         err = MP_VAL;
10515     }
10516 
10517 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
10518     if (err == MP_OKAY) {
10519         td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 157, NULL,
10520                                 DYNAMIC_TYPE_TMP_BUFFER);
10521         if (td == NULL)
10522             err = MEMORY_E;
10523     }
10524 #endif
10525 
10526     if (err == MP_OKAY) {
10527         norm = td;
10528         tmp  = td + 104;
10529         XMEMSET(td, 0, sizeof(sp_digit) * 157);
10530 
10531         sp_3072_mont_setup(m, &mp);
10532         sp_3072_mont_norm_52(norm, m);
10533 
10534         bits = ((bits + 4) / 5) * 5;
10535         i = ((bits + 59) / 60) - 1;
10536         c = bits % 60;
10537         if (c == 0) {
10538             c = 60;
10539         }
10540         if (i < 52) {
10541             n = e[i--] << (64 - c);
10542         }
10543         else {
10544             n = 0;
10545             i--;
10546         }
10547         if (c < 5) {
10548             n |= e[i--] << (4 - c);
10549             c += 60;
10550         }
10551         y = (int)((n >> 59) & 0x1f);
10552         n <<= 5;
10553         c -= 5;
10554         sp_3072_lshift_52(r, norm, (byte)y);
10555         while ((i >= 0) || (c >= 5)) {
10556             if (c >= 5) {
10557                 y = (byte)((n >> 59) & 0x1f);
10558                 n <<= 5;
10559                 c -= 5;
10560             }
10561             else if (c == 0) {
10562                 n = e[i--] << 4;
10563                 y = (byte)((n >> 59) & 0x1f);
10564                 n <<= 5;
10565                 c = 55;
10566             }
10567             else {
10568                 y = (byte)((n >> 59) & 0x1f);
10569                 n = e[i--] << 4;
10570                 c = 5 - c;
10571                 y |= (byte)((n >> (64 - c)) & ((1 << c) - 1));
10572                 n <<= c;
10573                 c = 60 - c;
10574             }
10575 
10576             sp_3072_mont_sqr_52(r, r, m, mp);
10577             sp_3072_mont_sqr_52(r, r, m, mp);
10578             sp_3072_mont_sqr_52(r, r, m, mp);
10579             sp_3072_mont_sqr_52(r, r, m, mp);
10580             sp_3072_mont_sqr_52(r, r, m, mp);
10581 
10582             sp_3072_lshift_52(r, r, (byte)y);
10583             sp_3072_mul_d_52(tmp, norm, (r[52] << 48) + (r[51] >> 12));
10584             r[52] = 0;
10585             r[51] &= 0xfffL;
10586             (void)sp_3072_add_52(r, r, tmp);
10587             sp_3072_norm_52(r);
10588             o = sp_3072_cmp_52(r, m);
10589             sp_3072_cond_sub_52(r, r, m, ((o < 0) ?
10590                                           (sp_digit)1 : (sp_digit)0) - 1);
10591         }
10592 
10593         sp_3072_mont_reduce_52(r, m, mp);
10594         n = sp_3072_cmp_52(r, m);
10595         sp_3072_cond_sub_52(r, r, m, ((n < 0) ?
10596                                                 (sp_digit)1 : (sp_digit)0) - 1);
10597     }
10598 
10599 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
10600     if (td != NULL)
10601         XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);
10602 #endif
10603 
10604     return err;
10605 }
10606 
10607 #endif /* HAVE_FFDHE_3072 */
10608 
10609 /* Perform the modular exponentiation for Diffie-Hellman.
10610  *
10611  * base     Base.
10612  * exp      Array of bytes that is the exponent.
10613  * expLen   Length of data, in bytes, in exponent.
10614  * mod      Modulus.
10615  * out      Buffer to hold big-endian bytes of exponentiation result.
10616  *          Must be at least 384 bytes long.
10617  * outLen   Length, in bytes, of exponentiation result.
10618  * returns 0 on success, MP_READ_E if there are too many bytes in an array
10619  * and MEMORY_E if memory allocation fails.
10620  */
sp_DhExp_3072(const mp_int * base,const byte * exp,word32 expLen,const mp_int * mod,byte * out,word32 * outLen)10621 int sp_DhExp_3072(const mp_int* base, const byte* exp, word32 expLen,
10622     const mp_int* mod, byte* out, word32* outLen)
10623 {
10624 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
10625     sp_digit* b = NULL;
10626 #else
10627     sp_digit b[52 * 4];
10628 #endif
10629     sp_digit* e = NULL;
10630     sp_digit* m = NULL;
10631     sp_digit* r = NULL;
10632     word32 i;
10633     int err = MP_OKAY;
10634 
10635     if (mp_count_bits(base) > 3072) {
10636         err = MP_READ_E;
10637     }
10638     else if (expLen > 384U) {
10639         err = MP_READ_E;
10640     }
10641     else if (mp_count_bits(mod) != 3072) {
10642         err = MP_READ_E;
10643     }
10644     else if (mp_iseven(mod)) {
10645         err = MP_VAL;
10646     }
10647 
10648 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
10649     if (err == MP_OKAY) {
10650         b = (sp_digit*)XMALLOC(sizeof(sp_digit) * 52 * 4, NULL,
10651             DYNAMIC_TYPE_DH);
10652         if (b == NULL)
10653             err = MEMORY_E;
10654     }
10655 #endif
10656 
10657     if (err == MP_OKAY) {
10658         e = b + 52 * 2;
10659         m = e + 52;
10660         r = b;
10661 
10662         sp_3072_from_mp(b, 52, base);
10663         sp_3072_from_bin(e, 52, exp, expLen);
10664         sp_3072_from_mp(m, 52, mod);
10665 
10666     #ifdef HAVE_FFDHE_3072
10667         if (base->used == 1 && base->dp[0] == 2U &&
10668                 ((m[51] << 20) | (m[50] >> 40)) == 0xffffffffL) {
10669             err = sp_3072_mod_exp_2_52(r, e, expLen * 8U, m);
10670         }
10671         else {
10672     #endif
10673             err = sp_3072_mod_exp_52(r, b, e, expLen * 8U, m, 0);
10674     #ifdef HAVE_FFDHE_3072
10675         }
10676     #endif
10677     }
10678 
10679     if (err == MP_OKAY) {
10680         sp_3072_to_bin_52(r, out);
10681         *outLen = 384;
10682         for (i=0; i<384U && out[i] == 0U; i++) {
10683             /* Search for first non-zero. */
10684         }
10685         *outLen -= i;
10686         XMEMMOVE(out, out + i, *outLen);
10687     }
10688 
10689 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
10690     if (b != NULL)
10691 #endif
10692     {
10693         /* only "e" is sensitive and needs zeroized */
10694         if (e != NULL)
10695             ForceZero(e, sizeof(sp_digit) * 52U);
10696     #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
10697         XFREE(b, NULL, DYNAMIC_TYPE_DH);
10698     #endif
10699     }
10700 
10701     return err;
10702 }
10703 #endif /* WOLFSSL_HAVE_SP_DH */
10704 
10705 /* Perform the modular exponentiation for Diffie-Hellman.
10706  *
10707  * base  Base. MP integer.
10708  * exp   Exponent. MP integer.
10709  * mod   Modulus. MP integer.
10710  * res   Result. MP integer.
10711  * returns 0 on success, MP_READ_E if there are too many bytes in an array
10712  * and MEMORY_E if memory allocation fails.
10713  */
sp_ModExp_1536(const mp_int * base,const mp_int * exp,const mp_int * mod,mp_int * res)10714 int sp_ModExp_1536(const mp_int* base, const mp_int* exp, const mp_int* mod,
10715     mp_int* res)
10716 {
10717 #ifdef WOLFSSL_SP_SMALL
10718     int err = MP_OKAY;
10719 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
10720     sp_digit* b = NULL;
10721 #else
10722     sp_digit b[26 * 4];
10723 #endif
10724     sp_digit* e = NULL;
10725     sp_digit* m = NULL;
10726     sp_digit* r = NULL;
10727     int expBits = mp_count_bits(exp);
10728 
10729     if (mp_count_bits(base) > 1536) {
10730         err = MP_READ_E;
10731     }
10732     else if (expBits > 1536) {
10733         err = MP_READ_E;
10734     }
10735     else if (mp_count_bits(mod) != 1536) {
10736         err = MP_READ_E;
10737     }
10738     else if (mp_iseven(mod)) {
10739         err = MP_VAL;
10740     }
10741 
10742 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
10743     if (err == MP_OKAY) {
10744         b = (sp_digit*)XMALLOC(sizeof(sp_digit) * 26 * 4, NULL,
10745             DYNAMIC_TYPE_DH);
10746         if (b == NULL)
10747             err = MEMORY_E;
10748     }
10749 #endif
10750 
10751     if (err == MP_OKAY) {
10752         e = b + 26 * 2;
10753         m = e + 26;
10754         r = b;
10755 
10756         sp_3072_from_mp(b, 26, base);
10757         sp_3072_from_mp(e, 26, exp);
10758         sp_3072_from_mp(m, 26, mod);
10759 
10760         err = sp_3072_mod_exp_26(r, b, e, mp_count_bits(exp), m, 0);
10761     }
10762 
10763     if (err == MP_OKAY) {
10764         XMEMSET(r + 26, 0, sizeof(*r) * 26U);
10765         err = sp_3072_to_mp(r, res);
10766     }
10767 
10768 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
10769     if (b != NULL)
10770 #endif
10771     {
10772         /* only "e" is sensitive and needs zeroized */
10773         if (e != NULL)
10774             ForceZero(e, sizeof(sp_digit) * 52U);
10775     #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
10776         XFREE(b, NULL, DYNAMIC_TYPE_DH);
10777     #endif
10778     }
10779     return err;
10780 #else
10781 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
10782     sp_digit* b = NULL;
10783 #else
10784     sp_digit b[26 * 4];
10785 #endif
10786     sp_digit* e = NULL;
10787     sp_digit* m = NULL;
10788     sp_digit* r = NULL;
10789     int err = MP_OKAY;
10790     int expBits = mp_count_bits(exp);
10791 
10792     if (mp_count_bits(base) > 1536) {
10793         err = MP_READ_E;
10794     }
10795     else if (expBits > 1536) {
10796         err = MP_READ_E;
10797     }
10798     else if (mp_count_bits(mod) != 1536) {
10799         err = MP_READ_E;
10800     }
10801     else if (mp_iseven(mod)) {
10802         err = MP_VAL;
10803     }
10804 
10805 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
10806     if (err == MP_OKAY) {
10807         b = (sp_digit*)XMALLOC(sizeof(sp_digit) * 26 * 4, NULL, DYNAMIC_TYPE_DH);
10808         if (b == NULL)
10809             err = MEMORY_E;
10810     }
10811 #endif
10812 
10813     if (err == MP_OKAY) {
10814         e = b + 26 * 2;
10815         m = e + 26;
10816         r = b;
10817 
10818         sp_3072_from_mp(b, 26, base);
10819         sp_3072_from_mp(e, 26, exp);
10820         sp_3072_from_mp(m, 26, mod);
10821 
10822         err = sp_3072_mod_exp_26(r, b, e, expBits, m, 0);
10823     }
10824 
10825     if (err == MP_OKAY) {
10826         XMEMSET(r + 26, 0, sizeof(*r) * 26U);
10827         err = sp_3072_to_mp(r, res);
10828     }
10829 
10830 
10831 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
10832     if (b != NULL)
10833 #endif
10834     {
10835         /* only "e" is sensitive and needs zeroized */
10836         if (e != NULL)
10837             ForceZero(e, sizeof(sp_digit) * 52U);
10838     #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
10839         XFREE(b, NULL, DYNAMIC_TYPE_DH);
10840     #endif
10841     }
10842 
10843     return err;
10844 #endif
10845 }
10846 
10847 #endif /* WOLFSSL_HAVE_SP_DH | (WOLFSSL_HAVE_SP_RSA & !WOLFSSL_RSA_PUBLIC_ONLY) */
10848 
10849 #else
10850 /* Read big endian unsigned byte array into r.
10851  *
10852  * r  A single precision integer.
10853  * size  Maximum number of bytes to convert
10854  * a  Byte array.
10855  * n  Number of bytes in array to read.
10856  */
sp_3072_from_bin(sp_digit * r,int size,const byte * a,int n)10857 static void sp_3072_from_bin(sp_digit* r, int size, const byte* a, int n)
10858 {
10859     int i;
10860     int j = 0;
10861     word32 s = 0;
10862 
10863     r[0] = 0;
10864     for (i = n-1; i >= 0; i--) {
10865         r[j] |= (((sp_digit)a[i]) << s);
10866         if (s >= 49U) {
10867             r[j] &= 0x1ffffffffffffffL;
10868             s = 57U - s;
10869             if (j + 1 >= size) {
10870                 break;
10871             }
10872             r[++j] = (sp_digit)a[i] >> s;
10873             s = 8U - s;
10874         }
10875         else {
10876             s += 8U;
10877         }
10878     }
10879 
10880     for (j++; j < size; j++) {
10881         r[j] = 0;
10882     }
10883 }
10884 
10885 /* Convert an mp_int to an array of sp_digit.
10886  *
10887  * r  A single precision integer.
10888  * size  Maximum number of bytes to convert
10889  * a  A multi-precision integer.
10890  */
sp_3072_from_mp(sp_digit * r,int size,const mp_int * a)10891 static void sp_3072_from_mp(sp_digit* r, int size, const mp_int* a)
10892 {
10893 #if DIGIT_BIT == 57
10894     int j;
10895 
10896     XMEMCPY(r, a->dp, sizeof(sp_digit) * a->used);
10897 
10898     for (j = a->used; j < size; j++) {
10899         r[j] = 0;
10900     }
10901 #elif DIGIT_BIT > 57
10902     int i;
10903     int j = 0;
10904     word32 s = 0;
10905 
10906     r[0] = 0;
10907     for (i = 0; i < a->used && j < size; i++) {
10908         r[j] |= ((sp_digit)a->dp[i] << s);
10909         r[j] &= 0x1ffffffffffffffL;
10910         s = 57U - s;
10911         if (j + 1 >= size) {
10912             break;
10913         }
10914         /* lint allow cast of mismatch word32 and mp_digit */
10915         r[++j] = (sp_digit)(a->dp[i] >> s); /*lint !e9033*/
10916         while ((s + 57U) <= (word32)DIGIT_BIT) {
10917             s += 57U;
10918             r[j] &= 0x1ffffffffffffffL;
10919             if (j + 1 >= size) {
10920                 break;
10921             }
10922             if (s < (word32)DIGIT_BIT) {
10923                 /* lint allow cast of mismatch word32 and mp_digit */
10924                 r[++j] = (sp_digit)(a->dp[i] >> s); /*lint !e9033*/
10925             }
10926             else {
10927                 r[++j] = (sp_digit)0;
10928             }
10929         }
10930         s = (word32)DIGIT_BIT - s;
10931     }
10932 
10933     for (j++; j < size; j++) {
10934         r[j] = 0;
10935     }
10936 #else
10937     int i;
10938     int j = 0;
10939     int s = 0;
10940 
10941     r[0] = 0;
10942     for (i = 0; i < a->used && j < size; i++) {
10943         r[j] |= ((sp_digit)a->dp[i]) << s;
10944         if (s + DIGIT_BIT >= 57) {
10945             r[j] &= 0x1ffffffffffffffL;
10946             if (j + 1 >= size) {
10947                 break;
10948             }
10949             s = 57 - s;
10950             if (s == DIGIT_BIT) {
10951                 r[++j] = 0;
10952                 s = 0;
10953             }
10954             else {
10955                 r[++j] = a->dp[i] >> s;
10956                 s = DIGIT_BIT - s;
10957             }
10958         }
10959         else {
10960             s += DIGIT_BIT;
10961         }
10962     }
10963 
10964     for (j++; j < size; j++) {
10965         r[j] = 0;
10966     }
10967 #endif
10968 }
10969 
10970 /* Write r as big endian to byte array.
10971  * Fixed length number of bytes written: 384
10972  *
10973  * r  A single precision integer.
10974  * a  Byte array.
10975  */
sp_3072_to_bin_54(sp_digit * r,byte * a)10976 static void sp_3072_to_bin_54(sp_digit* r, byte* a)
10977 {
10978     int i;
10979     int j;
10980     int s = 0;
10981     int b;
10982 
10983     for (i=0; i<53; i++) {
10984         r[i+1] += r[i] >> 57;
10985         r[i] &= 0x1ffffffffffffffL;
10986     }
10987     j = 3072 / 8 - 1;
10988     a[j] = 0;
10989     for (i=0; i<54 && j>=0; i++) {
10990         b = 0;
10991         /* lint allow cast of mismatch sp_digit and int */
10992         a[j--] |= (byte)(r[i] << s); /*lint !e9033*/
10993         b += 8 - s;
10994         if (j < 0) {
10995             break;
10996         }
10997         while (b < 57) {
10998             a[j--] = (byte)(r[i] >> b);
10999             b += 8;
11000             if (j < 0) {
11001                 break;
11002             }
11003         }
11004         s = 8 - (b - 57);
11005         if (j >= 0) {
11006             a[j] = 0;
11007         }
11008         if (s != 0) {
11009             j++;
11010         }
11011     }
11012 }
11013 
11014 #if (defined(WOLFSSL_HAVE_SP_RSA) && !defined(WOLFSSL_RSA_PUBLIC_ONLY)) || defined(WOLFSSL_HAVE_SP_DH)
11015 /* Normalize the values in each word to 57 bits.
11016  *
11017  * a  Array of sp_digit to normalize.
11018  */
sp_3072_norm_27(sp_digit * a)11019 static void sp_3072_norm_27(sp_digit* a)
11020 {
11021     int i;
11022     for (i = 0; i < 24; i += 8) {
11023         a[i+1] += a[i+0] >> 57; a[i+0] &= 0x1ffffffffffffffL;
11024         a[i+2] += a[i+1] >> 57; a[i+1] &= 0x1ffffffffffffffL;
11025         a[i+3] += a[i+2] >> 57; a[i+2] &= 0x1ffffffffffffffL;
11026         a[i+4] += a[i+3] >> 57; a[i+3] &= 0x1ffffffffffffffL;
11027         a[i+5] += a[i+4] >> 57; a[i+4] &= 0x1ffffffffffffffL;
11028         a[i+6] += a[i+5] >> 57; a[i+5] &= 0x1ffffffffffffffL;
11029         a[i+7] += a[i+6] >> 57; a[i+6] &= 0x1ffffffffffffffL;
11030         a[i+8] += a[i+7] >> 57; a[i+7] &= 0x1ffffffffffffffL;
11031     }
11032     a[25] += a[24] >> 57; a[24] &= 0x1ffffffffffffffL;
11033     a[26] += a[25] >> 57; a[25] &= 0x1ffffffffffffffL;
11034 }
11035 
11036 #endif /* (WOLFSSL_HAVE_SP_RSA && !WOLFSSL_RSA_PUBLIC_ONLY) || WOLFSSL_HAVE_SP_DH */
11037 /* Normalize the values in each word to 57 bits.
11038  *
11039  * a  Array of sp_digit to normalize.
11040  */
sp_3072_norm_54(sp_digit * a)11041 static void sp_3072_norm_54(sp_digit* a)
11042 {
11043     int i;
11044     for (i = 0; i < 48; i += 8) {
11045         a[i+1] += a[i+0] >> 57; a[i+0] &= 0x1ffffffffffffffL;
11046         a[i+2] += a[i+1] >> 57; a[i+1] &= 0x1ffffffffffffffL;
11047         a[i+3] += a[i+2] >> 57; a[i+2] &= 0x1ffffffffffffffL;
11048         a[i+4] += a[i+3] >> 57; a[i+3] &= 0x1ffffffffffffffL;
11049         a[i+5] += a[i+4] >> 57; a[i+4] &= 0x1ffffffffffffffL;
11050         a[i+6] += a[i+5] >> 57; a[i+5] &= 0x1ffffffffffffffL;
11051         a[i+7] += a[i+6] >> 57; a[i+6] &= 0x1ffffffffffffffL;
11052         a[i+8] += a[i+7] >> 57; a[i+7] &= 0x1ffffffffffffffL;
11053     }
11054     a[49] += a[48] >> 57; a[48] &= 0x1ffffffffffffffL;
11055     a[50] += a[49] >> 57; a[49] &= 0x1ffffffffffffffL;
11056     a[51] += a[50] >> 57; a[50] &= 0x1ffffffffffffffL;
11057     a[52] += a[51] >> 57; a[51] &= 0x1ffffffffffffffL;
11058     a[53] += a[52] >> 57; a[52] &= 0x1ffffffffffffffL;
11059 }
11060 
11061 #ifndef WOLFSSL_SP_SMALL
11062 /* Multiply a and b into r. (r = a * b)
11063  *
11064  * r  A single precision integer.
11065  * a  A single precision integer.
11066  * b  A single precision integer.
11067  */
sp_3072_mul_9(sp_digit * r,const sp_digit * a,const sp_digit * b)11068 SP_NOINLINE static void sp_3072_mul_9(sp_digit* r, const sp_digit* a,
11069     const sp_digit* b)
11070 {
11071     sp_uint128 t0   = ((sp_uint128)a[ 0]) * b[ 0];
11072     sp_uint128 t1   = ((sp_uint128)a[ 0]) * b[ 1]
11073                  + ((sp_uint128)a[ 1]) * b[ 0];
11074     sp_uint128 t2   = ((sp_uint128)a[ 0]) * b[ 2]
11075                  + ((sp_uint128)a[ 1]) * b[ 1]
11076                  + ((sp_uint128)a[ 2]) * b[ 0];
11077     sp_uint128 t3   = ((sp_uint128)a[ 0]) * b[ 3]
11078                  + ((sp_uint128)a[ 1]) * b[ 2]
11079                  + ((sp_uint128)a[ 2]) * b[ 1]
11080                  + ((sp_uint128)a[ 3]) * b[ 0];
11081     sp_uint128 t4   = ((sp_uint128)a[ 0]) * b[ 4]
11082                  + ((sp_uint128)a[ 1]) * b[ 3]
11083                  + ((sp_uint128)a[ 2]) * b[ 2]
11084                  + ((sp_uint128)a[ 3]) * b[ 1]
11085                  + ((sp_uint128)a[ 4]) * b[ 0];
11086     sp_uint128 t5   = ((sp_uint128)a[ 0]) * b[ 5]
11087                  + ((sp_uint128)a[ 1]) * b[ 4]
11088                  + ((sp_uint128)a[ 2]) * b[ 3]
11089                  + ((sp_uint128)a[ 3]) * b[ 2]
11090                  + ((sp_uint128)a[ 4]) * b[ 1]
11091                  + ((sp_uint128)a[ 5]) * b[ 0];
11092     sp_uint128 t6   = ((sp_uint128)a[ 0]) * b[ 6]
11093                  + ((sp_uint128)a[ 1]) * b[ 5]
11094                  + ((sp_uint128)a[ 2]) * b[ 4]
11095                  + ((sp_uint128)a[ 3]) * b[ 3]
11096                  + ((sp_uint128)a[ 4]) * b[ 2]
11097                  + ((sp_uint128)a[ 5]) * b[ 1]
11098                  + ((sp_uint128)a[ 6]) * b[ 0];
11099     sp_uint128 t7   = ((sp_uint128)a[ 0]) * b[ 7]
11100                  + ((sp_uint128)a[ 1]) * b[ 6]
11101                  + ((sp_uint128)a[ 2]) * b[ 5]
11102                  + ((sp_uint128)a[ 3]) * b[ 4]
11103                  + ((sp_uint128)a[ 4]) * b[ 3]
11104                  + ((sp_uint128)a[ 5]) * b[ 2]
11105                  + ((sp_uint128)a[ 6]) * b[ 1]
11106                  + ((sp_uint128)a[ 7]) * b[ 0];
11107     sp_uint128 t8   = ((sp_uint128)a[ 0]) * b[ 8]
11108                  + ((sp_uint128)a[ 1]) * b[ 7]
11109                  + ((sp_uint128)a[ 2]) * b[ 6]
11110                  + ((sp_uint128)a[ 3]) * b[ 5]
11111                  + ((sp_uint128)a[ 4]) * b[ 4]
11112                  + ((sp_uint128)a[ 5]) * b[ 3]
11113                  + ((sp_uint128)a[ 6]) * b[ 2]
11114                  + ((sp_uint128)a[ 7]) * b[ 1]
11115                  + ((sp_uint128)a[ 8]) * b[ 0];
11116     sp_uint128 t9   = ((sp_uint128)a[ 1]) * b[ 8]
11117                  + ((sp_uint128)a[ 2]) * b[ 7]
11118                  + ((sp_uint128)a[ 3]) * b[ 6]
11119                  + ((sp_uint128)a[ 4]) * b[ 5]
11120                  + ((sp_uint128)a[ 5]) * b[ 4]
11121                  + ((sp_uint128)a[ 6]) * b[ 3]
11122                  + ((sp_uint128)a[ 7]) * b[ 2]
11123                  + ((sp_uint128)a[ 8]) * b[ 1];
11124     sp_uint128 t10  = ((sp_uint128)a[ 2]) * b[ 8]
11125                  + ((sp_uint128)a[ 3]) * b[ 7]
11126                  + ((sp_uint128)a[ 4]) * b[ 6]
11127                  + ((sp_uint128)a[ 5]) * b[ 5]
11128                  + ((sp_uint128)a[ 6]) * b[ 4]
11129                  + ((sp_uint128)a[ 7]) * b[ 3]
11130                  + ((sp_uint128)a[ 8]) * b[ 2];
11131     sp_uint128 t11  = ((sp_uint128)a[ 3]) * b[ 8]
11132                  + ((sp_uint128)a[ 4]) * b[ 7]
11133                  + ((sp_uint128)a[ 5]) * b[ 6]
11134                  + ((sp_uint128)a[ 6]) * b[ 5]
11135                  + ((sp_uint128)a[ 7]) * b[ 4]
11136                  + ((sp_uint128)a[ 8]) * b[ 3];
11137     sp_uint128 t12  = ((sp_uint128)a[ 4]) * b[ 8]
11138                  + ((sp_uint128)a[ 5]) * b[ 7]
11139                  + ((sp_uint128)a[ 6]) * b[ 6]
11140                  + ((sp_uint128)a[ 7]) * b[ 5]
11141                  + ((sp_uint128)a[ 8]) * b[ 4];
11142     sp_uint128 t13  = ((sp_uint128)a[ 5]) * b[ 8]
11143                  + ((sp_uint128)a[ 6]) * b[ 7]
11144                  + ((sp_uint128)a[ 7]) * b[ 6]
11145                  + ((sp_uint128)a[ 8]) * b[ 5];
11146     sp_uint128 t14  = ((sp_uint128)a[ 6]) * b[ 8]
11147                  + ((sp_uint128)a[ 7]) * b[ 7]
11148                  + ((sp_uint128)a[ 8]) * b[ 6];
11149     sp_uint128 t15  = ((sp_uint128)a[ 7]) * b[ 8]
11150                  + ((sp_uint128)a[ 8]) * b[ 7];
11151     sp_uint128 t16  = ((sp_uint128)a[ 8]) * b[ 8];
11152 
11153     t1   += t0  >> 57; r[ 0] = t0  & 0x1ffffffffffffffL;
11154     t2   += t1  >> 57; r[ 1] = t1  & 0x1ffffffffffffffL;
11155     t3   += t2  >> 57; r[ 2] = t2  & 0x1ffffffffffffffL;
11156     t4   += t3  >> 57; r[ 3] = t3  & 0x1ffffffffffffffL;
11157     t5   += t4  >> 57; r[ 4] = t4  & 0x1ffffffffffffffL;
11158     t6   += t5  >> 57; r[ 5] = t5  & 0x1ffffffffffffffL;
11159     t7   += t6  >> 57; r[ 6] = t6  & 0x1ffffffffffffffL;
11160     t8   += t7  >> 57; r[ 7] = t7  & 0x1ffffffffffffffL;
11161     t9   += t8  >> 57; r[ 8] = t8  & 0x1ffffffffffffffL;
11162     t10  += t9  >> 57; r[ 9] = t9  & 0x1ffffffffffffffL;
11163     t11  += t10 >> 57; r[10] = t10 & 0x1ffffffffffffffL;
11164     t12  += t11 >> 57; r[11] = t11 & 0x1ffffffffffffffL;
11165     t13  += t12 >> 57; r[12] = t12 & 0x1ffffffffffffffL;
11166     t14  += t13 >> 57; r[13] = t13 & 0x1ffffffffffffffL;
11167     t15  += t14 >> 57; r[14] = t14 & 0x1ffffffffffffffL;
11168     t16  += t15 >> 57; r[15] = t15 & 0x1ffffffffffffffL;
11169     r[17] = (sp_digit)(t16 >> 57);
11170                        r[16] = t16 & 0x1ffffffffffffffL;
11171 }
11172 
11173 /* Square a and put result in r. (r = a * a)
11174  *
11175  * r  A single precision integer.
11176  * a  A single precision integer.
11177  */
sp_3072_sqr_9(sp_digit * r,const sp_digit * a)11178 SP_NOINLINE static void sp_3072_sqr_9(sp_digit* r, const sp_digit* a)
11179 {
11180     sp_uint128 t0   =  ((sp_uint128)a[ 0]) * a[ 0];
11181     sp_uint128 t1   = (((sp_uint128)a[ 0]) * a[ 1]) * 2;
11182     sp_uint128 t2   = (((sp_uint128)a[ 0]) * a[ 2]) * 2
11183                  +  ((sp_uint128)a[ 1]) * a[ 1];
11184     sp_uint128 t3   = (((sp_uint128)a[ 0]) * a[ 3]
11185                  +  ((sp_uint128)a[ 1]) * a[ 2]) * 2;
11186     sp_uint128 t4   = (((sp_uint128)a[ 0]) * a[ 4]
11187                  +  ((sp_uint128)a[ 1]) * a[ 3]) * 2
11188                  +  ((sp_uint128)a[ 2]) * a[ 2];
11189     sp_uint128 t5   = (((sp_uint128)a[ 0]) * a[ 5]
11190                  +  ((sp_uint128)a[ 1]) * a[ 4]
11191                  +  ((sp_uint128)a[ 2]) * a[ 3]) * 2;
11192     sp_uint128 t6   = (((sp_uint128)a[ 0]) * a[ 6]
11193                  +  ((sp_uint128)a[ 1]) * a[ 5]
11194                  +  ((sp_uint128)a[ 2]) * a[ 4]) * 2
11195                  +  ((sp_uint128)a[ 3]) * a[ 3];
11196     sp_uint128 t7   = (((sp_uint128)a[ 0]) * a[ 7]
11197                  +  ((sp_uint128)a[ 1]) * a[ 6]
11198                  +  ((sp_uint128)a[ 2]) * a[ 5]
11199                  +  ((sp_uint128)a[ 3]) * a[ 4]) * 2;
11200     sp_uint128 t8   = (((sp_uint128)a[ 0]) * a[ 8]
11201                  +  ((sp_uint128)a[ 1]) * a[ 7]
11202                  +  ((sp_uint128)a[ 2]) * a[ 6]
11203                  +  ((sp_uint128)a[ 3]) * a[ 5]) * 2
11204                  +  ((sp_uint128)a[ 4]) * a[ 4];
11205     sp_uint128 t9   = (((sp_uint128)a[ 1]) * a[ 8]
11206                  +  ((sp_uint128)a[ 2]) * a[ 7]
11207                  +  ((sp_uint128)a[ 3]) * a[ 6]
11208                  +  ((sp_uint128)a[ 4]) * a[ 5]) * 2;
11209     sp_uint128 t10  = (((sp_uint128)a[ 2]) * a[ 8]
11210                  +  ((sp_uint128)a[ 3]) * a[ 7]
11211                  +  ((sp_uint128)a[ 4]) * a[ 6]) * 2
11212                  +  ((sp_uint128)a[ 5]) * a[ 5];
11213     sp_uint128 t11  = (((sp_uint128)a[ 3]) * a[ 8]
11214                  +  ((sp_uint128)a[ 4]) * a[ 7]
11215                  +  ((sp_uint128)a[ 5]) * a[ 6]) * 2;
11216     sp_uint128 t12  = (((sp_uint128)a[ 4]) * a[ 8]
11217                  +  ((sp_uint128)a[ 5]) * a[ 7]) * 2
11218                  +  ((sp_uint128)a[ 6]) * a[ 6];
11219     sp_uint128 t13  = (((sp_uint128)a[ 5]) * a[ 8]
11220                  +  ((sp_uint128)a[ 6]) * a[ 7]) * 2;
11221     sp_uint128 t14  = (((sp_uint128)a[ 6]) * a[ 8]) * 2
11222                  +  ((sp_uint128)a[ 7]) * a[ 7];
11223     sp_uint128 t15  = (((sp_uint128)a[ 7]) * a[ 8]) * 2;
11224     sp_uint128 t16  =  ((sp_uint128)a[ 8]) * a[ 8];
11225 
11226     t1   += t0  >> 57; r[ 0] = t0  & 0x1ffffffffffffffL;
11227     t2   += t1  >> 57; r[ 1] = t1  & 0x1ffffffffffffffL;
11228     t3   += t2  >> 57; r[ 2] = t2  & 0x1ffffffffffffffL;
11229     t4   += t3  >> 57; r[ 3] = t3  & 0x1ffffffffffffffL;
11230     t5   += t4  >> 57; r[ 4] = t4  & 0x1ffffffffffffffL;
11231     t6   += t5  >> 57; r[ 5] = t5  & 0x1ffffffffffffffL;
11232     t7   += t6  >> 57; r[ 6] = t6  & 0x1ffffffffffffffL;
11233     t8   += t7  >> 57; r[ 7] = t7  & 0x1ffffffffffffffL;
11234     t9   += t8  >> 57; r[ 8] = t8  & 0x1ffffffffffffffL;
11235     t10  += t9  >> 57; r[ 9] = t9  & 0x1ffffffffffffffL;
11236     t11  += t10 >> 57; r[10] = t10 & 0x1ffffffffffffffL;
11237     t12  += t11 >> 57; r[11] = t11 & 0x1ffffffffffffffL;
11238     t13  += t12 >> 57; r[12] = t12 & 0x1ffffffffffffffL;
11239     t14  += t13 >> 57; r[13] = t13 & 0x1ffffffffffffffL;
11240     t15  += t14 >> 57; r[14] = t14 & 0x1ffffffffffffffL;
11241     t16  += t15 >> 57; r[15] = t15 & 0x1ffffffffffffffL;
11242     r[17] = (sp_digit)(t16 >> 57);
11243                        r[16] = t16 & 0x1ffffffffffffffL;
11244 }
11245 
11246 /* Add b to a into r. (r = a + b)
11247  *
11248  * r  A single precision integer.
11249  * a  A single precision integer.
11250  * b  A single precision integer.
11251  */
sp_3072_add_9(sp_digit * r,const sp_digit * a,const sp_digit * b)11252 SP_NOINLINE static int sp_3072_add_9(sp_digit* r, const sp_digit* a,
11253         const sp_digit* b)
11254 {
11255     r[ 0] = a[ 0] + b[ 0];
11256     r[ 1] = a[ 1] + b[ 1];
11257     r[ 2] = a[ 2] + b[ 2];
11258     r[ 3] = a[ 3] + b[ 3];
11259     r[ 4] = a[ 4] + b[ 4];
11260     r[ 5] = a[ 5] + b[ 5];
11261     r[ 6] = a[ 6] + b[ 6];
11262     r[ 7] = a[ 7] + b[ 7];
11263     r[ 8] = a[ 8] + b[ 8];
11264 
11265     return 0;
11266 }
11267 
11268 /* Sub b from a into r. (r = a - b)
11269  *
11270  * r  A single precision integer.
11271  * a  A single precision integer.
11272  * b  A single precision integer.
11273  */
sp_3072_sub_18(sp_digit * r,const sp_digit * a,const sp_digit * b)11274 SP_NOINLINE static int sp_3072_sub_18(sp_digit* r, const sp_digit* a,
11275         const sp_digit* b)
11276 {
11277     int i;
11278 
11279     for (i = 0; i < 16; i += 8) {
11280         r[i + 0] = a[i + 0] - b[i + 0];
11281         r[i + 1] = a[i + 1] - b[i + 1];
11282         r[i + 2] = a[i + 2] - b[i + 2];
11283         r[i + 3] = a[i + 3] - b[i + 3];
11284         r[i + 4] = a[i + 4] - b[i + 4];
11285         r[i + 5] = a[i + 5] - b[i + 5];
11286         r[i + 6] = a[i + 6] - b[i + 6];
11287         r[i + 7] = a[i + 7] - b[i + 7];
11288     }
11289     r[16] = a[16] - b[16];
11290     r[17] = a[17] - b[17];
11291 
11292     return 0;
11293 }
11294 
11295 /* Add b to a into r. (r = a + b)
11296  *
11297  * r  A single precision integer.
11298  * a  A single precision integer.
11299  * b  A single precision integer.
11300  */
sp_3072_add_18(sp_digit * r,const sp_digit * a,const sp_digit * b)11301 SP_NOINLINE static int sp_3072_add_18(sp_digit* r, const sp_digit* a,
11302         const sp_digit* b)
11303 {
11304     int i;
11305 
11306     for (i = 0; i < 16; i += 8) {
11307         r[i + 0] = a[i + 0] + b[i + 0];
11308         r[i + 1] = a[i + 1] + b[i + 1];
11309         r[i + 2] = a[i + 2] + b[i + 2];
11310         r[i + 3] = a[i + 3] + b[i + 3];
11311         r[i + 4] = a[i + 4] + b[i + 4];
11312         r[i + 5] = a[i + 5] + b[i + 5];
11313         r[i + 6] = a[i + 6] + b[i + 6];
11314         r[i + 7] = a[i + 7] + b[i + 7];
11315     }
11316     r[16] = a[16] + b[16];
11317     r[17] = a[17] + b[17];
11318 
11319     return 0;
11320 }
11321 
11322 /* Multiply a and b into r. (r = a * b)
11323  *
11324  * r  A single precision integer.
11325  * a  A single precision integer.
11326  * b  A single precision integer.
11327  */
sp_3072_mul_27(sp_digit * r,const sp_digit * a,const sp_digit * b)11328 SP_NOINLINE static void sp_3072_mul_27(sp_digit* r, const sp_digit* a,
11329     const sp_digit* b)
11330 {
11331     sp_digit p0[18];
11332     sp_digit p1[18];
11333     sp_digit p2[18];
11334     sp_digit p3[18];
11335     sp_digit p4[18];
11336     sp_digit p5[18];
11337     sp_digit t0[18];
11338     sp_digit t1[18];
11339     sp_digit t2[18];
11340     sp_digit a0[9];
11341     sp_digit a1[9];
11342     sp_digit a2[9];
11343     sp_digit b0[9];
11344     sp_digit b1[9];
11345     sp_digit b2[9];
11346     (void)sp_3072_add_9(a0, a, &a[9]);
11347     (void)sp_3072_add_9(b0, b, &b[9]);
11348     (void)sp_3072_add_9(a1, &a[9], &a[18]);
11349     (void)sp_3072_add_9(b1, &b[9], &b[18]);
11350     (void)sp_3072_add_9(a2, a0, &a[18]);
11351     (void)sp_3072_add_9(b2, b0, &b[18]);
11352     sp_3072_mul_9(p0, a, b);
11353     sp_3072_mul_9(p2, &a[9], &b[9]);
11354     sp_3072_mul_9(p4, &a[18], &b[18]);
11355     sp_3072_mul_9(p1, a0, b0);
11356     sp_3072_mul_9(p3, a1, b1);
11357     sp_3072_mul_9(p5, a2, b2);
11358     XMEMSET(r, 0, sizeof(*r)*2U*27U);
11359     (void)sp_3072_sub_18(t0, p3, p2);
11360     (void)sp_3072_sub_18(t1, p1, p2);
11361     (void)sp_3072_sub_18(t2, p5, t0);
11362     (void)sp_3072_sub_18(t2, t2, t1);
11363     (void)sp_3072_sub_18(t0, t0, p4);
11364     (void)sp_3072_sub_18(t1, t1, p0);
11365     (void)sp_3072_add_18(r, r, p0);
11366     (void)sp_3072_add_18(&r[9], &r[9], t1);
11367     (void)sp_3072_add_18(&r[18], &r[18], t2);
11368     (void)sp_3072_add_18(&r[27], &r[27], t0);
11369     (void)sp_3072_add_18(&r[36], &r[36], p4);
11370 }
11371 
11372 /* Square a into r. (r = a * a)
11373  *
11374  * r  A single precision integer.
11375  * a  A single precision integer.
11376  */
sp_3072_sqr_27(sp_digit * r,const sp_digit * a)11377 SP_NOINLINE static void sp_3072_sqr_27(sp_digit* r, const sp_digit* a)
11378 {
11379     sp_digit p0[18];
11380     sp_digit p1[18];
11381     sp_digit p2[18];
11382     sp_digit p3[18];
11383     sp_digit p4[18];
11384     sp_digit p5[18];
11385     sp_digit t0[18];
11386     sp_digit t1[18];
11387     sp_digit t2[18];
11388     sp_digit a0[9];
11389     sp_digit a1[9];
11390     sp_digit a2[9];
11391     (void)sp_3072_add_9(a0, a, &a[9]);
11392     (void)sp_3072_add_9(a1, &a[9], &a[18]);
11393     (void)sp_3072_add_9(a2, a0, &a[18]);
11394     sp_3072_sqr_9(p0, a);
11395     sp_3072_sqr_9(p2, &a[9]);
11396     sp_3072_sqr_9(p4, &a[18]);
11397     sp_3072_sqr_9(p1, a0);
11398     sp_3072_sqr_9(p3, a1);
11399     sp_3072_sqr_9(p5, a2);
11400     XMEMSET(r, 0, sizeof(*r)*2U*27U);
11401     (void)sp_3072_sub_18(t0, p3, p2);
11402     (void)sp_3072_sub_18(t1, p1, p2);
11403     (void)sp_3072_sub_18(t2, p5, t0);
11404     (void)sp_3072_sub_18(t2, t2, t1);
11405     (void)sp_3072_sub_18(t0, t0, p4);
11406     (void)sp_3072_sub_18(t1, t1, p0);
11407     (void)sp_3072_add_18(r, r, p0);
11408     (void)sp_3072_add_18(&r[9], &r[9], t1);
11409     (void)sp_3072_add_18(&r[18], &r[18], t2);
11410     (void)sp_3072_add_18(&r[27], &r[27], t0);
11411     (void)sp_3072_add_18(&r[36], &r[36], p4);
11412 }
11413 
11414 /* Add b to a into r. (r = a + b)
11415  *
11416  * r  A single precision integer.
11417  * a  A single precision integer.
11418  * b  A single precision integer.
11419  */
sp_3072_add_27(sp_digit * r,const sp_digit * a,const sp_digit * b)11420 SP_NOINLINE static int sp_3072_add_27(sp_digit* r, const sp_digit* a,
11421         const sp_digit* b)
11422 {
11423     int i;
11424 
11425     for (i = 0; i < 24; i += 8) {
11426         r[i + 0] = a[i + 0] + b[i + 0];
11427         r[i + 1] = a[i + 1] + b[i + 1];
11428         r[i + 2] = a[i + 2] + b[i + 2];
11429         r[i + 3] = a[i + 3] + b[i + 3];
11430         r[i + 4] = a[i + 4] + b[i + 4];
11431         r[i + 5] = a[i + 5] + b[i + 5];
11432         r[i + 6] = a[i + 6] + b[i + 6];
11433         r[i + 7] = a[i + 7] + b[i + 7];
11434     }
11435     r[24] = a[24] + b[24];
11436     r[25] = a[25] + b[25];
11437     r[26] = a[26] + b[26];
11438 
11439     return 0;
11440 }
11441 
11442 /* Add b to a into r. (r = a + b)
11443  *
11444  * r  A single precision integer.
11445  * a  A single precision integer.
11446  * b  A single precision integer.
11447  */
sp_3072_add_54(sp_digit * r,const sp_digit * a,const sp_digit * b)11448 SP_NOINLINE static int sp_3072_add_54(sp_digit* r, const sp_digit* a,
11449         const sp_digit* b)
11450 {
11451     int i;
11452 
11453     for (i = 0; i < 48; i += 8) {
11454         r[i + 0] = a[i + 0] + b[i + 0];
11455         r[i + 1] = a[i + 1] + b[i + 1];
11456         r[i + 2] = a[i + 2] + b[i + 2];
11457         r[i + 3] = a[i + 3] + b[i + 3];
11458         r[i + 4] = a[i + 4] + b[i + 4];
11459         r[i + 5] = a[i + 5] + b[i + 5];
11460         r[i + 6] = a[i + 6] + b[i + 6];
11461         r[i + 7] = a[i + 7] + b[i + 7];
11462     }
11463     r[48] = a[48] + b[48];
11464     r[49] = a[49] + b[49];
11465     r[50] = a[50] + b[50];
11466     r[51] = a[51] + b[51];
11467     r[52] = a[52] + b[52];
11468     r[53] = a[53] + b[53];
11469 
11470     return 0;
11471 }
11472 
11473 /* Sub b from a into r. (r = a - b)
11474  *
11475  * r  A single precision integer.
11476  * a  A single precision integer.
11477  * b  A single precision integer.
11478  */
sp_3072_sub_54(sp_digit * r,const sp_digit * a,const sp_digit * b)11479 SP_NOINLINE static int sp_3072_sub_54(sp_digit* r, const sp_digit* a,
11480         const sp_digit* b)
11481 {
11482     int i;
11483 
11484     for (i = 0; i < 48; i += 8) {
11485         r[i + 0] = a[i + 0] - b[i + 0];
11486         r[i + 1] = a[i + 1] - b[i + 1];
11487         r[i + 2] = a[i + 2] - b[i + 2];
11488         r[i + 3] = a[i + 3] - b[i + 3];
11489         r[i + 4] = a[i + 4] - b[i + 4];
11490         r[i + 5] = a[i + 5] - b[i + 5];
11491         r[i + 6] = a[i + 6] - b[i + 6];
11492         r[i + 7] = a[i + 7] - b[i + 7];
11493     }
11494     r[48] = a[48] - b[48];
11495     r[49] = a[49] - b[49];
11496     r[50] = a[50] - b[50];
11497     r[51] = a[51] - b[51];
11498     r[52] = a[52] - b[52];
11499     r[53] = a[53] - b[53];
11500 
11501     return 0;
11502 }
11503 
11504 /* Multiply a and b into r. (r = a * b)
11505  *
11506  * r  A single precision integer.
11507  * a  A single precision integer.
11508  * b  A single precision integer.
11509  */
sp_3072_mul_54(sp_digit * r,const sp_digit * a,const sp_digit * b)11510 SP_NOINLINE static void sp_3072_mul_54(sp_digit* r, const sp_digit* a,
11511     const sp_digit* b)
11512 {
11513     sp_digit* z0 = r;
11514     sp_digit z1[54];
11515     sp_digit* a1 = z1;
11516     sp_digit b1[27];
11517     sp_digit* z2 = r + 54;
11518     (void)sp_3072_add_27(a1, a, &a[27]);
11519     (void)sp_3072_add_27(b1, b, &b[27]);
11520     sp_3072_mul_27(z2, &a[27], &b[27]);
11521     sp_3072_mul_27(z0, a, b);
11522     sp_3072_mul_27(z1, a1, b1);
11523     (void)sp_3072_sub_54(z1, z1, z2);
11524     (void)sp_3072_sub_54(z1, z1, z0);
11525     (void)sp_3072_add_54(r + 27, r + 27, z1);
11526 }
11527 
11528 /* Square a and put result in r. (r = a * a)
11529  *
11530  * r  A single precision integer.
11531  * a  A single precision integer.
11532  */
sp_3072_sqr_54(sp_digit * r,const sp_digit * a)11533 SP_NOINLINE static void sp_3072_sqr_54(sp_digit* r, const sp_digit* a)
11534 {
11535     sp_digit* z0 = r;
11536     sp_digit z1[54];
11537     sp_digit* a1 = z1;
11538     sp_digit* z2 = r + 54;
11539     (void)sp_3072_add_27(a1, a, &a[27]);
11540     sp_3072_sqr_27(z2, &a[27]);
11541     sp_3072_sqr_27(z0, a);
11542     sp_3072_sqr_27(z1, a1);
11543     (void)sp_3072_sub_54(z1, z1, z2);
11544     (void)sp_3072_sub_54(z1, z1, z0);
11545     (void)sp_3072_add_54(r + 27, r + 27, z1);
11546 }
11547 
11548 #endif /* !WOLFSSL_SP_SMALL */
11549 /* Caclulate the bottom digit of -1/a mod 2^n.
11550  *
11551  * a    A single precision number.
11552  * rho  Bottom word of inverse.
11553  */
sp_3072_mont_setup(const sp_digit * a,sp_digit * rho)11554 static void sp_3072_mont_setup(const sp_digit* a, sp_digit* rho)
11555 {
11556     sp_digit x;
11557     sp_digit b;
11558 
11559     b = a[0];
11560     x = (((b + 2) & 4) << 1) + b; /* here x*a==1 mod 2**4 */
11561     x *= 2 - b * x;               /* here x*a==1 mod 2**8 */
11562     x *= 2 - b * x;               /* here x*a==1 mod 2**16 */
11563     x *= 2 - b * x;               /* here x*a==1 mod 2**32 */
11564     x *= 2 - b * x;               /* here x*a==1 mod 2**64 */
11565     x &= 0x1ffffffffffffffL;
11566 
11567     /* rho = -1/m mod b */
11568     *rho = ((sp_digit)1 << 57) - x;
11569 }
11570 
11571 /* Multiply a by scalar b into r. (r = a * b)
11572  *
11573  * r  A single precision integer.
11574  * a  A single precision integer.
11575  * b  A scalar.
11576  */
sp_3072_mul_d_54(sp_digit * r,const sp_digit * a,sp_digit b)11577 SP_NOINLINE static void sp_3072_mul_d_54(sp_digit* r, const sp_digit* a,
11578     sp_digit b)
11579 {
11580     sp_int128 tb = b;
11581     sp_int128 t = 0;
11582     sp_digit t2;
11583     sp_int128 p[4];
11584     int i;
11585 
11586     for (i = 0; i < 52; i += 4) {
11587         p[0] = tb * a[i + 0];
11588         p[1] = tb * a[i + 1];
11589         p[2] = tb * a[i + 2];
11590         p[3] = tb * a[i + 3];
11591         t += p[0];
11592         t2 = (sp_digit)(t & 0x1ffffffffffffffL);
11593         t >>= 57;
11594         r[i + 0] = (sp_digit)t2;
11595         t += p[1];
11596         t2 = (sp_digit)(t & 0x1ffffffffffffffL);
11597         t >>= 57;
11598         r[i + 1] = (sp_digit)t2;
11599         t += p[2];
11600         t2 = (sp_digit)(t & 0x1ffffffffffffffL);
11601         t >>= 57;
11602         r[i + 2] = (sp_digit)t2;
11603         t += p[3];
11604         t2 = (sp_digit)(t & 0x1ffffffffffffffL);
11605         t >>= 57;
11606         r[i + 3] = (sp_digit)t2;
11607     }
11608     t += tb * a[52];
11609     r[52] = (sp_digit)(t & 0x1ffffffffffffffL);
11610     t >>= 57;
11611     t += tb * a[53];
11612     r[53] = (sp_digit)(t & 0x1ffffffffffffffL);
11613     t >>= 57;
11614     r[54] = (sp_digit)(t & 0x1ffffffffffffffL);
11615 }
11616 
11617 #if (defined(WOLFSSL_HAVE_SP_RSA) && !defined(WOLFSSL_RSA_PUBLIC_ONLY)) || defined(WOLFSSL_HAVE_SP_DH)
11618 /* Sub b from a into r. (r = a - b)
11619  *
11620  * r  A single precision integer.
11621  * a  A single precision integer.
11622  * b  A single precision integer.
11623  */
sp_3072_sub_27(sp_digit * r,const sp_digit * a,const sp_digit * b)11624 SP_NOINLINE static int sp_3072_sub_27(sp_digit* r, const sp_digit* a,
11625         const sp_digit* b)
11626 {
11627     int i;
11628 
11629     for (i = 0; i < 24; i += 8) {
11630         r[i + 0] = a[i + 0] - b[i + 0];
11631         r[i + 1] = a[i + 1] - b[i + 1];
11632         r[i + 2] = a[i + 2] - b[i + 2];
11633         r[i + 3] = a[i + 3] - b[i + 3];
11634         r[i + 4] = a[i + 4] - b[i + 4];
11635         r[i + 5] = a[i + 5] - b[i + 5];
11636         r[i + 6] = a[i + 6] - b[i + 6];
11637         r[i + 7] = a[i + 7] - b[i + 7];
11638     }
11639     r[24] = a[24] - b[24];
11640     r[25] = a[25] - b[25];
11641     r[26] = a[26] - b[26];
11642 
11643     return 0;
11644 }
11645 
11646 /* r = 2^n mod m where n is the number of bits to reduce by.
11647  * Given m must be 3072 bits, just need to subtract.
11648  *
11649  * r  A single precision number.
11650  * m  A single precision number.
11651  */
sp_3072_mont_norm_27(sp_digit * r,const sp_digit * m)11652 static void sp_3072_mont_norm_27(sp_digit* r, const sp_digit* m)
11653 {
11654     /* Set r = 2^n - 1. */
11655     int i;
11656 
11657     for (i = 0; i < 24; i += 8) {
11658         r[i + 0] = 0x1ffffffffffffffL;
11659         r[i + 1] = 0x1ffffffffffffffL;
11660         r[i + 2] = 0x1ffffffffffffffL;
11661         r[i + 3] = 0x1ffffffffffffffL;
11662         r[i + 4] = 0x1ffffffffffffffL;
11663         r[i + 5] = 0x1ffffffffffffffL;
11664         r[i + 6] = 0x1ffffffffffffffL;
11665         r[i + 7] = 0x1ffffffffffffffL;
11666     }
11667     r[24] = 0x1ffffffffffffffL;
11668     r[25] = 0x1ffffffffffffffL;
11669     r[26] = 0x3fffffffffffffL;
11670 
11671     /* r = (2^n - 1) mod n */
11672     (void)sp_3072_sub_27(r, r, m);
11673 
11674     /* Add one so r = 2^n mod m */
11675     r[0] += 1;
11676 }
11677 
11678 /* Compare a with b in constant time.
11679  *
11680  * a  A single precision integer.
11681  * b  A single precision integer.
11682  * return -ve, 0 or +ve if a is less than, equal to or greater than b
11683  * respectively.
11684  */
sp_3072_cmp_27(const sp_digit * a,const sp_digit * b)11685 static sp_digit sp_3072_cmp_27(const sp_digit* a, const sp_digit* b)
11686 {
11687     sp_digit r = 0;
11688     int i;
11689 
11690     r |= (a[26] - b[26]) & (0 - (sp_digit)1);
11691     r |= (a[25] - b[25]) & (0 - (sp_digit)((r == 0) ? 1 : 0));
11692     r |= (a[24] - b[24]) & (0 - (sp_digit)((r == 0) ? 1 : 0));
11693     for (i = 16; i >= 0; i -= 8) {
11694         r |= (a[i + 7] - b[i + 7]) & (0 - (sp_digit)((r == 0) ? 1 : 0));
11695         r |= (a[i + 6] - b[i + 6]) & (0 - (sp_digit)((r == 0) ? 1 : 0));
11696         r |= (a[i + 5] - b[i + 5]) & (0 - (sp_digit)((r == 0) ? 1 : 0));
11697         r |= (a[i + 4] - b[i + 4]) & (0 - (sp_digit)((r == 0) ? 1 : 0));
11698         r |= (a[i + 3] - b[i + 3]) & (0 - (sp_digit)((r == 0) ? 1 : 0));
11699         r |= (a[i + 2] - b[i + 2]) & (0 - (sp_digit)((r == 0) ? 1 : 0));
11700         r |= (a[i + 1] - b[i + 1]) & (0 - (sp_digit)((r == 0) ? 1 : 0));
11701         r |= (a[i + 0] - b[i + 0]) & (0 - (sp_digit)((r == 0) ? 1 : 0));
11702     }
11703 
11704     return r;
11705 }
11706 
11707 /* Conditionally subtract b from a using the mask m.
11708  * m is -1 to subtract and 0 when not.
11709  *
11710  * r  A single precision number representing condition subtract result.
11711  * a  A single precision number to subtract from.
11712  * b  A single precision number to subtract.
11713  * m  Mask value to apply.
11714  */
sp_3072_cond_sub_27(sp_digit * r,const sp_digit * a,const sp_digit * b,const sp_digit m)11715 static void sp_3072_cond_sub_27(sp_digit* r, const sp_digit* a,
11716         const sp_digit* b, const sp_digit m)
11717 {
11718     int i;
11719 
11720     for (i = 0; i < 24; i += 8) {
11721         r[i + 0] = a[i + 0] - (b[i + 0] & m);
11722         r[i + 1] = a[i + 1] - (b[i + 1] & m);
11723         r[i + 2] = a[i + 2] - (b[i + 2] & m);
11724         r[i + 3] = a[i + 3] - (b[i + 3] & m);
11725         r[i + 4] = a[i + 4] - (b[i + 4] & m);
11726         r[i + 5] = a[i + 5] - (b[i + 5] & m);
11727         r[i + 6] = a[i + 6] - (b[i + 6] & m);
11728         r[i + 7] = a[i + 7] - (b[i + 7] & m);
11729     }
11730     r[24] = a[24] - (b[24] & m);
11731     r[25] = a[25] - (b[25] & m);
11732     r[26] = a[26] - (b[26] & m);
11733 }
11734 
11735 /* Mul a by scalar b and add into r. (r += a * b)
11736  *
11737  * r  A single precision integer.
11738  * a  A single precision integer.
11739  * b  A scalar.
11740  */
sp_3072_mul_add_27(sp_digit * r,const sp_digit * a,const sp_digit b)11741 SP_NOINLINE static void sp_3072_mul_add_27(sp_digit* r, const sp_digit* a,
11742         const sp_digit b)
11743 {
11744     sp_int128 tb = b;
11745     sp_int128 t[8];
11746     int i;
11747 
11748     t[0] = tb * a[0]; r[0] += (sp_digit)(t[0] & 0x1ffffffffffffffL);
11749     for (i = 0; i < 24; i += 8) {
11750         t[1] = tb * a[i+1];
11751         r[i+1] += (sp_digit)((t[0] >> 57) + (t[1] & 0x1ffffffffffffffL));
11752         t[2] = tb * a[i+2];
11753         r[i+2] += (sp_digit)((t[1] >> 57) + (t[2] & 0x1ffffffffffffffL));
11754         t[3] = tb * a[i+3];
11755         r[i+3] += (sp_digit)((t[2] >> 57) + (t[3] & 0x1ffffffffffffffL));
11756         t[4] = tb * a[i+4];
11757         r[i+4] += (sp_digit)((t[3] >> 57) + (t[4] & 0x1ffffffffffffffL));
11758         t[5] = tb * a[i+5];
11759         r[i+5] += (sp_digit)((t[4] >> 57) + (t[5] & 0x1ffffffffffffffL));
11760         t[6] = tb * a[i+6];
11761         r[i+6] += (sp_digit)((t[5] >> 57) + (t[6] & 0x1ffffffffffffffL));
11762         t[7] = tb * a[i+7];
11763         r[i+7] += (sp_digit)((t[6] >> 57) + (t[7] & 0x1ffffffffffffffL));
11764         t[0] = tb * a[i+8];
11765         r[i+8] += (sp_digit)((t[7] >> 57) + (t[0] & 0x1ffffffffffffffL));
11766     }
11767     t[1] = tb * a[25];
11768     r[25] += (sp_digit)((t[0] >> 57) + (t[1] & 0x1ffffffffffffffL));
11769     t[2] = tb * a[26];
11770     r[26] += (sp_digit)((t[1] >> 57) + (t[2] & 0x1ffffffffffffffL));
11771     r[27] +=  (sp_digit)(t[2] >> 57);
11772 }
11773 
11774 /* Shift the result in the high 1536 bits down to the bottom.
11775  *
11776  * r  A single precision number.
11777  * a  A single precision number.
11778  */
sp_3072_mont_shift_27(sp_digit * r,const sp_digit * a)11779 static void sp_3072_mont_shift_27(sp_digit* r, const sp_digit* a)
11780 {
11781     sp_digit n;
11782     sp_digit s;
11783     int i;
11784 
11785     s = a[27]; n = a[26] >> 54;
11786     for (i = 0; i < 24; i += 8) {
11787         n += (s & 0x1ffffffffffffffL) << 3; r[i+0] = n & 0x1ffffffffffffffL;
11788         n >>= 57; s = a[i+28] + (s >> 57);
11789         n += (s & 0x1ffffffffffffffL) << 3; r[i+1] = n & 0x1ffffffffffffffL;
11790         n >>= 57; s = a[i+29] + (s >> 57);
11791         n += (s & 0x1ffffffffffffffL) << 3; r[i+2] = n & 0x1ffffffffffffffL;
11792         n >>= 57; s = a[i+30] + (s >> 57);
11793         n += (s & 0x1ffffffffffffffL) << 3; r[i+3] = n & 0x1ffffffffffffffL;
11794         n >>= 57; s = a[i+31] + (s >> 57);
11795         n += (s & 0x1ffffffffffffffL) << 3; r[i+4] = n & 0x1ffffffffffffffL;
11796         n >>= 57; s = a[i+32] + (s >> 57);
11797         n += (s & 0x1ffffffffffffffL) << 3; r[i+5] = n & 0x1ffffffffffffffL;
11798         n >>= 57; s = a[i+33] + (s >> 57);
11799         n += (s & 0x1ffffffffffffffL) << 3; r[i+6] = n & 0x1ffffffffffffffL;
11800         n >>= 57; s = a[i+34] + (s >> 57);
11801         n += (s & 0x1ffffffffffffffL) << 3; r[i+7] = n & 0x1ffffffffffffffL;
11802         n >>= 57; s = a[i+35] + (s >> 57);
11803     }
11804     n += (s & 0x1ffffffffffffffL) << 3; r[24] = n & 0x1ffffffffffffffL;
11805     n >>= 57; s = a[52] + (s >> 57);
11806     n += (s & 0x1ffffffffffffffL) << 3; r[25] = n & 0x1ffffffffffffffL;
11807     n >>= 57; s = a[53] + (s >> 57);
11808     n += s << 3;              r[26] = n;
11809     XMEMSET(&r[27], 0, sizeof(*r) * 27U);
11810 }
11811 
11812 /* Reduce the number back to 3072 bits using Montgomery reduction.
11813  *
11814  * a   A single precision number to reduce in place.
11815  * m   The single precision number representing the modulus.
11816  * mp  The digit representing the negative inverse of m mod 2^n.
11817  */
sp_3072_mont_reduce_27(sp_digit * a,const sp_digit * m,sp_digit mp)11818 static void sp_3072_mont_reduce_27(sp_digit* a, const sp_digit* m, sp_digit mp)
11819 {
11820     int i;
11821     sp_digit mu;
11822 
11823     sp_3072_norm_27(a + 27);
11824 
11825     for (i=0; i<26; i++) {
11826         mu = (a[i] * mp) & 0x1ffffffffffffffL;
11827         sp_3072_mul_add_27(a+i, m, mu);
11828         a[i+1] += a[i] >> 57;
11829     }
11830     mu = (a[i] * mp) & 0x3fffffffffffffL;
11831     sp_3072_mul_add_27(a+i, m, mu);
11832     a[i+1] += a[i] >> 57;
11833     a[i] &= 0x1ffffffffffffffL;
11834     sp_3072_mont_shift_27(a, a);
11835     sp_3072_cond_sub_27(a, a, m, 0 - (((a[26] - m[26]) > 0) ?
11836             (sp_digit)1 : (sp_digit)0));
11837     sp_3072_norm_27(a);
11838 }
11839 
11840 /* Multiply two Montgomery form numbers mod the modulus (prime).
11841  * (r = a * b mod m)
11842  *
11843  * r   Result of multiplication.
11844  * a   First number to multiply in Montgomery form.
11845  * b   Second number to multiply in Montgomery form.
11846  * m   Modulus (prime).
11847  * mp  Montgomery mulitplier.
11848  */
sp_3072_mont_mul_27(sp_digit * r,const sp_digit * a,const sp_digit * b,const sp_digit * m,sp_digit mp)11849 static void sp_3072_mont_mul_27(sp_digit* r, const sp_digit* a,
11850         const sp_digit* b, const sp_digit* m, sp_digit mp)
11851 {
11852     sp_3072_mul_27(r, a, b);
11853     sp_3072_mont_reduce_27(r, m, mp);
11854 }
11855 
11856 /* Square the Montgomery form number. (r = a * a mod m)
11857  *
11858  * r   Result of squaring.
11859  * a   Number to square in Montgomery form.
11860  * m   Modulus (prime).
11861  * mp  Montgomery mulitplier.
11862  */
sp_3072_mont_sqr_27(sp_digit * r,const sp_digit * a,const sp_digit * m,sp_digit mp)11863 static void sp_3072_mont_sqr_27(sp_digit* r, const sp_digit* a,
11864         const sp_digit* m, sp_digit mp)
11865 {
11866     sp_3072_sqr_27(r, a);
11867     sp_3072_mont_reduce_27(r, m, mp);
11868 }
11869 
11870 /* Multiply a by scalar b into r. (r = a * b)
11871  *
11872  * r  A single precision integer.
11873  * a  A single precision integer.
11874  * b  A scalar.
11875  */
sp_3072_mul_d_27(sp_digit * r,const sp_digit * a,sp_digit b)11876 SP_NOINLINE static void sp_3072_mul_d_27(sp_digit* r, const sp_digit* a,
11877     sp_digit b)
11878 {
11879     sp_int128 tb = b;
11880     sp_int128 t = 0;
11881     sp_digit t2;
11882     sp_int128 p[4];
11883     int i;
11884 
11885     for (i = 0; i < 24; i += 4) {
11886         p[0] = tb * a[i + 0];
11887         p[1] = tb * a[i + 1];
11888         p[2] = tb * a[i + 2];
11889         p[3] = tb * a[i + 3];
11890         t += p[0];
11891         t2 = (sp_digit)(t & 0x1ffffffffffffffL);
11892         t >>= 57;
11893         r[i + 0] = (sp_digit)t2;
11894         t += p[1];
11895         t2 = (sp_digit)(t & 0x1ffffffffffffffL);
11896         t >>= 57;
11897         r[i + 1] = (sp_digit)t2;
11898         t += p[2];
11899         t2 = (sp_digit)(t & 0x1ffffffffffffffL);
11900         t >>= 57;
11901         r[i + 2] = (sp_digit)t2;
11902         t += p[3];
11903         t2 = (sp_digit)(t & 0x1ffffffffffffffL);
11904         t >>= 57;
11905         r[i + 3] = (sp_digit)t2;
11906     }
11907     t += tb * a[24];
11908     r[24] = (sp_digit)(t & 0x1ffffffffffffffL);
11909     t >>= 57;
11910     t += tb * a[25];
11911     r[25] = (sp_digit)(t & 0x1ffffffffffffffL);
11912     t >>= 57;
11913     t += tb * a[26];
11914     r[26] = (sp_digit)(t & 0x1ffffffffffffffL);
11915     t >>= 57;
11916     r[27] = (sp_digit)(t & 0x1ffffffffffffffL);
11917 }
11918 
11919 /* Conditionally add a and b using the mask m.
11920  * m is -1 to add and 0 when not.
11921  *
11922  * r  A single precision number representing conditional add result.
11923  * a  A single precision number to add with.
11924  * b  A single precision number to add.
11925  * m  Mask value to apply.
11926  */
sp_3072_cond_add_27(sp_digit * r,const sp_digit * a,const sp_digit * b,const sp_digit m)11927 static void sp_3072_cond_add_27(sp_digit* r, const sp_digit* a,
11928         const sp_digit* b, const sp_digit m)
11929 {
11930     int i;
11931 
11932     for (i = 0; i < 24; i += 8) {
11933         r[i + 0] = a[i + 0] + (b[i + 0] & m);
11934         r[i + 1] = a[i + 1] + (b[i + 1] & m);
11935         r[i + 2] = a[i + 2] + (b[i + 2] & m);
11936         r[i + 3] = a[i + 3] + (b[i + 3] & m);
11937         r[i + 4] = a[i + 4] + (b[i + 4] & m);
11938         r[i + 5] = a[i + 5] + (b[i + 5] & m);
11939         r[i + 6] = a[i + 6] + (b[i + 6] & m);
11940         r[i + 7] = a[i + 7] + (b[i + 7] & m);
11941     }
11942     r[24] = a[24] + (b[24] & m);
11943     r[25] = a[25] + (b[25] & m);
11944     r[26] = a[26] + (b[26] & m);
11945 }
11946 
sp_3072_rshift_27(sp_digit * r,const sp_digit * a,byte n)11947 SP_NOINLINE static void sp_3072_rshift_27(sp_digit* r, const sp_digit* a,
11948         byte n)
11949 {
11950     int i;
11951 
11952     for (i=0; i<24; i += 8) {
11953         r[i+0] = (a[i+0] >> n) | ((a[i+1] << (57 - n)) & 0x1ffffffffffffffL);
11954         r[i+1] = (a[i+1] >> n) | ((a[i+2] << (57 - n)) & 0x1ffffffffffffffL);
11955         r[i+2] = (a[i+2] >> n) | ((a[i+3] << (57 - n)) & 0x1ffffffffffffffL);
11956         r[i+3] = (a[i+3] >> n) | ((a[i+4] << (57 - n)) & 0x1ffffffffffffffL);
11957         r[i+4] = (a[i+4] >> n) | ((a[i+5] << (57 - n)) & 0x1ffffffffffffffL);
11958         r[i+5] = (a[i+5] >> n) | ((a[i+6] << (57 - n)) & 0x1ffffffffffffffL);
11959         r[i+6] = (a[i+6] >> n) | ((a[i+7] << (57 - n)) & 0x1ffffffffffffffL);
11960         r[i+7] = (a[i+7] >> n) | ((a[i+8] << (57 - n)) & 0x1ffffffffffffffL);
11961     }
11962     r[24] = (a[24] >> n) | ((a[25] << (57 - n)) & 0x1ffffffffffffffL);
11963     r[25] = (a[25] >> n) | ((a[26] << (57 - n)) & 0x1ffffffffffffffL);
11964     r[26] = a[26] >> n;
11965 }
11966 
11967 #ifdef WOLFSSL_SP_DIV_64
sp_3072_div_word_27(sp_digit d1,sp_digit d0,sp_digit dv)11968 static WC_INLINE sp_digit sp_3072_div_word_27(sp_digit d1, sp_digit d0,
11969     sp_digit dv)
11970 {
11971     sp_digit d;
11972     sp_digit r;
11973     sp_digit t;
11974 
11975     /* All 57 bits from d1 and top 6 bits from d0. */
11976     d = (d1 << 6) + (d0 >> 51);
11977     r = d / dv;
11978     d -= r * dv;
11979     /* Up to 7 bits in r */
11980     /* Next 6 bits from d0. */
11981     r <<= 6;
11982     d <<= 6;
11983     d += (d0 >> 45) & ((1 << 6) - 1);
11984     t = d / dv;
11985     d -= t * dv;
11986     r += t;
11987     /* Up to 13 bits in r */
11988     /* Next 6 bits from d0. */
11989     r <<= 6;
11990     d <<= 6;
11991     d += (d0 >> 39) & ((1 << 6) - 1);
11992     t = d / dv;
11993     d -= t * dv;
11994     r += t;
11995     /* Up to 19 bits in r */
11996     /* Next 6 bits from d0. */
11997     r <<= 6;
11998     d <<= 6;
11999     d += (d0 >> 33) & ((1 << 6) - 1);
12000     t = d / dv;
12001     d -= t * dv;
12002     r += t;
12003     /* Up to 25 bits in r */
12004     /* Next 6 bits from d0. */
12005     r <<= 6;
12006     d <<= 6;
12007     d += (d0 >> 27) & ((1 << 6) - 1);
12008     t = d / dv;
12009     d -= t * dv;
12010     r += t;
12011     /* Up to 31 bits in r */
12012     /* Next 6 bits from d0. */
12013     r <<= 6;
12014     d <<= 6;
12015     d += (d0 >> 21) & ((1 << 6) - 1);
12016     t = d / dv;
12017     d -= t * dv;
12018     r += t;
12019     /* Up to 37 bits in r */
12020     /* Next 6 bits from d0. */
12021     r <<= 6;
12022     d <<= 6;
12023     d += (d0 >> 15) & ((1 << 6) - 1);
12024     t = d / dv;
12025     d -= t * dv;
12026     r += t;
12027     /* Up to 43 bits in r */
12028     /* Next 6 bits from d0. */
12029     r <<= 6;
12030     d <<= 6;
12031     d += (d0 >> 9) & ((1 << 6) - 1);
12032     t = d / dv;
12033     d -= t * dv;
12034     r += t;
12035     /* Up to 49 bits in r */
12036     /* Next 6 bits from d0. */
12037     r <<= 6;
12038     d <<= 6;
12039     d += (d0 >> 3) & ((1 << 6) - 1);
12040     t = d / dv;
12041     d -= t * dv;
12042     r += t;
12043     /* Up to 55 bits in r */
12044     /* Remaining 3 bits from d0. */
12045     r <<= 3;
12046     d <<= 3;
12047     d += d0 & ((1 << 3) - 1);
12048     t = d / dv;
12049     r += t;
12050 
12051     /* All 57 bits from d1 and top 6 bits from d0. */
12052     return r;
12053 }
12054 #endif /* WOLFSSL_SP_DIV_64 */
12055 
12056 /* Divide d in a and put remainder into r (m*d + r = a)
12057  * m is not calculated as it is not needed at this time.
12058  *
12059  * Full implementation.
12060  *
12061  * a  Number to be divided.
12062  * d  Number to divide with.
12063  * m  Multiplier result.
12064  * r  Remainder from the division.
12065  * returns MEMORY_E when unable to allocate memory and MP_OKAY otherwise.
12066  */
sp_3072_div_27(const sp_digit * a,const sp_digit * d,const sp_digit * m,sp_digit * r)12067 static int sp_3072_div_27(const sp_digit* a, const sp_digit* d,
12068         const sp_digit* m, sp_digit* r)
12069 {
12070     int i;
12071 #ifndef WOLFSSL_SP_DIV_64
12072     sp_int128 d1;
12073 #endif
12074     sp_digit dv;
12075     sp_digit r1;
12076 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
12077     sp_digit* t1 = NULL;
12078 #else
12079     sp_digit t1[4 * 27 + 3];
12080 #endif
12081     sp_digit* t2 = NULL;
12082     sp_digit* sd = NULL;
12083     int err = MP_OKAY;
12084 
12085     (void)m;
12086 
12087 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
12088     t1 = (sp_digit*)XMALLOC(sizeof(sp_digit) * (4 * 27 + 3), NULL,
12089                                                        DYNAMIC_TYPE_TMP_BUFFER);
12090     if (t1 == NULL)
12091         err = MEMORY_E;
12092 #endif
12093 
12094     (void)m;
12095 
12096     if (err == MP_OKAY) {
12097         t2 = t1 + 54 + 1;
12098         sd = t2 + 27 + 1;
12099 
12100         sp_3072_mul_d_27(sd, d, (sp_digit)1 << 3);
12101         sp_3072_mul_d_54(t1, a, (sp_digit)1 << 3);
12102         dv = sd[26];
12103         t1[27 + 27] += t1[27 + 27 - 1] >> 57;
12104         t1[27 + 27 - 1] &= 0x1ffffffffffffffL;
12105         for (i=27; i>=0; i--) {
12106 #ifndef WOLFSSL_SP_DIV_64
12107             d1 = t1[27 + i];
12108             d1 <<= 57;
12109             d1 += t1[27 + i - 1];
12110             r1 = (sp_digit)(d1 / dv);
12111 #else
12112             r1 = sp_3072_div_word_27(t1[27 + i], t1[27 + i - 1], dv);
12113 #endif
12114 
12115             sp_3072_mul_d_27(t2, sd, r1);
12116             (void)sp_3072_sub_27(&t1[i], &t1[i], t2);
12117             sp_3072_norm_27(&t1[i]);
12118             t1[27 + i] -= t2[27];
12119             t1[27 + i] += t1[27 + i - 1] >> 57;
12120             t1[27 + i - 1] &= 0x1ffffffffffffffL;
12121 #ifndef WOLFSSL_SP_DIV_64
12122             d1 = -t1[27 + i];
12123             d1 <<= 57;
12124             d1 -= t1[27 + i - 1];
12125             r1 = (sp_digit)(d1 / dv);
12126 #else
12127             r1 = sp_3072_div_word_27(-t1[27 + i], -t1[27 + i - 1], dv);
12128 #endif
12129             r1 -= t1[27 + i];
12130             sp_3072_mul_d_27(t2, sd, r1);
12131             (void)sp_3072_add_27(&t1[i], &t1[i], t2);
12132             t1[27 + i] += t1[27 + i - 1] >> 57;
12133             t1[27 + i - 1] &= 0x1ffffffffffffffL;
12134         }
12135         t1[27 - 1] += t1[27 - 2] >> 57;
12136         t1[27 - 2] &= 0x1ffffffffffffffL;
12137         r1 = t1[27 - 1] / dv;
12138 
12139         sp_3072_mul_d_27(t2, sd, r1);
12140         sp_3072_sub_27(t1, t1, t2);
12141         XMEMCPY(r, t1, sizeof(*r) * 54U);
12142         for (i=0; i<26; i++) {
12143             r[i+1] += r[i] >> 57;
12144             r[i] &= 0x1ffffffffffffffL;
12145         }
12146         sp_3072_cond_add_27(r, r, sd, 0 - ((r[26] < 0) ?
12147                     (sp_digit)1 : (sp_digit)0));
12148 
12149         sp_3072_norm_27(r);
12150         sp_3072_rshift_27(r, r, 3);
12151     }
12152 
12153 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
12154     if (t1 != NULL)
12155         XFREE(t1, NULL, DYNAMIC_TYPE_TMP_BUFFER);
12156 #endif
12157 
12158     return err;
12159 }
12160 
12161 /* Reduce a modulo m into r. (r = a mod m)
12162  *
12163  * r  A single precision number that is the reduced result.
12164  * a  A single precision number that is to be reduced.
12165  * m  A single precision number that is the modulus to reduce with.
12166  * returns MEMORY_E when unable to allocate memory and MP_OKAY otherwise.
12167  */
sp_3072_mod_27(sp_digit * r,const sp_digit * a,const sp_digit * m)12168 static int sp_3072_mod_27(sp_digit* r, const sp_digit* a, const sp_digit* m)
12169 {
12170     return sp_3072_div_27(a, m, NULL, r);
12171 }
12172 
12173 /* Modular exponentiate a to the e mod m. (r = a^e mod m)
12174  *
12175  * r     A single precision number that is the result of the operation.
12176  * a     A single precision number being exponentiated.
12177  * e     A single precision number that is the exponent.
12178  * bits  The number of bits in the exponent.
12179  * m     A single precision number that is the modulus.
12180  * returns  0 on success.
12181  * returns  MEMORY_E on dynamic memory allocation failure.
12182  * returns  MP_VAL when base is even or exponent is 0.
12183  */
sp_3072_mod_exp_27(sp_digit * r,const sp_digit * a,const sp_digit * e,int bits,const sp_digit * m,int reduceA)12184 static int sp_3072_mod_exp_27(sp_digit* r, const sp_digit* a, const sp_digit* e,
12185     int bits, const sp_digit* m, int reduceA)
12186 {
12187 #if defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SP_FAST_MODEXP)
12188 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
12189     sp_digit* td = NULL;
12190 #else
12191     sp_digit td[3 * 54];
12192 #endif
12193     sp_digit* t[3] = {0, 0, 0};
12194     sp_digit* norm = NULL;
12195     sp_digit mp = 1;
12196     sp_digit n;
12197     int i;
12198     int c;
12199     byte y;
12200     int err = MP_OKAY;
12201 
12202     if ((m[0] & 1) == 0) {
12203         err = MP_VAL;
12204     }
12205     else if (bits == 0) {
12206         err = MP_VAL;
12207     }
12208 
12209 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
12210     if (err == MP_OKAY) {
12211         td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 3 * 27 * 2, NULL,
12212                                 DYNAMIC_TYPE_TMP_BUFFER);
12213         if (td == NULL)
12214             err = MEMORY_E;
12215     }
12216 #endif
12217 
12218     if (err == MP_OKAY) {
12219         norm = td;
12220         for (i=0; i<3; i++) {
12221             t[i] = td + (i * 27 * 2);
12222             XMEMSET(t[i], 0, sizeof(sp_digit) * 27U * 2U);
12223         }
12224 
12225         sp_3072_mont_setup(m, &mp);
12226         sp_3072_mont_norm_27(norm, m);
12227 
12228         if (reduceA != 0) {
12229             err = sp_3072_mod_27(t[1], a, m);
12230         }
12231         else {
12232             XMEMCPY(t[1], a, sizeof(sp_digit) * 27U);
12233         }
12234     }
12235     if (err == MP_OKAY) {
12236         sp_3072_mul_27(t[1], t[1], norm);
12237         err = sp_3072_mod_27(t[1], t[1], m);
12238     }
12239 
12240     if (err == MP_OKAY) {
12241         i = bits / 57;
12242         c = bits % 57;
12243         n = e[i--] << (57 - c);
12244         for (; ; c--) {
12245             if (c == 0) {
12246                 if (i == -1) {
12247                     break;
12248                 }
12249 
12250                 n = e[i--];
12251                 c = 57;
12252             }
12253 
12254             y = (int)((n >> 56) & 1);
12255             n <<= 1;
12256 
12257             sp_3072_mont_mul_27(t[y^1], t[0], t[1], m, mp);
12258 
12259             XMEMCPY(t[2], (void*)(((size_t)t[0] & addr_mask[y^1]) +
12260                                   ((size_t)t[1] & addr_mask[y])),
12261                                   sizeof(*t[2]) * 27 * 2);
12262             sp_3072_mont_sqr_27(t[2], t[2], m, mp);
12263             XMEMCPY((void*)(((size_t)t[0] & addr_mask[y^1]) +
12264                             ((size_t)t[1] & addr_mask[y])), t[2],
12265                             sizeof(*t[2]) * 27 * 2);
12266         }
12267 
12268         sp_3072_mont_reduce_27(t[0], m, mp);
12269         n = sp_3072_cmp_27(t[0], m);
12270         sp_3072_cond_sub_27(t[0], t[0], m, ((n < 0) ?
12271                     (sp_digit)1 : (sp_digit)0) - 1);
12272         XMEMCPY(r, t[0], sizeof(*r) * 27 * 2);
12273 
12274     }
12275 
12276 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
12277     if (td != NULL)
12278         XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);
12279 #endif
12280 
12281     return err;
12282 #elif !defined(WC_NO_CACHE_RESISTANT)
12283 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
12284     sp_digit* td = NULL;
12285 #else
12286     sp_digit td[3 * 54];
12287 #endif
12288     sp_digit* t[3] = {0, 0, 0};
12289     sp_digit* norm = NULL;
12290     sp_digit mp = 1;
12291     sp_digit n;
12292     int i;
12293     int c;
12294     byte y;
12295     int err = MP_OKAY;
12296 
12297     if ((m[0] & 1) == 0) {
12298         err = MP_VAL;
12299     }
12300     else if (bits == 0) {
12301         err = MP_VAL;
12302     }
12303 
12304 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
12305     if (err == MP_OKAY) {
12306         td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 3 * 27 * 2, NULL,
12307                                 DYNAMIC_TYPE_TMP_BUFFER);
12308         if (td == NULL)
12309             err = MEMORY_E;
12310     }
12311 #endif
12312 
12313     if (err == MP_OKAY) {
12314         norm = td;
12315         for (i=0; i<3; i++) {
12316             t[i] = td + (i * 27 * 2);
12317         }
12318 
12319         sp_3072_mont_setup(m, &mp);
12320         sp_3072_mont_norm_27(norm, m);
12321 
12322         if (reduceA != 0) {
12323             err = sp_3072_mod_27(t[1], a, m);
12324             if (err == MP_OKAY) {
12325                 sp_3072_mul_27(t[1], t[1], norm);
12326                 err = sp_3072_mod_27(t[1], t[1], m);
12327             }
12328         }
12329         else {
12330             sp_3072_mul_27(t[1], a, norm);
12331             err = sp_3072_mod_27(t[1], t[1], m);
12332         }
12333     }
12334 
12335     if (err == MP_OKAY) {
12336         i = bits / 57;
12337         c = bits % 57;
12338         n = e[i--] << (57 - c);
12339         for (; ; c--) {
12340             if (c == 0) {
12341                 if (i == -1) {
12342                     break;
12343                 }
12344 
12345                 n = e[i--];
12346                 c = 57;
12347             }
12348 
12349             y = (int)((n >> 56) & 1);
12350             n <<= 1;
12351 
12352             sp_3072_mont_mul_27(t[y^1], t[0], t[1], m, mp);
12353 
12354             XMEMCPY(t[2], (void*)(((size_t)t[0] & addr_mask[y^1]) +
12355                                   ((size_t)t[1] & addr_mask[y])),
12356                                   sizeof(*t[2]) * 27 * 2);
12357             sp_3072_mont_sqr_27(t[2], t[2], m, mp);
12358             XMEMCPY((void*)(((size_t)t[0] & addr_mask[y^1]) +
12359                             ((size_t)t[1] & addr_mask[y])), t[2],
12360                             sizeof(*t[2]) * 27 * 2);
12361         }
12362 
12363         sp_3072_mont_reduce_27(t[0], m, mp);
12364         n = sp_3072_cmp_27(t[0], m);
12365         sp_3072_cond_sub_27(t[0], t[0], m, ((n < 0) ?
12366                     (sp_digit)1 : (sp_digit)0) - 1);
12367         XMEMCPY(r, t[0], sizeof(*r) * 27 * 2);
12368     }
12369 
12370 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
12371     if (td != NULL)
12372         XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);
12373 #endif
12374 
12375     return err;
12376 #else
12377 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
12378     sp_digit* td = NULL;
12379 #else
12380     sp_digit td[(32 * 54) + 54];
12381 #endif
12382     sp_digit* t[32];
12383     sp_digit* rt = NULL;
12384     sp_digit* norm = NULL;
12385     sp_digit mp = 1;
12386     sp_digit n;
12387     int i;
12388     int c;
12389     byte y;
12390     int err = MP_OKAY;
12391 
12392     if ((m[0] & 1) == 0) {
12393         err = MP_VAL;
12394     }
12395     else if (bits == 0) {
12396         err = MP_VAL;
12397     }
12398 
12399 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
12400     if (err == MP_OKAY) {
12401         td = (sp_digit*)XMALLOC(sizeof(sp_digit) * ((32 * 54) + 54), NULL,
12402                                 DYNAMIC_TYPE_TMP_BUFFER);
12403         if (td == NULL)
12404             err = MEMORY_E;
12405     }
12406 #endif
12407 
12408     if (err == MP_OKAY) {
12409         norm = td;
12410         for (i=0; i<32; i++)
12411             t[i] = td + i * 54;
12412         rt = td + 1728;
12413 
12414         sp_3072_mont_setup(m, &mp);
12415         sp_3072_mont_norm_27(norm, m);
12416 
12417         if (reduceA != 0) {
12418             err = sp_3072_mod_27(t[1], a, m);
12419             if (err == MP_OKAY) {
12420                 sp_3072_mul_27(t[1], t[1], norm);
12421                 err = sp_3072_mod_27(t[1], t[1], m);
12422             }
12423         }
12424         else {
12425             sp_3072_mul_27(t[1], a, norm);
12426             err = sp_3072_mod_27(t[1], t[1], m);
12427         }
12428     }
12429 
12430     if (err == MP_OKAY) {
12431         sp_3072_mont_sqr_27(t[ 2], t[ 1], m, mp);
12432         sp_3072_mont_mul_27(t[ 3], t[ 2], t[ 1], m, mp);
12433         sp_3072_mont_sqr_27(t[ 4], t[ 2], m, mp);
12434         sp_3072_mont_mul_27(t[ 5], t[ 3], t[ 2], m, mp);
12435         sp_3072_mont_sqr_27(t[ 6], t[ 3], m, mp);
12436         sp_3072_mont_mul_27(t[ 7], t[ 4], t[ 3], m, mp);
12437         sp_3072_mont_sqr_27(t[ 8], t[ 4], m, mp);
12438         sp_3072_mont_mul_27(t[ 9], t[ 5], t[ 4], m, mp);
12439         sp_3072_mont_sqr_27(t[10], t[ 5], m, mp);
12440         sp_3072_mont_mul_27(t[11], t[ 6], t[ 5], m, mp);
12441         sp_3072_mont_sqr_27(t[12], t[ 6], m, mp);
12442         sp_3072_mont_mul_27(t[13], t[ 7], t[ 6], m, mp);
12443         sp_3072_mont_sqr_27(t[14], t[ 7], m, mp);
12444         sp_3072_mont_mul_27(t[15], t[ 8], t[ 7], m, mp);
12445         sp_3072_mont_sqr_27(t[16], t[ 8], m, mp);
12446         sp_3072_mont_mul_27(t[17], t[ 9], t[ 8], m, mp);
12447         sp_3072_mont_sqr_27(t[18], t[ 9], m, mp);
12448         sp_3072_mont_mul_27(t[19], t[10], t[ 9], m, mp);
12449         sp_3072_mont_sqr_27(t[20], t[10], m, mp);
12450         sp_3072_mont_mul_27(t[21], t[11], t[10], m, mp);
12451         sp_3072_mont_sqr_27(t[22], t[11], m, mp);
12452         sp_3072_mont_mul_27(t[23], t[12], t[11], m, mp);
12453         sp_3072_mont_sqr_27(t[24], t[12], m, mp);
12454         sp_3072_mont_mul_27(t[25], t[13], t[12], m, mp);
12455         sp_3072_mont_sqr_27(t[26], t[13], m, mp);
12456         sp_3072_mont_mul_27(t[27], t[14], t[13], m, mp);
12457         sp_3072_mont_sqr_27(t[28], t[14], m, mp);
12458         sp_3072_mont_mul_27(t[29], t[15], t[14], m, mp);
12459         sp_3072_mont_sqr_27(t[30], t[15], m, mp);
12460         sp_3072_mont_mul_27(t[31], t[16], t[15], m, mp);
12461 
12462         bits = ((bits + 4) / 5) * 5;
12463         i = ((bits + 56) / 57) - 1;
12464         c = bits % 57;
12465         if (c == 0) {
12466             c = 57;
12467         }
12468         if (i < 27) {
12469             n = e[i--] << (64 - c);
12470         }
12471         else {
12472             n = 0;
12473             i--;
12474         }
12475         if (c < 5) {
12476             n |= e[i--] << (7 - c);
12477             c += 57;
12478         }
12479         y = (int)((n >> 59) & 0x1f);
12480         n <<= 5;
12481         c -= 5;
12482         XMEMCPY(rt, t[y], sizeof(sp_digit) * 54);
12483         while ((i >= 0) || (c >= 5)) {
12484             if (c >= 5) {
12485                 y = (byte)((n >> 59) & 0x1f);
12486                 n <<= 5;
12487                 c -= 5;
12488             }
12489             else if (c == 0) {
12490                 n = e[i--] << 7;
12491                 y = (byte)((n >> 59) & 0x1f);
12492                 n <<= 5;
12493                 c = 52;
12494             }
12495             else {
12496                 y = (byte)((n >> 59) & 0x1f);
12497                 n = e[i--] << 7;
12498                 c = 5 - c;
12499                 y |= (byte)((n >> (64 - c)) & ((1 << c) - 1));
12500                 n <<= c;
12501                 c = 57 - c;
12502             }
12503 
12504             sp_3072_mont_sqr_27(rt, rt, m, mp);
12505             sp_3072_mont_sqr_27(rt, rt, m, mp);
12506             sp_3072_mont_sqr_27(rt, rt, m, mp);
12507             sp_3072_mont_sqr_27(rt, rt, m, mp);
12508             sp_3072_mont_sqr_27(rt, rt, m, mp);
12509 
12510             sp_3072_mont_mul_27(rt, rt, t[y], m, mp);
12511         }
12512 
12513         sp_3072_mont_reduce_27(rt, m, mp);
12514         n = sp_3072_cmp_27(rt, m);
12515         sp_3072_cond_sub_27(rt, rt, m, ((n < 0) ?
12516                    (sp_digit)1 : (sp_digit)0) - 1);
12517         XMEMCPY(r, rt, sizeof(sp_digit) * 54);
12518     }
12519 
12520 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
12521     if (td != NULL)
12522         XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);
12523 #endif
12524 
12525     return err;
12526 #endif
12527 }
12528 
12529 #endif /* (WOLFSSL_HAVE_SP_RSA & !WOLFSSL_RSA_PUBLIC_ONLY) | WOLFSSL_HAVE_SP_DH */
12530 
12531 /* r = 2^n mod m where n is the number of bits to reduce by.
12532  * Given m must be 3072 bits, just need to subtract.
12533  *
12534  * r  A single precision number.
12535  * m  A single precision number.
12536  */
sp_3072_mont_norm_54(sp_digit * r,const sp_digit * m)12537 static void sp_3072_mont_norm_54(sp_digit* r, const sp_digit* m)
12538 {
12539     /* Set r = 2^n - 1. */
12540     int i;
12541 
12542     for (i = 0; i < 48; i += 8) {
12543         r[i + 0] = 0x1ffffffffffffffL;
12544         r[i + 1] = 0x1ffffffffffffffL;
12545         r[i + 2] = 0x1ffffffffffffffL;
12546         r[i + 3] = 0x1ffffffffffffffL;
12547         r[i + 4] = 0x1ffffffffffffffL;
12548         r[i + 5] = 0x1ffffffffffffffL;
12549         r[i + 6] = 0x1ffffffffffffffL;
12550         r[i + 7] = 0x1ffffffffffffffL;
12551     }
12552     r[48] = 0x1ffffffffffffffL;
12553     r[49] = 0x1ffffffffffffffL;
12554     r[50] = 0x1ffffffffffffffL;
12555     r[51] = 0x1ffffffffffffffL;
12556     r[52] = 0x1ffffffffffffffL;
12557     r[53] = 0x7ffffffffffffL;
12558 
12559     /* r = (2^n - 1) mod n */
12560     (void)sp_3072_sub_54(r, r, m);
12561 
12562     /* Add one so r = 2^n mod m */
12563     r[0] += 1;
12564 }
12565 
12566 /* Compare a with b in constant time.
12567  *
12568  * a  A single precision integer.
12569  * b  A single precision integer.
12570  * return -ve, 0 or +ve if a is less than, equal to or greater than b
12571  * respectively.
12572  */
sp_3072_cmp_54(const sp_digit * a,const sp_digit * b)12573 static sp_digit sp_3072_cmp_54(const sp_digit* a, const sp_digit* b)
12574 {
12575     sp_digit r = 0;
12576     int i;
12577 
12578     r |= (a[53] - b[53]) & (0 - (sp_digit)1);
12579     r |= (a[52] - b[52]) & (0 - (sp_digit)((r == 0) ? 1 : 0));
12580     r |= (a[51] - b[51]) & (0 - (sp_digit)((r == 0) ? 1 : 0));
12581     r |= (a[50] - b[50]) & (0 - (sp_digit)((r == 0) ? 1 : 0));
12582     r |= (a[49] - b[49]) & (0 - (sp_digit)((r == 0) ? 1 : 0));
12583     r |= (a[48] - b[48]) & (0 - (sp_digit)((r == 0) ? 1 : 0));
12584     for (i = 40; i >= 0; i -= 8) {
12585         r |= (a[i + 7] - b[i + 7]) & (0 - (sp_digit)((r == 0) ? 1 : 0));
12586         r |= (a[i + 6] - b[i + 6]) & (0 - (sp_digit)((r == 0) ? 1 : 0));
12587         r |= (a[i + 5] - b[i + 5]) & (0 - (sp_digit)((r == 0) ? 1 : 0));
12588         r |= (a[i + 4] - b[i + 4]) & (0 - (sp_digit)((r == 0) ? 1 : 0));
12589         r |= (a[i + 3] - b[i + 3]) & (0 - (sp_digit)((r == 0) ? 1 : 0));
12590         r |= (a[i + 2] - b[i + 2]) & (0 - (sp_digit)((r == 0) ? 1 : 0));
12591         r |= (a[i + 1] - b[i + 1]) & (0 - (sp_digit)((r == 0) ? 1 : 0));
12592         r |= (a[i + 0] - b[i + 0]) & (0 - (sp_digit)((r == 0) ? 1 : 0));
12593     }
12594 
12595     return r;
12596 }
12597 
12598 /* Conditionally subtract b from a using the mask m.
12599  * m is -1 to subtract and 0 when not.
12600  *
12601  * r  A single precision number representing condition subtract result.
12602  * a  A single precision number to subtract from.
12603  * b  A single precision number to subtract.
12604  * m  Mask value to apply.
12605  */
sp_3072_cond_sub_54(sp_digit * r,const sp_digit * a,const sp_digit * b,const sp_digit m)12606 static void sp_3072_cond_sub_54(sp_digit* r, const sp_digit* a,
12607         const sp_digit* b, const sp_digit m)
12608 {
12609     int i;
12610 
12611     for (i = 0; i < 48; i += 8) {
12612         r[i + 0] = a[i + 0] - (b[i + 0] & m);
12613         r[i + 1] = a[i + 1] - (b[i + 1] & m);
12614         r[i + 2] = a[i + 2] - (b[i + 2] & m);
12615         r[i + 3] = a[i + 3] - (b[i + 3] & m);
12616         r[i + 4] = a[i + 4] - (b[i + 4] & m);
12617         r[i + 5] = a[i + 5] - (b[i + 5] & m);
12618         r[i + 6] = a[i + 6] - (b[i + 6] & m);
12619         r[i + 7] = a[i + 7] - (b[i + 7] & m);
12620     }
12621     r[48] = a[48] - (b[48] & m);
12622     r[49] = a[49] - (b[49] & m);
12623     r[50] = a[50] - (b[50] & m);
12624     r[51] = a[51] - (b[51] & m);
12625     r[52] = a[52] - (b[52] & m);
12626     r[53] = a[53] - (b[53] & m);
12627 }
12628 
12629 /* Mul a by scalar b and add into r. (r += a * b)
12630  *
12631  * r  A single precision integer.
12632  * a  A single precision integer.
12633  * b  A scalar.
12634  */
sp_3072_mul_add_54(sp_digit * r,const sp_digit * a,const sp_digit b)12635 SP_NOINLINE static void sp_3072_mul_add_54(sp_digit* r, const sp_digit* a,
12636         const sp_digit b)
12637 {
12638     sp_int128 tb = b;
12639     sp_int128 t[8];
12640     int i;
12641 
12642     t[0] = tb * a[0]; r[0] += (sp_digit)(t[0] & 0x1ffffffffffffffL);
12643     for (i = 0; i < 48; i += 8) {
12644         t[1] = tb * a[i+1];
12645         r[i+1] += (sp_digit)((t[0] >> 57) + (t[1] & 0x1ffffffffffffffL));
12646         t[2] = tb * a[i+2];
12647         r[i+2] += (sp_digit)((t[1] >> 57) + (t[2] & 0x1ffffffffffffffL));
12648         t[3] = tb * a[i+3];
12649         r[i+3] += (sp_digit)((t[2] >> 57) + (t[3] & 0x1ffffffffffffffL));
12650         t[4] = tb * a[i+4];
12651         r[i+4] += (sp_digit)((t[3] >> 57) + (t[4] & 0x1ffffffffffffffL));
12652         t[5] = tb * a[i+5];
12653         r[i+5] += (sp_digit)((t[4] >> 57) + (t[5] & 0x1ffffffffffffffL));
12654         t[6] = tb * a[i+6];
12655         r[i+6] += (sp_digit)((t[5] >> 57) + (t[6] & 0x1ffffffffffffffL));
12656         t[7] = tb * a[i+7];
12657         r[i+7] += (sp_digit)((t[6] >> 57) + (t[7] & 0x1ffffffffffffffL));
12658         t[0] = tb * a[i+8];
12659         r[i+8] += (sp_digit)((t[7] >> 57) + (t[0] & 0x1ffffffffffffffL));
12660     }
12661     t[1] = tb * a[49];
12662     r[49] += (sp_digit)((t[0] >> 57) + (t[1] & 0x1ffffffffffffffL));
12663     t[2] = tb * a[50];
12664     r[50] += (sp_digit)((t[1] >> 57) + (t[2] & 0x1ffffffffffffffL));
12665     t[3] = tb * a[51];
12666     r[51] += (sp_digit)((t[2] >> 57) + (t[3] & 0x1ffffffffffffffL));
12667     t[4] = tb * a[52];
12668     r[52] += (sp_digit)((t[3] >> 57) + (t[4] & 0x1ffffffffffffffL));
12669     t[5] = tb * a[53];
12670     r[53] += (sp_digit)((t[4] >> 57) + (t[5] & 0x1ffffffffffffffL));
12671     r[54] +=  (sp_digit)(t[5] >> 57);
12672 }
12673 
12674 /* Shift the result in the high 3072 bits down to the bottom.
12675  *
12676  * r  A single precision number.
12677  * a  A single precision number.
12678  */
sp_3072_mont_shift_54(sp_digit * r,const sp_digit * a)12679 static void sp_3072_mont_shift_54(sp_digit* r, const sp_digit* a)
12680 {
12681     int i;
12682     sp_int128 n = a[53] >> 51;
12683     n += ((sp_int128)a[54]) << 6;
12684     for (i = 0; i < 48; i += 8) {
12685         r[i + 0] = n & 0x1ffffffffffffffL;
12686         n >>= 57; n += ((sp_int128)a[i + 55]) << 6;
12687         r[i + 1] = n & 0x1ffffffffffffffL;
12688         n >>= 57; n += ((sp_int128)a[i + 56]) << 6;
12689         r[i + 2] = n & 0x1ffffffffffffffL;
12690         n >>= 57; n += ((sp_int128)a[i + 57]) << 6;
12691         r[i + 3] = n & 0x1ffffffffffffffL;
12692         n >>= 57; n += ((sp_int128)a[i + 58]) << 6;
12693         r[i + 4] = n & 0x1ffffffffffffffL;
12694         n >>= 57; n += ((sp_int128)a[i + 59]) << 6;
12695         r[i + 5] = n & 0x1ffffffffffffffL;
12696         n >>= 57; n += ((sp_int128)a[i + 60]) << 6;
12697         r[i + 6] = n & 0x1ffffffffffffffL;
12698         n >>= 57; n += ((sp_int128)a[i + 61]) << 6;
12699         r[i + 7] = n & 0x1ffffffffffffffL;
12700         n >>= 57; n += ((sp_int128)a[i + 62]) << 6;
12701     }
12702     r[48] = n & 0x1ffffffffffffffL; n >>= 57; n += ((sp_int128)a[103]) << 6;
12703     r[49] = n & 0x1ffffffffffffffL; n >>= 57; n += ((sp_int128)a[104]) << 6;
12704     r[50] = n & 0x1ffffffffffffffL; n >>= 57; n += ((sp_int128)a[105]) << 6;
12705     r[51] = n & 0x1ffffffffffffffL; n >>= 57; n += ((sp_int128)a[106]) << 6;
12706     r[52] = n & 0x1ffffffffffffffL; n >>= 57; n += ((sp_int128)a[107]) << 6;
12707     r[53] = (sp_digit)n;
12708     XMEMSET(&r[54], 0, sizeof(*r) * 54U);
12709 }
12710 
12711 /* Reduce the number back to 3072 bits using Montgomery reduction.
12712  *
12713  * a   A single precision number to reduce in place.
12714  * m   The single precision number representing the modulus.
12715  * mp  The digit representing the negative inverse of m mod 2^n.
12716  */
sp_3072_mont_reduce_54(sp_digit * a,const sp_digit * m,sp_digit mp)12717 static void sp_3072_mont_reduce_54(sp_digit* a, const sp_digit* m, sp_digit mp)
12718 {
12719     int i;
12720     sp_digit mu;
12721 
12722     sp_3072_norm_54(a + 54);
12723 
12724 #ifdef WOLFSSL_SP_DH
12725     if (mp != 1) {
12726         for (i=0; i<53; i++) {
12727             mu = (a[i] * mp) & 0x1ffffffffffffffL;
12728             sp_3072_mul_add_54(a+i, m, mu);
12729             a[i+1] += a[i] >> 57;
12730         }
12731         mu = (a[i] * mp) & 0x7ffffffffffffL;
12732         sp_3072_mul_add_54(a+i, m, mu);
12733         a[i+1] += a[i] >> 57;
12734         a[i] &= 0x1ffffffffffffffL;
12735     }
12736     else {
12737         for (i=0; i<53; i++) {
12738             mu = a[i] & 0x1ffffffffffffffL;
12739             sp_3072_mul_add_54(a+i, m, mu);
12740             a[i+1] += a[i] >> 57;
12741         }
12742         mu = a[i] & 0x7ffffffffffffL;
12743         sp_3072_mul_add_54(a+i, m, mu);
12744         a[i+1] += a[i] >> 57;
12745         a[i] &= 0x1ffffffffffffffL;
12746     }
12747 #else
12748     for (i=0; i<53; i++) {
12749         mu = (a[i] * mp) & 0x1ffffffffffffffL;
12750         sp_3072_mul_add_54(a+i, m, mu);
12751         a[i+1] += a[i] >> 57;
12752     }
12753     mu = (a[i] * mp) & 0x7ffffffffffffL;
12754     sp_3072_mul_add_54(a+i, m, mu);
12755     a[i+1] += a[i] >> 57;
12756     a[i] &= 0x1ffffffffffffffL;
12757 #endif
12758     sp_3072_mont_shift_54(a, a);
12759     sp_3072_cond_sub_54(a, a, m, 0 - (((a[53] - m[53]) > 0) ?
12760             (sp_digit)1 : (sp_digit)0));
12761     sp_3072_norm_54(a);
12762 }
12763 
12764 /* Multiply two Montgomery form numbers mod the modulus (prime).
12765  * (r = a * b mod m)
12766  *
12767  * r   Result of multiplication.
12768  * a   First number to multiply in Montgomery form.
12769  * b   Second number to multiply in Montgomery form.
12770  * m   Modulus (prime).
12771  * mp  Montgomery mulitplier.
12772  */
sp_3072_mont_mul_54(sp_digit * r,const sp_digit * a,const sp_digit * b,const sp_digit * m,sp_digit mp)12773 static void sp_3072_mont_mul_54(sp_digit* r, const sp_digit* a,
12774         const sp_digit* b, const sp_digit* m, sp_digit mp)
12775 {
12776     sp_3072_mul_54(r, a, b);
12777     sp_3072_mont_reduce_54(r, m, mp);
12778 }
12779 
12780 /* Square the Montgomery form number. (r = a * a mod m)
12781  *
12782  * r   Result of squaring.
12783  * a   Number to square in Montgomery form.
12784  * m   Modulus (prime).
12785  * mp  Montgomery mulitplier.
12786  */
sp_3072_mont_sqr_54(sp_digit * r,const sp_digit * a,const sp_digit * m,sp_digit mp)12787 static void sp_3072_mont_sqr_54(sp_digit* r, const sp_digit* a,
12788         const sp_digit* m, sp_digit mp)
12789 {
12790     sp_3072_sqr_54(r, a);
12791     sp_3072_mont_reduce_54(r, m, mp);
12792 }
12793 
12794 /* Multiply a by scalar b into r. (r = a * b)
12795  *
12796  * r  A single precision integer.
12797  * a  A single precision integer.
12798  * b  A scalar.
12799  */
sp_3072_mul_d_108(sp_digit * r,const sp_digit * a,sp_digit b)12800 SP_NOINLINE static void sp_3072_mul_d_108(sp_digit* r, const sp_digit* a,
12801     sp_digit b)
12802 {
12803     sp_int128 tb = b;
12804     sp_int128 t = 0;
12805     sp_digit t2;
12806     sp_int128 p[4];
12807     int i;
12808 
12809     for (i = 0; i < 108; i += 4) {
12810         p[0] = tb * a[i + 0];
12811         p[1] = tb * a[i + 1];
12812         p[2] = tb * a[i + 2];
12813         p[3] = tb * a[i + 3];
12814         t += p[0];
12815         t2 = (sp_digit)(t & 0x1ffffffffffffffL);
12816         t >>= 57;
12817         r[i + 0] = (sp_digit)t2;
12818         t += p[1];
12819         t2 = (sp_digit)(t & 0x1ffffffffffffffL);
12820         t >>= 57;
12821         r[i + 1] = (sp_digit)t2;
12822         t += p[2];
12823         t2 = (sp_digit)(t & 0x1ffffffffffffffL);
12824         t >>= 57;
12825         r[i + 2] = (sp_digit)t2;
12826         t += p[3];
12827         t2 = (sp_digit)(t & 0x1ffffffffffffffL);
12828         t >>= 57;
12829         r[i + 3] = (sp_digit)t2;
12830     }
12831     r[108] = (sp_digit)(t & 0x1ffffffffffffffL);
12832 }
12833 
12834 /* Conditionally add a and b using the mask m.
12835  * m is -1 to add and 0 when not.
12836  *
12837  * r  A single precision number representing conditional add result.
12838  * a  A single precision number to add with.
12839  * b  A single precision number to add.
12840  * m  Mask value to apply.
12841  */
sp_3072_cond_add_54(sp_digit * r,const sp_digit * a,const sp_digit * b,const sp_digit m)12842 static void sp_3072_cond_add_54(sp_digit* r, const sp_digit* a,
12843         const sp_digit* b, const sp_digit m)
12844 {
12845     int i;
12846 
12847     for (i = 0; i < 48; i += 8) {
12848         r[i + 0] = a[i + 0] + (b[i + 0] & m);
12849         r[i + 1] = a[i + 1] + (b[i + 1] & m);
12850         r[i + 2] = a[i + 2] + (b[i + 2] & m);
12851         r[i + 3] = a[i + 3] + (b[i + 3] & m);
12852         r[i + 4] = a[i + 4] + (b[i + 4] & m);
12853         r[i + 5] = a[i + 5] + (b[i + 5] & m);
12854         r[i + 6] = a[i + 6] + (b[i + 6] & m);
12855         r[i + 7] = a[i + 7] + (b[i + 7] & m);
12856     }
12857     r[48] = a[48] + (b[48] & m);
12858     r[49] = a[49] + (b[49] & m);
12859     r[50] = a[50] + (b[50] & m);
12860     r[51] = a[51] + (b[51] & m);
12861     r[52] = a[52] + (b[52] & m);
12862     r[53] = a[53] + (b[53] & m);
12863 }
12864 
sp_3072_rshift_54(sp_digit * r,const sp_digit * a,byte n)12865 SP_NOINLINE static void sp_3072_rshift_54(sp_digit* r, const sp_digit* a,
12866         byte n)
12867 {
12868     int i;
12869 
12870     for (i=0; i<48; i += 8) {
12871         r[i+0] = (a[i+0] >> n) | ((a[i+1] << (57 - n)) & 0x1ffffffffffffffL);
12872         r[i+1] = (a[i+1] >> n) | ((a[i+2] << (57 - n)) & 0x1ffffffffffffffL);
12873         r[i+2] = (a[i+2] >> n) | ((a[i+3] << (57 - n)) & 0x1ffffffffffffffL);
12874         r[i+3] = (a[i+3] >> n) | ((a[i+4] << (57 - n)) & 0x1ffffffffffffffL);
12875         r[i+4] = (a[i+4] >> n) | ((a[i+5] << (57 - n)) & 0x1ffffffffffffffL);
12876         r[i+5] = (a[i+5] >> n) | ((a[i+6] << (57 - n)) & 0x1ffffffffffffffL);
12877         r[i+6] = (a[i+6] >> n) | ((a[i+7] << (57 - n)) & 0x1ffffffffffffffL);
12878         r[i+7] = (a[i+7] >> n) | ((a[i+8] << (57 - n)) & 0x1ffffffffffffffL);
12879     }
12880     r[48] = (a[48] >> n) | ((a[49] << (57 - n)) & 0x1ffffffffffffffL);
12881     r[49] = (a[49] >> n) | ((a[50] << (57 - n)) & 0x1ffffffffffffffL);
12882     r[50] = (a[50] >> n) | ((a[51] << (57 - n)) & 0x1ffffffffffffffL);
12883     r[51] = (a[51] >> n) | ((a[52] << (57 - n)) & 0x1ffffffffffffffL);
12884     r[52] = (a[52] >> n) | ((a[53] << (57 - n)) & 0x1ffffffffffffffL);
12885     r[53] = a[53] >> n;
12886 }
12887 
12888 #ifdef WOLFSSL_SP_DIV_64
sp_3072_div_word_54(sp_digit d1,sp_digit d0,sp_digit dv)12889 static WC_INLINE sp_digit sp_3072_div_word_54(sp_digit d1, sp_digit d0,
12890     sp_digit dv)
12891 {
12892     sp_digit d;
12893     sp_digit r;
12894     sp_digit t;
12895 
12896     /* All 57 bits from d1 and top 6 bits from d0. */
12897     d = (d1 << 6) + (d0 >> 51);
12898     r = d / dv;
12899     d -= r * dv;
12900     /* Up to 7 bits in r */
12901     /* Next 6 bits from d0. */
12902     r <<= 6;
12903     d <<= 6;
12904     d += (d0 >> 45) & ((1 << 6) - 1);
12905     t = d / dv;
12906     d -= t * dv;
12907     r += t;
12908     /* Up to 13 bits in r */
12909     /* Next 6 bits from d0. */
12910     r <<= 6;
12911     d <<= 6;
12912     d += (d0 >> 39) & ((1 << 6) - 1);
12913     t = d / dv;
12914     d -= t * dv;
12915     r += t;
12916     /* Up to 19 bits in r */
12917     /* Next 6 bits from d0. */
12918     r <<= 6;
12919     d <<= 6;
12920     d += (d0 >> 33) & ((1 << 6) - 1);
12921     t = d / dv;
12922     d -= t * dv;
12923     r += t;
12924     /* Up to 25 bits in r */
12925     /* Next 6 bits from d0. */
12926     r <<= 6;
12927     d <<= 6;
12928     d += (d0 >> 27) & ((1 << 6) - 1);
12929     t = d / dv;
12930     d -= t * dv;
12931     r += t;
12932     /* Up to 31 bits in r */
12933     /* Next 6 bits from d0. */
12934     r <<= 6;
12935     d <<= 6;
12936     d += (d0 >> 21) & ((1 << 6) - 1);
12937     t = d / dv;
12938     d -= t * dv;
12939     r += t;
12940     /* Up to 37 bits in r */
12941     /* Next 6 bits from d0. */
12942     r <<= 6;
12943     d <<= 6;
12944     d += (d0 >> 15) & ((1 << 6) - 1);
12945     t = d / dv;
12946     d -= t * dv;
12947     r += t;
12948     /* Up to 43 bits in r */
12949     /* Next 6 bits from d0. */
12950     r <<= 6;
12951     d <<= 6;
12952     d += (d0 >> 9) & ((1 << 6) - 1);
12953     t = d / dv;
12954     d -= t * dv;
12955     r += t;
12956     /* Up to 49 bits in r */
12957     /* Next 6 bits from d0. */
12958     r <<= 6;
12959     d <<= 6;
12960     d += (d0 >> 3) & ((1 << 6) - 1);
12961     t = d / dv;
12962     d -= t * dv;
12963     r += t;
12964     /* Up to 55 bits in r */
12965     /* Remaining 3 bits from d0. */
12966     r <<= 3;
12967     d <<= 3;
12968     d += d0 & ((1 << 3) - 1);
12969     t = d / dv;
12970     r += t;
12971 
12972     /* All 57 bits from d1 and top 6 bits from d0. */
12973     return r;
12974 }
12975 #endif /* WOLFSSL_SP_DIV_64 */
12976 
12977 /* Divide d in a and put remainder into r (m*d + r = a)
12978  * m is not calculated as it is not needed at this time.
12979  *
12980  * Full implementation.
12981  *
12982  * a  Number to be divided.
12983  * d  Number to divide with.
12984  * m  Multiplier result.
12985  * r  Remainder from the division.
12986  * returns MEMORY_E when unable to allocate memory and MP_OKAY otherwise.
12987  */
sp_3072_div_54(const sp_digit * a,const sp_digit * d,const sp_digit * m,sp_digit * r)12988 static int sp_3072_div_54(const sp_digit* a, const sp_digit* d,
12989         const sp_digit* m, sp_digit* r)
12990 {
12991     int i;
12992 #ifndef WOLFSSL_SP_DIV_64
12993     sp_int128 d1;
12994 #endif
12995     sp_digit dv;
12996     sp_digit r1;
12997 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
12998     sp_digit* t1 = NULL;
12999 #else
13000     sp_digit t1[4 * 54 + 3];
13001 #endif
13002     sp_digit* t2 = NULL;
13003     sp_digit* sd = NULL;
13004     int err = MP_OKAY;
13005 
13006     (void)m;
13007 
13008 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
13009     t1 = (sp_digit*)XMALLOC(sizeof(sp_digit) * (4 * 54 + 3), NULL,
13010                                                        DYNAMIC_TYPE_TMP_BUFFER);
13011     if (t1 == NULL)
13012         err = MEMORY_E;
13013 #endif
13014 
13015     (void)m;
13016 
13017     if (err == MP_OKAY) {
13018         t2 = t1 + 108 + 1;
13019         sd = t2 + 54 + 1;
13020 
13021         sp_3072_mul_d_54(sd, d, (sp_digit)1 << 6);
13022         sp_3072_mul_d_108(t1, a, (sp_digit)1 << 6);
13023         dv = sd[53];
13024         t1[54 + 54] += t1[54 + 54 - 1] >> 57;
13025         t1[54 + 54 - 1] &= 0x1ffffffffffffffL;
13026         for (i=54; i>=0; i--) {
13027 #ifndef WOLFSSL_SP_DIV_64
13028             d1 = t1[54 + i];
13029             d1 <<= 57;
13030             d1 += t1[54 + i - 1];
13031             r1 = (sp_digit)(d1 / dv);
13032 #else
13033             r1 = sp_3072_div_word_54(t1[54 + i], t1[54 + i - 1], dv);
13034 #endif
13035 
13036             sp_3072_mul_d_54(t2, sd, r1);
13037             (void)sp_3072_sub_54(&t1[i], &t1[i], t2);
13038             sp_3072_norm_54(&t1[i]);
13039             t1[54 + i] -= t2[54];
13040             t1[54 + i] += t1[54 + i - 1] >> 57;
13041             t1[54 + i - 1] &= 0x1ffffffffffffffL;
13042 #ifndef WOLFSSL_SP_DIV_64
13043             d1 = -t1[54 + i];
13044             d1 <<= 57;
13045             d1 -= t1[54 + i - 1];
13046             r1 = (sp_digit)(d1 / dv);
13047 #else
13048             r1 = sp_3072_div_word_54(-t1[54 + i], -t1[54 + i - 1], dv);
13049 #endif
13050             r1 -= t1[54 + i];
13051             sp_3072_mul_d_54(t2, sd, r1);
13052             (void)sp_3072_add_54(&t1[i], &t1[i], t2);
13053             t1[54 + i] += t1[54 + i - 1] >> 57;
13054             t1[54 + i - 1] &= 0x1ffffffffffffffL;
13055         }
13056         t1[54 - 1] += t1[54 - 2] >> 57;
13057         t1[54 - 2] &= 0x1ffffffffffffffL;
13058         r1 = t1[54 - 1] / dv;
13059 
13060         sp_3072_mul_d_54(t2, sd, r1);
13061         sp_3072_sub_54(t1, t1, t2);
13062         XMEMCPY(r, t1, sizeof(*r) * 108U);
13063         for (i=0; i<53; i++) {
13064             r[i+1] += r[i] >> 57;
13065             r[i] &= 0x1ffffffffffffffL;
13066         }
13067         sp_3072_cond_add_54(r, r, sd, 0 - ((r[53] < 0) ?
13068                     (sp_digit)1 : (sp_digit)0));
13069 
13070         sp_3072_norm_54(r);
13071         sp_3072_rshift_54(r, r, 6);
13072     }
13073 
13074 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
13075     if (t1 != NULL)
13076         XFREE(t1, NULL, DYNAMIC_TYPE_TMP_BUFFER);
13077 #endif
13078 
13079     return err;
13080 }
13081 
13082 /* Reduce a modulo m into r. (r = a mod m)
13083  *
13084  * r  A single precision number that is the reduced result.
13085  * a  A single precision number that is to be reduced.
13086  * m  A single precision number that is the modulus to reduce with.
13087  * returns MEMORY_E when unable to allocate memory and MP_OKAY otherwise.
13088  */
sp_3072_mod_54(sp_digit * r,const sp_digit * a,const sp_digit * m)13089 static int sp_3072_mod_54(sp_digit* r, const sp_digit* a, const sp_digit* m)
13090 {
13091     return sp_3072_div_54(a, m, NULL, r);
13092 }
13093 
13094 #if (defined(WOLFSSL_HAVE_SP_RSA) && !defined(WOLFSSL_RSA_PUBLIC_ONLY)) || defined(WOLFSSL_HAVE_SP_DH)
13095 #if (defined(WOLFSSL_HAVE_SP_RSA) && !defined(WOLFSSL_RSA_PUBLIC_ONLY)) || \
13096                                                      defined(WOLFSSL_HAVE_SP_DH)
13097 /* Modular exponentiate a to the e mod m. (r = a^e mod m)
13098  *
13099  * r     A single precision number that is the result of the operation.
13100  * a     A single precision number being exponentiated.
13101  * e     A single precision number that is the exponent.
13102  * bits  The number of bits in the exponent.
13103  * m     A single precision number that is the modulus.
13104  * returns  0 on success.
13105  * returns  MEMORY_E on dynamic memory allocation failure.
13106  * returns  MP_VAL when base is even or exponent is 0.
13107  */
sp_3072_mod_exp_54(sp_digit * r,const sp_digit * a,const sp_digit * e,int bits,const sp_digit * m,int reduceA)13108 static int sp_3072_mod_exp_54(sp_digit* r, const sp_digit* a, const sp_digit* e,
13109     int bits, const sp_digit* m, int reduceA)
13110 {
13111 #if defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SP_FAST_MODEXP)
13112 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
13113     sp_digit* td = NULL;
13114 #else
13115     sp_digit td[3 * 108];
13116 #endif
13117     sp_digit* t[3] = {0, 0, 0};
13118     sp_digit* norm = NULL;
13119     sp_digit mp = 1;
13120     sp_digit n;
13121     int i;
13122     int c;
13123     byte y;
13124     int err = MP_OKAY;
13125 
13126     if ((m[0] & 1) == 0) {
13127         err = MP_VAL;
13128     }
13129     else if (bits == 0) {
13130         err = MP_VAL;
13131     }
13132 
13133 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
13134     if (err == MP_OKAY) {
13135         td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 3 * 54 * 2, NULL,
13136                                 DYNAMIC_TYPE_TMP_BUFFER);
13137         if (td == NULL)
13138             err = MEMORY_E;
13139     }
13140 #endif
13141 
13142     if (err == MP_OKAY) {
13143         norm = td;
13144         for (i=0; i<3; i++) {
13145             t[i] = td + (i * 54 * 2);
13146             XMEMSET(t[i], 0, sizeof(sp_digit) * 54U * 2U);
13147         }
13148 
13149         sp_3072_mont_setup(m, &mp);
13150         sp_3072_mont_norm_54(norm, m);
13151 
13152         if (reduceA != 0) {
13153             err = sp_3072_mod_54(t[1], a, m);
13154         }
13155         else {
13156             XMEMCPY(t[1], a, sizeof(sp_digit) * 54U);
13157         }
13158     }
13159     if (err == MP_OKAY) {
13160         sp_3072_mul_54(t[1], t[1], norm);
13161         err = sp_3072_mod_54(t[1], t[1], m);
13162     }
13163 
13164     if (err == MP_OKAY) {
13165         i = bits / 57;
13166         c = bits % 57;
13167         n = e[i--] << (57 - c);
13168         for (; ; c--) {
13169             if (c == 0) {
13170                 if (i == -1) {
13171                     break;
13172                 }
13173 
13174                 n = e[i--];
13175                 c = 57;
13176             }
13177 
13178             y = (int)((n >> 56) & 1);
13179             n <<= 1;
13180 
13181             sp_3072_mont_mul_54(t[y^1], t[0], t[1], m, mp);
13182 
13183             XMEMCPY(t[2], (void*)(((size_t)t[0] & addr_mask[y^1]) +
13184                                   ((size_t)t[1] & addr_mask[y])),
13185                                   sizeof(*t[2]) * 54 * 2);
13186             sp_3072_mont_sqr_54(t[2], t[2], m, mp);
13187             XMEMCPY((void*)(((size_t)t[0] & addr_mask[y^1]) +
13188                             ((size_t)t[1] & addr_mask[y])), t[2],
13189                             sizeof(*t[2]) * 54 * 2);
13190         }
13191 
13192         sp_3072_mont_reduce_54(t[0], m, mp);
13193         n = sp_3072_cmp_54(t[0], m);
13194         sp_3072_cond_sub_54(t[0], t[0], m, ((n < 0) ?
13195                     (sp_digit)1 : (sp_digit)0) - 1);
13196         XMEMCPY(r, t[0], sizeof(*r) * 54 * 2);
13197 
13198     }
13199 
13200 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
13201     if (td != NULL)
13202         XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);
13203 #endif
13204 
13205     return err;
13206 #elif !defined(WC_NO_CACHE_RESISTANT)
13207 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
13208     sp_digit* td = NULL;
13209 #else
13210     sp_digit td[3 * 108];
13211 #endif
13212     sp_digit* t[3] = {0, 0, 0};
13213     sp_digit* norm = NULL;
13214     sp_digit mp = 1;
13215     sp_digit n;
13216     int i;
13217     int c;
13218     byte y;
13219     int err = MP_OKAY;
13220 
13221     if ((m[0] & 1) == 0) {
13222         err = MP_VAL;
13223     }
13224     else if (bits == 0) {
13225         err = MP_VAL;
13226     }
13227 
13228 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
13229     if (err == MP_OKAY) {
13230         td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 3 * 54 * 2, NULL,
13231                                 DYNAMIC_TYPE_TMP_BUFFER);
13232         if (td == NULL)
13233             err = MEMORY_E;
13234     }
13235 #endif
13236 
13237     if (err == MP_OKAY) {
13238         norm = td;
13239         for (i=0; i<3; i++) {
13240             t[i] = td + (i * 54 * 2);
13241         }
13242 
13243         sp_3072_mont_setup(m, &mp);
13244         sp_3072_mont_norm_54(norm, m);
13245 
13246         if (reduceA != 0) {
13247             err = sp_3072_mod_54(t[1], a, m);
13248             if (err == MP_OKAY) {
13249                 sp_3072_mul_54(t[1], t[1], norm);
13250                 err = sp_3072_mod_54(t[1], t[1], m);
13251             }
13252         }
13253         else {
13254             sp_3072_mul_54(t[1], a, norm);
13255             err = sp_3072_mod_54(t[1], t[1], m);
13256         }
13257     }
13258 
13259     if (err == MP_OKAY) {
13260         i = bits / 57;
13261         c = bits % 57;
13262         n = e[i--] << (57 - c);
13263         for (; ; c--) {
13264             if (c == 0) {
13265                 if (i == -1) {
13266                     break;
13267                 }
13268 
13269                 n = e[i--];
13270                 c = 57;
13271             }
13272 
13273             y = (int)((n >> 56) & 1);
13274             n <<= 1;
13275 
13276             sp_3072_mont_mul_54(t[y^1], t[0], t[1], m, mp);
13277 
13278             XMEMCPY(t[2], (void*)(((size_t)t[0] & addr_mask[y^1]) +
13279                                   ((size_t)t[1] & addr_mask[y])),
13280                                   sizeof(*t[2]) * 54 * 2);
13281             sp_3072_mont_sqr_54(t[2], t[2], m, mp);
13282             XMEMCPY((void*)(((size_t)t[0] & addr_mask[y^1]) +
13283                             ((size_t)t[1] & addr_mask[y])), t[2],
13284                             sizeof(*t[2]) * 54 * 2);
13285         }
13286 
13287         sp_3072_mont_reduce_54(t[0], m, mp);
13288         n = sp_3072_cmp_54(t[0], m);
13289         sp_3072_cond_sub_54(t[0], t[0], m, ((n < 0) ?
13290                     (sp_digit)1 : (sp_digit)0) - 1);
13291         XMEMCPY(r, t[0], sizeof(*r) * 54 * 2);
13292     }
13293 
13294 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
13295     if (td != NULL)
13296         XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);
13297 #endif
13298 
13299     return err;
13300 #else
13301 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
13302     sp_digit* td = NULL;
13303 #else
13304     sp_digit td[(16 * 108) + 108];
13305 #endif
13306     sp_digit* t[16];
13307     sp_digit* rt = NULL;
13308     sp_digit* norm = NULL;
13309     sp_digit mp = 1;
13310     sp_digit n;
13311     int i;
13312     int c;
13313     byte y;
13314     int err = MP_OKAY;
13315 
13316     if ((m[0] & 1) == 0) {
13317         err = MP_VAL;
13318     }
13319     else if (bits == 0) {
13320         err = MP_VAL;
13321     }
13322 
13323 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
13324     if (err == MP_OKAY) {
13325         td = (sp_digit*)XMALLOC(sizeof(sp_digit) * ((16 * 108) + 108), NULL,
13326                                 DYNAMIC_TYPE_TMP_BUFFER);
13327         if (td == NULL)
13328             err = MEMORY_E;
13329     }
13330 #endif
13331 
13332     if (err == MP_OKAY) {
13333         norm = td;
13334         for (i=0; i<16; i++)
13335             t[i] = td + i * 108;
13336         rt = td + 1728;
13337 
13338         sp_3072_mont_setup(m, &mp);
13339         sp_3072_mont_norm_54(norm, m);
13340 
13341         if (reduceA != 0) {
13342             err = sp_3072_mod_54(t[1], a, m);
13343             if (err == MP_OKAY) {
13344                 sp_3072_mul_54(t[1], t[1], norm);
13345                 err = sp_3072_mod_54(t[1], t[1], m);
13346             }
13347         }
13348         else {
13349             sp_3072_mul_54(t[1], a, norm);
13350             err = sp_3072_mod_54(t[1], t[1], m);
13351         }
13352     }
13353 
13354     if (err == MP_OKAY) {
13355         sp_3072_mont_sqr_54(t[ 2], t[ 1], m, mp);
13356         sp_3072_mont_mul_54(t[ 3], t[ 2], t[ 1], m, mp);
13357         sp_3072_mont_sqr_54(t[ 4], t[ 2], m, mp);
13358         sp_3072_mont_mul_54(t[ 5], t[ 3], t[ 2], m, mp);
13359         sp_3072_mont_sqr_54(t[ 6], t[ 3], m, mp);
13360         sp_3072_mont_mul_54(t[ 7], t[ 4], t[ 3], m, mp);
13361         sp_3072_mont_sqr_54(t[ 8], t[ 4], m, mp);
13362         sp_3072_mont_mul_54(t[ 9], t[ 5], t[ 4], m, mp);
13363         sp_3072_mont_sqr_54(t[10], t[ 5], m, mp);
13364         sp_3072_mont_mul_54(t[11], t[ 6], t[ 5], m, mp);
13365         sp_3072_mont_sqr_54(t[12], t[ 6], m, mp);
13366         sp_3072_mont_mul_54(t[13], t[ 7], t[ 6], m, mp);
13367         sp_3072_mont_sqr_54(t[14], t[ 7], m, mp);
13368         sp_3072_mont_mul_54(t[15], t[ 8], t[ 7], m, mp);
13369 
13370         bits = ((bits + 3) / 4) * 4;
13371         i = ((bits + 56) / 57) - 1;
13372         c = bits % 57;
13373         if (c == 0) {
13374             c = 57;
13375         }
13376         if (i < 54) {
13377             n = e[i--] << (64 - c);
13378         }
13379         else {
13380             n = 0;
13381             i--;
13382         }
13383         if (c < 4) {
13384             n |= e[i--] << (7 - c);
13385             c += 57;
13386         }
13387         y = (int)((n >> 60) & 0xf);
13388         n <<= 4;
13389         c -= 4;
13390         XMEMCPY(rt, t[y], sizeof(sp_digit) * 108);
13391         while ((i >= 0) || (c >= 4)) {
13392             if (c >= 4) {
13393                 y = (byte)((n >> 60) & 0xf);
13394                 n <<= 4;
13395                 c -= 4;
13396             }
13397             else if (c == 0) {
13398                 n = e[i--] << 7;
13399                 y = (byte)((n >> 60) & 0xf);
13400                 n <<= 4;
13401                 c = 53;
13402             }
13403             else {
13404                 y = (byte)((n >> 60) & 0xf);
13405                 n = e[i--] << 7;
13406                 c = 4 - c;
13407                 y |= (byte)((n >> (64 - c)) & ((1 << c) - 1));
13408                 n <<= c;
13409                 c = 57 - c;
13410             }
13411 
13412             sp_3072_mont_sqr_54(rt, rt, m, mp);
13413             sp_3072_mont_sqr_54(rt, rt, m, mp);
13414             sp_3072_mont_sqr_54(rt, rt, m, mp);
13415             sp_3072_mont_sqr_54(rt, rt, m, mp);
13416 
13417             sp_3072_mont_mul_54(rt, rt, t[y], m, mp);
13418         }
13419 
13420         sp_3072_mont_reduce_54(rt, m, mp);
13421         n = sp_3072_cmp_54(rt, m);
13422         sp_3072_cond_sub_54(rt, rt, m, ((n < 0) ?
13423                    (sp_digit)1 : (sp_digit)0) - 1);
13424         XMEMCPY(r, rt, sizeof(sp_digit) * 108);
13425     }
13426 
13427 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
13428     if (td != NULL)
13429         XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);
13430 #endif
13431 
13432     return err;
13433 #endif
13434 }
13435 #endif /* (WOLFSSL_HAVE_SP_RSA & !WOLFSSL_RSA_PUBLIC_ONLY) || */
13436        /* WOLFSSL_HAVE_SP_DH */
13437 
13438 #endif /* (WOLFSSL_HAVE_SP_RSA && !WOLFSSL_RSA_PUBLIC_ONLY) || WOLFSSL_HAVE_SP_DH */
13439 #ifdef WOLFSSL_HAVE_SP_RSA
13440 /* RSA public key operation.
13441  *
13442  * in      Array of bytes representing the number to exponentiate, base.
13443  * inLen   Number of bytes in base.
13444  * em      Public exponent.
13445  * mm      Modulus.
13446  * out     Buffer to hold big-endian bytes of exponentiation result.
13447  *         Must be at least 384 bytes long.
13448  * outLen  Number of bytes in result.
13449  * returns 0 on success, MP_TO_E when the outLen is too small, MP_READ_E when
13450  * an array is too long and MEMORY_E when dynamic memory allocation fails.
13451  */
sp_RsaPublic_3072(const byte * in,word32 inLen,const mp_int * em,const mp_int * mm,byte * out,word32 * outLen)13452 int sp_RsaPublic_3072(const byte* in, word32 inLen, const mp_int* em,
13453     const mp_int* mm, byte* out, word32* outLen)
13454 {
13455 #ifdef WOLFSSL_SP_SMALL
13456 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
13457     sp_digit* a = NULL;
13458 #else
13459     sp_digit a[54 * 5];
13460 #endif
13461     sp_digit* m = NULL;
13462     sp_digit* r = NULL;
13463     sp_digit* norm = NULL;
13464     sp_digit e[1] = {0};
13465     sp_digit mp;
13466     int i;
13467     int err = MP_OKAY;
13468 
13469     if (*outLen < 384U) {
13470         err = MP_TO_E;
13471     }
13472 
13473     if (err == MP_OKAY) {
13474         if (mp_count_bits(em) > 57) {
13475             err = MP_READ_E;
13476         }
13477         else if (inLen > 384U) {
13478             err = MP_READ_E;
13479         }
13480         else if (mp_count_bits(mm) != 3072) {
13481             err = MP_READ_E;
13482         }
13483         else if (mp_iseven(mm)) {
13484             err = MP_VAL;
13485         }
13486     }
13487 
13488 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
13489     if (err == MP_OKAY) {
13490         a = (sp_digit*)XMALLOC(sizeof(sp_digit) * 54 * 5, NULL,
13491                                                               DYNAMIC_TYPE_RSA);
13492         if (a == NULL)
13493             err = MEMORY_E;
13494     }
13495 #endif
13496 
13497     if (err == MP_OKAY) {
13498         r = a + 54 * 2;
13499         m = r + 54 * 2;
13500         norm = r;
13501 
13502         sp_3072_from_bin(a, 54, in, inLen);
13503 #if DIGIT_BIT >= 57
13504         e[0] = (sp_digit)em->dp[0];
13505 #else
13506         e[0] = (sp_digit)em->dp[0];
13507         if (em->used > 1) {
13508             e[0] |= ((sp_digit)em->dp[1]) << DIGIT_BIT;
13509         }
13510 #endif
13511         if (e[0] == 0) {
13512             err = MP_EXPTMOD_E;
13513         }
13514     }
13515 
13516     if (err == MP_OKAY) {
13517         sp_3072_from_mp(m, 54, mm);
13518 
13519         sp_3072_mont_setup(m, &mp);
13520         sp_3072_mont_norm_54(norm, m);
13521     }
13522     if (err == MP_OKAY) {
13523         sp_3072_mul_54(a, a, norm);
13524         err = sp_3072_mod_54(a, a, m);
13525     }
13526     if (err == MP_OKAY) {
13527         for (i=56; i>=0; i--) {
13528             if ((e[0] >> i) != 0) {
13529                 break;
13530             }
13531         }
13532 
13533         XMEMCPY(r, a, sizeof(sp_digit) * 54 * 2);
13534         for (i--; i>=0; i--) {
13535             sp_3072_mont_sqr_54(r, r, m, mp);
13536 
13537             if (((e[0] >> i) & 1) == 1) {
13538                 sp_3072_mont_mul_54(r, r, a, m, mp);
13539             }
13540         }
13541         sp_3072_mont_reduce_54(r, m, mp);
13542         mp = sp_3072_cmp_54(r, m);
13543         sp_3072_cond_sub_54(r, r, m, ((mp < 0) ?
13544                     (sp_digit)1 : (sp_digit)0)- 1);
13545 
13546         sp_3072_to_bin_54(r, out);
13547         *outLen = 384;
13548     }
13549 
13550 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
13551     if (a != NULL)
13552         XFREE(a, NULL, DYNAMIC_TYPE_RSA);
13553 #endif
13554 
13555     return err;
13556 #else
13557 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
13558     sp_digit* d = NULL;
13559 #else
13560     sp_digit d[54 * 5];
13561 #endif
13562     sp_digit* a = NULL;
13563     sp_digit* m = NULL;
13564     sp_digit* r = NULL;
13565     sp_digit e[1] = {0};
13566     int err = MP_OKAY;
13567 
13568     if (*outLen < 384U) {
13569         err = MP_TO_E;
13570     }
13571     if (err == MP_OKAY) {
13572         if (mp_count_bits(em) > 57) {
13573             err = MP_READ_E;
13574         }
13575         else if (inLen > 384U) {
13576             err = MP_READ_E;
13577         }
13578         else if (mp_count_bits(mm) != 3072) {
13579             err = MP_READ_E;
13580         }
13581         else if (mp_iseven(mm)) {
13582             err = MP_VAL;
13583         }
13584     }
13585 
13586 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
13587     if (err == MP_OKAY) {
13588         d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 54 * 5, NULL,
13589                                                               DYNAMIC_TYPE_RSA);
13590         if (d == NULL)
13591             err = MEMORY_E;
13592     }
13593 #endif
13594 
13595     if (err == MP_OKAY) {
13596         a = d;
13597         r = a + 54 * 2;
13598         m = r + 54 * 2;
13599 
13600         sp_3072_from_bin(a, 54, in, inLen);
13601 #if DIGIT_BIT >= 57
13602         e[0] = (sp_digit)em->dp[0];
13603 #else
13604         e[0] = (sp_digit)em->dp[0];
13605         if (em->used > 1) {
13606             e[0] |= ((sp_digit)em->dp[1]) << DIGIT_BIT;
13607         }
13608 #endif
13609         if (e[0] == 0) {
13610             err = MP_EXPTMOD_E;
13611         }
13612     }
13613     if (err == MP_OKAY) {
13614         sp_3072_from_mp(m, 54, mm);
13615 
13616         if (e[0] == 0x3) {
13617             sp_3072_sqr_54(r, a);
13618             err = sp_3072_mod_54(r, r, m);
13619             if (err == MP_OKAY) {
13620                 sp_3072_mul_54(r, a, r);
13621                 err = sp_3072_mod_54(r, r, m);
13622             }
13623         }
13624         else {
13625             sp_digit* norm = r;
13626             int i;
13627             sp_digit mp;
13628 
13629             sp_3072_mont_setup(m, &mp);
13630             sp_3072_mont_norm_54(norm, m);
13631 
13632             sp_3072_mul_54(a, a, norm);
13633             err = sp_3072_mod_54(a, a, m);
13634 
13635             if (err == MP_OKAY) {
13636                 for (i=56; i>=0; i--) {
13637                     if ((e[0] >> i) != 0) {
13638                         break;
13639                     }
13640                 }
13641 
13642                 XMEMCPY(r, a, sizeof(sp_digit) * 108U);
13643                 for (i--; i>=0; i--) {
13644                     sp_3072_mont_sqr_54(r, r, m, mp);
13645 
13646                     if (((e[0] >> i) & 1) == 1) {
13647                         sp_3072_mont_mul_54(r, r, a, m, mp);
13648                     }
13649                 }
13650                 sp_3072_mont_reduce_54(r, m, mp);
13651                 mp = sp_3072_cmp_54(r, m);
13652                 sp_3072_cond_sub_54(r, r, m, ((mp < 0) ?
13653                            (sp_digit)1 : (sp_digit)0) - 1);
13654             }
13655         }
13656     }
13657 
13658     if (err == MP_OKAY) {
13659         sp_3072_to_bin_54(r, out);
13660         *outLen = 384;
13661     }
13662 
13663 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
13664     if (d != NULL)
13665         XFREE(d, NULL, DYNAMIC_TYPE_RSA);
13666 #endif
13667 
13668     return err;
13669 #endif /* WOLFSSL_SP_SMALL */
13670 }
13671 
13672 #ifndef WOLFSSL_RSA_PUBLIC_ONLY
13673 #if !defined(SP_RSA_PRIVATE_EXP_D) && !defined(RSA_LOW_MEM)
13674 #endif /* !SP_RSA_PRIVATE_EXP_D & !RSA_LOW_MEM */
13675 /* RSA private key operation.
13676  *
13677  * in      Array of bytes representing the number to exponentiate, base.
13678  * inLen   Number of bytes in base.
13679  * dm      Private exponent.
13680  * pm      First prime.
13681  * qm      Second prime.
13682  * dpm     First prime's CRT exponent.
13683  * dqm     Second prime's CRT exponent.
13684  * qim     Inverse of second prime mod p.
13685  * mm      Modulus.
13686  * out     Buffer to hold big-endian bytes of exponentiation result.
13687  *         Must be at least 384 bytes long.
13688  * outLen  Number of bytes in result.
13689  * returns 0 on success, MP_TO_E when the outLen is too small, MP_READ_E when
13690  * an array is too long and MEMORY_E when dynamic memory allocation fails.
13691  */
sp_RsaPrivate_3072(const byte * in,word32 inLen,const mp_int * dm,const mp_int * pm,const mp_int * qm,const mp_int * dpm,const mp_int * dqm,const mp_int * qim,const mp_int * mm,byte * out,word32 * outLen)13692 int sp_RsaPrivate_3072(const byte* in, word32 inLen, const mp_int* dm,
13693     const mp_int* pm, const mp_int* qm, const mp_int* dpm, const mp_int* dqm,
13694     const mp_int* qim, const mp_int* mm, byte* out, word32* outLen)
13695 {
13696 #if defined(SP_RSA_PRIVATE_EXP_D) || defined(RSA_LOW_MEM)
13697 #if defined(WOLFSSL_SP_SMALL)
13698 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
13699     sp_digit* d = NULL;
13700 #else
13701     sp_digit  d[54 * 4];
13702 #endif
13703     sp_digit* a = NULL;
13704     sp_digit* m = NULL;
13705     sp_digit* r = NULL;
13706     int err = MP_OKAY;
13707 
13708     (void)pm;
13709     (void)qm;
13710     (void)dpm;
13711     (void)dqm;
13712     (void)qim;
13713 
13714     if (*outLen < 384U) {
13715         err = MP_TO_E;
13716     }
13717     if (err == MP_OKAY) {
13718         if (mp_count_bits(dm) > 3072) {
13719            err = MP_READ_E;
13720         }
13721         else if (inLen > 384) {
13722             err = MP_READ_E;
13723         }
13724         else if (mp_count_bits(mm) != 3072) {
13725             err = MP_READ_E;
13726         }
13727         else if (mp_iseven(mm)) {
13728             err = MP_VAL;
13729         }
13730     }
13731 
13732 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
13733     if (err == MP_OKAY) {
13734         d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 54 * 4, NULL,
13735                                                               DYNAMIC_TYPE_RSA);
13736         if (d == NULL)
13737             err = MEMORY_E;
13738     }
13739 #endif
13740 
13741     if (err == MP_OKAY) {
13742         a = d + 54;
13743         m = a + 108;
13744         r = a;
13745 
13746         sp_3072_from_bin(a, 54, in, inLen);
13747         sp_3072_from_mp(d, 54, dm);
13748         sp_3072_from_mp(m, 54, mm);
13749         err = sp_3072_mod_exp_54(r, a, d, 3072, m, 0);
13750     }
13751 
13752     if (err == MP_OKAY) {
13753         sp_3072_to_bin_54(r, out);
13754         *outLen = 384;
13755     }
13756 
13757 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
13758     if (d != NULL)
13759 #endif
13760     {
13761         /* only "a" and "r" are sensitive and need zeroized (same pointer) */
13762         if (a != NULL)
13763             ForceZero(a, sizeof(sp_digit) * 54);
13764 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
13765         XFREE(d, NULL, DYNAMIC_TYPE_RSA);
13766 #endif
13767     }
13768 
13769     return err;
13770 #else
13771 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
13772     sp_digit* d = NULL;
13773 #else
13774     sp_digit d[54 * 4];
13775 #endif
13776     sp_digit* a = NULL;
13777     sp_digit* m = NULL;
13778     sp_digit* r = NULL;
13779     int err = MP_OKAY;
13780 
13781     (void)pm;
13782     (void)qm;
13783     (void)dpm;
13784     (void)dqm;
13785     (void)qim;
13786 
13787     if (*outLen < 384U) {
13788         err = MP_TO_E;
13789     }
13790     if (err == MP_OKAY) {
13791         if (mp_count_bits(dm) > 3072) {
13792             err = MP_READ_E;
13793         }
13794         else if (inLen > 384U) {
13795             err = MP_READ_E;
13796         }
13797         else if (mp_count_bits(mm) != 3072) {
13798             err = MP_READ_E;
13799         }
13800         else if (mp_iseven(mm)) {
13801             err = MP_VAL;
13802         }
13803     }
13804 
13805 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
13806     if (err == MP_OKAY) {
13807         d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 54 * 4, NULL,
13808                                                               DYNAMIC_TYPE_RSA);
13809         if (d == NULL)
13810             err = MEMORY_E;
13811     }
13812 #endif
13813 
13814     if (err == MP_OKAY) {
13815         a = d + 54;
13816         m = a + 108;
13817         r = a;
13818 
13819         sp_3072_from_bin(a, 54, in, inLen);
13820         sp_3072_from_mp(d, 54, dm);
13821         sp_3072_from_mp(m, 54, mm);
13822         err = sp_3072_mod_exp_54(r, a, d, 3072, m, 0);
13823     }
13824 
13825     if (err == MP_OKAY) {
13826         sp_3072_to_bin_54(r, out);
13827         *outLen = 384;
13828     }
13829 
13830 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
13831     if (d != NULL)
13832 #endif
13833     {
13834         /* only "a" and "r" are sensitive and need zeroized (same pointer) */
13835         if (a != NULL)
13836             ForceZero(a, sizeof(sp_digit) * 54);
13837 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
13838         XFREE(d, NULL, DYNAMIC_TYPE_RSA);
13839 #endif
13840     }
13841 
13842     return err;
13843 #endif /* WOLFSSL_SP_SMALL */
13844 #else
13845 #if defined(WOLFSSL_SP_SMALL)
13846 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
13847     sp_digit* a = NULL;
13848 #else
13849     sp_digit a[27 * 8];
13850 #endif
13851     sp_digit* p = NULL;
13852     sp_digit* dp = NULL;
13853     sp_digit* dq = NULL;
13854     sp_digit* qi = NULL;
13855     sp_digit* tmpa = NULL;
13856     sp_digit* tmpb = NULL;
13857     sp_digit* r = NULL;
13858     int err = MP_OKAY;
13859 
13860     (void)dm;
13861     (void)mm;
13862 
13863     if (*outLen < 384U) {
13864         err = MP_TO_E;
13865     }
13866     if (err == MP_OKAY) {
13867         if (inLen > 384) {
13868             err = MP_READ_E;
13869         }
13870         else if (mp_count_bits(mm) != 3072) {
13871             err = MP_READ_E;
13872         }
13873         else if (mp_iseven(mm)) {
13874             err = MP_VAL;
13875         }
13876     }
13877 
13878 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
13879     if (err == MP_OKAY) {
13880         a = (sp_digit*)XMALLOC(sizeof(sp_digit) * 27 * 8, NULL,
13881                                                               DYNAMIC_TYPE_RSA);
13882         if (a == NULL)
13883             err = MEMORY_E;
13884     }
13885 #endif
13886     if (err == MP_OKAY) {
13887         p = a + 54;
13888         qi = dq = dp = p + 27;
13889         tmpa = qi + 27;
13890         tmpb = tmpa + 54;
13891         r = a;
13892 
13893         sp_3072_from_bin(a, 54, in, inLen);
13894         sp_3072_from_mp(p, 27, pm);
13895         sp_3072_from_mp(dp, 27, dpm);
13896         err = sp_3072_mod_exp_27(tmpa, a, dp, 1536, p, 1);
13897     }
13898     if (err == MP_OKAY) {
13899         sp_3072_from_mp(p, 27, qm);
13900         sp_3072_from_mp(dq, 27, dqm);
13901         err = sp_3072_mod_exp_27(tmpb, a, dq, 1536, p, 1);
13902     }
13903     if (err == MP_OKAY) {
13904         sp_3072_from_mp(p, 27, pm);
13905         (void)sp_3072_sub_27(tmpa, tmpa, tmpb);
13906         sp_3072_norm_27(tmpa);
13907         sp_3072_cond_add_27(tmpa, tmpa, p, 0 - ((sp_int_digit)tmpa[26] >> 63));
13908         sp_3072_cond_add_27(tmpa, tmpa, p, 0 - ((sp_int_digit)tmpa[26] >> 63));
13909         sp_3072_norm_27(tmpa);
13910 
13911         sp_3072_from_mp(qi, 27, qim);
13912         sp_3072_mul_27(tmpa, tmpa, qi);
13913         err = sp_3072_mod_27(tmpa, tmpa, p);
13914     }
13915 
13916     if (err == MP_OKAY) {
13917         sp_3072_from_mp(p, 27, qm);
13918         sp_3072_mul_27(tmpa, p, tmpa);
13919         (void)sp_3072_add_54(r, tmpb, tmpa);
13920         sp_3072_norm_54(r);
13921 
13922         sp_3072_to_bin_54(r, out);
13923         *outLen = 384;
13924     }
13925 
13926 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
13927     if (a != NULL)
13928 #endif
13929     {
13930         ForceZero(a, sizeof(sp_digit) * 27 * 8);
13931 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
13932         XFREE(a, NULL, DYNAMIC_TYPE_RSA);
13933 #endif
13934     }
13935 
13936     return err;
13937 #else
13938 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
13939     sp_digit* a = NULL;
13940 #else
13941     sp_digit a[27 * 13];
13942 #endif
13943     sp_digit* p = NULL;
13944     sp_digit* q = NULL;
13945     sp_digit* dp = NULL;
13946     sp_digit* dq = NULL;
13947     sp_digit* qi = NULL;
13948     sp_digit* tmpa = NULL;
13949     sp_digit* tmpb = NULL;
13950     sp_digit* r = NULL;
13951     int err = MP_OKAY;
13952 
13953     (void)dm;
13954     (void)mm;
13955 
13956     if (*outLen < 384U) {
13957         err = MP_TO_E;
13958     }
13959     if (err == MP_OKAY) {
13960         if (inLen > 384U) {
13961             err = MP_READ_E;
13962         }
13963         else if (mp_count_bits(mm) != 3072) {
13964             err = MP_READ_E;
13965         }
13966         else if (mp_iseven(mm)) {
13967             err = MP_VAL;
13968         }
13969     }
13970 
13971 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
13972     if (err == MP_OKAY) {
13973         a = (sp_digit*)XMALLOC(sizeof(sp_digit) * 27 * 13, NULL,
13974                                                               DYNAMIC_TYPE_RSA);
13975         if (a == NULL)
13976             err = MEMORY_E;
13977     }
13978 #endif
13979 
13980     if (err == MP_OKAY) {
13981         p = a + 54 * 2;
13982         q = p + 27;
13983         dp = q + 27;
13984         dq = dp + 27;
13985         qi = dq + 27;
13986         tmpa = qi + 27;
13987         tmpb = tmpa + 54;
13988         r = a;
13989 
13990         sp_3072_from_bin(a, 54, in, inLen);
13991         sp_3072_from_mp(p, 27, pm);
13992         sp_3072_from_mp(q, 27, qm);
13993         sp_3072_from_mp(dp, 27, dpm);
13994         sp_3072_from_mp(dq, 27, dqm);
13995         sp_3072_from_mp(qi, 27, qim);
13996 
13997         err = sp_3072_mod_exp_27(tmpa, a, dp, 1536, p, 1);
13998     }
13999     if (err == MP_OKAY) {
14000         err = sp_3072_mod_exp_27(tmpb, a, dq, 1536, q, 1);
14001     }
14002 
14003     if (err == MP_OKAY) {
14004         (void)sp_3072_sub_27(tmpa, tmpa, tmpb);
14005         sp_3072_norm_27(tmpa);
14006         sp_3072_cond_add_27(tmpa, tmpa, p, 0 - ((sp_int_digit)tmpa[26] >> 63));
14007         sp_3072_cond_add_27(tmpa, tmpa, p, 0 - ((sp_int_digit)tmpa[26] >> 63));
14008         sp_3072_norm_27(tmpa);
14009         sp_3072_mul_27(tmpa, tmpa, qi);
14010         err = sp_3072_mod_27(tmpa, tmpa, p);
14011     }
14012 
14013     if (err == MP_OKAY) {
14014         sp_3072_mul_27(tmpa, tmpa, q);
14015         (void)sp_3072_add_54(r, tmpb, tmpa);
14016         sp_3072_norm_54(r);
14017 
14018         sp_3072_to_bin_54(r, out);
14019         *outLen = 384;
14020     }
14021 
14022 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
14023 if (a != NULL)
14024 #endif
14025     {
14026         ForceZero(a, sizeof(sp_digit) * 27 * 13);
14027     #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
14028         XFREE(a, NULL, DYNAMIC_TYPE_RSA);
14029     #endif
14030     }
14031 
14032     return err;
14033 #endif /* WOLFSSL_SP_SMALL */
14034 #endif /* SP_RSA_PRIVATE_EXP_D || RSA_LOW_MEM */
14035 }
14036 
14037 #endif /* !WOLFSSL_RSA_PUBLIC_ONLY */
14038 #endif /* WOLFSSL_HAVE_SP_RSA */
14039 #if defined(WOLFSSL_HAVE_SP_DH) || (defined(WOLFSSL_HAVE_SP_RSA) && \
14040                                               !defined(WOLFSSL_RSA_PUBLIC_ONLY))
14041 /* Convert an array of sp_digit to an mp_int.
14042  *
14043  * a  A single precision integer.
14044  * r  A multi-precision integer.
14045  */
sp_3072_to_mp(const sp_digit * a,mp_int * r)14046 static int sp_3072_to_mp(const sp_digit* a, mp_int* r)
14047 {
14048     int err;
14049 
14050     err = mp_grow(r, (3072 + DIGIT_BIT - 1) / DIGIT_BIT);
14051     if (err == MP_OKAY) { /*lint !e774 case where err is always MP_OKAY*/
14052 #if DIGIT_BIT == 57
14053         XMEMCPY(r->dp, a, sizeof(sp_digit) * 54);
14054         r->used = 54;
14055         mp_clamp(r);
14056 #elif DIGIT_BIT < 57
14057         int i;
14058         int j = 0;
14059         int s = 0;
14060 
14061         r->dp[0] = 0;
14062         for (i = 0; i < 54; i++) {
14063             r->dp[j] |= (mp_digit)(a[i] << s);
14064             r->dp[j] &= ((sp_digit)1 << DIGIT_BIT) - 1;
14065             s = DIGIT_BIT - s;
14066             r->dp[++j] = (mp_digit)(a[i] >> s);
14067             while (s + DIGIT_BIT <= 57) {
14068                 s += DIGIT_BIT;
14069                 r->dp[j++] &= ((sp_digit)1 << DIGIT_BIT) - 1;
14070                 if (s == SP_WORD_SIZE) {
14071                     r->dp[j] = 0;
14072                 }
14073                 else {
14074                     r->dp[j] = (mp_digit)(a[i] >> s);
14075                 }
14076             }
14077             s = 57 - s;
14078         }
14079         r->used = (3072 + DIGIT_BIT - 1) / DIGIT_BIT;
14080         mp_clamp(r);
14081 #else
14082         int i;
14083         int j = 0;
14084         int s = 0;
14085 
14086         r->dp[0] = 0;
14087         for (i = 0; i < 54; i++) {
14088             r->dp[j] |= ((mp_digit)a[i]) << s;
14089             if (s + 57 >= DIGIT_BIT) {
14090     #if DIGIT_BIT != 32 && DIGIT_BIT != 64
14091                 r->dp[j] &= ((sp_digit)1 << DIGIT_BIT) - 1;
14092     #endif
14093                 s = DIGIT_BIT - s;
14094                 r->dp[++j] = a[i] >> s;
14095                 s = 57 - s;
14096             }
14097             else {
14098                 s += 57;
14099             }
14100         }
14101         r->used = (3072 + DIGIT_BIT - 1) / DIGIT_BIT;
14102         mp_clamp(r);
14103 #endif
14104     }
14105 
14106     return err;
14107 }
14108 
14109 /* Perform the modular exponentiation for Diffie-Hellman.
14110  *
14111  * base  Base. MP integer.
14112  * exp   Exponent. MP integer.
14113  * mod   Modulus. MP integer.
14114  * res   Result. MP integer.
14115  * returns 0 on success, MP_READ_E if there are too many bytes in an array
14116  * and MEMORY_E if memory allocation fails.
14117  */
sp_ModExp_3072(const mp_int * base,const mp_int * exp,const mp_int * mod,mp_int * res)14118 int sp_ModExp_3072(const mp_int* base, const mp_int* exp, const mp_int* mod,
14119     mp_int* res)
14120 {
14121 #ifdef WOLFSSL_SP_SMALL
14122     int err = MP_OKAY;
14123 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
14124     sp_digit* b = NULL;
14125 #else
14126     sp_digit b[54 * 4];
14127 #endif
14128     sp_digit* e = NULL;
14129     sp_digit* m = NULL;
14130     sp_digit* r = NULL;
14131     int expBits = mp_count_bits(exp);
14132 
14133     if (mp_count_bits(base) > 3072) {
14134         err = MP_READ_E;
14135     }
14136     else if (expBits > 3072) {
14137         err = MP_READ_E;
14138     }
14139     else if (mp_count_bits(mod) != 3072) {
14140         err = MP_READ_E;
14141     }
14142     else if (mp_iseven(mod)) {
14143         err = MP_VAL;
14144     }
14145 
14146 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
14147     if (err == MP_OKAY) {
14148         b = (sp_digit*)XMALLOC(sizeof(sp_digit) * 54 * 4, NULL,
14149             DYNAMIC_TYPE_DH);
14150         if (b == NULL)
14151             err = MEMORY_E;
14152     }
14153 #endif
14154 
14155     if (err == MP_OKAY) {
14156         e = b + 54 * 2;
14157         m = e + 54;
14158         r = b;
14159 
14160         sp_3072_from_mp(b, 54, base);
14161         sp_3072_from_mp(e, 54, exp);
14162         sp_3072_from_mp(m, 54, mod);
14163 
14164         err = sp_3072_mod_exp_54(r, b, e, mp_count_bits(exp), m, 0);
14165     }
14166 
14167     if (err == MP_OKAY) {
14168         err = sp_3072_to_mp(r, res);
14169     }
14170 
14171 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
14172     if (b != NULL)
14173 #endif
14174     {
14175         /* only "e" is sensitive and needs zeroized */
14176         if (e != NULL)
14177             ForceZero(e, sizeof(sp_digit) * 54U);
14178     #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
14179         XFREE(b, NULL, DYNAMIC_TYPE_DH);
14180     #endif
14181     }
14182     return err;
14183 #else
14184 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
14185     sp_digit* b = NULL;
14186 #else
14187     sp_digit b[54 * 4];
14188 #endif
14189     sp_digit* e = NULL;
14190     sp_digit* m = NULL;
14191     sp_digit* r = NULL;
14192     int err = MP_OKAY;
14193     int expBits = mp_count_bits(exp);
14194 
14195     if (mp_count_bits(base) > 3072) {
14196         err = MP_READ_E;
14197     }
14198     else if (expBits > 3072) {
14199         err = MP_READ_E;
14200     }
14201     else if (mp_count_bits(mod) != 3072) {
14202         err = MP_READ_E;
14203     }
14204     else if (mp_iseven(mod)) {
14205         err = MP_VAL;
14206     }
14207 
14208 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
14209     if (err == MP_OKAY) {
14210         b = (sp_digit*)XMALLOC(sizeof(sp_digit) * 54 * 4, NULL, DYNAMIC_TYPE_DH);
14211         if (b == NULL)
14212             err = MEMORY_E;
14213     }
14214 #endif
14215 
14216     if (err == MP_OKAY) {
14217         e = b + 54 * 2;
14218         m = e + 54;
14219         r = b;
14220 
14221         sp_3072_from_mp(b, 54, base);
14222         sp_3072_from_mp(e, 54, exp);
14223         sp_3072_from_mp(m, 54, mod);
14224 
14225         err = sp_3072_mod_exp_54(r, b, e, expBits, m, 0);
14226     }
14227 
14228     if (err == MP_OKAY) {
14229         err = sp_3072_to_mp(r, res);
14230     }
14231 
14232 
14233 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
14234     if (b != NULL)
14235 #endif
14236     {
14237         /* only "e" is sensitive and needs zeroized */
14238         if (e != NULL)
14239             ForceZero(e, sizeof(sp_digit) * 54U);
14240     #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
14241         XFREE(b, NULL, DYNAMIC_TYPE_DH);
14242     #endif
14243     }
14244 
14245     return err;
14246 #endif
14247 }
14248 
14249 #ifdef WOLFSSL_HAVE_SP_DH
14250 
14251 #ifdef HAVE_FFDHE_3072
sp_3072_lshift_54(sp_digit * r,const sp_digit * a,byte n)14252 SP_NOINLINE static void sp_3072_lshift_54(sp_digit* r, const sp_digit* a,
14253         byte n)
14254 {
14255     sp_int_digit s;
14256     sp_int_digit t;
14257 
14258     s = (sp_int_digit)a[53];
14259     r[54] = s >> (57U - n);
14260     s = (sp_int_digit)(a[53]); t = (sp_int_digit)(a[52]);
14261     r[53] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;
14262     s = (sp_int_digit)(a[52]); t = (sp_int_digit)(a[51]);
14263     r[52] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;
14264     s = (sp_int_digit)(a[51]); t = (sp_int_digit)(a[50]);
14265     r[51] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;
14266     s = (sp_int_digit)(a[50]); t = (sp_int_digit)(a[49]);
14267     r[50] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;
14268     s = (sp_int_digit)(a[49]); t = (sp_int_digit)(a[48]);
14269     r[49] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;
14270     s = (sp_int_digit)(a[48]); t = (sp_int_digit)(a[47]);
14271     r[48] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;
14272     s = (sp_int_digit)(a[47]); t = (sp_int_digit)(a[46]);
14273     r[47] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;
14274     s = (sp_int_digit)(a[46]); t = (sp_int_digit)(a[45]);
14275     r[46] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;
14276     s = (sp_int_digit)(a[45]); t = (sp_int_digit)(a[44]);
14277     r[45] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;
14278     s = (sp_int_digit)(a[44]); t = (sp_int_digit)(a[43]);
14279     r[44] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;
14280     s = (sp_int_digit)(a[43]); t = (sp_int_digit)(a[42]);
14281     r[43] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;
14282     s = (sp_int_digit)(a[42]); t = (sp_int_digit)(a[41]);
14283     r[42] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;
14284     s = (sp_int_digit)(a[41]); t = (sp_int_digit)(a[40]);
14285     r[41] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;
14286     s = (sp_int_digit)(a[40]); t = (sp_int_digit)(a[39]);
14287     r[40] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;
14288     s = (sp_int_digit)(a[39]); t = (sp_int_digit)(a[38]);
14289     r[39] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;
14290     s = (sp_int_digit)(a[38]); t = (sp_int_digit)(a[37]);
14291     r[38] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;
14292     s = (sp_int_digit)(a[37]); t = (sp_int_digit)(a[36]);
14293     r[37] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;
14294     s = (sp_int_digit)(a[36]); t = (sp_int_digit)(a[35]);
14295     r[36] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;
14296     s = (sp_int_digit)(a[35]); t = (sp_int_digit)(a[34]);
14297     r[35] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;
14298     s = (sp_int_digit)(a[34]); t = (sp_int_digit)(a[33]);
14299     r[34] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;
14300     s = (sp_int_digit)(a[33]); t = (sp_int_digit)(a[32]);
14301     r[33] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;
14302     s = (sp_int_digit)(a[32]); t = (sp_int_digit)(a[31]);
14303     r[32] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;
14304     s = (sp_int_digit)(a[31]); t = (sp_int_digit)(a[30]);
14305     r[31] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;
14306     s = (sp_int_digit)(a[30]); t = (sp_int_digit)(a[29]);
14307     r[30] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;
14308     s = (sp_int_digit)(a[29]); t = (sp_int_digit)(a[28]);
14309     r[29] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;
14310     s = (sp_int_digit)(a[28]); t = (sp_int_digit)(a[27]);
14311     r[28] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;
14312     s = (sp_int_digit)(a[27]); t = (sp_int_digit)(a[26]);
14313     r[27] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;
14314     s = (sp_int_digit)(a[26]); t = (sp_int_digit)(a[25]);
14315     r[26] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;
14316     s = (sp_int_digit)(a[25]); t = (sp_int_digit)(a[24]);
14317     r[25] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;
14318     s = (sp_int_digit)(a[24]); t = (sp_int_digit)(a[23]);
14319     r[24] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;
14320     s = (sp_int_digit)(a[23]); t = (sp_int_digit)(a[22]);
14321     r[23] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;
14322     s = (sp_int_digit)(a[22]); t = (sp_int_digit)(a[21]);
14323     r[22] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;
14324     s = (sp_int_digit)(a[21]); t = (sp_int_digit)(a[20]);
14325     r[21] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;
14326     s = (sp_int_digit)(a[20]); t = (sp_int_digit)(a[19]);
14327     r[20] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;
14328     s = (sp_int_digit)(a[19]); t = (sp_int_digit)(a[18]);
14329     r[19] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;
14330     s = (sp_int_digit)(a[18]); t = (sp_int_digit)(a[17]);
14331     r[18] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;
14332     s = (sp_int_digit)(a[17]); t = (sp_int_digit)(a[16]);
14333     r[17] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;
14334     s = (sp_int_digit)(a[16]); t = (sp_int_digit)(a[15]);
14335     r[16] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;
14336     s = (sp_int_digit)(a[15]); t = (sp_int_digit)(a[14]);
14337     r[15] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;
14338     s = (sp_int_digit)(a[14]); t = (sp_int_digit)(a[13]);
14339     r[14] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;
14340     s = (sp_int_digit)(a[13]); t = (sp_int_digit)(a[12]);
14341     r[13] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;
14342     s = (sp_int_digit)(a[12]); t = (sp_int_digit)(a[11]);
14343     r[12] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;
14344     s = (sp_int_digit)(a[11]); t = (sp_int_digit)(a[10]);
14345     r[11] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;
14346     s = (sp_int_digit)(a[10]); t = (sp_int_digit)(a[9]);
14347     r[10] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;
14348     s = (sp_int_digit)(a[9]); t = (sp_int_digit)(a[8]);
14349     r[9] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;
14350     s = (sp_int_digit)(a[8]); t = (sp_int_digit)(a[7]);
14351     r[8] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;
14352     s = (sp_int_digit)(a[7]); t = (sp_int_digit)(a[6]);
14353     r[7] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;
14354     s = (sp_int_digit)(a[6]); t = (sp_int_digit)(a[5]);
14355     r[6] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;
14356     s = (sp_int_digit)(a[5]); t = (sp_int_digit)(a[4]);
14357     r[5] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;
14358     s = (sp_int_digit)(a[4]); t = (sp_int_digit)(a[3]);
14359     r[4] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;
14360     s = (sp_int_digit)(a[3]); t = (sp_int_digit)(a[2]);
14361     r[3] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;
14362     s = (sp_int_digit)(a[2]); t = (sp_int_digit)(a[1]);
14363     r[2] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;
14364     s = (sp_int_digit)(a[1]); t = (sp_int_digit)(a[0]);
14365     r[1] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;
14366     r[0] = (a[0] << n) & 0x1ffffffffffffffL;
14367 }
14368 
14369 /* Modular exponentiate 2 to the e mod m. (r = 2^e mod m)
14370  *
14371  * r     A single precision number that is the result of the operation.
14372  * e     A single precision number that is the exponent.
14373  * bits  The number of bits in the exponent.
14374  * m     A single precision number that is the modulus.
14375  * returns  0 on success.
14376  * returns  MEMORY_E on dynamic memory allocation failure.
14377  * returns  MP_VAL when base is even.
14378  */
sp_3072_mod_exp_2_54(sp_digit * r,const sp_digit * e,int bits,const sp_digit * m)14379 static int sp_3072_mod_exp_2_54(sp_digit* r, const sp_digit* e, int bits, const sp_digit* m)
14380 {
14381 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
14382     sp_digit* td = NULL;
14383 #else
14384     sp_digit td[163];
14385 #endif
14386     sp_digit* norm = NULL;
14387     sp_digit* tmp = NULL;
14388     sp_digit mp = 1;
14389     sp_digit n;
14390     sp_digit o;
14391     int i;
14392     int c;
14393     byte y;
14394     int err = MP_OKAY;
14395 
14396     if ((m[0] & 1) == 0) {
14397         err = MP_VAL;
14398     }
14399 
14400 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
14401     if (err == MP_OKAY) {
14402         td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 163, NULL,
14403                                 DYNAMIC_TYPE_TMP_BUFFER);
14404         if (td == NULL)
14405             err = MEMORY_E;
14406     }
14407 #endif
14408 
14409     if (err == MP_OKAY) {
14410         norm = td;
14411         tmp  = td + 108;
14412         XMEMSET(td, 0, sizeof(sp_digit) * 163);
14413 
14414         sp_3072_mont_setup(m, &mp);
14415         sp_3072_mont_norm_54(norm, m);
14416 
14417         bits = ((bits + 4) / 5) * 5;
14418         i = ((bits + 56) / 57) - 1;
14419         c = bits % 57;
14420         if (c == 0) {
14421             c = 57;
14422         }
14423         if (i < 54) {
14424             n = e[i--] << (64 - c);
14425         }
14426         else {
14427             n = 0;
14428             i--;
14429         }
14430         if (c < 5) {
14431             n |= e[i--] << (7 - c);
14432             c += 57;
14433         }
14434         y = (int)((n >> 59) & 0x1f);
14435         n <<= 5;
14436         c -= 5;
14437         sp_3072_lshift_54(r, norm, (byte)y);
14438         while ((i >= 0) || (c >= 5)) {
14439             if (c >= 5) {
14440                 y = (byte)((n >> 59) & 0x1f);
14441                 n <<= 5;
14442                 c -= 5;
14443             }
14444             else if (c == 0) {
14445                 n = e[i--] << 7;
14446                 y = (byte)((n >> 59) & 0x1f);
14447                 n <<= 5;
14448                 c = 52;
14449             }
14450             else {
14451                 y = (byte)((n >> 59) & 0x1f);
14452                 n = e[i--] << 7;
14453                 c = 5 - c;
14454                 y |= (byte)((n >> (64 - c)) & ((1 << c) - 1));
14455                 n <<= c;
14456                 c = 57 - c;
14457             }
14458 
14459             sp_3072_mont_sqr_54(r, r, m, mp);
14460             sp_3072_mont_sqr_54(r, r, m, mp);
14461             sp_3072_mont_sqr_54(r, r, m, mp);
14462             sp_3072_mont_sqr_54(r, r, m, mp);
14463             sp_3072_mont_sqr_54(r, r, m, mp);
14464 
14465             sp_3072_lshift_54(r, r, (byte)y);
14466             sp_3072_mul_d_54(tmp, norm, (r[54] << 6) + (r[53] >> 51));
14467             r[54] = 0;
14468             r[53] &= 0x7ffffffffffffL;
14469             (void)sp_3072_add_54(r, r, tmp);
14470             sp_3072_norm_54(r);
14471             o = sp_3072_cmp_54(r, m);
14472             sp_3072_cond_sub_54(r, r, m, ((o < 0) ?
14473                                           (sp_digit)1 : (sp_digit)0) - 1);
14474         }
14475 
14476         sp_3072_mont_reduce_54(r, m, mp);
14477         n = sp_3072_cmp_54(r, m);
14478         sp_3072_cond_sub_54(r, r, m, ((n < 0) ?
14479                                                 (sp_digit)1 : (sp_digit)0) - 1);
14480     }
14481 
14482 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
14483     if (td != NULL)
14484         XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);
14485 #endif
14486 
14487     return err;
14488 }
14489 
14490 #endif /* HAVE_FFDHE_3072 */
14491 
14492 /* Perform the modular exponentiation for Diffie-Hellman.
14493  *
14494  * base     Base.
14495  * exp      Array of bytes that is the exponent.
14496  * expLen   Length of data, in bytes, in exponent.
14497  * mod      Modulus.
14498  * out      Buffer to hold big-endian bytes of exponentiation result.
14499  *          Must be at least 384 bytes long.
14500  * outLen   Length, in bytes, of exponentiation result.
14501  * returns 0 on success, MP_READ_E if there are too many bytes in an array
14502  * and MEMORY_E if memory allocation fails.
14503  */
sp_DhExp_3072(const mp_int * base,const byte * exp,word32 expLen,const mp_int * mod,byte * out,word32 * outLen)14504 int sp_DhExp_3072(const mp_int* base, const byte* exp, word32 expLen,
14505     const mp_int* mod, byte* out, word32* outLen)
14506 {
14507 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
14508     sp_digit* b = NULL;
14509 #else
14510     sp_digit b[54 * 4];
14511 #endif
14512     sp_digit* e = NULL;
14513     sp_digit* m = NULL;
14514     sp_digit* r = NULL;
14515     word32 i;
14516     int err = MP_OKAY;
14517 
14518     if (mp_count_bits(base) > 3072) {
14519         err = MP_READ_E;
14520     }
14521     else if (expLen > 384U) {
14522         err = MP_READ_E;
14523     }
14524     else if (mp_count_bits(mod) != 3072) {
14525         err = MP_READ_E;
14526     }
14527     else if (mp_iseven(mod)) {
14528         err = MP_VAL;
14529     }
14530 
14531 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
14532     if (err == MP_OKAY) {
14533         b = (sp_digit*)XMALLOC(sizeof(sp_digit) * 54 * 4, NULL,
14534             DYNAMIC_TYPE_DH);
14535         if (b == NULL)
14536             err = MEMORY_E;
14537     }
14538 #endif
14539 
14540     if (err == MP_OKAY) {
14541         e = b + 54 * 2;
14542         m = e + 54;
14543         r = b;
14544 
14545         sp_3072_from_mp(b, 54, base);
14546         sp_3072_from_bin(e, 54, exp, expLen);
14547         sp_3072_from_mp(m, 54, mod);
14548 
14549     #ifdef HAVE_FFDHE_3072
14550         if (base->used == 1 && base->dp[0] == 2U &&
14551                 (m[53] >> 19) == 0xffffffffL) {
14552             err = sp_3072_mod_exp_2_54(r, e, expLen * 8U, m);
14553         }
14554         else {
14555     #endif
14556             err = sp_3072_mod_exp_54(r, b, e, expLen * 8U, m, 0);
14557     #ifdef HAVE_FFDHE_3072
14558         }
14559     #endif
14560     }
14561 
14562     if (err == MP_OKAY) {
14563         sp_3072_to_bin_54(r, out);
14564         *outLen = 384;
14565         for (i=0; i<384U && out[i] == 0U; i++) {
14566             /* Search for first non-zero. */
14567         }
14568         *outLen -= i;
14569         XMEMMOVE(out, out + i, *outLen);
14570     }
14571 
14572 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
14573     if (b != NULL)
14574 #endif
14575     {
14576         /* only "e" is sensitive and needs zeroized */
14577         if (e != NULL)
14578             ForceZero(e, sizeof(sp_digit) * 54U);
14579     #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
14580         XFREE(b, NULL, DYNAMIC_TYPE_DH);
14581     #endif
14582     }
14583 
14584     return err;
14585 }
14586 #endif /* WOLFSSL_HAVE_SP_DH */
14587 
14588 /* Perform the modular exponentiation for Diffie-Hellman.
14589  *
14590  * base  Base. MP integer.
14591  * exp   Exponent. MP integer.
14592  * mod   Modulus. MP integer.
14593  * res   Result. MP integer.
14594  * returns 0 on success, MP_READ_E if there are too many bytes in an array
14595  * and MEMORY_E if memory allocation fails.
14596  */
sp_ModExp_1536(const mp_int * base,const mp_int * exp,const mp_int * mod,mp_int * res)14597 int sp_ModExp_1536(const mp_int* base, const mp_int* exp, const mp_int* mod,
14598     mp_int* res)
14599 {
14600 #ifdef WOLFSSL_SP_SMALL
14601     int err = MP_OKAY;
14602 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
14603     sp_digit* b = NULL;
14604 #else
14605     sp_digit b[27 * 4];
14606 #endif
14607     sp_digit* e = NULL;
14608     sp_digit* m = NULL;
14609     sp_digit* r = NULL;
14610     int expBits = mp_count_bits(exp);
14611 
14612     if (mp_count_bits(base) > 1536) {
14613         err = MP_READ_E;
14614     }
14615     else if (expBits > 1536) {
14616         err = MP_READ_E;
14617     }
14618     else if (mp_count_bits(mod) != 1536) {
14619         err = MP_READ_E;
14620     }
14621     else if (mp_iseven(mod)) {
14622         err = MP_VAL;
14623     }
14624 
14625 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
14626     if (err == MP_OKAY) {
14627         b = (sp_digit*)XMALLOC(sizeof(sp_digit) * 27 * 4, NULL,
14628             DYNAMIC_TYPE_DH);
14629         if (b == NULL)
14630             err = MEMORY_E;
14631     }
14632 #endif
14633 
14634     if (err == MP_OKAY) {
14635         e = b + 27 * 2;
14636         m = e + 27;
14637         r = b;
14638 
14639         sp_3072_from_mp(b, 27, base);
14640         sp_3072_from_mp(e, 27, exp);
14641         sp_3072_from_mp(m, 27, mod);
14642 
14643         err = sp_3072_mod_exp_27(r, b, e, mp_count_bits(exp), m, 0);
14644     }
14645 
14646     if (err == MP_OKAY) {
14647         XMEMSET(r + 27, 0, sizeof(*r) * 27U);
14648         err = sp_3072_to_mp(r, res);
14649     }
14650 
14651 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
14652     if (b != NULL)
14653 #endif
14654     {
14655         /* only "e" is sensitive and needs zeroized */
14656         if (e != NULL)
14657             ForceZero(e, sizeof(sp_digit) * 54U);
14658     #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
14659         XFREE(b, NULL, DYNAMIC_TYPE_DH);
14660     #endif
14661     }
14662     return err;
14663 #else
14664 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
14665     sp_digit* b = NULL;
14666 #else
14667     sp_digit b[27 * 4];
14668 #endif
14669     sp_digit* e = NULL;
14670     sp_digit* m = NULL;
14671     sp_digit* r = NULL;
14672     int err = MP_OKAY;
14673     int expBits = mp_count_bits(exp);
14674 
14675     if (mp_count_bits(base) > 1536) {
14676         err = MP_READ_E;
14677     }
14678     else if (expBits > 1536) {
14679         err = MP_READ_E;
14680     }
14681     else if (mp_count_bits(mod) != 1536) {
14682         err = MP_READ_E;
14683     }
14684     else if (mp_iseven(mod)) {
14685         err = MP_VAL;
14686     }
14687 
14688 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
14689     if (err == MP_OKAY) {
14690         b = (sp_digit*)XMALLOC(sizeof(sp_digit) * 27 * 4, NULL, DYNAMIC_TYPE_DH);
14691         if (b == NULL)
14692             err = MEMORY_E;
14693     }
14694 #endif
14695 
14696     if (err == MP_OKAY) {
14697         e = b + 27 * 2;
14698         m = e + 27;
14699         r = b;
14700 
14701         sp_3072_from_mp(b, 27, base);
14702         sp_3072_from_mp(e, 27, exp);
14703         sp_3072_from_mp(m, 27, mod);
14704 
14705         err = sp_3072_mod_exp_27(r, b, e, expBits, m, 0);
14706     }
14707 
14708     if (err == MP_OKAY) {
14709         XMEMSET(r + 27, 0, sizeof(*r) * 27U);
14710         err = sp_3072_to_mp(r, res);
14711     }
14712 
14713 
14714 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
14715     if (b != NULL)
14716 #endif
14717     {
14718         /* only "e" is sensitive and needs zeroized */
14719         if (e != NULL)
14720             ForceZero(e, sizeof(sp_digit) * 54U);
14721     #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
14722         XFREE(b, NULL, DYNAMIC_TYPE_DH);
14723     #endif
14724     }
14725 
14726     return err;
14727 #endif
14728 }
14729 
14730 #endif /* WOLFSSL_HAVE_SP_DH | (WOLFSSL_HAVE_SP_RSA & !WOLFSSL_RSA_PUBLIC_ONLY) */
14731 
14732 #endif /* WOLFSSL_SP_SMALL */
14733 #endif /* !WOLFSSL_SP_NO_3072 */
14734 
14735 #ifdef WOLFSSL_SP_4096
14736 #ifdef WOLFSSL_SP_SMALL
14737 /* Read big endian unsigned byte array into r.
14738  *
14739  * r  A single precision integer.
14740  * size  Maximum number of bytes to convert
14741  * a  Byte array.
14742  * n  Number of bytes in array to read.
14743  */
sp_4096_from_bin(sp_digit * r,int size,const byte * a,int n)14744 static void sp_4096_from_bin(sp_digit* r, int size, const byte* a, int n)
14745 {
14746     int i;
14747     int j = 0;
14748     word32 s = 0;
14749 
14750     r[0] = 0;
14751     for (i = n-1; i >= 0; i--) {
14752         r[j] |= (((sp_digit)a[i]) << s);
14753         if (s >= 51U) {
14754             r[j] &= 0x7ffffffffffffffL;
14755             s = 59U - s;
14756             if (j + 1 >= size) {
14757                 break;
14758             }
14759             r[++j] = (sp_digit)a[i] >> s;
14760             s = 8U - s;
14761         }
14762         else {
14763             s += 8U;
14764         }
14765     }
14766 
14767     for (j++; j < size; j++) {
14768         r[j] = 0;
14769     }
14770 }
14771 
14772 /* Convert an mp_int to an array of sp_digit.
14773  *
14774  * r  A single precision integer.
14775  * size  Maximum number of bytes to convert
14776  * a  A multi-precision integer.
14777  */
sp_4096_from_mp(sp_digit * r,int size,const mp_int * a)14778 static void sp_4096_from_mp(sp_digit* r, int size, const mp_int* a)
14779 {
14780 #if DIGIT_BIT == 59
14781     int j;
14782 
14783     XMEMCPY(r, a->dp, sizeof(sp_digit) * a->used);
14784 
14785     for (j = a->used; j < size; j++) {
14786         r[j] = 0;
14787     }
14788 #elif DIGIT_BIT > 59
14789     int i;
14790     int j = 0;
14791     word32 s = 0;
14792 
14793     r[0] = 0;
14794     for (i = 0; i < a->used && j < size; i++) {
14795         r[j] |= ((sp_digit)a->dp[i] << s);
14796         r[j] &= 0x7ffffffffffffffL;
14797         s = 59U - s;
14798         if (j + 1 >= size) {
14799             break;
14800         }
14801         /* lint allow cast of mismatch word32 and mp_digit */
14802         r[++j] = (sp_digit)(a->dp[i] >> s); /*lint !e9033*/
14803         while ((s + 59U) <= (word32)DIGIT_BIT) {
14804             s += 59U;
14805             r[j] &= 0x7ffffffffffffffL;
14806             if (j + 1 >= size) {
14807                 break;
14808             }
14809             if (s < (word32)DIGIT_BIT) {
14810                 /* lint allow cast of mismatch word32 and mp_digit */
14811                 r[++j] = (sp_digit)(a->dp[i] >> s); /*lint !e9033*/
14812             }
14813             else {
14814                 r[++j] = (sp_digit)0;
14815             }
14816         }
14817         s = (word32)DIGIT_BIT - s;
14818     }
14819 
14820     for (j++; j < size; j++) {
14821         r[j] = 0;
14822     }
14823 #else
14824     int i;
14825     int j = 0;
14826     int s = 0;
14827 
14828     r[0] = 0;
14829     for (i = 0; i < a->used && j < size; i++) {
14830         r[j] |= ((sp_digit)a->dp[i]) << s;
14831         if (s + DIGIT_BIT >= 59) {
14832             r[j] &= 0x7ffffffffffffffL;
14833             if (j + 1 >= size) {
14834                 break;
14835             }
14836             s = 59 - s;
14837             if (s == DIGIT_BIT) {
14838                 r[++j] = 0;
14839                 s = 0;
14840             }
14841             else {
14842                 r[++j] = a->dp[i] >> s;
14843                 s = DIGIT_BIT - s;
14844             }
14845         }
14846         else {
14847             s += DIGIT_BIT;
14848         }
14849     }
14850 
14851     for (j++; j < size; j++) {
14852         r[j] = 0;
14853     }
14854 #endif
14855 }
14856 
14857 /* Write r as big endian to byte array.
14858  * Fixed length number of bytes written: 512
14859  *
14860  * r  A single precision integer.
14861  * a  Byte array.
14862  */
sp_4096_to_bin_70(sp_digit * r,byte * a)14863 static void sp_4096_to_bin_70(sp_digit* r, byte* a)
14864 {
14865     int i;
14866     int j;
14867     int s = 0;
14868     int b;
14869 
14870     for (i=0; i<69; i++) {
14871         r[i+1] += r[i] >> 59;
14872         r[i] &= 0x7ffffffffffffffL;
14873     }
14874     j = 4096 / 8 - 1;
14875     a[j] = 0;
14876     for (i=0; i<70 && j>=0; i++) {
14877         b = 0;
14878         /* lint allow cast of mismatch sp_digit and int */
14879         a[j--] |= (byte)(r[i] << s); /*lint !e9033*/
14880         b += 8 - s;
14881         if (j < 0) {
14882             break;
14883         }
14884         while (b < 59) {
14885             a[j--] = (byte)(r[i] >> b);
14886             b += 8;
14887             if (j < 0) {
14888                 break;
14889             }
14890         }
14891         s = 8 - (b - 59);
14892         if (j >= 0) {
14893             a[j] = 0;
14894         }
14895         if (s != 0) {
14896             j++;
14897         }
14898     }
14899 }
14900 
14901 #if (defined(WOLFSSL_HAVE_SP_RSA) && !defined(WOLFSSL_RSA_PUBLIC_ONLY)) || defined(WOLFSSL_HAVE_SP_DH)
14902 #if defined(WOLFSSL_HAVE_SP_RSA) && !defined(SP_RSA_PRIVATE_EXP_D)
14903 /* Normalize the values in each word to 59 bits.
14904  *
14905  * a  Array of sp_digit to normalize.
14906  */
sp_4096_norm_35(sp_digit * a)14907 static void sp_4096_norm_35(sp_digit* a)
14908 {
14909     int i;
14910     for (i = 0; i < 34; i++) {
14911         a[i+1] += a[i] >> 59;
14912         a[i] &= 0x7ffffffffffffffL;
14913     }
14914 }
14915 
14916 #endif /* WOLFSSL_HAVE_SP_RSA & !SP_RSA_PRIVATE_EXP_D */
14917 #endif /* (WOLFSSL_HAVE_SP_RSA && !WOLFSSL_RSA_PUBLIC_ONLY) || WOLFSSL_HAVE_SP_DH */
14918 /* Normalize the values in each word to 59 bits.
14919  *
14920  * a  Array of sp_digit to normalize.
14921  */
sp_4096_norm_70(sp_digit * a)14922 static void sp_4096_norm_70(sp_digit* a)
14923 {
14924     int i;
14925     for (i = 0; i < 69; i++) {
14926         a[i+1] += a[i] >> 59;
14927         a[i] &= 0x7ffffffffffffffL;
14928     }
14929 }
14930 
14931 /* Multiply a and b into r. (r = a * b)
14932  *
14933  * r  A single precision integer.
14934  * a  A single precision integer.
14935  * b  A single precision integer.
14936  */
sp_4096_mul_70(sp_digit * r,const sp_digit * a,const sp_digit * b)14937 SP_NOINLINE static void sp_4096_mul_70(sp_digit* r, const sp_digit* a,
14938     const sp_digit* b)
14939 {
14940     int i;
14941     int imax;
14942     int k;
14943     sp_uint128 c;
14944     sp_uint128 lo;
14945 
14946     c = ((sp_uint128)a[69]) * b[69];
14947     r[139] = (sp_digit)(c >> 59);
14948     c &= 0x7ffffffffffffffL;
14949     for (k = 137; k >= 0; k--) {
14950         if (k >= 70) {
14951             i = k - 69;
14952             imax = 69;
14953         }
14954         else {
14955             i = 0;
14956             imax = k;
14957         }
14958         lo = 0;
14959         for (; i <= imax; i++) {
14960             lo += ((sp_uint128)a[i]) * b[k - i];
14961         }
14962         c += lo >> 59;
14963         r[k + 2] += (sp_digit)(c >> 59);
14964         r[k + 1]  = (sp_digit)(c & 0x7ffffffffffffffL);
14965         c = lo & 0x7ffffffffffffffL;
14966     }
14967     r[0] = (sp_digit)c;
14968 }
14969 
14970 /* Square a and put result in r. (r = a * a)
14971  *
14972  * r  A single precision integer.
14973  * a  A single precision integer.
14974  */
sp_4096_sqr_70(sp_digit * r,const sp_digit * a)14975 SP_NOINLINE static void sp_4096_sqr_70(sp_digit* r, const sp_digit* a)
14976 {
14977     int i;
14978     int imax;
14979     int k;
14980     sp_uint128 c;
14981     sp_uint128 t;
14982 
14983     c = ((sp_uint128)a[69]) * a[69];
14984     r[139] = (sp_digit)(c >> 59);
14985     c = (c & 0x7ffffffffffffffL) << 59;
14986     for (k = 137; k >= 0; k--) {
14987         i = (k + 1) / 2;
14988         if ((k & 1) == 0) {
14989            c += ((sp_uint128)a[i]) * a[i];
14990            i++;
14991         }
14992         if (k < 69) {
14993             imax = k;
14994         }
14995         else {
14996             imax = 69;
14997         }
14998         t = 0;
14999         for (; i <= imax; i++) {
15000             t += ((sp_uint128)a[i]) * a[k - i];
15001         }
15002         c += t * 2;
15003 
15004         r[k + 2] += (sp_digit) (c >> 118);
15005         r[k + 1]  = (sp_digit)((c >> 59) & 0x7ffffffffffffffL);
15006         c = (c & 0x7ffffffffffffffL) << 59;
15007     }
15008     r[0] = (sp_digit)(c >> 59);
15009 }
15010 
15011 /* Caclulate the bottom digit of -1/a mod 2^n.
15012  *
15013  * a    A single precision number.
15014  * rho  Bottom word of inverse.
15015  */
sp_4096_mont_setup(const sp_digit * a,sp_digit * rho)15016 static void sp_4096_mont_setup(const sp_digit* a, sp_digit* rho)
15017 {
15018     sp_digit x;
15019     sp_digit b;
15020 
15021     b = a[0];
15022     x = (((b + 2) & 4) << 1) + b; /* here x*a==1 mod 2**4 */
15023     x *= 2 - b * x;               /* here x*a==1 mod 2**8 */
15024     x *= 2 - b * x;               /* here x*a==1 mod 2**16 */
15025     x *= 2 - b * x;               /* here x*a==1 mod 2**32 */
15026     x *= 2 - b * x;               /* here x*a==1 mod 2**64 */
15027     x &= 0x7ffffffffffffffL;
15028 
15029     /* rho = -1/m mod b */
15030     *rho = ((sp_digit)1 << 59) - x;
15031 }
15032 
15033 /* Multiply a by scalar b into r. (r = a * b)
15034  *
15035  * r  A single precision integer.
15036  * a  A single precision integer.
15037  * b  A scalar.
15038  */
sp_4096_mul_d_70(sp_digit * r,const sp_digit * a,sp_digit b)15039 SP_NOINLINE static void sp_4096_mul_d_70(sp_digit* r, const sp_digit* a,
15040     sp_digit b)
15041 {
15042     sp_int128 tb = b;
15043     sp_int128 t = 0;
15044     int i;
15045 
15046     for (i = 0; i < 70; i++) {
15047         t += tb * a[i];
15048         r[i] = (sp_digit)(t & 0x7ffffffffffffffL);
15049         t >>= 59;
15050     }
15051     r[70] = (sp_digit)t;
15052 }
15053 
15054 #if (defined(WOLFSSL_HAVE_SP_RSA) || defined(WOLFSSL_HAVE_SP_DH)) && !defined(WOLFSSL_RSA_PUBLIC_ONLY)
15055 #if defined(WOLFSSL_HAVE_SP_RSA) && !defined(SP_RSA_PRIVATE_EXP_D)
15056 /* Sub b from a into r. (r = a - b)
15057  *
15058  * r  A single precision integer.
15059  * a  A single precision integer.
15060  * b  A single precision integer.
15061  */
sp_4096_sub_35(sp_digit * r,const sp_digit * a,const sp_digit * b)15062 SP_NOINLINE static int sp_4096_sub_35(sp_digit* r, const sp_digit* a,
15063         const sp_digit* b)
15064 {
15065     int i;
15066 
15067     for (i = 0; i < 35; i++) {
15068         r[i] = a[i] - b[i];
15069     }
15070 
15071     return 0;
15072 }
15073 
15074 /* r = 2^n mod m where n is the number of bits to reduce by.
15075  * Given m must be 4096 bits, just need to subtract.
15076  *
15077  * r  A single precision number.
15078  * m  A single precision number.
15079  */
sp_4096_mont_norm_35(sp_digit * r,const sp_digit * m)15080 static void sp_4096_mont_norm_35(sp_digit* r, const sp_digit* m)
15081 {
15082     /* Set r = 2^n - 1. */
15083     int i;
15084 
15085     for (i=0; i<34; i++) {
15086         r[i] = 0x7ffffffffffffffL;
15087     }
15088     r[34] = 0x3ffffffffffL;
15089 
15090     /* r = (2^n - 1) mod n */
15091     (void)sp_4096_sub_35(r, r, m);
15092 
15093     /* Add one so r = 2^n mod m */
15094     r[0] += 1;
15095 }
15096 
15097 /* Compare a with b in constant time.
15098  *
15099  * a  A single precision integer.
15100  * b  A single precision integer.
15101  * return -ve, 0 or +ve if a is less than, equal to or greater than b
15102  * respectively.
15103  */
sp_4096_cmp_35(const sp_digit * a,const sp_digit * b)15104 static sp_digit sp_4096_cmp_35(const sp_digit* a, const sp_digit* b)
15105 {
15106     sp_digit r = 0;
15107     int i;
15108 
15109     for (i=34; i>=0; i--) {
15110         r |= (a[i] - b[i]) & (0 - (sp_digit)((r == 0) ? 1 : 0));
15111     }
15112 
15113     return r;
15114 }
15115 
15116 /* Conditionally subtract b from a using the mask m.
15117  * m is -1 to subtract and 0 when not.
15118  *
15119  * r  A single precision number representing condition subtract result.
15120  * a  A single precision number to subtract from.
15121  * b  A single precision number to subtract.
15122  * m  Mask value to apply.
15123  */
sp_4096_cond_sub_35(sp_digit * r,const sp_digit * a,const sp_digit * b,const sp_digit m)15124 static void sp_4096_cond_sub_35(sp_digit* r, const sp_digit* a,
15125         const sp_digit* b, const sp_digit m)
15126 {
15127     int i;
15128 
15129     for (i = 0; i < 35; i++) {
15130         r[i] = a[i] - (b[i] & m);
15131     }
15132 }
15133 
15134 /* Mul a by scalar b and add into r. (r += a * b)
15135  *
15136  * r  A single precision integer.
15137  * a  A single precision integer.
15138  * b  A scalar.
15139  */
sp_4096_mul_add_35(sp_digit * r,const sp_digit * a,const sp_digit b)15140 SP_NOINLINE static void sp_4096_mul_add_35(sp_digit* r, const sp_digit* a,
15141         const sp_digit b)
15142 {
15143     sp_int128 tb = b;
15144     sp_int128 t[4];
15145     int i;
15146 
15147     t[0] = 0;
15148     for (i = 0; i < 32; i += 4) {
15149         t[0] += (tb * a[i+0]) + r[i+0];
15150         t[1]  = (tb * a[i+1]) + r[i+1];
15151         t[2]  = (tb * a[i+2]) + r[i+2];
15152         t[3]  = (tb * a[i+3]) + r[i+3];
15153         r[i+0] = t[0] & 0x7ffffffffffffffL;
15154         t[1] += t[0] >> 59;
15155         r[i+1] = t[1] & 0x7ffffffffffffffL;
15156         t[2] += t[1] >> 59;
15157         r[i+2] = t[2] & 0x7ffffffffffffffL;
15158         t[3] += t[2] >> 59;
15159         r[i+3] = t[3] & 0x7ffffffffffffffL;
15160         t[0]  = t[3] >> 59;
15161     }
15162     t[0] += (tb * a[32]) + r[32];
15163     t[1]  = (tb * a[33]) + r[33];
15164     t[2]  = (tb * a[34]) + r[34];
15165     r[32] = t[0] & 0x7ffffffffffffffL;
15166     t[1] += t[0] >> 59;
15167     r[33] = t[1] & 0x7ffffffffffffffL;
15168     t[2] += t[1] >> 59;
15169     r[34] = t[2] & 0x7ffffffffffffffL;
15170     r[35] +=  (sp_digit)(t[2] >> 59);
15171 }
15172 
15173 /* Shift the result in the high 2048 bits down to the bottom.
15174  *
15175  * r  A single precision number.
15176  * a  A single precision number.
15177  */
sp_4096_mont_shift_35(sp_digit * r,const sp_digit * a)15178 static void sp_4096_mont_shift_35(sp_digit* r, const sp_digit* a)
15179 {
15180     int i;
15181     sp_int128 n = a[34] >> 42;
15182     n += ((sp_int128)a[35]) << 17;
15183 
15184     for (i = 0; i < 34; i++) {
15185         r[i] = n & 0x7ffffffffffffffL;
15186         n >>= 59;
15187         n += ((sp_int128)a[36 + i]) << 17;
15188     }
15189     r[34] = (sp_digit)n;
15190     XMEMSET(&r[35], 0, sizeof(*r) * 35U);
15191 }
15192 
15193 /* Reduce the number back to 4096 bits using Montgomery reduction.
15194  *
15195  * a   A single precision number to reduce in place.
15196  * m   The single precision number representing the modulus.
15197  * mp  The digit representing the negative inverse of m mod 2^n.
15198  */
sp_4096_mont_reduce_35(sp_digit * a,const sp_digit * m,sp_digit mp)15199 static void sp_4096_mont_reduce_35(sp_digit* a, const sp_digit* m, sp_digit mp)
15200 {
15201     int i;
15202     sp_digit mu;
15203 
15204     sp_4096_norm_35(a + 35);
15205 
15206     for (i=0; i<34; i++) {
15207         mu = (a[i] * mp) & 0x7ffffffffffffffL;
15208         sp_4096_mul_add_35(a+i, m, mu);
15209         a[i+1] += a[i] >> 59;
15210     }
15211     mu = (a[i] * mp) & 0x3ffffffffffL;
15212     sp_4096_mul_add_35(a+i, m, mu);
15213     a[i+1] += a[i] >> 59;
15214     a[i] &= 0x7ffffffffffffffL;
15215     sp_4096_mont_shift_35(a, a);
15216     sp_4096_cond_sub_35(a, a, m, 0 - (((a[34] - m[34]) > 0) ?
15217             (sp_digit)1 : (sp_digit)0));
15218     sp_4096_norm_35(a);
15219 }
15220 
15221 /* Multiply a and b into r. (r = a * b)
15222  *
15223  * r  A single precision integer.
15224  * a  A single precision integer.
15225  * b  A single precision integer.
15226  */
sp_4096_mul_35(sp_digit * r,const sp_digit * a,const sp_digit * b)15227 SP_NOINLINE static void sp_4096_mul_35(sp_digit* r, const sp_digit* a,
15228     const sp_digit* b)
15229 {
15230     int i;
15231     int imax;
15232     int k;
15233     sp_uint128 c;
15234     sp_uint128 lo;
15235 
15236     c = ((sp_uint128)a[34]) * b[34];
15237     r[69] = (sp_digit)(c >> 59);
15238     c &= 0x7ffffffffffffffL;
15239     for (k = 67; k >= 0; k--) {
15240         if (k >= 35) {
15241             i = k - 34;
15242             imax = 34;
15243         }
15244         else {
15245             i = 0;
15246             imax = k;
15247         }
15248         lo = 0;
15249         for (; i <= imax; i++) {
15250             lo += ((sp_uint128)a[i]) * b[k - i];
15251         }
15252         c += lo >> 59;
15253         r[k + 2] += (sp_digit)(c >> 59);
15254         r[k + 1]  = (sp_digit)(c & 0x7ffffffffffffffL);
15255         c = lo & 0x7ffffffffffffffL;
15256     }
15257     r[0] = (sp_digit)c;
15258 }
15259 
15260 /* Multiply two Montgomery form numbers mod the modulus (prime).
15261  * (r = a * b mod m)
15262  *
15263  * r   Result of multiplication.
15264  * a   First number to multiply in Montgomery form.
15265  * b   Second number to multiply in Montgomery form.
15266  * m   Modulus (prime).
15267  * mp  Montgomery mulitplier.
15268  */
sp_4096_mont_mul_35(sp_digit * r,const sp_digit * a,const sp_digit * b,const sp_digit * m,sp_digit mp)15269 static void sp_4096_mont_mul_35(sp_digit* r, const sp_digit* a,
15270         const sp_digit* b, const sp_digit* m, sp_digit mp)
15271 {
15272     sp_4096_mul_35(r, a, b);
15273     sp_4096_mont_reduce_35(r, m, mp);
15274 }
15275 
15276 /* Square a and put result in r. (r = a * a)
15277  *
15278  * r  A single precision integer.
15279  * a  A single precision integer.
15280  */
sp_4096_sqr_35(sp_digit * r,const sp_digit * a)15281 SP_NOINLINE static void sp_4096_sqr_35(sp_digit* r, const sp_digit* a)
15282 {
15283     int i;
15284     int imax;
15285     int k;
15286     sp_uint128 c;
15287     sp_uint128 t;
15288 
15289     c = ((sp_uint128)a[34]) * a[34];
15290     r[69] = (sp_digit)(c >> 59);
15291     c = (c & 0x7ffffffffffffffL) << 59;
15292     for (k = 67; k >= 0; k--) {
15293         i = (k + 1) / 2;
15294         if ((k & 1) == 0) {
15295            c += ((sp_uint128)a[i]) * a[i];
15296            i++;
15297         }
15298         if (k < 34) {
15299             imax = k;
15300         }
15301         else {
15302             imax = 34;
15303         }
15304         t = 0;
15305         for (; i <= imax; i++) {
15306             t += ((sp_uint128)a[i]) * a[k - i];
15307         }
15308         c += t * 2;
15309 
15310         r[k + 2] += (sp_digit) (c >> 118);
15311         r[k + 1]  = (sp_digit)((c >> 59) & 0x7ffffffffffffffL);
15312         c = (c & 0x7ffffffffffffffL) << 59;
15313     }
15314     r[0] = (sp_digit)(c >> 59);
15315 }
15316 
15317 /* Square the Montgomery form number. (r = a * a mod m)
15318  *
15319  * r   Result of squaring.
15320  * a   Number to square in Montgomery form.
15321  * m   Modulus (prime).
15322  * mp  Montgomery mulitplier.
15323  */
sp_4096_mont_sqr_35(sp_digit * r,const sp_digit * a,const sp_digit * m,sp_digit mp)15324 static void sp_4096_mont_sqr_35(sp_digit* r, const sp_digit* a,
15325         const sp_digit* m, sp_digit mp)
15326 {
15327     sp_4096_sqr_35(r, a);
15328     sp_4096_mont_reduce_35(r, m, mp);
15329 }
15330 
15331 /* Multiply a by scalar b into r. (r = a * b)
15332  *
15333  * r  A single precision integer.
15334  * a  A single precision integer.
15335  * b  A scalar.
15336  */
sp_4096_mul_d_35(sp_digit * r,const sp_digit * a,sp_digit b)15337 SP_NOINLINE static void sp_4096_mul_d_35(sp_digit* r, const sp_digit* a,
15338     sp_digit b)
15339 {
15340     sp_int128 tb = b;
15341     sp_int128 t = 0;
15342     int i;
15343 
15344     for (i = 0; i < 35; i++) {
15345         t += tb * a[i];
15346         r[i] = (sp_digit)(t & 0x7ffffffffffffffL);
15347         t >>= 59;
15348     }
15349     r[35] = (sp_digit)t;
15350 }
15351 
15352 /* Conditionally add a and b using the mask m.
15353  * m is -1 to add and 0 when not.
15354  *
15355  * r  A single precision number representing conditional add result.
15356  * a  A single precision number to add with.
15357  * b  A single precision number to add.
15358  * m  Mask value to apply.
15359  */
sp_4096_cond_add_35(sp_digit * r,const sp_digit * a,const sp_digit * b,const sp_digit m)15360 static void sp_4096_cond_add_35(sp_digit* r, const sp_digit* a,
15361         const sp_digit* b, const sp_digit m)
15362 {
15363     int i;
15364 
15365     for (i = 0; i < 35; i++) {
15366         r[i] = a[i] + (b[i] & m);
15367     }
15368 }
15369 
15370 /* Add b to a into r. (r = a + b)
15371  *
15372  * r  A single precision integer.
15373  * a  A single precision integer.
15374  * b  A single precision integer.
15375  */
sp_4096_add_35(sp_digit * r,const sp_digit * a,const sp_digit * b)15376 SP_NOINLINE static int sp_4096_add_35(sp_digit* r, const sp_digit* a,
15377         const sp_digit* b)
15378 {
15379     int i;
15380 
15381     for (i = 0; i < 35; i++) {
15382         r[i] = a[i] + b[i];
15383     }
15384 
15385     return 0;
15386 }
15387 
sp_4096_rshift_35(sp_digit * r,const sp_digit * a,byte n)15388 SP_NOINLINE static void sp_4096_rshift_35(sp_digit* r, const sp_digit* a,
15389         byte n)
15390 {
15391     int i;
15392 
15393     for (i=0; i<34; i++) {
15394         r[i] = ((a[i] >> n) | (a[i + 1] << (59 - n))) & 0x7ffffffffffffffL;
15395     }
15396     r[34] = a[34] >> n;
15397 }
15398 
15399 #ifdef WOLFSSL_SP_DIV_64
sp_4096_div_word_35(sp_digit d1,sp_digit d0,sp_digit dv)15400 static WC_INLINE sp_digit sp_4096_div_word_35(sp_digit d1, sp_digit d0,
15401     sp_digit dv)
15402 {
15403     sp_digit d;
15404     sp_digit r;
15405     sp_digit t;
15406 
15407     /* All 59 bits from d1 and top 4 bits from d0. */
15408     d = (d1 << 4) + (d0 >> 55);
15409     r = d / dv;
15410     d -= r * dv;
15411     /* Up to 5 bits in r */
15412     /* Next 4 bits from d0. */
15413     r <<= 4;
15414     d <<= 4;
15415     d += (d0 >> 51) & ((1 << 4) - 1);
15416     t = d / dv;
15417     d -= t * dv;
15418     r += t;
15419     /* Up to 9 bits in r */
15420     /* Next 4 bits from d0. */
15421     r <<= 4;
15422     d <<= 4;
15423     d += (d0 >> 47) & ((1 << 4) - 1);
15424     t = d / dv;
15425     d -= t * dv;
15426     r += t;
15427     /* Up to 13 bits in r */
15428     /* Next 4 bits from d0. */
15429     r <<= 4;
15430     d <<= 4;
15431     d += (d0 >> 43) & ((1 << 4) - 1);
15432     t = d / dv;
15433     d -= t * dv;
15434     r += t;
15435     /* Up to 17 bits in r */
15436     /* Next 4 bits from d0. */
15437     r <<= 4;
15438     d <<= 4;
15439     d += (d0 >> 39) & ((1 << 4) - 1);
15440     t = d / dv;
15441     d -= t * dv;
15442     r += t;
15443     /* Up to 21 bits in r */
15444     /* Next 4 bits from d0. */
15445     r <<= 4;
15446     d <<= 4;
15447     d += (d0 >> 35) & ((1 << 4) - 1);
15448     t = d / dv;
15449     d -= t * dv;
15450     r += t;
15451     /* Up to 25 bits in r */
15452     /* Next 4 bits from d0. */
15453     r <<= 4;
15454     d <<= 4;
15455     d += (d0 >> 31) & ((1 << 4) - 1);
15456     t = d / dv;
15457     d -= t * dv;
15458     r += t;
15459     /* Up to 29 bits in r */
15460     /* Next 4 bits from d0. */
15461     r <<= 4;
15462     d <<= 4;
15463     d += (d0 >> 27) & ((1 << 4) - 1);
15464     t = d / dv;
15465     d -= t * dv;
15466     r += t;
15467     /* Up to 33 bits in r */
15468     /* Next 4 bits from d0. */
15469     r <<= 4;
15470     d <<= 4;
15471     d += (d0 >> 23) & ((1 << 4) - 1);
15472     t = d / dv;
15473     d -= t * dv;
15474     r += t;
15475     /* Up to 37 bits in r */
15476     /* Next 4 bits from d0. */
15477     r <<= 4;
15478     d <<= 4;
15479     d += (d0 >> 19) & ((1 << 4) - 1);
15480     t = d / dv;
15481     d -= t * dv;
15482     r += t;
15483     /* Up to 41 bits in r */
15484     /* Next 4 bits from d0. */
15485     r <<= 4;
15486     d <<= 4;
15487     d += (d0 >> 15) & ((1 << 4) - 1);
15488     t = d / dv;
15489     d -= t * dv;
15490     r += t;
15491     /* Up to 45 bits in r */
15492     /* Next 4 bits from d0. */
15493     r <<= 4;
15494     d <<= 4;
15495     d += (d0 >> 11) & ((1 << 4) - 1);
15496     t = d / dv;
15497     d -= t * dv;
15498     r += t;
15499     /* Up to 49 bits in r */
15500     /* Next 4 bits from d0. */
15501     r <<= 4;
15502     d <<= 4;
15503     d += (d0 >> 7) & ((1 << 4) - 1);
15504     t = d / dv;
15505     d -= t * dv;
15506     r += t;
15507     /* Up to 53 bits in r */
15508     /* Next 4 bits from d0. */
15509     r <<= 4;
15510     d <<= 4;
15511     d += (d0 >> 3) & ((1 << 4) - 1);
15512     t = d / dv;
15513     d -= t * dv;
15514     r += t;
15515     /* Up to 57 bits in r */
15516     /* Remaining 3 bits from d0. */
15517     r <<= 3;
15518     d <<= 3;
15519     d += d0 & ((1 << 3) - 1);
15520     t = d / dv;
15521     r += t;
15522 
15523     /* All 59 bits from d1 and top 4 bits from d0. */
15524     return r;
15525 }
15526 #endif /* WOLFSSL_SP_DIV_64 */
15527 
15528 /* Divide d in a and put remainder into r (m*d + r = a)
15529  * m is not calculated as it is not needed at this time.
15530  *
15531  * Full implementation.
15532  *
15533  * a  Number to be divided.
15534  * d  Number to divide with.
15535  * m  Multiplier result.
15536  * r  Remainder from the division.
15537  * returns MEMORY_E when unable to allocate memory and MP_OKAY otherwise.
15538  */
sp_4096_div_35(const sp_digit * a,const sp_digit * d,const sp_digit * m,sp_digit * r)15539 static int sp_4096_div_35(const sp_digit* a, const sp_digit* d,
15540         const sp_digit* m, sp_digit* r)
15541 {
15542     int i;
15543 #ifndef WOLFSSL_SP_DIV_64
15544     sp_int128 d1;
15545 #endif
15546     sp_digit dv;
15547     sp_digit r1;
15548 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
15549     sp_digit* t1 = NULL;
15550 #else
15551     sp_digit t1[4 * 35 + 3];
15552 #endif
15553     sp_digit* t2 = NULL;
15554     sp_digit* sd = NULL;
15555     int err = MP_OKAY;
15556 
15557     (void)m;
15558 
15559 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
15560     t1 = (sp_digit*)XMALLOC(sizeof(sp_digit) * (4 * 35 + 3), NULL,
15561                                                        DYNAMIC_TYPE_TMP_BUFFER);
15562     if (t1 == NULL)
15563         err = MEMORY_E;
15564 #endif
15565 
15566     (void)m;
15567 
15568     if (err == MP_OKAY) {
15569         t2 = t1 + 70 + 1;
15570         sd = t2 + 35 + 1;
15571 
15572         sp_4096_mul_d_35(sd, d, (sp_digit)1 << 17);
15573         sp_4096_mul_d_70(t1, a, (sp_digit)1 << 17);
15574         dv = sd[34];
15575         t1[35 + 35] += t1[35 + 35 - 1] >> 59;
15576         t1[35 + 35 - 1] &= 0x7ffffffffffffffL;
15577         for (i=35; i>=0; i--) {
15578 #ifndef WOLFSSL_SP_DIV_64
15579             d1 = t1[35 + i];
15580             d1 <<= 59;
15581             d1 += t1[35 + i - 1];
15582             r1 = (sp_digit)(d1 / dv);
15583 #else
15584             r1 = sp_4096_div_word_35(t1[35 + i], t1[35 + i - 1], dv);
15585 #endif
15586 
15587             sp_4096_mul_d_35(t2, sd, r1);
15588             (void)sp_4096_sub_35(&t1[i], &t1[i], t2);
15589             sp_4096_norm_35(&t1[i]);
15590             t1[35 + i] -= t2[35];
15591             t1[35 + i] += t1[35 + i - 1] >> 59;
15592             t1[35 + i - 1] &= 0x7ffffffffffffffL;
15593 #ifndef WOLFSSL_SP_DIV_64
15594             d1 = -t1[35 + i];
15595             d1 <<= 59;
15596             d1 -= t1[35 + i - 1];
15597             r1 = (sp_digit)(d1 / dv);
15598 #else
15599             r1 = sp_4096_div_word_35(-t1[35 + i], -t1[35 + i - 1], dv);
15600 #endif
15601             r1 -= t1[35 + i];
15602             sp_4096_mul_d_35(t2, sd, r1);
15603             (void)sp_4096_add_35(&t1[i], &t1[i], t2);
15604             t1[35 + i] += t1[35 + i - 1] >> 59;
15605             t1[35 + i - 1] &= 0x7ffffffffffffffL;
15606         }
15607         t1[35 - 1] += t1[35 - 2] >> 59;
15608         t1[35 - 2] &= 0x7ffffffffffffffL;
15609         r1 = t1[35 - 1] / dv;
15610 
15611         sp_4096_mul_d_35(t2, sd, r1);
15612         sp_4096_sub_35(t1, t1, t2);
15613         XMEMCPY(r, t1, sizeof(*r) * 70U);
15614         for (i=0; i<34; i++) {
15615             r[i+1] += r[i] >> 59;
15616             r[i] &= 0x7ffffffffffffffL;
15617         }
15618         sp_4096_cond_add_35(r, r, sd, 0 - ((r[34] < 0) ?
15619                     (sp_digit)1 : (sp_digit)0));
15620 
15621         sp_4096_norm_35(r);
15622         sp_4096_rshift_35(r, r, 17);
15623     }
15624 
15625 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
15626     if (t1 != NULL)
15627         XFREE(t1, NULL, DYNAMIC_TYPE_TMP_BUFFER);
15628 #endif
15629 
15630     return err;
15631 }
15632 
15633 /* Reduce a modulo m into r. (r = a mod m)
15634  *
15635  * r  A single precision number that is the reduced result.
15636  * a  A single precision number that is to be reduced.
15637  * m  A single precision number that is the modulus to reduce with.
15638  * returns MEMORY_E when unable to allocate memory and MP_OKAY otherwise.
15639  */
sp_4096_mod_35(sp_digit * r,const sp_digit * a,const sp_digit * m)15640 static int sp_4096_mod_35(sp_digit* r, const sp_digit* a, const sp_digit* m)
15641 {
15642     return sp_4096_div_35(a, m, NULL, r);
15643 }
15644 
15645 /* Modular exponentiate a to the e mod m. (r = a^e mod m)
15646  *
15647  * r     A single precision number that is the result of the operation.
15648  * a     A single precision number being exponentiated.
15649  * e     A single precision number that is the exponent.
15650  * bits  The number of bits in the exponent.
15651  * m     A single precision number that is the modulus.
15652  * returns  0 on success.
15653  * returns  MEMORY_E on dynamic memory allocation failure.
15654  * returns  MP_VAL when base is even or exponent is 0.
15655  */
sp_4096_mod_exp_35(sp_digit * r,const sp_digit * a,const sp_digit * e,int bits,const sp_digit * m,int reduceA)15656 static int sp_4096_mod_exp_35(sp_digit* r, const sp_digit* a, const sp_digit* e,
15657     int bits, const sp_digit* m, int reduceA)
15658 {
15659 #if defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SP_FAST_MODEXP)
15660 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
15661     sp_digit* td = NULL;
15662 #else
15663     sp_digit td[3 * 70];
15664 #endif
15665     sp_digit* t[3] = {0, 0, 0};
15666     sp_digit* norm = NULL;
15667     sp_digit mp = 1;
15668     sp_digit n;
15669     int i;
15670     int c;
15671     byte y;
15672     int err = MP_OKAY;
15673 
15674     if ((m[0] & 1) == 0) {
15675         err = MP_VAL;
15676     }
15677     else if (bits == 0) {
15678         err = MP_VAL;
15679     }
15680 
15681 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
15682     if (err == MP_OKAY) {
15683         td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 3 * 35 * 2, NULL,
15684                                 DYNAMIC_TYPE_TMP_BUFFER);
15685         if (td == NULL)
15686             err = MEMORY_E;
15687     }
15688 #endif
15689 
15690     if (err == MP_OKAY) {
15691         norm = td;
15692         for (i=0; i<3; i++) {
15693             t[i] = td + (i * 35 * 2);
15694             XMEMSET(t[i], 0, sizeof(sp_digit) * 35U * 2U);
15695         }
15696 
15697         sp_4096_mont_setup(m, &mp);
15698         sp_4096_mont_norm_35(norm, m);
15699 
15700         if (reduceA != 0) {
15701             err = sp_4096_mod_35(t[1], a, m);
15702         }
15703         else {
15704             XMEMCPY(t[1], a, sizeof(sp_digit) * 35U);
15705         }
15706     }
15707     if (err == MP_OKAY) {
15708         sp_4096_mul_35(t[1], t[1], norm);
15709         err = sp_4096_mod_35(t[1], t[1], m);
15710     }
15711 
15712     if (err == MP_OKAY) {
15713         i = bits / 59;
15714         c = bits % 59;
15715         n = e[i--] << (59 - c);
15716         for (; ; c--) {
15717             if (c == 0) {
15718                 if (i == -1) {
15719                     break;
15720                 }
15721 
15722                 n = e[i--];
15723                 c = 59;
15724             }
15725 
15726             y = (int)((n >> 58) & 1);
15727             n <<= 1;
15728 
15729             sp_4096_mont_mul_35(t[y^1], t[0], t[1], m, mp);
15730 
15731             XMEMCPY(t[2], (void*)(((size_t)t[0] & addr_mask[y^1]) +
15732                                   ((size_t)t[1] & addr_mask[y])),
15733                                   sizeof(*t[2]) * 35 * 2);
15734             sp_4096_mont_sqr_35(t[2], t[2], m, mp);
15735             XMEMCPY((void*)(((size_t)t[0] & addr_mask[y^1]) +
15736                             ((size_t)t[1] & addr_mask[y])), t[2],
15737                             sizeof(*t[2]) * 35 * 2);
15738         }
15739 
15740         sp_4096_mont_reduce_35(t[0], m, mp);
15741         n = sp_4096_cmp_35(t[0], m);
15742         sp_4096_cond_sub_35(t[0], t[0], m, ((n < 0) ?
15743                     (sp_digit)1 : (sp_digit)0) - 1);
15744         XMEMCPY(r, t[0], sizeof(*r) * 35 * 2);
15745 
15746     }
15747 
15748 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
15749     if (td != NULL)
15750         XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);
15751 #endif
15752 
15753     return err;
15754 #elif !defined(WC_NO_CACHE_RESISTANT)
15755 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
15756     sp_digit* td = NULL;
15757 #else
15758     sp_digit td[3 * 70];
15759 #endif
15760     sp_digit* t[3] = {0, 0, 0};
15761     sp_digit* norm = NULL;
15762     sp_digit mp = 1;
15763     sp_digit n;
15764     int i;
15765     int c;
15766     byte y;
15767     int err = MP_OKAY;
15768 
15769     if ((m[0] & 1) == 0) {
15770         err = MP_VAL;
15771     }
15772     else if (bits == 0) {
15773         err = MP_VAL;
15774     }
15775 
15776 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
15777     if (err == MP_OKAY) {
15778         td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 3 * 35 * 2, NULL,
15779                                 DYNAMIC_TYPE_TMP_BUFFER);
15780         if (td == NULL)
15781             err = MEMORY_E;
15782     }
15783 #endif
15784 
15785     if (err == MP_OKAY) {
15786         norm = td;
15787         for (i=0; i<3; i++) {
15788             t[i] = td + (i * 35 * 2);
15789         }
15790 
15791         sp_4096_mont_setup(m, &mp);
15792         sp_4096_mont_norm_35(norm, m);
15793 
15794         if (reduceA != 0) {
15795             err = sp_4096_mod_35(t[1], a, m);
15796             if (err == MP_OKAY) {
15797                 sp_4096_mul_35(t[1], t[1], norm);
15798                 err = sp_4096_mod_35(t[1], t[1], m);
15799             }
15800         }
15801         else {
15802             sp_4096_mul_35(t[1], a, norm);
15803             err = sp_4096_mod_35(t[1], t[1], m);
15804         }
15805     }
15806 
15807     if (err == MP_OKAY) {
15808         i = bits / 59;
15809         c = bits % 59;
15810         n = e[i--] << (59 - c);
15811         for (; ; c--) {
15812             if (c == 0) {
15813                 if (i == -1) {
15814                     break;
15815                 }
15816 
15817                 n = e[i--];
15818                 c = 59;
15819             }
15820 
15821             y = (int)((n >> 58) & 1);
15822             n <<= 1;
15823 
15824             sp_4096_mont_mul_35(t[y^1], t[0], t[1], m, mp);
15825 
15826             XMEMCPY(t[2], (void*)(((size_t)t[0] & addr_mask[y^1]) +
15827                                   ((size_t)t[1] & addr_mask[y])),
15828                                   sizeof(*t[2]) * 35 * 2);
15829             sp_4096_mont_sqr_35(t[2], t[2], m, mp);
15830             XMEMCPY((void*)(((size_t)t[0] & addr_mask[y^1]) +
15831                             ((size_t)t[1] & addr_mask[y])), t[2],
15832                             sizeof(*t[2]) * 35 * 2);
15833         }
15834 
15835         sp_4096_mont_reduce_35(t[0], m, mp);
15836         n = sp_4096_cmp_35(t[0], m);
15837         sp_4096_cond_sub_35(t[0], t[0], m, ((n < 0) ?
15838                     (sp_digit)1 : (sp_digit)0) - 1);
15839         XMEMCPY(r, t[0], sizeof(*r) * 35 * 2);
15840     }
15841 
15842 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
15843     if (td != NULL)
15844         XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);
15845 #endif
15846 
15847     return err;
15848 #else
15849 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
15850     sp_digit* td = NULL;
15851 #else
15852     sp_digit td[(32 * 70) + 70];
15853 #endif
15854     sp_digit* t[32];
15855     sp_digit* rt = NULL;
15856     sp_digit* norm = NULL;
15857     sp_digit mp = 1;
15858     sp_digit n;
15859     int i;
15860     int c;
15861     byte y;
15862     int err = MP_OKAY;
15863 
15864     if ((m[0] & 1) == 0) {
15865         err = MP_VAL;
15866     }
15867     else if (bits == 0) {
15868         err = MP_VAL;
15869     }
15870 
15871 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
15872     if (err == MP_OKAY) {
15873         td = (sp_digit*)XMALLOC(sizeof(sp_digit) * ((32 * 70) + 70), NULL,
15874                                 DYNAMIC_TYPE_TMP_BUFFER);
15875         if (td == NULL)
15876             err = MEMORY_E;
15877     }
15878 #endif
15879 
15880     if (err == MP_OKAY) {
15881         norm = td;
15882         for (i=0; i<32; i++)
15883             t[i] = td + i * 70;
15884         rt = td + 2240;
15885 
15886         sp_4096_mont_setup(m, &mp);
15887         sp_4096_mont_norm_35(norm, m);
15888 
15889         if (reduceA != 0) {
15890             err = sp_4096_mod_35(t[1], a, m);
15891             if (err == MP_OKAY) {
15892                 sp_4096_mul_35(t[1], t[1], norm);
15893                 err = sp_4096_mod_35(t[1], t[1], m);
15894             }
15895         }
15896         else {
15897             sp_4096_mul_35(t[1], a, norm);
15898             err = sp_4096_mod_35(t[1], t[1], m);
15899         }
15900     }
15901 
15902     if (err == MP_OKAY) {
15903         sp_4096_mont_sqr_35(t[ 2], t[ 1], m, mp);
15904         sp_4096_mont_mul_35(t[ 3], t[ 2], t[ 1], m, mp);
15905         sp_4096_mont_sqr_35(t[ 4], t[ 2], m, mp);
15906         sp_4096_mont_mul_35(t[ 5], t[ 3], t[ 2], m, mp);
15907         sp_4096_mont_sqr_35(t[ 6], t[ 3], m, mp);
15908         sp_4096_mont_mul_35(t[ 7], t[ 4], t[ 3], m, mp);
15909         sp_4096_mont_sqr_35(t[ 8], t[ 4], m, mp);
15910         sp_4096_mont_mul_35(t[ 9], t[ 5], t[ 4], m, mp);
15911         sp_4096_mont_sqr_35(t[10], t[ 5], m, mp);
15912         sp_4096_mont_mul_35(t[11], t[ 6], t[ 5], m, mp);
15913         sp_4096_mont_sqr_35(t[12], t[ 6], m, mp);
15914         sp_4096_mont_mul_35(t[13], t[ 7], t[ 6], m, mp);
15915         sp_4096_mont_sqr_35(t[14], t[ 7], m, mp);
15916         sp_4096_mont_mul_35(t[15], t[ 8], t[ 7], m, mp);
15917         sp_4096_mont_sqr_35(t[16], t[ 8], m, mp);
15918         sp_4096_mont_mul_35(t[17], t[ 9], t[ 8], m, mp);
15919         sp_4096_mont_sqr_35(t[18], t[ 9], m, mp);
15920         sp_4096_mont_mul_35(t[19], t[10], t[ 9], m, mp);
15921         sp_4096_mont_sqr_35(t[20], t[10], m, mp);
15922         sp_4096_mont_mul_35(t[21], t[11], t[10], m, mp);
15923         sp_4096_mont_sqr_35(t[22], t[11], m, mp);
15924         sp_4096_mont_mul_35(t[23], t[12], t[11], m, mp);
15925         sp_4096_mont_sqr_35(t[24], t[12], m, mp);
15926         sp_4096_mont_mul_35(t[25], t[13], t[12], m, mp);
15927         sp_4096_mont_sqr_35(t[26], t[13], m, mp);
15928         sp_4096_mont_mul_35(t[27], t[14], t[13], m, mp);
15929         sp_4096_mont_sqr_35(t[28], t[14], m, mp);
15930         sp_4096_mont_mul_35(t[29], t[15], t[14], m, mp);
15931         sp_4096_mont_sqr_35(t[30], t[15], m, mp);
15932         sp_4096_mont_mul_35(t[31], t[16], t[15], m, mp);
15933 
15934         bits = ((bits + 4) / 5) * 5;
15935         i = ((bits + 58) / 59) - 1;
15936         c = bits % 59;
15937         if (c == 0) {
15938             c = 59;
15939         }
15940         if (i < 35) {
15941             n = e[i--] << (64 - c);
15942         }
15943         else {
15944             n = 0;
15945             i--;
15946         }
15947         if (c < 5) {
15948             n |= e[i--] << (5 - c);
15949             c += 59;
15950         }
15951         y = (int)((n >> 59) & 0x1f);
15952         n <<= 5;
15953         c -= 5;
15954         XMEMCPY(rt, t[y], sizeof(sp_digit) * 70);
15955         while ((i >= 0) || (c >= 5)) {
15956             if (c >= 5) {
15957                 y = (byte)((n >> 59) & 0x1f);
15958                 n <<= 5;
15959                 c -= 5;
15960             }
15961             else if (c == 0) {
15962                 n = e[i--] << 5;
15963                 y = (byte)((n >> 59) & 0x1f);
15964                 n <<= 5;
15965                 c = 54;
15966             }
15967             else {
15968                 y = (byte)((n >> 59) & 0x1f);
15969                 n = e[i--] << 5;
15970                 c = 5 - c;
15971                 y |= (byte)((n >> (64 - c)) & ((1 << c) - 1));
15972                 n <<= c;
15973                 c = 59 - c;
15974             }
15975 
15976             sp_4096_mont_sqr_35(rt, rt, m, mp);
15977             sp_4096_mont_sqr_35(rt, rt, m, mp);
15978             sp_4096_mont_sqr_35(rt, rt, m, mp);
15979             sp_4096_mont_sqr_35(rt, rt, m, mp);
15980             sp_4096_mont_sqr_35(rt, rt, m, mp);
15981 
15982             sp_4096_mont_mul_35(rt, rt, t[y], m, mp);
15983         }
15984 
15985         sp_4096_mont_reduce_35(rt, m, mp);
15986         n = sp_4096_cmp_35(rt, m);
15987         sp_4096_cond_sub_35(rt, rt, m, ((n < 0) ?
15988                    (sp_digit)1 : (sp_digit)0) - 1);
15989         XMEMCPY(r, rt, sizeof(sp_digit) * 70);
15990     }
15991 
15992 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
15993     if (td != NULL)
15994         XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);
15995 #endif
15996 
15997     return err;
15998 #endif
15999 }
16000 
16001 #endif /* WOLFSSL_HAVE_SP_RSA & !SP_RSA_PRIVATE_EXP_D */
16002 #endif /* (WOLFSSL_HAVE_SP_RSA | WOLFSSL_HAVE_SP_DH) & !WOLFSSL_RSA_PUBLIC_ONLY */
16003 
16004 /* Sub b from a into r. (r = a - b)
16005  *
16006  * r  A single precision integer.
16007  * a  A single precision integer.
16008  * b  A single precision integer.
16009  */
sp_4096_sub_70(sp_digit * r,const sp_digit * a,const sp_digit * b)16010 SP_NOINLINE static int sp_4096_sub_70(sp_digit* r, const sp_digit* a,
16011         const sp_digit* b)
16012 {
16013     int i;
16014 
16015     for (i = 0; i < 70; i++) {
16016         r[i] = a[i] - b[i];
16017     }
16018 
16019     return 0;
16020 }
16021 
16022 /* r = 2^n mod m where n is the number of bits to reduce by.
16023  * Given m must be 4096 bits, just need to subtract.
16024  *
16025  * r  A single precision number.
16026  * m  A single precision number.
16027  */
sp_4096_mont_norm_70(sp_digit * r,const sp_digit * m)16028 static void sp_4096_mont_norm_70(sp_digit* r, const sp_digit* m)
16029 {
16030     /* Set r = 2^n - 1. */
16031     int i;
16032 
16033     for (i=0; i<69; i++) {
16034         r[i] = 0x7ffffffffffffffL;
16035     }
16036     r[69] = 0x1ffffffL;
16037 
16038     /* r = (2^n - 1) mod n */
16039     (void)sp_4096_sub_70(r, r, m);
16040 
16041     /* Add one so r = 2^n mod m */
16042     r[0] += 1;
16043 }
16044 
16045 /* Compare a with b in constant time.
16046  *
16047  * a  A single precision integer.
16048  * b  A single precision integer.
16049  * return -ve, 0 or +ve if a is less than, equal to or greater than b
16050  * respectively.
16051  */
sp_4096_cmp_70(const sp_digit * a,const sp_digit * b)16052 static sp_digit sp_4096_cmp_70(const sp_digit* a, const sp_digit* b)
16053 {
16054     sp_digit r = 0;
16055     int i;
16056 
16057     for (i=69; i>=0; i--) {
16058         r |= (a[i] - b[i]) & (0 - (sp_digit)((r == 0) ? 1 : 0));
16059     }
16060 
16061     return r;
16062 }
16063 
16064 /* Conditionally subtract b from a using the mask m.
16065  * m is -1 to subtract and 0 when not.
16066  *
16067  * r  A single precision number representing condition subtract result.
16068  * a  A single precision number to subtract from.
16069  * b  A single precision number to subtract.
16070  * m  Mask value to apply.
16071  */
sp_4096_cond_sub_70(sp_digit * r,const sp_digit * a,const sp_digit * b,const sp_digit m)16072 static void sp_4096_cond_sub_70(sp_digit* r, const sp_digit* a,
16073         const sp_digit* b, const sp_digit m)
16074 {
16075     int i;
16076 
16077     for (i = 0; i < 70; i++) {
16078         r[i] = a[i] - (b[i] & m);
16079     }
16080 }
16081 
16082 /* Mul a by scalar b and add into r. (r += a * b)
16083  *
16084  * r  A single precision integer.
16085  * a  A single precision integer.
16086  * b  A scalar.
16087  */
sp_4096_mul_add_70(sp_digit * r,const sp_digit * a,const sp_digit b)16088 SP_NOINLINE static void sp_4096_mul_add_70(sp_digit* r, const sp_digit* a,
16089         const sp_digit b)
16090 {
16091     sp_int128 tb = b;
16092     sp_int128 t[4];
16093     int i;
16094 
16095     t[0] = 0;
16096     for (i = 0; i < 68; i += 4) {
16097         t[0] += (tb * a[i+0]) + r[i+0];
16098         t[1]  = (tb * a[i+1]) + r[i+1];
16099         t[2]  = (tb * a[i+2]) + r[i+2];
16100         t[3]  = (tb * a[i+3]) + r[i+3];
16101         r[i+0] = t[0] & 0x7ffffffffffffffL;
16102         t[1] += t[0] >> 59;
16103         r[i+1] = t[1] & 0x7ffffffffffffffL;
16104         t[2] += t[1] >> 59;
16105         r[i+2] = t[2] & 0x7ffffffffffffffL;
16106         t[3] += t[2] >> 59;
16107         r[i+3] = t[3] & 0x7ffffffffffffffL;
16108         t[0]  = t[3] >> 59;
16109     }
16110     t[0] += (tb * a[68]) + r[68];
16111     t[1]  = (tb * a[69]) + r[69];
16112     r[68] = t[0] & 0x7ffffffffffffffL;
16113     t[1] += t[0] >> 59;
16114     r[69] = t[1] & 0x7ffffffffffffffL;
16115     r[70] +=  (sp_digit)(t[1] >> 59);
16116 }
16117 
16118 /* Shift the result in the high 4096 bits down to the bottom.
16119  *
16120  * r  A single precision number.
16121  * a  A single precision number.
16122  */
sp_4096_mont_shift_70(sp_digit * r,const sp_digit * a)16123 static void sp_4096_mont_shift_70(sp_digit* r, const sp_digit* a)
16124 {
16125     int i;
16126     sp_int128 n = a[69] >> 25;
16127     n += ((sp_int128)a[70]) << 34;
16128 
16129     for (i = 0; i < 69; i++) {
16130         r[i] = n & 0x7ffffffffffffffL;
16131         n >>= 59;
16132         n += ((sp_int128)a[71 + i]) << 34;
16133     }
16134     r[69] = (sp_digit)n;
16135     XMEMSET(&r[70], 0, sizeof(*r) * 70U);
16136 }
16137 
16138 /* Reduce the number back to 4096 bits using Montgomery reduction.
16139  *
16140  * a   A single precision number to reduce in place.
16141  * m   The single precision number representing the modulus.
16142  * mp  The digit representing the negative inverse of m mod 2^n.
16143  */
sp_4096_mont_reduce_70(sp_digit * a,const sp_digit * m,sp_digit mp)16144 static void sp_4096_mont_reduce_70(sp_digit* a, const sp_digit* m, sp_digit mp)
16145 {
16146     int i;
16147     sp_digit mu;
16148 
16149     sp_4096_norm_70(a + 70);
16150 
16151 #ifdef WOLFSSL_SP_DH
16152     if (mp != 1) {
16153         for (i=0; i<69; i++) {
16154             mu = (a[i] * mp) & 0x7ffffffffffffffL;
16155             sp_4096_mul_add_70(a+i, m, mu);
16156             a[i+1] += a[i] >> 59;
16157         }
16158         mu = (a[i] * mp) & 0x1ffffffL;
16159         sp_4096_mul_add_70(a+i, m, mu);
16160         a[i+1] += a[i] >> 59;
16161         a[i] &= 0x7ffffffffffffffL;
16162     }
16163     else {
16164         for (i=0; i<69; i++) {
16165             mu = a[i] & 0x7ffffffffffffffL;
16166             sp_4096_mul_add_70(a+i, m, mu);
16167             a[i+1] += a[i] >> 59;
16168         }
16169         mu = a[i] & 0x1ffffffL;
16170         sp_4096_mul_add_70(a+i, m, mu);
16171         a[i+1] += a[i] >> 59;
16172         a[i] &= 0x7ffffffffffffffL;
16173     }
16174 #else
16175     for (i=0; i<69; i++) {
16176         mu = (a[i] * mp) & 0x7ffffffffffffffL;
16177         sp_4096_mul_add_70(a+i, m, mu);
16178         a[i+1] += a[i] >> 59;
16179     }
16180     mu = (a[i] * mp) & 0x1ffffffL;
16181     sp_4096_mul_add_70(a+i, m, mu);
16182     a[i+1] += a[i] >> 59;
16183     a[i] &= 0x7ffffffffffffffL;
16184 #endif
16185     sp_4096_mont_shift_70(a, a);
16186     sp_4096_cond_sub_70(a, a, m, 0 - (((a[69] - m[69]) > 0) ?
16187             (sp_digit)1 : (sp_digit)0));
16188     sp_4096_norm_70(a);
16189 }
16190 
16191 /* Multiply two Montgomery form numbers mod the modulus (prime).
16192  * (r = a * b mod m)
16193  *
16194  * r   Result of multiplication.
16195  * a   First number to multiply in Montgomery form.
16196  * b   Second number to multiply in Montgomery form.
16197  * m   Modulus (prime).
16198  * mp  Montgomery mulitplier.
16199  */
sp_4096_mont_mul_70(sp_digit * r,const sp_digit * a,const sp_digit * b,const sp_digit * m,sp_digit mp)16200 static void sp_4096_mont_mul_70(sp_digit* r, const sp_digit* a,
16201         const sp_digit* b, const sp_digit* m, sp_digit mp)
16202 {
16203     sp_4096_mul_70(r, a, b);
16204     sp_4096_mont_reduce_70(r, m, mp);
16205 }
16206 
16207 /* Square the Montgomery form number. (r = a * a mod m)
16208  *
16209  * r   Result of squaring.
16210  * a   Number to square in Montgomery form.
16211  * m   Modulus (prime).
16212  * mp  Montgomery mulitplier.
16213  */
sp_4096_mont_sqr_70(sp_digit * r,const sp_digit * a,const sp_digit * m,sp_digit mp)16214 static void sp_4096_mont_sqr_70(sp_digit* r, const sp_digit* a,
16215         const sp_digit* m, sp_digit mp)
16216 {
16217     sp_4096_sqr_70(r, a);
16218     sp_4096_mont_reduce_70(r, m, mp);
16219 }
16220 
16221 /* Multiply a by scalar b into r. (r = a * b)
16222  *
16223  * r  A single precision integer.
16224  * a  A single precision integer.
16225  * b  A scalar.
16226  */
sp_4096_mul_d_140(sp_digit * r,const sp_digit * a,sp_digit b)16227 SP_NOINLINE static void sp_4096_mul_d_140(sp_digit* r, const sp_digit* a,
16228     sp_digit b)
16229 {
16230     sp_int128 tb = b;
16231     sp_int128 t = 0;
16232     int i;
16233 
16234     for (i = 0; i < 140; i++) {
16235         t += tb * a[i];
16236         r[i] = (sp_digit)(t & 0x7ffffffffffffffL);
16237         t >>= 59;
16238     }
16239     r[140] = (sp_digit)t;
16240 }
16241 
16242 /* Conditionally add a and b using the mask m.
16243  * m is -1 to add and 0 when not.
16244  *
16245  * r  A single precision number representing conditional add result.
16246  * a  A single precision number to add with.
16247  * b  A single precision number to add.
16248  * m  Mask value to apply.
16249  */
sp_4096_cond_add_70(sp_digit * r,const sp_digit * a,const sp_digit * b,const sp_digit m)16250 static void sp_4096_cond_add_70(sp_digit* r, const sp_digit* a,
16251         const sp_digit* b, const sp_digit m)
16252 {
16253     int i;
16254 
16255     for (i = 0; i < 35; i++) {
16256         r[i] = a[i] + (b[i] & m);
16257     }
16258 }
16259 
16260 /* Add b to a into r. (r = a + b)
16261  *
16262  * r  A single precision integer.
16263  * a  A single precision integer.
16264  * b  A single precision integer.
16265  */
sp_4096_add_70(sp_digit * r,const sp_digit * a,const sp_digit * b)16266 SP_NOINLINE static int sp_4096_add_70(sp_digit* r, const sp_digit* a,
16267         const sp_digit* b)
16268 {
16269     int i;
16270 
16271     for (i = 0; i < 70; i++) {
16272         r[i] = a[i] + b[i];
16273     }
16274 
16275     return 0;
16276 }
16277 
sp_4096_rshift_70(sp_digit * r,const sp_digit * a,byte n)16278 SP_NOINLINE static void sp_4096_rshift_70(sp_digit* r, const sp_digit* a,
16279         byte n)
16280 {
16281     int i;
16282 
16283     for (i=0; i<69; i++) {
16284         r[i] = ((a[i] >> n) | (a[i + 1] << (59 - n))) & 0x7ffffffffffffffL;
16285     }
16286     r[69] = a[69] >> n;
16287 }
16288 
16289 #ifdef WOLFSSL_SP_DIV_64
sp_4096_div_word_70(sp_digit d1,sp_digit d0,sp_digit dv)16290 static WC_INLINE sp_digit sp_4096_div_word_70(sp_digit d1, sp_digit d0,
16291     sp_digit dv)
16292 {
16293     sp_digit d;
16294     sp_digit r;
16295     sp_digit t;
16296 
16297     /* All 59 bits from d1 and top 4 bits from d0. */
16298     d = (d1 << 4) + (d0 >> 55);
16299     r = d / dv;
16300     d -= r * dv;
16301     /* Up to 5 bits in r */
16302     /* Next 4 bits from d0. */
16303     r <<= 4;
16304     d <<= 4;
16305     d += (d0 >> 51) & ((1 << 4) - 1);
16306     t = d / dv;
16307     d -= t * dv;
16308     r += t;
16309     /* Up to 9 bits in r */
16310     /* Next 4 bits from d0. */
16311     r <<= 4;
16312     d <<= 4;
16313     d += (d0 >> 47) & ((1 << 4) - 1);
16314     t = d / dv;
16315     d -= t * dv;
16316     r += t;
16317     /* Up to 13 bits in r */
16318     /* Next 4 bits from d0. */
16319     r <<= 4;
16320     d <<= 4;
16321     d += (d0 >> 43) & ((1 << 4) - 1);
16322     t = d / dv;
16323     d -= t * dv;
16324     r += t;
16325     /* Up to 17 bits in r */
16326     /* Next 4 bits from d0. */
16327     r <<= 4;
16328     d <<= 4;
16329     d += (d0 >> 39) & ((1 << 4) - 1);
16330     t = d / dv;
16331     d -= t * dv;
16332     r += t;
16333     /* Up to 21 bits in r */
16334     /* Next 4 bits from d0. */
16335     r <<= 4;
16336     d <<= 4;
16337     d += (d0 >> 35) & ((1 << 4) - 1);
16338     t = d / dv;
16339     d -= t * dv;
16340     r += t;
16341     /* Up to 25 bits in r */
16342     /* Next 4 bits from d0. */
16343     r <<= 4;
16344     d <<= 4;
16345     d += (d0 >> 31) & ((1 << 4) - 1);
16346     t = d / dv;
16347     d -= t * dv;
16348     r += t;
16349     /* Up to 29 bits in r */
16350     /* Next 4 bits from d0. */
16351     r <<= 4;
16352     d <<= 4;
16353     d += (d0 >> 27) & ((1 << 4) - 1);
16354     t = d / dv;
16355     d -= t * dv;
16356     r += t;
16357     /* Up to 33 bits in r */
16358     /* Next 4 bits from d0. */
16359     r <<= 4;
16360     d <<= 4;
16361     d += (d0 >> 23) & ((1 << 4) - 1);
16362     t = d / dv;
16363     d -= t * dv;
16364     r += t;
16365     /* Up to 37 bits in r */
16366     /* Next 4 bits from d0. */
16367     r <<= 4;
16368     d <<= 4;
16369     d += (d0 >> 19) & ((1 << 4) - 1);
16370     t = d / dv;
16371     d -= t * dv;
16372     r += t;
16373     /* Up to 41 bits in r */
16374     /* Next 4 bits from d0. */
16375     r <<= 4;
16376     d <<= 4;
16377     d += (d0 >> 15) & ((1 << 4) - 1);
16378     t = d / dv;
16379     d -= t * dv;
16380     r += t;
16381     /* Up to 45 bits in r */
16382     /* Next 4 bits from d0. */
16383     r <<= 4;
16384     d <<= 4;
16385     d += (d0 >> 11) & ((1 << 4) - 1);
16386     t = d / dv;
16387     d -= t * dv;
16388     r += t;
16389     /* Up to 49 bits in r */
16390     /* Next 4 bits from d0. */
16391     r <<= 4;
16392     d <<= 4;
16393     d += (d0 >> 7) & ((1 << 4) - 1);
16394     t = d / dv;
16395     d -= t * dv;
16396     r += t;
16397     /* Up to 53 bits in r */
16398     /* Next 4 bits from d0. */
16399     r <<= 4;
16400     d <<= 4;
16401     d += (d0 >> 3) & ((1 << 4) - 1);
16402     t = d / dv;
16403     d -= t * dv;
16404     r += t;
16405     /* Up to 57 bits in r */
16406     /* Remaining 3 bits from d0. */
16407     r <<= 3;
16408     d <<= 3;
16409     d += d0 & ((1 << 3) - 1);
16410     t = d / dv;
16411     r += t;
16412 
16413     /* All 59 bits from d1 and top 4 bits from d0. */
16414     return r;
16415 }
16416 #endif /* WOLFSSL_SP_DIV_64 */
16417 
16418 /* Divide d in a and put remainder into r (m*d + r = a)
16419  * m is not calculated as it is not needed at this time.
16420  *
16421  * Full implementation.
16422  *
16423  * a  Number to be divided.
16424  * d  Number to divide with.
16425  * m  Multiplier result.
16426  * r  Remainder from the division.
16427  * returns MEMORY_E when unable to allocate memory and MP_OKAY otherwise.
16428  */
sp_4096_div_70(const sp_digit * a,const sp_digit * d,const sp_digit * m,sp_digit * r)16429 static int sp_4096_div_70(const sp_digit* a, const sp_digit* d,
16430         const sp_digit* m, sp_digit* r)
16431 {
16432     int i;
16433 #ifndef WOLFSSL_SP_DIV_64
16434     sp_int128 d1;
16435 #endif
16436     sp_digit dv;
16437     sp_digit r1;
16438 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
16439     sp_digit* t1 = NULL;
16440 #else
16441     sp_digit t1[4 * 70 + 3];
16442 #endif
16443     sp_digit* t2 = NULL;
16444     sp_digit* sd = NULL;
16445     int err = MP_OKAY;
16446 
16447     (void)m;
16448 
16449 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
16450     t1 = (sp_digit*)XMALLOC(sizeof(sp_digit) * (4 * 70 + 3), NULL,
16451                                                        DYNAMIC_TYPE_TMP_BUFFER);
16452     if (t1 == NULL)
16453         err = MEMORY_E;
16454 #endif
16455 
16456     (void)m;
16457 
16458     if (err == MP_OKAY) {
16459         t2 = t1 + 140 + 1;
16460         sd = t2 + 70 + 1;
16461 
16462         sp_4096_mul_d_70(sd, d, (sp_digit)1 << 34);
16463         sp_4096_mul_d_140(t1, a, (sp_digit)1 << 34);
16464         dv = sd[69];
16465         t1[70 + 70] += t1[70 + 70 - 1] >> 59;
16466         t1[70 + 70 - 1] &= 0x7ffffffffffffffL;
16467         for (i=70; i>=0; i--) {
16468 #ifndef WOLFSSL_SP_DIV_64
16469             d1 = t1[70 + i];
16470             d1 <<= 59;
16471             d1 += t1[70 + i - 1];
16472             r1 = (sp_digit)(d1 / dv);
16473 #else
16474             r1 = sp_4096_div_word_70(t1[70 + i], t1[70 + i - 1], dv);
16475 #endif
16476 
16477             sp_4096_mul_d_70(t2, sd, r1);
16478             (void)sp_4096_sub_70(&t1[i], &t1[i], t2);
16479             sp_4096_norm_70(&t1[i]);
16480             t1[70 + i] -= t2[70];
16481             t1[70 + i] += t1[70 + i - 1] >> 59;
16482             t1[70 + i - 1] &= 0x7ffffffffffffffL;
16483 #ifndef WOLFSSL_SP_DIV_64
16484             d1 = -t1[70 + i];
16485             d1 <<= 59;
16486             d1 -= t1[70 + i - 1];
16487             r1 = (sp_digit)(d1 / dv);
16488 #else
16489             r1 = sp_4096_div_word_70(-t1[70 + i], -t1[70 + i - 1], dv);
16490 #endif
16491             r1 -= t1[70 + i];
16492             sp_4096_mul_d_70(t2, sd, r1);
16493             (void)sp_4096_add_70(&t1[i], &t1[i], t2);
16494             t1[70 + i] += t1[70 + i - 1] >> 59;
16495             t1[70 + i - 1] &= 0x7ffffffffffffffL;
16496         }
16497         t1[70 - 1] += t1[70 - 2] >> 59;
16498         t1[70 - 2] &= 0x7ffffffffffffffL;
16499         r1 = t1[70 - 1] / dv;
16500 
16501         sp_4096_mul_d_70(t2, sd, r1);
16502         sp_4096_sub_70(t1, t1, t2);
16503         XMEMCPY(r, t1, sizeof(*r) * 140U);
16504         for (i=0; i<69; i++) {
16505             r[i+1] += r[i] >> 59;
16506             r[i] &= 0x7ffffffffffffffL;
16507         }
16508         sp_4096_cond_add_70(r, r, sd, 0 - ((r[69] < 0) ?
16509                     (sp_digit)1 : (sp_digit)0));
16510 
16511         sp_4096_norm_70(r);
16512         sp_4096_rshift_70(r, r, 34);
16513     }
16514 
16515 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
16516     if (t1 != NULL)
16517         XFREE(t1, NULL, DYNAMIC_TYPE_TMP_BUFFER);
16518 #endif
16519 
16520     return err;
16521 }
16522 
16523 /* Reduce a modulo m into r. (r = a mod m)
16524  *
16525  * r  A single precision number that is the reduced result.
16526  * a  A single precision number that is to be reduced.
16527  * m  A single precision number that is the modulus to reduce with.
16528  * returns MEMORY_E when unable to allocate memory and MP_OKAY otherwise.
16529  */
sp_4096_mod_70(sp_digit * r,const sp_digit * a,const sp_digit * m)16530 static int sp_4096_mod_70(sp_digit* r, const sp_digit* a, const sp_digit* m)
16531 {
16532     return sp_4096_div_70(a, m, NULL, r);
16533 }
16534 
16535 #if (defined(WOLFSSL_HAVE_SP_RSA) && !defined(WOLFSSL_RSA_PUBLIC_ONLY)) || defined(WOLFSSL_HAVE_SP_DH)
16536 /* Modular exponentiate a to the e mod m. (r = a^e mod m)
16537  *
16538  * r     A single precision number that is the result of the operation.
16539  * a     A single precision number being exponentiated.
16540  * e     A single precision number that is the exponent.
16541  * bits  The number of bits in the exponent.
16542  * m     A single precision number that is the modulus.
16543  * returns  0 on success.
16544  * returns  MEMORY_E on dynamic memory allocation failure.
16545  * returns  MP_VAL when base is even or exponent is 0.
16546  */
sp_4096_mod_exp_70(sp_digit * r,const sp_digit * a,const sp_digit * e,int bits,const sp_digit * m,int reduceA)16547 static int sp_4096_mod_exp_70(sp_digit* r, const sp_digit* a, const sp_digit* e,
16548     int bits, const sp_digit* m, int reduceA)
16549 {
16550 #if defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SP_FAST_MODEXP)
16551 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
16552     sp_digit* td = NULL;
16553 #else
16554     sp_digit td[3 * 140];
16555 #endif
16556     sp_digit* t[3] = {0, 0, 0};
16557     sp_digit* norm = NULL;
16558     sp_digit mp = 1;
16559     sp_digit n;
16560     int i;
16561     int c;
16562     byte y;
16563     int err = MP_OKAY;
16564 
16565     if ((m[0] & 1) == 0) {
16566         err = MP_VAL;
16567     }
16568     else if (bits == 0) {
16569         err = MP_VAL;
16570     }
16571 
16572 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
16573     if (err == MP_OKAY) {
16574         td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 3 * 70 * 2, NULL,
16575                                 DYNAMIC_TYPE_TMP_BUFFER);
16576         if (td == NULL)
16577             err = MEMORY_E;
16578     }
16579 #endif
16580 
16581     if (err == MP_OKAY) {
16582         norm = td;
16583         for (i=0; i<3; i++) {
16584             t[i] = td + (i * 70 * 2);
16585             XMEMSET(t[i], 0, sizeof(sp_digit) * 70U * 2U);
16586         }
16587 
16588         sp_4096_mont_setup(m, &mp);
16589         sp_4096_mont_norm_70(norm, m);
16590 
16591         if (reduceA != 0) {
16592             err = sp_4096_mod_70(t[1], a, m);
16593         }
16594         else {
16595             XMEMCPY(t[1], a, sizeof(sp_digit) * 70U);
16596         }
16597     }
16598     if (err == MP_OKAY) {
16599         sp_4096_mul_70(t[1], t[1], norm);
16600         err = sp_4096_mod_70(t[1], t[1], m);
16601     }
16602 
16603     if (err == MP_OKAY) {
16604         i = bits / 59;
16605         c = bits % 59;
16606         n = e[i--] << (59 - c);
16607         for (; ; c--) {
16608             if (c == 0) {
16609                 if (i == -1) {
16610                     break;
16611                 }
16612 
16613                 n = e[i--];
16614                 c = 59;
16615             }
16616 
16617             y = (int)((n >> 58) & 1);
16618             n <<= 1;
16619 
16620             sp_4096_mont_mul_70(t[y^1], t[0], t[1], m, mp);
16621 
16622             XMEMCPY(t[2], (void*)(((size_t)t[0] & addr_mask[y^1]) +
16623                                   ((size_t)t[1] & addr_mask[y])),
16624                                   sizeof(*t[2]) * 70 * 2);
16625             sp_4096_mont_sqr_70(t[2], t[2], m, mp);
16626             XMEMCPY((void*)(((size_t)t[0] & addr_mask[y^1]) +
16627                             ((size_t)t[1] & addr_mask[y])), t[2],
16628                             sizeof(*t[2]) * 70 * 2);
16629         }
16630 
16631         sp_4096_mont_reduce_70(t[0], m, mp);
16632         n = sp_4096_cmp_70(t[0], m);
16633         sp_4096_cond_sub_70(t[0], t[0], m, ((n < 0) ?
16634                     (sp_digit)1 : (sp_digit)0) - 1);
16635         XMEMCPY(r, t[0], sizeof(*r) * 70 * 2);
16636 
16637     }
16638 
16639 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
16640     if (td != NULL)
16641         XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);
16642 #endif
16643 
16644     return err;
16645 #elif !defined(WC_NO_CACHE_RESISTANT)
16646 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
16647     sp_digit* td = NULL;
16648 #else
16649     sp_digit td[3 * 140];
16650 #endif
16651     sp_digit* t[3] = {0, 0, 0};
16652     sp_digit* norm = NULL;
16653     sp_digit mp = 1;
16654     sp_digit n;
16655     int i;
16656     int c;
16657     byte y;
16658     int err = MP_OKAY;
16659 
16660     if ((m[0] & 1) == 0) {
16661         err = MP_VAL;
16662     }
16663     else if (bits == 0) {
16664         err = MP_VAL;
16665     }
16666 
16667 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
16668     if (err == MP_OKAY) {
16669         td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 3 * 70 * 2, NULL,
16670                                 DYNAMIC_TYPE_TMP_BUFFER);
16671         if (td == NULL)
16672             err = MEMORY_E;
16673     }
16674 #endif
16675 
16676     if (err == MP_OKAY) {
16677         norm = td;
16678         for (i=0; i<3; i++) {
16679             t[i] = td + (i * 70 * 2);
16680         }
16681 
16682         sp_4096_mont_setup(m, &mp);
16683         sp_4096_mont_norm_70(norm, m);
16684 
16685         if (reduceA != 0) {
16686             err = sp_4096_mod_70(t[1], a, m);
16687             if (err == MP_OKAY) {
16688                 sp_4096_mul_70(t[1], t[1], norm);
16689                 err = sp_4096_mod_70(t[1], t[1], m);
16690             }
16691         }
16692         else {
16693             sp_4096_mul_70(t[1], a, norm);
16694             err = sp_4096_mod_70(t[1], t[1], m);
16695         }
16696     }
16697 
16698     if (err == MP_OKAY) {
16699         i = bits / 59;
16700         c = bits % 59;
16701         n = e[i--] << (59 - c);
16702         for (; ; c--) {
16703             if (c == 0) {
16704                 if (i == -1) {
16705                     break;
16706                 }
16707 
16708                 n = e[i--];
16709                 c = 59;
16710             }
16711 
16712             y = (int)((n >> 58) & 1);
16713             n <<= 1;
16714 
16715             sp_4096_mont_mul_70(t[y^1], t[0], t[1], m, mp);
16716 
16717             XMEMCPY(t[2], (void*)(((size_t)t[0] & addr_mask[y^1]) +
16718                                   ((size_t)t[1] & addr_mask[y])),
16719                                   sizeof(*t[2]) * 70 * 2);
16720             sp_4096_mont_sqr_70(t[2], t[2], m, mp);
16721             XMEMCPY((void*)(((size_t)t[0] & addr_mask[y^1]) +
16722                             ((size_t)t[1] & addr_mask[y])), t[2],
16723                             sizeof(*t[2]) * 70 * 2);
16724         }
16725 
16726         sp_4096_mont_reduce_70(t[0], m, mp);
16727         n = sp_4096_cmp_70(t[0], m);
16728         sp_4096_cond_sub_70(t[0], t[0], m, ((n < 0) ?
16729                     (sp_digit)1 : (sp_digit)0) - 1);
16730         XMEMCPY(r, t[0], sizeof(*r) * 70 * 2);
16731     }
16732 
16733 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
16734     if (td != NULL)
16735         XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);
16736 #endif
16737 
16738     return err;
16739 #else
16740 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
16741     sp_digit* td = NULL;
16742 #else
16743     sp_digit td[(16 * 140) + 140];
16744 #endif
16745     sp_digit* t[16];
16746     sp_digit* rt = NULL;
16747     sp_digit* norm = NULL;
16748     sp_digit mp = 1;
16749     sp_digit n;
16750     int i;
16751     int c;
16752     byte y;
16753     int err = MP_OKAY;
16754 
16755     if ((m[0] & 1) == 0) {
16756         err = MP_VAL;
16757     }
16758     else if (bits == 0) {
16759         err = MP_VAL;
16760     }
16761 
16762 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
16763     if (err == MP_OKAY) {
16764         td = (sp_digit*)XMALLOC(sizeof(sp_digit) * ((16 * 140) + 140), NULL,
16765                                 DYNAMIC_TYPE_TMP_BUFFER);
16766         if (td == NULL)
16767             err = MEMORY_E;
16768     }
16769 #endif
16770 
16771     if (err == MP_OKAY) {
16772         norm = td;
16773         for (i=0; i<16; i++)
16774             t[i] = td + i * 140;
16775         rt = td + 2240;
16776 
16777         sp_4096_mont_setup(m, &mp);
16778         sp_4096_mont_norm_70(norm, m);
16779 
16780         if (reduceA != 0) {
16781             err = sp_4096_mod_70(t[1], a, m);
16782             if (err == MP_OKAY) {
16783                 sp_4096_mul_70(t[1], t[1], norm);
16784                 err = sp_4096_mod_70(t[1], t[1], m);
16785             }
16786         }
16787         else {
16788             sp_4096_mul_70(t[1], a, norm);
16789             err = sp_4096_mod_70(t[1], t[1], m);
16790         }
16791     }
16792 
16793     if (err == MP_OKAY) {
16794         sp_4096_mont_sqr_70(t[ 2], t[ 1], m, mp);
16795         sp_4096_mont_mul_70(t[ 3], t[ 2], t[ 1], m, mp);
16796         sp_4096_mont_sqr_70(t[ 4], t[ 2], m, mp);
16797         sp_4096_mont_mul_70(t[ 5], t[ 3], t[ 2], m, mp);
16798         sp_4096_mont_sqr_70(t[ 6], t[ 3], m, mp);
16799         sp_4096_mont_mul_70(t[ 7], t[ 4], t[ 3], m, mp);
16800         sp_4096_mont_sqr_70(t[ 8], t[ 4], m, mp);
16801         sp_4096_mont_mul_70(t[ 9], t[ 5], t[ 4], m, mp);
16802         sp_4096_mont_sqr_70(t[10], t[ 5], m, mp);
16803         sp_4096_mont_mul_70(t[11], t[ 6], t[ 5], m, mp);
16804         sp_4096_mont_sqr_70(t[12], t[ 6], m, mp);
16805         sp_4096_mont_mul_70(t[13], t[ 7], t[ 6], m, mp);
16806         sp_4096_mont_sqr_70(t[14], t[ 7], m, mp);
16807         sp_4096_mont_mul_70(t[15], t[ 8], t[ 7], m, mp);
16808 
16809         bits = ((bits + 3) / 4) * 4;
16810         i = ((bits + 58) / 59) - 1;
16811         c = bits % 59;
16812         if (c == 0) {
16813             c = 59;
16814         }
16815         if (i < 70) {
16816             n = e[i--] << (64 - c);
16817         }
16818         else {
16819             n = 0;
16820             i--;
16821         }
16822         if (c < 4) {
16823             n |= e[i--] << (5 - c);
16824             c += 59;
16825         }
16826         y = (int)((n >> 60) & 0xf);
16827         n <<= 4;
16828         c -= 4;
16829         XMEMCPY(rt, t[y], sizeof(sp_digit) * 140);
16830         while ((i >= 0) || (c >= 4)) {
16831             if (c >= 4) {
16832                 y = (byte)((n >> 60) & 0xf);
16833                 n <<= 4;
16834                 c -= 4;
16835             }
16836             else if (c == 0) {
16837                 n = e[i--] << 5;
16838                 y = (byte)((n >> 60) & 0xf);
16839                 n <<= 4;
16840                 c = 55;
16841             }
16842             else {
16843                 y = (byte)((n >> 60) & 0xf);
16844                 n = e[i--] << 5;
16845                 c = 4 - c;
16846                 y |= (byte)((n >> (64 - c)) & ((1 << c) - 1));
16847                 n <<= c;
16848                 c = 59 - c;
16849             }
16850 
16851             sp_4096_mont_sqr_70(rt, rt, m, mp);
16852             sp_4096_mont_sqr_70(rt, rt, m, mp);
16853             sp_4096_mont_sqr_70(rt, rt, m, mp);
16854             sp_4096_mont_sqr_70(rt, rt, m, mp);
16855 
16856             sp_4096_mont_mul_70(rt, rt, t[y], m, mp);
16857         }
16858 
16859         sp_4096_mont_reduce_70(rt, m, mp);
16860         n = sp_4096_cmp_70(rt, m);
16861         sp_4096_cond_sub_70(rt, rt, m, ((n < 0) ?
16862                    (sp_digit)1 : (sp_digit)0) - 1);
16863         XMEMCPY(r, rt, sizeof(sp_digit) * 140);
16864     }
16865 
16866 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
16867     if (td != NULL)
16868         XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);
16869 #endif
16870 
16871     return err;
16872 #endif
16873 }
16874 
16875 #endif /* (WOLFSSL_HAVE_SP_RSA && !WOLFSSL_RSA_PUBLIC_ONLY) || WOLFSSL_HAVE_SP_DH */
16876 #ifdef WOLFSSL_HAVE_SP_RSA
16877 /* RSA public key operation.
16878  *
16879  * in      Array of bytes representing the number to exponentiate, base.
16880  * inLen   Number of bytes in base.
16881  * em      Public exponent.
16882  * mm      Modulus.
16883  * out     Buffer to hold big-endian bytes of exponentiation result.
16884  *         Must be at least 512 bytes long.
16885  * outLen  Number of bytes in result.
16886  * returns 0 on success, MP_TO_E when the outLen is too small, MP_READ_E when
16887  * an array is too long and MEMORY_E when dynamic memory allocation fails.
16888  */
sp_RsaPublic_4096(const byte * in,word32 inLen,const mp_int * em,const mp_int * mm,byte * out,word32 * outLen)16889 int sp_RsaPublic_4096(const byte* in, word32 inLen, const mp_int* em,
16890     const mp_int* mm, byte* out, word32* outLen)
16891 {
16892 #ifdef WOLFSSL_SP_SMALL
16893 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
16894     sp_digit* a = NULL;
16895 #else
16896     sp_digit a[70 * 5];
16897 #endif
16898     sp_digit* m = NULL;
16899     sp_digit* r = NULL;
16900     sp_digit* norm = NULL;
16901     sp_digit e[1] = {0};
16902     sp_digit mp;
16903     int i;
16904     int err = MP_OKAY;
16905 
16906     if (*outLen < 512U) {
16907         err = MP_TO_E;
16908     }
16909 
16910     if (err == MP_OKAY) {
16911         if (mp_count_bits(em) > 59) {
16912             err = MP_READ_E;
16913         }
16914         else if (inLen > 512U) {
16915             err = MP_READ_E;
16916         }
16917         else if (mp_count_bits(mm) != 4096) {
16918             err = MP_READ_E;
16919         }
16920         else if (mp_iseven(mm)) {
16921             err = MP_VAL;
16922         }
16923     }
16924 
16925 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
16926     if (err == MP_OKAY) {
16927         a = (sp_digit*)XMALLOC(sizeof(sp_digit) * 70 * 5, NULL,
16928                                                               DYNAMIC_TYPE_RSA);
16929         if (a == NULL)
16930             err = MEMORY_E;
16931     }
16932 #endif
16933 
16934     if (err == MP_OKAY) {
16935         r = a + 70 * 2;
16936         m = r + 70 * 2;
16937         norm = r;
16938 
16939         sp_4096_from_bin(a, 70, in, inLen);
16940 #if DIGIT_BIT >= 59
16941         e[0] = (sp_digit)em->dp[0];
16942 #else
16943         e[0] = (sp_digit)em->dp[0];
16944         if (em->used > 1) {
16945             e[0] |= ((sp_digit)em->dp[1]) << DIGIT_BIT;
16946         }
16947 #endif
16948         if (e[0] == 0) {
16949             err = MP_EXPTMOD_E;
16950         }
16951     }
16952 
16953     if (err == MP_OKAY) {
16954         sp_4096_from_mp(m, 70, mm);
16955 
16956         sp_4096_mont_setup(m, &mp);
16957         sp_4096_mont_norm_70(norm, m);
16958     }
16959     if (err == MP_OKAY) {
16960         sp_4096_mul_70(a, a, norm);
16961         err = sp_4096_mod_70(a, a, m);
16962     }
16963     if (err == MP_OKAY) {
16964         for (i=58; i>=0; i--) {
16965             if ((e[0] >> i) != 0) {
16966                 break;
16967             }
16968         }
16969 
16970         XMEMCPY(r, a, sizeof(sp_digit) * 70 * 2);
16971         for (i--; i>=0; i--) {
16972             sp_4096_mont_sqr_70(r, r, m, mp);
16973 
16974             if (((e[0] >> i) & 1) == 1) {
16975                 sp_4096_mont_mul_70(r, r, a, m, mp);
16976             }
16977         }
16978         sp_4096_mont_reduce_70(r, m, mp);
16979         mp = sp_4096_cmp_70(r, m);
16980         sp_4096_cond_sub_70(r, r, m, ((mp < 0) ?
16981                     (sp_digit)1 : (sp_digit)0)- 1);
16982 
16983         sp_4096_to_bin_70(r, out);
16984         *outLen = 512;
16985     }
16986 
16987 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
16988     if (a != NULL)
16989         XFREE(a, NULL, DYNAMIC_TYPE_RSA);
16990 #endif
16991 
16992     return err;
16993 #else
16994 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
16995     sp_digit* d = NULL;
16996 #else
16997     sp_digit d[70 * 5];
16998 #endif
16999     sp_digit* a = NULL;
17000     sp_digit* m = NULL;
17001     sp_digit* r = NULL;
17002     sp_digit e[1] = {0};
17003     int err = MP_OKAY;
17004 
17005     if (*outLen < 512U) {
17006         err = MP_TO_E;
17007     }
17008     if (err == MP_OKAY) {
17009         if (mp_count_bits(em) > 59) {
17010             err = MP_READ_E;
17011         }
17012         else if (inLen > 512U) {
17013             err = MP_READ_E;
17014         }
17015         else if (mp_count_bits(mm) != 4096) {
17016             err = MP_READ_E;
17017         }
17018         else if (mp_iseven(mm)) {
17019             err = MP_VAL;
17020         }
17021     }
17022 
17023 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
17024     if (err == MP_OKAY) {
17025         d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 70 * 5, NULL,
17026                                                               DYNAMIC_TYPE_RSA);
17027         if (d == NULL)
17028             err = MEMORY_E;
17029     }
17030 #endif
17031 
17032     if (err == MP_OKAY) {
17033         a = d;
17034         r = a + 70 * 2;
17035         m = r + 70 * 2;
17036 
17037         sp_4096_from_bin(a, 70, in, inLen);
17038 #if DIGIT_BIT >= 59
17039         e[0] = (sp_digit)em->dp[0];
17040 #else
17041         e[0] = (sp_digit)em->dp[0];
17042         if (em->used > 1) {
17043             e[0] |= ((sp_digit)em->dp[1]) << DIGIT_BIT;
17044         }
17045 #endif
17046         if (e[0] == 0) {
17047             err = MP_EXPTMOD_E;
17048         }
17049     }
17050     if (err == MP_OKAY) {
17051         sp_4096_from_mp(m, 70, mm);
17052 
17053         if (e[0] == 0x3) {
17054             sp_4096_sqr_70(r, a);
17055             err = sp_4096_mod_70(r, r, m);
17056             if (err == MP_OKAY) {
17057                 sp_4096_mul_70(r, a, r);
17058                 err = sp_4096_mod_70(r, r, m);
17059             }
17060         }
17061         else {
17062             sp_digit* norm = r;
17063             int i;
17064             sp_digit mp;
17065 
17066             sp_4096_mont_setup(m, &mp);
17067             sp_4096_mont_norm_70(norm, m);
17068 
17069             sp_4096_mul_70(a, a, norm);
17070             err = sp_4096_mod_70(a, a, m);
17071 
17072             if (err == MP_OKAY) {
17073                 for (i=58; i>=0; i--) {
17074                     if ((e[0] >> i) != 0) {
17075                         break;
17076                     }
17077                 }
17078 
17079                 XMEMCPY(r, a, sizeof(sp_digit) * 140U);
17080                 for (i--; i>=0; i--) {
17081                     sp_4096_mont_sqr_70(r, r, m, mp);
17082 
17083                     if (((e[0] >> i) & 1) == 1) {
17084                         sp_4096_mont_mul_70(r, r, a, m, mp);
17085                     }
17086                 }
17087                 sp_4096_mont_reduce_70(r, m, mp);
17088                 mp = sp_4096_cmp_70(r, m);
17089                 sp_4096_cond_sub_70(r, r, m, ((mp < 0) ?
17090                            (sp_digit)1 : (sp_digit)0) - 1);
17091             }
17092         }
17093     }
17094 
17095     if (err == MP_OKAY) {
17096         sp_4096_to_bin_70(r, out);
17097         *outLen = 512;
17098     }
17099 
17100 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
17101     if (d != NULL)
17102         XFREE(d, NULL, DYNAMIC_TYPE_RSA);
17103 #endif
17104 
17105     return err;
17106 #endif /* WOLFSSL_SP_SMALL */
17107 }
17108 
17109 #ifndef WOLFSSL_RSA_PUBLIC_ONLY
17110 #if !defined(SP_RSA_PRIVATE_EXP_D) && !defined(RSA_LOW_MEM)
17111 #endif /* !SP_RSA_PRIVATE_EXP_D & !RSA_LOW_MEM */
17112 /* RSA private key operation.
17113  *
17114  * in      Array of bytes representing the number to exponentiate, base.
17115  * inLen   Number of bytes in base.
17116  * dm      Private exponent.
17117  * pm      First prime.
17118  * qm      Second prime.
17119  * dpm     First prime's CRT exponent.
17120  * dqm     Second prime's CRT exponent.
17121  * qim     Inverse of second prime mod p.
17122  * mm      Modulus.
17123  * out     Buffer to hold big-endian bytes of exponentiation result.
17124  *         Must be at least 512 bytes long.
17125  * outLen  Number of bytes in result.
17126  * returns 0 on success, MP_TO_E when the outLen is too small, MP_READ_E when
17127  * an array is too long and MEMORY_E when dynamic memory allocation fails.
17128  */
sp_RsaPrivate_4096(const byte * in,word32 inLen,const mp_int * dm,const mp_int * pm,const mp_int * qm,const mp_int * dpm,const mp_int * dqm,const mp_int * qim,const mp_int * mm,byte * out,word32 * outLen)17129 int sp_RsaPrivate_4096(const byte* in, word32 inLen, const mp_int* dm,
17130     const mp_int* pm, const mp_int* qm, const mp_int* dpm, const mp_int* dqm,
17131     const mp_int* qim, const mp_int* mm, byte* out, word32* outLen)
17132 {
17133 #if defined(SP_RSA_PRIVATE_EXP_D) || defined(RSA_LOW_MEM)
17134 #if defined(WOLFSSL_SP_SMALL)
17135 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
17136     sp_digit* d = NULL;
17137 #else
17138     sp_digit  d[70 * 4];
17139 #endif
17140     sp_digit* a = NULL;
17141     sp_digit* m = NULL;
17142     sp_digit* r = NULL;
17143     int err = MP_OKAY;
17144 
17145     (void)pm;
17146     (void)qm;
17147     (void)dpm;
17148     (void)dqm;
17149     (void)qim;
17150 
17151     if (*outLen < 512U) {
17152         err = MP_TO_E;
17153     }
17154     if (err == MP_OKAY) {
17155         if (mp_count_bits(dm) > 4096) {
17156            err = MP_READ_E;
17157         }
17158         else if (inLen > 512) {
17159             err = MP_READ_E;
17160         }
17161         else if (mp_count_bits(mm) != 4096) {
17162             err = MP_READ_E;
17163         }
17164         else if (mp_iseven(mm)) {
17165             err = MP_VAL;
17166         }
17167     }
17168 
17169 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
17170     if (err == MP_OKAY) {
17171         d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 70 * 4, NULL,
17172                                                               DYNAMIC_TYPE_RSA);
17173         if (d == NULL)
17174             err = MEMORY_E;
17175     }
17176 #endif
17177 
17178     if (err == MP_OKAY) {
17179         a = d + 70;
17180         m = a + 140;
17181         r = a;
17182 
17183         sp_4096_from_bin(a, 70, in, inLen);
17184         sp_4096_from_mp(d, 70, dm);
17185         sp_4096_from_mp(m, 70, mm);
17186         err = sp_4096_mod_exp_70(r, a, d, 4096, m, 0);
17187     }
17188 
17189     if (err == MP_OKAY) {
17190         sp_4096_to_bin_70(r, out);
17191         *outLen = 512;
17192     }
17193 
17194 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
17195     if (d != NULL)
17196 #endif
17197     {
17198         /* only "a" and "r" are sensitive and need zeroized (same pointer) */
17199         if (a != NULL)
17200             ForceZero(a, sizeof(sp_digit) * 70);
17201 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
17202         XFREE(d, NULL, DYNAMIC_TYPE_RSA);
17203 #endif
17204     }
17205 
17206     return err;
17207 #else
17208 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
17209     sp_digit* d = NULL;
17210 #else
17211     sp_digit d[70 * 4];
17212 #endif
17213     sp_digit* a = NULL;
17214     sp_digit* m = NULL;
17215     sp_digit* r = NULL;
17216     int err = MP_OKAY;
17217 
17218     (void)pm;
17219     (void)qm;
17220     (void)dpm;
17221     (void)dqm;
17222     (void)qim;
17223 
17224     if (*outLen < 512U) {
17225         err = MP_TO_E;
17226     }
17227     if (err == MP_OKAY) {
17228         if (mp_count_bits(dm) > 4096) {
17229             err = MP_READ_E;
17230         }
17231         else if (inLen > 512U) {
17232             err = MP_READ_E;
17233         }
17234         else if (mp_count_bits(mm) != 4096) {
17235             err = MP_READ_E;
17236         }
17237         else if (mp_iseven(mm)) {
17238             err = MP_VAL;
17239         }
17240     }
17241 
17242 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
17243     if (err == MP_OKAY) {
17244         d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 70 * 4, NULL,
17245                                                               DYNAMIC_TYPE_RSA);
17246         if (d == NULL)
17247             err = MEMORY_E;
17248     }
17249 #endif
17250 
17251     if (err == MP_OKAY) {
17252         a = d + 70;
17253         m = a + 140;
17254         r = a;
17255 
17256         sp_4096_from_bin(a, 70, in, inLen);
17257         sp_4096_from_mp(d, 70, dm);
17258         sp_4096_from_mp(m, 70, mm);
17259         err = sp_4096_mod_exp_70(r, a, d, 4096, m, 0);
17260     }
17261 
17262     if (err == MP_OKAY) {
17263         sp_4096_to_bin_70(r, out);
17264         *outLen = 512;
17265     }
17266 
17267 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
17268     if (d != NULL)
17269 #endif
17270     {
17271         /* only "a" and "r" are sensitive and need zeroized (same pointer) */
17272         if (a != NULL)
17273             ForceZero(a, sizeof(sp_digit) * 70);
17274 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
17275         XFREE(d, NULL, DYNAMIC_TYPE_RSA);
17276 #endif
17277     }
17278 
17279     return err;
17280 #endif /* WOLFSSL_SP_SMALL */
17281 #else
17282 #if defined(WOLFSSL_SP_SMALL)
17283 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
17284     sp_digit* a = NULL;
17285 #else
17286     sp_digit a[35 * 8];
17287 #endif
17288     sp_digit* p = NULL;
17289     sp_digit* dp = NULL;
17290     sp_digit* dq = NULL;
17291     sp_digit* qi = NULL;
17292     sp_digit* tmpa = NULL;
17293     sp_digit* tmpb = NULL;
17294     sp_digit* r = NULL;
17295     int err = MP_OKAY;
17296 
17297     (void)dm;
17298     (void)mm;
17299 
17300     if (*outLen < 512U) {
17301         err = MP_TO_E;
17302     }
17303     if (err == MP_OKAY) {
17304         if (inLen > 512) {
17305             err = MP_READ_E;
17306         }
17307         else if (mp_count_bits(mm) != 4096) {
17308             err = MP_READ_E;
17309         }
17310         else if (mp_iseven(mm)) {
17311             err = MP_VAL;
17312         }
17313     }
17314 
17315 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
17316     if (err == MP_OKAY) {
17317         a = (sp_digit*)XMALLOC(sizeof(sp_digit) * 35 * 8, NULL,
17318                                                               DYNAMIC_TYPE_RSA);
17319         if (a == NULL)
17320             err = MEMORY_E;
17321     }
17322 #endif
17323     if (err == MP_OKAY) {
17324         p = a + 70;
17325         qi = dq = dp = p + 35;
17326         tmpa = qi + 35;
17327         tmpb = tmpa + 70;
17328         r = a;
17329 
17330         sp_4096_from_bin(a, 70, in, inLen);
17331         sp_4096_from_mp(p, 35, pm);
17332         sp_4096_from_mp(dp, 35, dpm);
17333         err = sp_4096_mod_exp_35(tmpa, a, dp, 2048, p, 1);
17334     }
17335     if (err == MP_OKAY) {
17336         sp_4096_from_mp(p, 35, qm);
17337         sp_4096_from_mp(dq, 35, dqm);
17338         err = sp_4096_mod_exp_35(tmpb, a, dq, 2048, p, 1);
17339     }
17340     if (err == MP_OKAY) {
17341         sp_4096_from_mp(p, 35, pm);
17342         (void)sp_4096_sub_35(tmpa, tmpa, tmpb);
17343         sp_4096_norm_35(tmpa);
17344         sp_4096_cond_add_35(tmpa, tmpa, p, 0 - ((sp_int_digit)tmpa[34] >> 63));
17345         sp_4096_cond_add_35(tmpa, tmpa, p, 0 - ((sp_int_digit)tmpa[34] >> 63));
17346         sp_4096_norm_35(tmpa);
17347 
17348         sp_4096_from_mp(qi, 35, qim);
17349         sp_4096_mul_35(tmpa, tmpa, qi);
17350         err = sp_4096_mod_35(tmpa, tmpa, p);
17351     }
17352 
17353     if (err == MP_OKAY) {
17354         sp_4096_from_mp(p, 35, qm);
17355         sp_4096_mul_35(tmpa, p, tmpa);
17356         (void)sp_4096_add_70(r, tmpb, tmpa);
17357         sp_4096_norm_70(r);
17358 
17359         sp_4096_to_bin_70(r, out);
17360         *outLen = 512;
17361     }
17362 
17363 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
17364     if (a != NULL)
17365 #endif
17366     {
17367         ForceZero(a, sizeof(sp_digit) * 35 * 8);
17368 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
17369         XFREE(a, NULL, DYNAMIC_TYPE_RSA);
17370 #endif
17371     }
17372 
17373     return err;
17374 #else
17375 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
17376     sp_digit* a = NULL;
17377 #else
17378     sp_digit a[35 * 13];
17379 #endif
17380     sp_digit* p = NULL;
17381     sp_digit* q = NULL;
17382     sp_digit* dp = NULL;
17383     sp_digit* dq = NULL;
17384     sp_digit* qi = NULL;
17385     sp_digit* tmpa = NULL;
17386     sp_digit* tmpb = NULL;
17387     sp_digit* r = NULL;
17388     int err = MP_OKAY;
17389 
17390     (void)dm;
17391     (void)mm;
17392 
17393     if (*outLen < 512U) {
17394         err = MP_TO_E;
17395     }
17396     if (err == MP_OKAY) {
17397         if (inLen > 512U) {
17398             err = MP_READ_E;
17399         }
17400         else if (mp_count_bits(mm) != 4096) {
17401             err = MP_READ_E;
17402         }
17403         else if (mp_iseven(mm)) {
17404             err = MP_VAL;
17405         }
17406     }
17407 
17408 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
17409     if (err == MP_OKAY) {
17410         a = (sp_digit*)XMALLOC(sizeof(sp_digit) * 35 * 13, NULL,
17411                                                               DYNAMIC_TYPE_RSA);
17412         if (a == NULL)
17413             err = MEMORY_E;
17414     }
17415 #endif
17416 
17417     if (err == MP_OKAY) {
17418         p = a + 70 * 2;
17419         q = p + 35;
17420         dp = q + 35;
17421         dq = dp + 35;
17422         qi = dq + 35;
17423         tmpa = qi + 35;
17424         tmpb = tmpa + 70;
17425         r = a;
17426 
17427         sp_4096_from_bin(a, 70, in, inLen);
17428         sp_4096_from_mp(p, 35, pm);
17429         sp_4096_from_mp(q, 35, qm);
17430         sp_4096_from_mp(dp, 35, dpm);
17431         sp_4096_from_mp(dq, 35, dqm);
17432         sp_4096_from_mp(qi, 35, qim);
17433 
17434         err = sp_4096_mod_exp_35(tmpa, a, dp, 2048, p, 1);
17435     }
17436     if (err == MP_OKAY) {
17437         err = sp_4096_mod_exp_35(tmpb, a, dq, 2048, q, 1);
17438     }
17439 
17440     if (err == MP_OKAY) {
17441         (void)sp_4096_sub_35(tmpa, tmpa, tmpb);
17442         sp_4096_norm_35(tmpa);
17443         sp_4096_cond_add_35(tmpa, tmpa, p, 0 - ((sp_int_digit)tmpa[34] >> 63));
17444         sp_4096_cond_add_35(tmpa, tmpa, p, 0 - ((sp_int_digit)tmpa[34] >> 63));
17445         sp_4096_norm_35(tmpa);
17446         sp_4096_mul_35(tmpa, tmpa, qi);
17447         err = sp_4096_mod_35(tmpa, tmpa, p);
17448     }
17449 
17450     if (err == MP_OKAY) {
17451         sp_4096_mul_35(tmpa, tmpa, q);
17452         (void)sp_4096_add_70(r, tmpb, tmpa);
17453         sp_4096_norm_70(r);
17454 
17455         sp_4096_to_bin_70(r, out);
17456         *outLen = 512;
17457     }
17458 
17459 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
17460 if (a != NULL)
17461 #endif
17462     {
17463         ForceZero(a, sizeof(sp_digit) * 35 * 13);
17464     #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
17465         XFREE(a, NULL, DYNAMIC_TYPE_RSA);
17466     #endif
17467     }
17468 
17469     return err;
17470 #endif /* WOLFSSL_SP_SMALL */
17471 #endif /* SP_RSA_PRIVATE_EXP_D || RSA_LOW_MEM */
17472 }
17473 
17474 #endif /* !WOLFSSL_RSA_PUBLIC_ONLY */
17475 #endif /* WOLFSSL_HAVE_SP_RSA */
17476 #if defined(WOLFSSL_HAVE_SP_DH) || (defined(WOLFSSL_HAVE_SP_RSA) && \
17477                                               !defined(WOLFSSL_RSA_PUBLIC_ONLY))
17478 /* Convert an array of sp_digit to an mp_int.
17479  *
17480  * a  A single precision integer.
17481  * r  A multi-precision integer.
17482  */
sp_4096_to_mp(const sp_digit * a,mp_int * r)17483 static int sp_4096_to_mp(const sp_digit* a, mp_int* r)
17484 {
17485     int err;
17486 
17487     err = mp_grow(r, (4096 + DIGIT_BIT - 1) / DIGIT_BIT);
17488     if (err == MP_OKAY) { /*lint !e774 case where err is always MP_OKAY*/
17489 #if DIGIT_BIT == 59
17490         XMEMCPY(r->dp, a, sizeof(sp_digit) * 70);
17491         r->used = 70;
17492         mp_clamp(r);
17493 #elif DIGIT_BIT < 59
17494         int i;
17495         int j = 0;
17496         int s = 0;
17497 
17498         r->dp[0] = 0;
17499         for (i = 0; i < 70; i++) {
17500             r->dp[j] |= (mp_digit)(a[i] << s);
17501             r->dp[j] &= ((sp_digit)1 << DIGIT_BIT) - 1;
17502             s = DIGIT_BIT - s;
17503             r->dp[++j] = (mp_digit)(a[i] >> s);
17504             while (s + DIGIT_BIT <= 59) {
17505                 s += DIGIT_BIT;
17506                 r->dp[j++] &= ((sp_digit)1 << DIGIT_BIT) - 1;
17507                 if (s == SP_WORD_SIZE) {
17508                     r->dp[j] = 0;
17509                 }
17510                 else {
17511                     r->dp[j] = (mp_digit)(a[i] >> s);
17512                 }
17513             }
17514             s = 59 - s;
17515         }
17516         r->used = (4096 + DIGIT_BIT - 1) / DIGIT_BIT;
17517         mp_clamp(r);
17518 #else
17519         int i;
17520         int j = 0;
17521         int s = 0;
17522 
17523         r->dp[0] = 0;
17524         for (i = 0; i < 70; i++) {
17525             r->dp[j] |= ((mp_digit)a[i]) << s;
17526             if (s + 59 >= DIGIT_BIT) {
17527     #if DIGIT_BIT != 32 && DIGIT_BIT != 64
17528                 r->dp[j] &= ((sp_digit)1 << DIGIT_BIT) - 1;
17529     #endif
17530                 s = DIGIT_BIT - s;
17531                 r->dp[++j] = a[i] >> s;
17532                 s = 59 - s;
17533             }
17534             else {
17535                 s += 59;
17536             }
17537         }
17538         r->used = (4096 + DIGIT_BIT - 1) / DIGIT_BIT;
17539         mp_clamp(r);
17540 #endif
17541     }
17542 
17543     return err;
17544 }
17545 
17546 /* Perform the modular exponentiation for Diffie-Hellman.
17547  *
17548  * base  Base. MP integer.
17549  * exp   Exponent. MP integer.
17550  * mod   Modulus. MP integer.
17551  * res   Result. MP integer.
17552  * returns 0 on success, MP_READ_E if there are too many bytes in an array
17553  * and MEMORY_E if memory allocation fails.
17554  */
sp_ModExp_4096(const mp_int * base,const mp_int * exp,const mp_int * mod,mp_int * res)17555 int sp_ModExp_4096(const mp_int* base, const mp_int* exp, const mp_int* mod,
17556     mp_int* res)
17557 {
17558 #ifdef WOLFSSL_SP_SMALL
17559     int err = MP_OKAY;
17560 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
17561     sp_digit* b = NULL;
17562 #else
17563     sp_digit b[70 * 4];
17564 #endif
17565     sp_digit* e = NULL;
17566     sp_digit* m = NULL;
17567     sp_digit* r = NULL;
17568     int expBits = mp_count_bits(exp);
17569 
17570     if (mp_count_bits(base) > 4096) {
17571         err = MP_READ_E;
17572     }
17573     else if (expBits > 4096) {
17574         err = MP_READ_E;
17575     }
17576     else if (mp_count_bits(mod) != 4096) {
17577         err = MP_READ_E;
17578     }
17579     else if (mp_iseven(mod)) {
17580         err = MP_VAL;
17581     }
17582 
17583 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
17584     if (err == MP_OKAY) {
17585         b = (sp_digit*)XMALLOC(sizeof(sp_digit) * 70 * 4, NULL,
17586             DYNAMIC_TYPE_DH);
17587         if (b == NULL)
17588             err = MEMORY_E;
17589     }
17590 #endif
17591 
17592     if (err == MP_OKAY) {
17593         e = b + 70 * 2;
17594         m = e + 70;
17595         r = b;
17596 
17597         sp_4096_from_mp(b, 70, base);
17598         sp_4096_from_mp(e, 70, exp);
17599         sp_4096_from_mp(m, 70, mod);
17600 
17601         err = sp_4096_mod_exp_70(r, b, e, mp_count_bits(exp), m, 0);
17602     }
17603 
17604     if (err == MP_OKAY) {
17605         err = sp_4096_to_mp(r, res);
17606     }
17607 
17608 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
17609     if (b != NULL)
17610 #endif
17611     {
17612         /* only "e" is sensitive and needs zeroized */
17613         if (e != NULL)
17614             ForceZero(e, sizeof(sp_digit) * 70U);
17615     #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
17616         XFREE(b, NULL, DYNAMIC_TYPE_DH);
17617     #endif
17618     }
17619     return err;
17620 #else
17621 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
17622     sp_digit* b = NULL;
17623 #else
17624     sp_digit b[70 * 4];
17625 #endif
17626     sp_digit* e = NULL;
17627     sp_digit* m = NULL;
17628     sp_digit* r = NULL;
17629     int err = MP_OKAY;
17630     int expBits = mp_count_bits(exp);
17631 
17632     if (mp_count_bits(base) > 4096) {
17633         err = MP_READ_E;
17634     }
17635     else if (expBits > 4096) {
17636         err = MP_READ_E;
17637     }
17638     else if (mp_count_bits(mod) != 4096) {
17639         err = MP_READ_E;
17640     }
17641     else if (mp_iseven(mod)) {
17642         err = MP_VAL;
17643     }
17644 
17645 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
17646     if (err == MP_OKAY) {
17647         b = (sp_digit*)XMALLOC(sizeof(sp_digit) * 70 * 4, NULL, DYNAMIC_TYPE_DH);
17648         if (b == NULL)
17649             err = MEMORY_E;
17650     }
17651 #endif
17652 
17653     if (err == MP_OKAY) {
17654         e = b + 70 * 2;
17655         m = e + 70;
17656         r = b;
17657 
17658         sp_4096_from_mp(b, 70, base);
17659         sp_4096_from_mp(e, 70, exp);
17660         sp_4096_from_mp(m, 70, mod);
17661 
17662         err = sp_4096_mod_exp_70(r, b, e, expBits, m, 0);
17663     }
17664 
17665     if (err == MP_OKAY) {
17666         err = sp_4096_to_mp(r, res);
17667     }
17668 
17669 
17670 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
17671     if (b != NULL)
17672 #endif
17673     {
17674         /* only "e" is sensitive and needs zeroized */
17675         if (e != NULL)
17676             ForceZero(e, sizeof(sp_digit) * 70U);
17677     #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
17678         XFREE(b, NULL, DYNAMIC_TYPE_DH);
17679     #endif
17680     }
17681 
17682     return err;
17683 #endif
17684 }
17685 
17686 #ifdef WOLFSSL_HAVE_SP_DH
17687 
17688 #ifdef HAVE_FFDHE_4096
sp_4096_lshift_70(sp_digit * r,const sp_digit * a,byte n)17689 SP_NOINLINE static void sp_4096_lshift_70(sp_digit* r, const sp_digit* a,
17690         byte n)
17691 {
17692     int i;
17693 
17694     r[70] = a[69] >> (59 - n);
17695     for (i=69; i>0; i--) {
17696         r[i] = ((a[i] << n) | (a[i-1] >> (59 - n))) & 0x7ffffffffffffffL;
17697     }
17698     r[0] = (a[0] << n) & 0x7ffffffffffffffL;
17699 }
17700 
17701 /* Modular exponentiate 2 to the e mod m. (r = 2^e mod m)
17702  *
17703  * r     A single precision number that is the result of the operation.
17704  * e     A single precision number that is the exponent.
17705  * bits  The number of bits in the exponent.
17706  * m     A single precision number that is the modulus.
17707  * returns  0 on success.
17708  * returns  MEMORY_E on dynamic memory allocation failure.
17709  * returns  MP_VAL when base is even.
17710  */
sp_4096_mod_exp_2_70(sp_digit * r,const sp_digit * e,int bits,const sp_digit * m)17711 static int sp_4096_mod_exp_2_70(sp_digit* r, const sp_digit* e, int bits, const sp_digit* m)
17712 {
17713 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
17714     sp_digit* td = NULL;
17715 #else
17716     sp_digit td[211];
17717 #endif
17718     sp_digit* norm = NULL;
17719     sp_digit* tmp = NULL;
17720     sp_digit mp = 1;
17721     sp_digit n;
17722     sp_digit o;
17723     int i;
17724     int c;
17725     byte y;
17726     int err = MP_OKAY;
17727 
17728     if ((m[0] & 1) == 0) {
17729         err = MP_VAL;
17730     }
17731 
17732 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
17733     if (err == MP_OKAY) {
17734         td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 211, NULL,
17735                                 DYNAMIC_TYPE_TMP_BUFFER);
17736         if (td == NULL)
17737             err = MEMORY_E;
17738     }
17739 #endif
17740 
17741     if (err == MP_OKAY) {
17742         norm = td;
17743         tmp  = td + 140;
17744         XMEMSET(td, 0, sizeof(sp_digit) * 211);
17745 
17746         sp_4096_mont_setup(m, &mp);
17747         sp_4096_mont_norm_70(norm, m);
17748 
17749         bits = ((bits + 4) / 5) * 5;
17750         i = ((bits + 58) / 59) - 1;
17751         c = bits % 59;
17752         if (c == 0) {
17753             c = 59;
17754         }
17755         if (i < 70) {
17756             n = e[i--] << (64 - c);
17757         }
17758         else {
17759             n = 0;
17760             i--;
17761         }
17762         if (c < 5) {
17763             n |= e[i--] << (5 - c);
17764             c += 59;
17765         }
17766         y = (int)((n >> 59) & 0x1f);
17767         n <<= 5;
17768         c -= 5;
17769         sp_4096_lshift_70(r, norm, (byte)y);
17770         while ((i >= 0) || (c >= 5)) {
17771             if (c >= 5) {
17772                 y = (byte)((n >> 59) & 0x1f);
17773                 n <<= 5;
17774                 c -= 5;
17775             }
17776             else if (c == 0) {
17777                 n = e[i--] << 5;
17778                 y = (byte)((n >> 59) & 0x1f);
17779                 n <<= 5;
17780                 c = 54;
17781             }
17782             else {
17783                 y = (byte)((n >> 59) & 0x1f);
17784                 n = e[i--] << 5;
17785                 c = 5 - c;
17786                 y |= (byte)((n >> (64 - c)) & ((1 << c) - 1));
17787                 n <<= c;
17788                 c = 59 - c;
17789             }
17790 
17791             sp_4096_mont_sqr_70(r, r, m, mp);
17792             sp_4096_mont_sqr_70(r, r, m, mp);
17793             sp_4096_mont_sqr_70(r, r, m, mp);
17794             sp_4096_mont_sqr_70(r, r, m, mp);
17795             sp_4096_mont_sqr_70(r, r, m, mp);
17796 
17797             sp_4096_lshift_70(r, r, (byte)y);
17798             sp_4096_mul_d_70(tmp, norm, (r[70] << 34) + (r[69] >> 25));
17799             r[70] = 0;
17800             r[69] &= 0x1ffffffL;
17801             (void)sp_4096_add_70(r, r, tmp);
17802             sp_4096_norm_70(r);
17803             o = sp_4096_cmp_70(r, m);
17804             sp_4096_cond_sub_70(r, r, m, ((o < 0) ?
17805                                           (sp_digit)1 : (sp_digit)0) - 1);
17806         }
17807 
17808         sp_4096_mont_reduce_70(r, m, mp);
17809         n = sp_4096_cmp_70(r, m);
17810         sp_4096_cond_sub_70(r, r, m, ((n < 0) ?
17811                                                 (sp_digit)1 : (sp_digit)0) - 1);
17812     }
17813 
17814 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
17815     if (td != NULL)
17816         XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);
17817 #endif
17818 
17819     return err;
17820 }
17821 
17822 #endif /* HAVE_FFDHE_4096 */
17823 
17824 /* Perform the modular exponentiation for Diffie-Hellman.
17825  *
17826  * base     Base.
17827  * exp      Array of bytes that is the exponent.
17828  * expLen   Length of data, in bytes, in exponent.
17829  * mod      Modulus.
17830  * out      Buffer to hold big-endian bytes of exponentiation result.
17831  *          Must be at least 512 bytes long.
17832  * outLen   Length, in bytes, of exponentiation result.
17833  * returns 0 on success, MP_READ_E if there are too many bytes in an array
17834  * and MEMORY_E if memory allocation fails.
17835  */
sp_DhExp_4096(const mp_int * base,const byte * exp,word32 expLen,const mp_int * mod,byte * out,word32 * outLen)17836 int sp_DhExp_4096(const mp_int* base, const byte* exp, word32 expLen,
17837     const mp_int* mod, byte* out, word32* outLen)
17838 {
17839 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
17840     sp_digit* b = NULL;
17841 #else
17842     sp_digit b[70 * 4];
17843 #endif
17844     sp_digit* e = NULL;
17845     sp_digit* m = NULL;
17846     sp_digit* r = NULL;
17847     word32 i;
17848     int err = MP_OKAY;
17849 
17850     if (mp_count_bits(base) > 4096) {
17851         err = MP_READ_E;
17852     }
17853     else if (expLen > 512U) {
17854         err = MP_READ_E;
17855     }
17856     else if (mp_count_bits(mod) != 4096) {
17857         err = MP_READ_E;
17858     }
17859     else if (mp_iseven(mod)) {
17860         err = MP_VAL;
17861     }
17862 
17863 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
17864     if (err == MP_OKAY) {
17865         b = (sp_digit*)XMALLOC(sizeof(sp_digit) * 70 * 4, NULL,
17866             DYNAMIC_TYPE_DH);
17867         if (b == NULL)
17868             err = MEMORY_E;
17869     }
17870 #endif
17871 
17872     if (err == MP_OKAY) {
17873         e = b + 70 * 2;
17874         m = e + 70;
17875         r = b;
17876 
17877         sp_4096_from_mp(b, 70, base);
17878         sp_4096_from_bin(e, 70, exp, expLen);
17879         sp_4096_from_mp(m, 70, mod);
17880 
17881     #ifdef HAVE_FFDHE_4096
17882         if (base->used == 1 && base->dp[0] == 2U &&
17883                 ((m[69] << 7) | (m[68] >> 52)) == 0xffffffffL) {
17884             err = sp_4096_mod_exp_2_70(r, e, expLen * 8U, m);
17885         }
17886         else {
17887     #endif
17888             err = sp_4096_mod_exp_70(r, b, e, expLen * 8U, m, 0);
17889     #ifdef HAVE_FFDHE_4096
17890         }
17891     #endif
17892     }
17893 
17894     if (err == MP_OKAY) {
17895         sp_4096_to_bin_70(r, out);
17896         *outLen = 512;
17897         for (i=0; i<512U && out[i] == 0U; i++) {
17898             /* Search for first non-zero. */
17899         }
17900         *outLen -= i;
17901         XMEMMOVE(out, out + i, *outLen);
17902     }
17903 
17904 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
17905     if (b != NULL)
17906 #endif
17907     {
17908         /* only "e" is sensitive and needs zeroized */
17909         if (e != NULL)
17910             ForceZero(e, sizeof(sp_digit) * 70U);
17911     #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
17912         XFREE(b, NULL, DYNAMIC_TYPE_DH);
17913     #endif
17914     }
17915 
17916     return err;
17917 }
17918 #endif /* WOLFSSL_HAVE_SP_DH */
17919 
17920 #endif /* WOLFSSL_HAVE_SP_DH | (WOLFSSL_HAVE_SP_RSA & !WOLFSSL_RSA_PUBLIC_ONLY) */
17921 
17922 #else
17923 /* Read big endian unsigned byte array into r.
17924  *
17925  * r  A single precision integer.
17926  * size  Maximum number of bytes to convert
17927  * a  Byte array.
17928  * n  Number of bytes in array to read.
17929  */
sp_4096_from_bin(sp_digit * r,int size,const byte * a,int n)17930 static void sp_4096_from_bin(sp_digit* r, int size, const byte* a, int n)
17931 {
17932     int i;
17933     int j = 0;
17934     word32 s = 0;
17935 
17936     r[0] = 0;
17937     for (i = n-1; i >= 0; i--) {
17938         r[j] |= (((sp_digit)a[i]) << s);
17939         if (s >= 45U) {
17940             r[j] &= 0x1fffffffffffffL;
17941             s = 53U - s;
17942             if (j + 1 >= size) {
17943                 break;
17944             }
17945             r[++j] = (sp_digit)a[i] >> s;
17946             s = 8U - s;
17947         }
17948         else {
17949             s += 8U;
17950         }
17951     }
17952 
17953     for (j++; j < size; j++) {
17954         r[j] = 0;
17955     }
17956 }
17957 
17958 /* Convert an mp_int to an array of sp_digit.
17959  *
17960  * r  A single precision integer.
17961  * size  Maximum number of bytes to convert
17962  * a  A multi-precision integer.
17963  */
sp_4096_from_mp(sp_digit * r,int size,const mp_int * a)17964 static void sp_4096_from_mp(sp_digit* r, int size, const mp_int* a)
17965 {
17966 #if DIGIT_BIT == 53
17967     int j;
17968 
17969     XMEMCPY(r, a->dp, sizeof(sp_digit) * a->used);
17970 
17971     for (j = a->used; j < size; j++) {
17972         r[j] = 0;
17973     }
17974 #elif DIGIT_BIT > 53
17975     int i;
17976     int j = 0;
17977     word32 s = 0;
17978 
17979     r[0] = 0;
17980     for (i = 0; i < a->used && j < size; i++) {
17981         r[j] |= ((sp_digit)a->dp[i] << s);
17982         r[j] &= 0x1fffffffffffffL;
17983         s = 53U - s;
17984         if (j + 1 >= size) {
17985             break;
17986         }
17987         /* lint allow cast of mismatch word32 and mp_digit */
17988         r[++j] = (sp_digit)(a->dp[i] >> s); /*lint !e9033*/
17989         while ((s + 53U) <= (word32)DIGIT_BIT) {
17990             s += 53U;
17991             r[j] &= 0x1fffffffffffffL;
17992             if (j + 1 >= size) {
17993                 break;
17994             }
17995             if (s < (word32)DIGIT_BIT) {
17996                 /* lint allow cast of mismatch word32 and mp_digit */
17997                 r[++j] = (sp_digit)(a->dp[i] >> s); /*lint !e9033*/
17998             }
17999             else {
18000                 r[++j] = (sp_digit)0;
18001             }
18002         }
18003         s = (word32)DIGIT_BIT - s;
18004     }
18005 
18006     for (j++; j < size; j++) {
18007         r[j] = 0;
18008     }
18009 #else
18010     int i;
18011     int j = 0;
18012     int s = 0;
18013 
18014     r[0] = 0;
18015     for (i = 0; i < a->used && j < size; i++) {
18016         r[j] |= ((sp_digit)a->dp[i]) << s;
18017         if (s + DIGIT_BIT >= 53) {
18018             r[j] &= 0x1fffffffffffffL;
18019             if (j + 1 >= size) {
18020                 break;
18021             }
18022             s = 53 - s;
18023             if (s == DIGIT_BIT) {
18024                 r[++j] = 0;
18025                 s = 0;
18026             }
18027             else {
18028                 r[++j] = a->dp[i] >> s;
18029                 s = DIGIT_BIT - s;
18030             }
18031         }
18032         else {
18033             s += DIGIT_BIT;
18034         }
18035     }
18036 
18037     for (j++; j < size; j++) {
18038         r[j] = 0;
18039     }
18040 #endif
18041 }
18042 
18043 /* Write r as big endian to byte array.
18044  * Fixed length number of bytes written: 512
18045  *
18046  * r  A single precision integer.
18047  * a  Byte array.
18048  */
sp_4096_to_bin_78(sp_digit * r,byte * a)18049 static void sp_4096_to_bin_78(sp_digit* r, byte* a)
18050 {
18051     int i;
18052     int j;
18053     int s = 0;
18054     int b;
18055 
18056     for (i=0; i<77; i++) {
18057         r[i+1] += r[i] >> 53;
18058         r[i] &= 0x1fffffffffffffL;
18059     }
18060     j = 4096 / 8 - 1;
18061     a[j] = 0;
18062     for (i=0; i<78 && j>=0; i++) {
18063         b = 0;
18064         /* lint allow cast of mismatch sp_digit and int */
18065         a[j--] |= (byte)(r[i] << s); /*lint !e9033*/
18066         b += 8 - s;
18067         if (j < 0) {
18068             break;
18069         }
18070         while (b < 53) {
18071             a[j--] = (byte)(r[i] >> b);
18072             b += 8;
18073             if (j < 0) {
18074                 break;
18075             }
18076         }
18077         s = 8 - (b - 53);
18078         if (j >= 0) {
18079             a[j] = 0;
18080         }
18081         if (s != 0) {
18082             j++;
18083         }
18084     }
18085 }
18086 
18087 #if (defined(WOLFSSL_HAVE_SP_RSA) && !defined(WOLFSSL_RSA_PUBLIC_ONLY)) || defined(WOLFSSL_HAVE_SP_DH)
18088 #if defined(WOLFSSL_HAVE_SP_RSA) && !defined(SP_RSA_PRIVATE_EXP_D)
18089 /* Normalize the values in each word to 53 bits.
18090  *
18091  * a  Array of sp_digit to normalize.
18092  */
sp_4096_norm_39(sp_digit * a)18093 static void sp_4096_norm_39(sp_digit* a)
18094 {
18095     int i;
18096     for (i = 0; i < 32; i += 8) {
18097         a[i+1] += a[i+0] >> 53; a[i+0] &= 0x1fffffffffffffL;
18098         a[i+2] += a[i+1] >> 53; a[i+1] &= 0x1fffffffffffffL;
18099         a[i+3] += a[i+2] >> 53; a[i+2] &= 0x1fffffffffffffL;
18100         a[i+4] += a[i+3] >> 53; a[i+3] &= 0x1fffffffffffffL;
18101         a[i+5] += a[i+4] >> 53; a[i+4] &= 0x1fffffffffffffL;
18102         a[i+6] += a[i+5] >> 53; a[i+5] &= 0x1fffffffffffffL;
18103         a[i+7] += a[i+6] >> 53; a[i+6] &= 0x1fffffffffffffL;
18104         a[i+8] += a[i+7] >> 53; a[i+7] &= 0x1fffffffffffffL;
18105     }
18106     a[33] += a[32] >> 53; a[32] &= 0x1fffffffffffffL;
18107     a[34] += a[33] >> 53; a[33] &= 0x1fffffffffffffL;
18108     a[35] += a[34] >> 53; a[34] &= 0x1fffffffffffffL;
18109     a[36] += a[35] >> 53; a[35] &= 0x1fffffffffffffL;
18110     a[37] += a[36] >> 53; a[36] &= 0x1fffffffffffffL;
18111     a[38] += a[37] >> 53; a[37] &= 0x1fffffffffffffL;
18112 }
18113 
18114 #endif /* WOLFSSL_HAVE_SP_RSA & !SP_RSA_PRIVATE_EXP_D */
18115 #endif /* (WOLFSSL_HAVE_SP_RSA && !WOLFSSL_RSA_PUBLIC_ONLY) || WOLFSSL_HAVE_SP_DH */
18116 /* Normalize the values in each word to 53 bits.
18117  *
18118  * a  Array of sp_digit to normalize.
18119  */
sp_4096_norm_78(sp_digit * a)18120 static void sp_4096_norm_78(sp_digit* a)
18121 {
18122     int i;
18123     for (i = 0; i < 72; i += 8) {
18124         a[i+1] += a[i+0] >> 53; a[i+0] &= 0x1fffffffffffffL;
18125         a[i+2] += a[i+1] >> 53; a[i+1] &= 0x1fffffffffffffL;
18126         a[i+3] += a[i+2] >> 53; a[i+2] &= 0x1fffffffffffffL;
18127         a[i+4] += a[i+3] >> 53; a[i+3] &= 0x1fffffffffffffL;
18128         a[i+5] += a[i+4] >> 53; a[i+4] &= 0x1fffffffffffffL;
18129         a[i+6] += a[i+5] >> 53; a[i+5] &= 0x1fffffffffffffL;
18130         a[i+7] += a[i+6] >> 53; a[i+6] &= 0x1fffffffffffffL;
18131         a[i+8] += a[i+7] >> 53; a[i+7] &= 0x1fffffffffffffL;
18132     }
18133     a[73] += a[72] >> 53; a[72] &= 0x1fffffffffffffL;
18134     a[74] += a[73] >> 53; a[73] &= 0x1fffffffffffffL;
18135     a[75] += a[74] >> 53; a[74] &= 0x1fffffffffffffL;
18136     a[76] += a[75] >> 53; a[75] &= 0x1fffffffffffffL;
18137     a[77] += a[76] >> 53; a[76] &= 0x1fffffffffffffL;
18138 }
18139 
18140 #ifndef WOLFSSL_SP_SMALL
18141 /* Multiply a and b into r. (r = a * b)
18142  *
18143  * r  A single precision integer.
18144  * a  A single precision integer.
18145  * b  A single precision integer.
18146  */
sp_4096_mul_13(sp_digit * r,const sp_digit * a,const sp_digit * b)18147 SP_NOINLINE static void sp_4096_mul_13(sp_digit* r, const sp_digit* a,
18148     const sp_digit* b)
18149 {
18150     sp_uint128 t0   = ((sp_uint128)a[ 0]) * b[ 0];
18151     sp_uint128 t1   = ((sp_uint128)a[ 0]) * b[ 1]
18152                  + ((sp_uint128)a[ 1]) * b[ 0];
18153     sp_uint128 t2   = ((sp_uint128)a[ 0]) * b[ 2]
18154                  + ((sp_uint128)a[ 1]) * b[ 1]
18155                  + ((sp_uint128)a[ 2]) * b[ 0];
18156     sp_uint128 t3   = ((sp_uint128)a[ 0]) * b[ 3]
18157                  + ((sp_uint128)a[ 1]) * b[ 2]
18158                  + ((sp_uint128)a[ 2]) * b[ 1]
18159                  + ((sp_uint128)a[ 3]) * b[ 0];
18160     sp_uint128 t4   = ((sp_uint128)a[ 0]) * b[ 4]
18161                  + ((sp_uint128)a[ 1]) * b[ 3]
18162                  + ((sp_uint128)a[ 2]) * b[ 2]
18163                  + ((sp_uint128)a[ 3]) * b[ 1]
18164                  + ((sp_uint128)a[ 4]) * b[ 0];
18165     sp_uint128 t5   = ((sp_uint128)a[ 0]) * b[ 5]
18166                  + ((sp_uint128)a[ 1]) * b[ 4]
18167                  + ((sp_uint128)a[ 2]) * b[ 3]
18168                  + ((sp_uint128)a[ 3]) * b[ 2]
18169                  + ((sp_uint128)a[ 4]) * b[ 1]
18170                  + ((sp_uint128)a[ 5]) * b[ 0];
18171     sp_uint128 t6   = ((sp_uint128)a[ 0]) * b[ 6]
18172                  + ((sp_uint128)a[ 1]) * b[ 5]
18173                  + ((sp_uint128)a[ 2]) * b[ 4]
18174                  + ((sp_uint128)a[ 3]) * b[ 3]
18175                  + ((sp_uint128)a[ 4]) * b[ 2]
18176                  + ((sp_uint128)a[ 5]) * b[ 1]
18177                  + ((sp_uint128)a[ 6]) * b[ 0];
18178     sp_uint128 t7   = ((sp_uint128)a[ 0]) * b[ 7]
18179                  + ((sp_uint128)a[ 1]) * b[ 6]
18180                  + ((sp_uint128)a[ 2]) * b[ 5]
18181                  + ((sp_uint128)a[ 3]) * b[ 4]
18182                  + ((sp_uint128)a[ 4]) * b[ 3]
18183                  + ((sp_uint128)a[ 5]) * b[ 2]
18184                  + ((sp_uint128)a[ 6]) * b[ 1]
18185                  + ((sp_uint128)a[ 7]) * b[ 0];
18186     sp_uint128 t8   = ((sp_uint128)a[ 0]) * b[ 8]
18187                  + ((sp_uint128)a[ 1]) * b[ 7]
18188                  + ((sp_uint128)a[ 2]) * b[ 6]
18189                  + ((sp_uint128)a[ 3]) * b[ 5]
18190                  + ((sp_uint128)a[ 4]) * b[ 4]
18191                  + ((sp_uint128)a[ 5]) * b[ 3]
18192                  + ((sp_uint128)a[ 6]) * b[ 2]
18193                  + ((sp_uint128)a[ 7]) * b[ 1]
18194                  + ((sp_uint128)a[ 8]) * b[ 0];
18195     sp_uint128 t9   = ((sp_uint128)a[ 0]) * b[ 9]
18196                  + ((sp_uint128)a[ 1]) * b[ 8]
18197                  + ((sp_uint128)a[ 2]) * b[ 7]
18198                  + ((sp_uint128)a[ 3]) * b[ 6]
18199                  + ((sp_uint128)a[ 4]) * b[ 5]
18200                  + ((sp_uint128)a[ 5]) * b[ 4]
18201                  + ((sp_uint128)a[ 6]) * b[ 3]
18202                  + ((sp_uint128)a[ 7]) * b[ 2]
18203                  + ((sp_uint128)a[ 8]) * b[ 1]
18204                  + ((sp_uint128)a[ 9]) * b[ 0];
18205     sp_uint128 t10  = ((sp_uint128)a[ 0]) * b[10]
18206                  + ((sp_uint128)a[ 1]) * b[ 9]
18207                  + ((sp_uint128)a[ 2]) * b[ 8]
18208                  + ((sp_uint128)a[ 3]) * b[ 7]
18209                  + ((sp_uint128)a[ 4]) * b[ 6]
18210                  + ((sp_uint128)a[ 5]) * b[ 5]
18211                  + ((sp_uint128)a[ 6]) * b[ 4]
18212                  + ((sp_uint128)a[ 7]) * b[ 3]
18213                  + ((sp_uint128)a[ 8]) * b[ 2]
18214                  + ((sp_uint128)a[ 9]) * b[ 1]
18215                  + ((sp_uint128)a[10]) * b[ 0];
18216     sp_uint128 t11  = ((sp_uint128)a[ 0]) * b[11]
18217                  + ((sp_uint128)a[ 1]) * b[10]
18218                  + ((sp_uint128)a[ 2]) * b[ 9]
18219                  + ((sp_uint128)a[ 3]) * b[ 8]
18220                  + ((sp_uint128)a[ 4]) * b[ 7]
18221                  + ((sp_uint128)a[ 5]) * b[ 6]
18222                  + ((sp_uint128)a[ 6]) * b[ 5]
18223                  + ((sp_uint128)a[ 7]) * b[ 4]
18224                  + ((sp_uint128)a[ 8]) * b[ 3]
18225                  + ((sp_uint128)a[ 9]) * b[ 2]
18226                  + ((sp_uint128)a[10]) * b[ 1]
18227                  + ((sp_uint128)a[11]) * b[ 0];
18228     sp_uint128 t12  = ((sp_uint128)a[ 0]) * b[12]
18229                  + ((sp_uint128)a[ 1]) * b[11]
18230                  + ((sp_uint128)a[ 2]) * b[10]
18231                  + ((sp_uint128)a[ 3]) * b[ 9]
18232                  + ((sp_uint128)a[ 4]) * b[ 8]
18233                  + ((sp_uint128)a[ 5]) * b[ 7]
18234                  + ((sp_uint128)a[ 6]) * b[ 6]
18235                  + ((sp_uint128)a[ 7]) * b[ 5]
18236                  + ((sp_uint128)a[ 8]) * b[ 4]
18237                  + ((sp_uint128)a[ 9]) * b[ 3]
18238                  + ((sp_uint128)a[10]) * b[ 2]
18239                  + ((sp_uint128)a[11]) * b[ 1]
18240                  + ((sp_uint128)a[12]) * b[ 0];
18241     sp_uint128 t13  = ((sp_uint128)a[ 1]) * b[12]
18242                  + ((sp_uint128)a[ 2]) * b[11]
18243                  + ((sp_uint128)a[ 3]) * b[10]
18244                  + ((sp_uint128)a[ 4]) * b[ 9]
18245                  + ((sp_uint128)a[ 5]) * b[ 8]
18246                  + ((sp_uint128)a[ 6]) * b[ 7]
18247                  + ((sp_uint128)a[ 7]) * b[ 6]
18248                  + ((sp_uint128)a[ 8]) * b[ 5]
18249                  + ((sp_uint128)a[ 9]) * b[ 4]
18250                  + ((sp_uint128)a[10]) * b[ 3]
18251                  + ((sp_uint128)a[11]) * b[ 2]
18252                  + ((sp_uint128)a[12]) * b[ 1];
18253     sp_uint128 t14  = ((sp_uint128)a[ 2]) * b[12]
18254                  + ((sp_uint128)a[ 3]) * b[11]
18255                  + ((sp_uint128)a[ 4]) * b[10]
18256                  + ((sp_uint128)a[ 5]) * b[ 9]
18257                  + ((sp_uint128)a[ 6]) * b[ 8]
18258                  + ((sp_uint128)a[ 7]) * b[ 7]
18259                  + ((sp_uint128)a[ 8]) * b[ 6]
18260                  + ((sp_uint128)a[ 9]) * b[ 5]
18261                  + ((sp_uint128)a[10]) * b[ 4]
18262                  + ((sp_uint128)a[11]) * b[ 3]
18263                  + ((sp_uint128)a[12]) * b[ 2];
18264     sp_uint128 t15  = ((sp_uint128)a[ 3]) * b[12]
18265                  + ((sp_uint128)a[ 4]) * b[11]
18266                  + ((sp_uint128)a[ 5]) * b[10]
18267                  + ((sp_uint128)a[ 6]) * b[ 9]
18268                  + ((sp_uint128)a[ 7]) * b[ 8]
18269                  + ((sp_uint128)a[ 8]) * b[ 7]
18270                  + ((sp_uint128)a[ 9]) * b[ 6]
18271                  + ((sp_uint128)a[10]) * b[ 5]
18272                  + ((sp_uint128)a[11]) * b[ 4]
18273                  + ((sp_uint128)a[12]) * b[ 3];
18274     sp_uint128 t16  = ((sp_uint128)a[ 4]) * b[12]
18275                  + ((sp_uint128)a[ 5]) * b[11]
18276                  + ((sp_uint128)a[ 6]) * b[10]
18277                  + ((sp_uint128)a[ 7]) * b[ 9]
18278                  + ((sp_uint128)a[ 8]) * b[ 8]
18279                  + ((sp_uint128)a[ 9]) * b[ 7]
18280                  + ((sp_uint128)a[10]) * b[ 6]
18281                  + ((sp_uint128)a[11]) * b[ 5]
18282                  + ((sp_uint128)a[12]) * b[ 4];
18283     sp_uint128 t17  = ((sp_uint128)a[ 5]) * b[12]
18284                  + ((sp_uint128)a[ 6]) * b[11]
18285                  + ((sp_uint128)a[ 7]) * b[10]
18286                  + ((sp_uint128)a[ 8]) * b[ 9]
18287                  + ((sp_uint128)a[ 9]) * b[ 8]
18288                  + ((sp_uint128)a[10]) * b[ 7]
18289                  + ((sp_uint128)a[11]) * b[ 6]
18290                  + ((sp_uint128)a[12]) * b[ 5];
18291     sp_uint128 t18  = ((sp_uint128)a[ 6]) * b[12]
18292                  + ((sp_uint128)a[ 7]) * b[11]
18293                  + ((sp_uint128)a[ 8]) * b[10]
18294                  + ((sp_uint128)a[ 9]) * b[ 9]
18295                  + ((sp_uint128)a[10]) * b[ 8]
18296                  + ((sp_uint128)a[11]) * b[ 7]
18297                  + ((sp_uint128)a[12]) * b[ 6];
18298     sp_uint128 t19  = ((sp_uint128)a[ 7]) * b[12]
18299                  + ((sp_uint128)a[ 8]) * b[11]
18300                  + ((sp_uint128)a[ 9]) * b[10]
18301                  + ((sp_uint128)a[10]) * b[ 9]
18302                  + ((sp_uint128)a[11]) * b[ 8]
18303                  + ((sp_uint128)a[12]) * b[ 7];
18304     sp_uint128 t20  = ((sp_uint128)a[ 8]) * b[12]
18305                  + ((sp_uint128)a[ 9]) * b[11]
18306                  + ((sp_uint128)a[10]) * b[10]
18307                  + ((sp_uint128)a[11]) * b[ 9]
18308                  + ((sp_uint128)a[12]) * b[ 8];
18309     sp_uint128 t21  = ((sp_uint128)a[ 9]) * b[12]
18310                  + ((sp_uint128)a[10]) * b[11]
18311                  + ((sp_uint128)a[11]) * b[10]
18312                  + ((sp_uint128)a[12]) * b[ 9];
18313     sp_uint128 t22  = ((sp_uint128)a[10]) * b[12]
18314                  + ((sp_uint128)a[11]) * b[11]
18315                  + ((sp_uint128)a[12]) * b[10];
18316     sp_uint128 t23  = ((sp_uint128)a[11]) * b[12]
18317                  + ((sp_uint128)a[12]) * b[11];
18318     sp_uint128 t24  = ((sp_uint128)a[12]) * b[12];
18319 
18320     t1   += t0  >> 53; r[ 0] = t0  & 0x1fffffffffffffL;
18321     t2   += t1  >> 53; r[ 1] = t1  & 0x1fffffffffffffL;
18322     t3   += t2  >> 53; r[ 2] = t2  & 0x1fffffffffffffL;
18323     t4   += t3  >> 53; r[ 3] = t3  & 0x1fffffffffffffL;
18324     t5   += t4  >> 53; r[ 4] = t4  & 0x1fffffffffffffL;
18325     t6   += t5  >> 53; r[ 5] = t5  & 0x1fffffffffffffL;
18326     t7   += t6  >> 53; r[ 6] = t6  & 0x1fffffffffffffL;
18327     t8   += t7  >> 53; r[ 7] = t7  & 0x1fffffffffffffL;
18328     t9   += t8  >> 53; r[ 8] = t8  & 0x1fffffffffffffL;
18329     t10  += t9  >> 53; r[ 9] = t9  & 0x1fffffffffffffL;
18330     t11  += t10 >> 53; r[10] = t10 & 0x1fffffffffffffL;
18331     t12  += t11 >> 53; r[11] = t11 & 0x1fffffffffffffL;
18332     t13  += t12 >> 53; r[12] = t12 & 0x1fffffffffffffL;
18333     t14  += t13 >> 53; r[13] = t13 & 0x1fffffffffffffL;
18334     t15  += t14 >> 53; r[14] = t14 & 0x1fffffffffffffL;
18335     t16  += t15 >> 53; r[15] = t15 & 0x1fffffffffffffL;
18336     t17  += t16 >> 53; r[16] = t16 & 0x1fffffffffffffL;
18337     t18  += t17 >> 53; r[17] = t17 & 0x1fffffffffffffL;
18338     t19  += t18 >> 53; r[18] = t18 & 0x1fffffffffffffL;
18339     t20  += t19 >> 53; r[19] = t19 & 0x1fffffffffffffL;
18340     t21  += t20 >> 53; r[20] = t20 & 0x1fffffffffffffL;
18341     t22  += t21 >> 53; r[21] = t21 & 0x1fffffffffffffL;
18342     t23  += t22 >> 53; r[22] = t22 & 0x1fffffffffffffL;
18343     t24  += t23 >> 53; r[23] = t23 & 0x1fffffffffffffL;
18344     r[25] = (sp_digit)(t24 >> 53);
18345                        r[24] = t24 & 0x1fffffffffffffL;
18346 }
18347 
18348 /* Square a and put result in r. (r = a * a)
18349  *
18350  * r  A single precision integer.
18351  * a  A single precision integer.
18352  */
sp_4096_sqr_13(sp_digit * r,const sp_digit * a)18353 SP_NOINLINE static void sp_4096_sqr_13(sp_digit* r, const sp_digit* a)
18354 {
18355     sp_uint128 t0   =  ((sp_uint128)a[ 0]) * a[ 0];
18356     sp_uint128 t1   = (((sp_uint128)a[ 0]) * a[ 1]) * 2;
18357     sp_uint128 t2   = (((sp_uint128)a[ 0]) * a[ 2]) * 2
18358                  +  ((sp_uint128)a[ 1]) * a[ 1];
18359     sp_uint128 t3   = (((sp_uint128)a[ 0]) * a[ 3]
18360                  +  ((sp_uint128)a[ 1]) * a[ 2]) * 2;
18361     sp_uint128 t4   = (((sp_uint128)a[ 0]) * a[ 4]
18362                  +  ((sp_uint128)a[ 1]) * a[ 3]) * 2
18363                  +  ((sp_uint128)a[ 2]) * a[ 2];
18364     sp_uint128 t5   = (((sp_uint128)a[ 0]) * a[ 5]
18365                  +  ((sp_uint128)a[ 1]) * a[ 4]
18366                  +  ((sp_uint128)a[ 2]) * a[ 3]) * 2;
18367     sp_uint128 t6   = (((sp_uint128)a[ 0]) * a[ 6]
18368                  +  ((sp_uint128)a[ 1]) * a[ 5]
18369                  +  ((sp_uint128)a[ 2]) * a[ 4]) * 2
18370                  +  ((sp_uint128)a[ 3]) * a[ 3];
18371     sp_uint128 t7   = (((sp_uint128)a[ 0]) * a[ 7]
18372                  +  ((sp_uint128)a[ 1]) * a[ 6]
18373                  +  ((sp_uint128)a[ 2]) * a[ 5]
18374                  +  ((sp_uint128)a[ 3]) * a[ 4]) * 2;
18375     sp_uint128 t8   = (((sp_uint128)a[ 0]) * a[ 8]
18376                  +  ((sp_uint128)a[ 1]) * a[ 7]
18377                  +  ((sp_uint128)a[ 2]) * a[ 6]
18378                  +  ((sp_uint128)a[ 3]) * a[ 5]) * 2
18379                  +  ((sp_uint128)a[ 4]) * a[ 4];
18380     sp_uint128 t9   = (((sp_uint128)a[ 0]) * a[ 9]
18381                  +  ((sp_uint128)a[ 1]) * a[ 8]
18382                  +  ((sp_uint128)a[ 2]) * a[ 7]
18383                  +  ((sp_uint128)a[ 3]) * a[ 6]
18384                  +  ((sp_uint128)a[ 4]) * a[ 5]) * 2;
18385     sp_uint128 t10  = (((sp_uint128)a[ 0]) * a[10]
18386                  +  ((sp_uint128)a[ 1]) * a[ 9]
18387                  +  ((sp_uint128)a[ 2]) * a[ 8]
18388                  +  ((sp_uint128)a[ 3]) * a[ 7]
18389                  +  ((sp_uint128)a[ 4]) * a[ 6]) * 2
18390                  +  ((sp_uint128)a[ 5]) * a[ 5];
18391     sp_uint128 t11  = (((sp_uint128)a[ 0]) * a[11]
18392                  +  ((sp_uint128)a[ 1]) * a[10]
18393                  +  ((sp_uint128)a[ 2]) * a[ 9]
18394                  +  ((sp_uint128)a[ 3]) * a[ 8]
18395                  +  ((sp_uint128)a[ 4]) * a[ 7]
18396                  +  ((sp_uint128)a[ 5]) * a[ 6]) * 2;
18397     sp_uint128 t12  = (((sp_uint128)a[ 0]) * a[12]
18398                  +  ((sp_uint128)a[ 1]) * a[11]
18399                  +  ((sp_uint128)a[ 2]) * a[10]
18400                  +  ((sp_uint128)a[ 3]) * a[ 9]
18401                  +  ((sp_uint128)a[ 4]) * a[ 8]
18402                  +  ((sp_uint128)a[ 5]) * a[ 7]) * 2
18403                  +  ((sp_uint128)a[ 6]) * a[ 6];
18404     sp_uint128 t13  = (((sp_uint128)a[ 1]) * a[12]
18405                  +  ((sp_uint128)a[ 2]) * a[11]
18406                  +  ((sp_uint128)a[ 3]) * a[10]
18407                  +  ((sp_uint128)a[ 4]) * a[ 9]
18408                  +  ((sp_uint128)a[ 5]) * a[ 8]
18409                  +  ((sp_uint128)a[ 6]) * a[ 7]) * 2;
18410     sp_uint128 t14  = (((sp_uint128)a[ 2]) * a[12]
18411                  +  ((sp_uint128)a[ 3]) * a[11]
18412                  +  ((sp_uint128)a[ 4]) * a[10]
18413                  +  ((sp_uint128)a[ 5]) * a[ 9]
18414                  +  ((sp_uint128)a[ 6]) * a[ 8]) * 2
18415                  +  ((sp_uint128)a[ 7]) * a[ 7];
18416     sp_uint128 t15  = (((sp_uint128)a[ 3]) * a[12]
18417                  +  ((sp_uint128)a[ 4]) * a[11]
18418                  +  ((sp_uint128)a[ 5]) * a[10]
18419                  +  ((sp_uint128)a[ 6]) * a[ 9]
18420                  +  ((sp_uint128)a[ 7]) * a[ 8]) * 2;
18421     sp_uint128 t16  = (((sp_uint128)a[ 4]) * a[12]
18422                  +  ((sp_uint128)a[ 5]) * a[11]
18423                  +  ((sp_uint128)a[ 6]) * a[10]
18424                  +  ((sp_uint128)a[ 7]) * a[ 9]) * 2
18425                  +  ((sp_uint128)a[ 8]) * a[ 8];
18426     sp_uint128 t17  = (((sp_uint128)a[ 5]) * a[12]
18427                  +  ((sp_uint128)a[ 6]) * a[11]
18428                  +  ((sp_uint128)a[ 7]) * a[10]
18429                  +  ((sp_uint128)a[ 8]) * a[ 9]) * 2;
18430     sp_uint128 t18  = (((sp_uint128)a[ 6]) * a[12]
18431                  +  ((sp_uint128)a[ 7]) * a[11]
18432                  +  ((sp_uint128)a[ 8]) * a[10]) * 2
18433                  +  ((sp_uint128)a[ 9]) * a[ 9];
18434     sp_uint128 t19  = (((sp_uint128)a[ 7]) * a[12]
18435                  +  ((sp_uint128)a[ 8]) * a[11]
18436                  +  ((sp_uint128)a[ 9]) * a[10]) * 2;
18437     sp_uint128 t20  = (((sp_uint128)a[ 8]) * a[12]
18438                  +  ((sp_uint128)a[ 9]) * a[11]) * 2
18439                  +  ((sp_uint128)a[10]) * a[10];
18440     sp_uint128 t21  = (((sp_uint128)a[ 9]) * a[12]
18441                  +  ((sp_uint128)a[10]) * a[11]) * 2;
18442     sp_uint128 t22  = (((sp_uint128)a[10]) * a[12]) * 2
18443                  +  ((sp_uint128)a[11]) * a[11];
18444     sp_uint128 t23  = (((sp_uint128)a[11]) * a[12]) * 2;
18445     sp_uint128 t24  =  ((sp_uint128)a[12]) * a[12];
18446 
18447     t1   += t0  >> 53; r[ 0] = t0  & 0x1fffffffffffffL;
18448     t2   += t1  >> 53; r[ 1] = t1  & 0x1fffffffffffffL;
18449     t3   += t2  >> 53; r[ 2] = t2  & 0x1fffffffffffffL;
18450     t4   += t3  >> 53; r[ 3] = t3  & 0x1fffffffffffffL;
18451     t5   += t4  >> 53; r[ 4] = t4  & 0x1fffffffffffffL;
18452     t6   += t5  >> 53; r[ 5] = t5  & 0x1fffffffffffffL;
18453     t7   += t6  >> 53; r[ 6] = t6  & 0x1fffffffffffffL;
18454     t8   += t7  >> 53; r[ 7] = t7  & 0x1fffffffffffffL;
18455     t9   += t8  >> 53; r[ 8] = t8  & 0x1fffffffffffffL;
18456     t10  += t9  >> 53; r[ 9] = t9  & 0x1fffffffffffffL;
18457     t11  += t10 >> 53; r[10] = t10 & 0x1fffffffffffffL;
18458     t12  += t11 >> 53; r[11] = t11 & 0x1fffffffffffffL;
18459     t13  += t12 >> 53; r[12] = t12 & 0x1fffffffffffffL;
18460     t14  += t13 >> 53; r[13] = t13 & 0x1fffffffffffffL;
18461     t15  += t14 >> 53; r[14] = t14 & 0x1fffffffffffffL;
18462     t16  += t15 >> 53; r[15] = t15 & 0x1fffffffffffffL;
18463     t17  += t16 >> 53; r[16] = t16 & 0x1fffffffffffffL;
18464     t18  += t17 >> 53; r[17] = t17 & 0x1fffffffffffffL;
18465     t19  += t18 >> 53; r[18] = t18 & 0x1fffffffffffffL;
18466     t20  += t19 >> 53; r[19] = t19 & 0x1fffffffffffffL;
18467     t21  += t20 >> 53; r[20] = t20 & 0x1fffffffffffffL;
18468     t22  += t21 >> 53; r[21] = t21 & 0x1fffffffffffffL;
18469     t23  += t22 >> 53; r[22] = t22 & 0x1fffffffffffffL;
18470     t24  += t23 >> 53; r[23] = t23 & 0x1fffffffffffffL;
18471     r[25] = (sp_digit)(t24 >> 53);
18472                        r[24] = t24 & 0x1fffffffffffffL;
18473 }
18474 
18475 /* Add b to a into r. (r = a + b)
18476  *
18477  * r  A single precision integer.
18478  * a  A single precision integer.
18479  * b  A single precision integer.
18480  */
sp_4096_add_13(sp_digit * r,const sp_digit * a,const sp_digit * b)18481 SP_NOINLINE static int sp_4096_add_13(sp_digit* r, const sp_digit* a,
18482         const sp_digit* b)
18483 {
18484     r[ 0] = a[ 0] + b[ 0];
18485     r[ 1] = a[ 1] + b[ 1];
18486     r[ 2] = a[ 2] + b[ 2];
18487     r[ 3] = a[ 3] + b[ 3];
18488     r[ 4] = a[ 4] + b[ 4];
18489     r[ 5] = a[ 5] + b[ 5];
18490     r[ 6] = a[ 6] + b[ 6];
18491     r[ 7] = a[ 7] + b[ 7];
18492     r[ 8] = a[ 8] + b[ 8];
18493     r[ 9] = a[ 9] + b[ 9];
18494     r[10] = a[10] + b[10];
18495     r[11] = a[11] + b[11];
18496     r[12] = a[12] + b[12];
18497 
18498     return 0;
18499 }
18500 
18501 /* Sub b from a into r. (r = a - b)
18502  *
18503  * r  A single precision integer.
18504  * a  A single precision integer.
18505  * b  A single precision integer.
18506  */
sp_4096_sub_26(sp_digit * r,const sp_digit * a,const sp_digit * b)18507 SP_NOINLINE static int sp_4096_sub_26(sp_digit* r, const sp_digit* a,
18508         const sp_digit* b)
18509 {
18510     int i;
18511 
18512     for (i = 0; i < 24; i += 8) {
18513         r[i + 0] = a[i + 0] - b[i + 0];
18514         r[i + 1] = a[i + 1] - b[i + 1];
18515         r[i + 2] = a[i + 2] - b[i + 2];
18516         r[i + 3] = a[i + 3] - b[i + 3];
18517         r[i + 4] = a[i + 4] - b[i + 4];
18518         r[i + 5] = a[i + 5] - b[i + 5];
18519         r[i + 6] = a[i + 6] - b[i + 6];
18520         r[i + 7] = a[i + 7] - b[i + 7];
18521     }
18522     r[24] = a[24] - b[24];
18523     r[25] = a[25] - b[25];
18524 
18525     return 0;
18526 }
18527 
18528 /* Add b to a into r. (r = a + b)
18529  *
18530  * r  A single precision integer.
18531  * a  A single precision integer.
18532  * b  A single precision integer.
18533  */
sp_4096_add_26(sp_digit * r,const sp_digit * a,const sp_digit * b)18534 SP_NOINLINE static int sp_4096_add_26(sp_digit* r, const sp_digit* a,
18535         const sp_digit* b)
18536 {
18537     int i;
18538 
18539     for (i = 0; i < 24; i += 8) {
18540         r[i + 0] = a[i + 0] + b[i + 0];
18541         r[i + 1] = a[i + 1] + b[i + 1];
18542         r[i + 2] = a[i + 2] + b[i + 2];
18543         r[i + 3] = a[i + 3] + b[i + 3];
18544         r[i + 4] = a[i + 4] + b[i + 4];
18545         r[i + 5] = a[i + 5] + b[i + 5];
18546         r[i + 6] = a[i + 6] + b[i + 6];
18547         r[i + 7] = a[i + 7] + b[i + 7];
18548     }
18549     r[24] = a[24] + b[24];
18550     r[25] = a[25] + b[25];
18551 
18552     return 0;
18553 }
18554 
18555 /* Multiply a and b into r. (r = a * b)
18556  *
18557  * r  A single precision integer.
18558  * a  A single precision integer.
18559  * b  A single precision integer.
18560  */
sp_4096_mul_39(sp_digit * r,const sp_digit * a,const sp_digit * b)18561 SP_NOINLINE static void sp_4096_mul_39(sp_digit* r, const sp_digit* a,
18562     const sp_digit* b)
18563 {
18564     sp_digit p0[26];
18565     sp_digit p1[26];
18566     sp_digit p2[26];
18567     sp_digit p3[26];
18568     sp_digit p4[26];
18569     sp_digit p5[26];
18570     sp_digit t0[26];
18571     sp_digit t1[26];
18572     sp_digit t2[26];
18573     sp_digit a0[13];
18574     sp_digit a1[13];
18575     sp_digit a2[13];
18576     sp_digit b0[13];
18577     sp_digit b1[13];
18578     sp_digit b2[13];
18579     (void)sp_4096_add_13(a0, a, &a[13]);
18580     (void)sp_4096_add_13(b0, b, &b[13]);
18581     (void)sp_4096_add_13(a1, &a[13], &a[26]);
18582     (void)sp_4096_add_13(b1, &b[13], &b[26]);
18583     (void)sp_4096_add_13(a2, a0, &a[26]);
18584     (void)sp_4096_add_13(b2, b0, &b[26]);
18585     sp_4096_mul_13(p0, a, b);
18586     sp_4096_mul_13(p2, &a[13], &b[13]);
18587     sp_4096_mul_13(p4, &a[26], &b[26]);
18588     sp_4096_mul_13(p1, a0, b0);
18589     sp_4096_mul_13(p3, a1, b1);
18590     sp_4096_mul_13(p5, a2, b2);
18591     XMEMSET(r, 0, sizeof(*r)*2U*39U);
18592     (void)sp_4096_sub_26(t0, p3, p2);
18593     (void)sp_4096_sub_26(t1, p1, p2);
18594     (void)sp_4096_sub_26(t2, p5, t0);
18595     (void)sp_4096_sub_26(t2, t2, t1);
18596     (void)sp_4096_sub_26(t0, t0, p4);
18597     (void)sp_4096_sub_26(t1, t1, p0);
18598     (void)sp_4096_add_26(r, r, p0);
18599     (void)sp_4096_add_26(&r[13], &r[13], t1);
18600     (void)sp_4096_add_26(&r[26], &r[26], t2);
18601     (void)sp_4096_add_26(&r[39], &r[39], t0);
18602     (void)sp_4096_add_26(&r[52], &r[52], p4);
18603 }
18604 
18605 /* Square a into r. (r = a * a)
18606  *
18607  * r  A single precision integer.
18608  * a  A single precision integer.
18609  */
sp_4096_sqr_39(sp_digit * r,const sp_digit * a)18610 SP_NOINLINE static void sp_4096_sqr_39(sp_digit* r, const sp_digit* a)
18611 {
18612     sp_digit p0[26];
18613     sp_digit p1[26];
18614     sp_digit p2[26];
18615     sp_digit p3[26];
18616     sp_digit p4[26];
18617     sp_digit p5[26];
18618     sp_digit t0[26];
18619     sp_digit t1[26];
18620     sp_digit t2[26];
18621     sp_digit a0[13];
18622     sp_digit a1[13];
18623     sp_digit a2[13];
18624     (void)sp_4096_add_13(a0, a, &a[13]);
18625     (void)sp_4096_add_13(a1, &a[13], &a[26]);
18626     (void)sp_4096_add_13(a2, a0, &a[26]);
18627     sp_4096_sqr_13(p0, a);
18628     sp_4096_sqr_13(p2, &a[13]);
18629     sp_4096_sqr_13(p4, &a[26]);
18630     sp_4096_sqr_13(p1, a0);
18631     sp_4096_sqr_13(p3, a1);
18632     sp_4096_sqr_13(p5, a2);
18633     XMEMSET(r, 0, sizeof(*r)*2U*39U);
18634     (void)sp_4096_sub_26(t0, p3, p2);
18635     (void)sp_4096_sub_26(t1, p1, p2);
18636     (void)sp_4096_sub_26(t2, p5, t0);
18637     (void)sp_4096_sub_26(t2, t2, t1);
18638     (void)sp_4096_sub_26(t0, t0, p4);
18639     (void)sp_4096_sub_26(t1, t1, p0);
18640     (void)sp_4096_add_26(r, r, p0);
18641     (void)sp_4096_add_26(&r[13], &r[13], t1);
18642     (void)sp_4096_add_26(&r[26], &r[26], t2);
18643     (void)sp_4096_add_26(&r[39], &r[39], t0);
18644     (void)sp_4096_add_26(&r[52], &r[52], p4);
18645 }
18646 
18647 /* Add b to a into r. (r = a + b)
18648  *
18649  * r  A single precision integer.
18650  * a  A single precision integer.
18651  * b  A single precision integer.
18652  */
sp_4096_add_39(sp_digit * r,const sp_digit * a,const sp_digit * b)18653 SP_NOINLINE static int sp_4096_add_39(sp_digit* r, const sp_digit* a,
18654         const sp_digit* b)
18655 {
18656     int i;
18657 
18658     for (i = 0; i < 32; i += 8) {
18659         r[i + 0] = a[i + 0] + b[i + 0];
18660         r[i + 1] = a[i + 1] + b[i + 1];
18661         r[i + 2] = a[i + 2] + b[i + 2];
18662         r[i + 3] = a[i + 3] + b[i + 3];
18663         r[i + 4] = a[i + 4] + b[i + 4];
18664         r[i + 5] = a[i + 5] + b[i + 5];
18665         r[i + 6] = a[i + 6] + b[i + 6];
18666         r[i + 7] = a[i + 7] + b[i + 7];
18667     }
18668     r[32] = a[32] + b[32];
18669     r[33] = a[33] + b[33];
18670     r[34] = a[34] + b[34];
18671     r[35] = a[35] + b[35];
18672     r[36] = a[36] + b[36];
18673     r[37] = a[37] + b[37];
18674     r[38] = a[38] + b[38];
18675 
18676     return 0;
18677 }
18678 
18679 /* Add b to a into r. (r = a + b)
18680  *
18681  * r  A single precision integer.
18682  * a  A single precision integer.
18683  * b  A single precision integer.
18684  */
sp_4096_add_78(sp_digit * r,const sp_digit * a,const sp_digit * b)18685 SP_NOINLINE static int sp_4096_add_78(sp_digit* r, const sp_digit* a,
18686         const sp_digit* b)
18687 {
18688     int i;
18689 
18690     for (i = 0; i < 72; i += 8) {
18691         r[i + 0] = a[i + 0] + b[i + 0];
18692         r[i + 1] = a[i + 1] + b[i + 1];
18693         r[i + 2] = a[i + 2] + b[i + 2];
18694         r[i + 3] = a[i + 3] + b[i + 3];
18695         r[i + 4] = a[i + 4] + b[i + 4];
18696         r[i + 5] = a[i + 5] + b[i + 5];
18697         r[i + 6] = a[i + 6] + b[i + 6];
18698         r[i + 7] = a[i + 7] + b[i + 7];
18699     }
18700     r[72] = a[72] + b[72];
18701     r[73] = a[73] + b[73];
18702     r[74] = a[74] + b[74];
18703     r[75] = a[75] + b[75];
18704     r[76] = a[76] + b[76];
18705     r[77] = a[77] + b[77];
18706 
18707     return 0;
18708 }
18709 
18710 /* Sub b from a into r. (r = a - b)
18711  *
18712  * r  A single precision integer.
18713  * a  A single precision integer.
18714  * b  A single precision integer.
18715  */
sp_4096_sub_78(sp_digit * r,const sp_digit * a,const sp_digit * b)18716 SP_NOINLINE static int sp_4096_sub_78(sp_digit* r, const sp_digit* a,
18717         const sp_digit* b)
18718 {
18719     int i;
18720 
18721     for (i = 0; i < 72; i += 8) {
18722         r[i + 0] = a[i + 0] - b[i + 0];
18723         r[i + 1] = a[i + 1] - b[i + 1];
18724         r[i + 2] = a[i + 2] - b[i + 2];
18725         r[i + 3] = a[i + 3] - b[i + 3];
18726         r[i + 4] = a[i + 4] - b[i + 4];
18727         r[i + 5] = a[i + 5] - b[i + 5];
18728         r[i + 6] = a[i + 6] - b[i + 6];
18729         r[i + 7] = a[i + 7] - b[i + 7];
18730     }
18731     r[72] = a[72] - b[72];
18732     r[73] = a[73] - b[73];
18733     r[74] = a[74] - b[74];
18734     r[75] = a[75] - b[75];
18735     r[76] = a[76] - b[76];
18736     r[77] = a[77] - b[77];
18737 
18738     return 0;
18739 }
18740 
18741 /* Multiply a and b into r. (r = a * b)
18742  *
18743  * r  A single precision integer.
18744  * a  A single precision integer.
18745  * b  A single precision integer.
18746  */
sp_4096_mul_78(sp_digit * r,const sp_digit * a,const sp_digit * b)18747 SP_NOINLINE static void sp_4096_mul_78(sp_digit* r, const sp_digit* a,
18748     const sp_digit* b)
18749 {
18750     sp_digit* z0 = r;
18751     sp_digit z1[78];
18752     sp_digit* a1 = z1;
18753     sp_digit b1[39];
18754     sp_digit* z2 = r + 78;
18755     (void)sp_4096_add_39(a1, a, &a[39]);
18756     (void)sp_4096_add_39(b1, b, &b[39]);
18757     sp_4096_mul_39(z2, &a[39], &b[39]);
18758     sp_4096_mul_39(z0, a, b);
18759     sp_4096_mul_39(z1, a1, b1);
18760     (void)sp_4096_sub_78(z1, z1, z2);
18761     (void)sp_4096_sub_78(z1, z1, z0);
18762     (void)sp_4096_add_78(r + 39, r + 39, z1);
18763 }
18764 
18765 /* Square a and put result in r. (r = a * a)
18766  *
18767  * r  A single precision integer.
18768  * a  A single precision integer.
18769  */
sp_4096_sqr_78(sp_digit * r,const sp_digit * a)18770 SP_NOINLINE static void sp_4096_sqr_78(sp_digit* r, const sp_digit* a)
18771 {
18772     sp_digit* z0 = r;
18773     sp_digit z1[78];
18774     sp_digit* a1 = z1;
18775     sp_digit* z2 = r + 78;
18776     (void)sp_4096_add_39(a1, a, &a[39]);
18777     sp_4096_sqr_39(z2, &a[39]);
18778     sp_4096_sqr_39(z0, a);
18779     sp_4096_sqr_39(z1, a1);
18780     (void)sp_4096_sub_78(z1, z1, z2);
18781     (void)sp_4096_sub_78(z1, z1, z0);
18782     (void)sp_4096_add_78(r + 39, r + 39, z1);
18783 }
18784 
18785 #endif /* !WOLFSSL_SP_SMALL */
18786 /* Caclulate the bottom digit of -1/a mod 2^n.
18787  *
18788  * a    A single precision number.
18789  * rho  Bottom word of inverse.
18790  */
sp_4096_mont_setup(const sp_digit * a,sp_digit * rho)18791 static void sp_4096_mont_setup(const sp_digit* a, sp_digit* rho)
18792 {
18793     sp_digit x;
18794     sp_digit b;
18795 
18796     b = a[0];
18797     x = (((b + 2) & 4) << 1) + b; /* here x*a==1 mod 2**4 */
18798     x *= 2 - b * x;               /* here x*a==1 mod 2**8 */
18799     x *= 2 - b * x;               /* here x*a==1 mod 2**16 */
18800     x *= 2 - b * x;               /* here x*a==1 mod 2**32 */
18801     x *= 2 - b * x;               /* here x*a==1 mod 2**64 */
18802     x &= 0x1fffffffffffffL;
18803 
18804     /* rho = -1/m mod b */
18805     *rho = ((sp_digit)1 << 53) - x;
18806 }
18807 
18808 /* Multiply a by scalar b into r. (r = a * b)
18809  *
18810  * r  A single precision integer.
18811  * a  A single precision integer.
18812  * b  A scalar.
18813  */
sp_4096_mul_d_78(sp_digit * r,const sp_digit * a,sp_digit b)18814 SP_NOINLINE static void sp_4096_mul_d_78(sp_digit* r, const sp_digit* a,
18815     sp_digit b)
18816 {
18817     sp_int128 tb = b;
18818     sp_int128 t = 0;
18819     sp_digit t2;
18820     sp_int128 p[4];
18821     int i;
18822 
18823     for (i = 0; i < 76; i += 4) {
18824         p[0] = tb * a[i + 0];
18825         p[1] = tb * a[i + 1];
18826         p[2] = tb * a[i + 2];
18827         p[3] = tb * a[i + 3];
18828         t += p[0];
18829         t2 = (sp_digit)(t & 0x1fffffffffffffL);
18830         t >>= 53;
18831         r[i + 0] = (sp_digit)t2;
18832         t += p[1];
18833         t2 = (sp_digit)(t & 0x1fffffffffffffL);
18834         t >>= 53;
18835         r[i + 1] = (sp_digit)t2;
18836         t += p[2];
18837         t2 = (sp_digit)(t & 0x1fffffffffffffL);
18838         t >>= 53;
18839         r[i + 2] = (sp_digit)t2;
18840         t += p[3];
18841         t2 = (sp_digit)(t & 0x1fffffffffffffL);
18842         t >>= 53;
18843         r[i + 3] = (sp_digit)t2;
18844     }
18845     t += tb * a[76];
18846     r[76] = (sp_digit)(t & 0x1fffffffffffffL);
18847     t >>= 53;
18848     t += tb * a[77];
18849     r[77] = (sp_digit)(t & 0x1fffffffffffffL);
18850     t >>= 53;
18851     r[78] = (sp_digit)(t & 0x1fffffffffffffL);
18852 }
18853 
18854 #if (defined(WOLFSSL_HAVE_SP_RSA) || defined(WOLFSSL_HAVE_SP_DH)) && !defined(WOLFSSL_RSA_PUBLIC_ONLY)
18855 #if defined(WOLFSSL_HAVE_SP_RSA) && !defined(SP_RSA_PRIVATE_EXP_D)
18856 /* Sub b from a into r. (r = a - b)
18857  *
18858  * r  A single precision integer.
18859  * a  A single precision integer.
18860  * b  A single precision integer.
18861  */
sp_4096_sub_39(sp_digit * r,const sp_digit * a,const sp_digit * b)18862 SP_NOINLINE static int sp_4096_sub_39(sp_digit* r, const sp_digit* a,
18863         const sp_digit* b)
18864 {
18865     int i;
18866 
18867     for (i = 0; i < 32; i += 8) {
18868         r[i + 0] = a[i + 0] - b[i + 0];
18869         r[i + 1] = a[i + 1] - b[i + 1];
18870         r[i + 2] = a[i + 2] - b[i + 2];
18871         r[i + 3] = a[i + 3] - b[i + 3];
18872         r[i + 4] = a[i + 4] - b[i + 4];
18873         r[i + 5] = a[i + 5] - b[i + 5];
18874         r[i + 6] = a[i + 6] - b[i + 6];
18875         r[i + 7] = a[i + 7] - b[i + 7];
18876     }
18877     r[32] = a[32] - b[32];
18878     r[33] = a[33] - b[33];
18879     r[34] = a[34] - b[34];
18880     r[35] = a[35] - b[35];
18881     r[36] = a[36] - b[36];
18882     r[37] = a[37] - b[37];
18883     r[38] = a[38] - b[38];
18884 
18885     return 0;
18886 }
18887 
18888 /* r = 2^n mod m where n is the number of bits to reduce by.
18889  * Given m must be 4096 bits, just need to subtract.
18890  *
18891  * r  A single precision number.
18892  * m  A single precision number.
18893  */
sp_4096_mont_norm_39(sp_digit * r,const sp_digit * m)18894 static void sp_4096_mont_norm_39(sp_digit* r, const sp_digit* m)
18895 {
18896     /* Set r = 2^n - 1. */
18897     int i;
18898 
18899     for (i = 0; i < 32; i += 8) {
18900         r[i + 0] = 0x1fffffffffffffL;
18901         r[i + 1] = 0x1fffffffffffffL;
18902         r[i + 2] = 0x1fffffffffffffL;
18903         r[i + 3] = 0x1fffffffffffffL;
18904         r[i + 4] = 0x1fffffffffffffL;
18905         r[i + 5] = 0x1fffffffffffffL;
18906         r[i + 6] = 0x1fffffffffffffL;
18907         r[i + 7] = 0x1fffffffffffffL;
18908     }
18909     r[32] = 0x1fffffffffffffL;
18910     r[33] = 0x1fffffffffffffL;
18911     r[34] = 0x1fffffffffffffL;
18912     r[35] = 0x1fffffffffffffL;
18913     r[36] = 0x1fffffffffffffL;
18914     r[37] = 0x1fffffffffffffL;
18915     r[38] = 0x3ffffffffL;
18916 
18917     /* r = (2^n - 1) mod n */
18918     (void)sp_4096_sub_39(r, r, m);
18919 
18920     /* Add one so r = 2^n mod m */
18921     r[0] += 1;
18922 }
18923 
18924 /* Compare a with b in constant time.
18925  *
18926  * a  A single precision integer.
18927  * b  A single precision integer.
18928  * return -ve, 0 or +ve if a is less than, equal to or greater than b
18929  * respectively.
18930  */
sp_4096_cmp_39(const sp_digit * a,const sp_digit * b)18931 static sp_digit sp_4096_cmp_39(const sp_digit* a, const sp_digit* b)
18932 {
18933     sp_digit r = 0;
18934     int i;
18935 
18936     r |= (a[38] - b[38]) & (0 - (sp_digit)1);
18937     r |= (a[37] - b[37]) & (0 - (sp_digit)((r == 0) ? 1 : 0));
18938     r |= (a[36] - b[36]) & (0 - (sp_digit)((r == 0) ? 1 : 0));
18939     r |= (a[35] - b[35]) & (0 - (sp_digit)((r == 0) ? 1 : 0));
18940     r |= (a[34] - b[34]) & (0 - (sp_digit)((r == 0) ? 1 : 0));
18941     r |= (a[33] - b[33]) & (0 - (sp_digit)((r == 0) ? 1 : 0));
18942     r |= (a[32] - b[32]) & (0 - (sp_digit)((r == 0) ? 1 : 0));
18943     for (i = 24; i >= 0; i -= 8) {
18944         r |= (a[i + 7] - b[i + 7]) & (0 - (sp_digit)((r == 0) ? 1 : 0));
18945         r |= (a[i + 6] - b[i + 6]) & (0 - (sp_digit)((r == 0) ? 1 : 0));
18946         r |= (a[i + 5] - b[i + 5]) & (0 - (sp_digit)((r == 0) ? 1 : 0));
18947         r |= (a[i + 4] - b[i + 4]) & (0 - (sp_digit)((r == 0) ? 1 : 0));
18948         r |= (a[i + 3] - b[i + 3]) & (0 - (sp_digit)((r == 0) ? 1 : 0));
18949         r |= (a[i + 2] - b[i + 2]) & (0 - (sp_digit)((r == 0) ? 1 : 0));
18950         r |= (a[i + 1] - b[i + 1]) & (0 - (sp_digit)((r == 0) ? 1 : 0));
18951         r |= (a[i + 0] - b[i + 0]) & (0 - (sp_digit)((r == 0) ? 1 : 0));
18952     }
18953 
18954     return r;
18955 }
18956 
18957 /* Conditionally subtract b from a using the mask m.
18958  * m is -1 to subtract and 0 when not.
18959  *
18960  * r  A single precision number representing condition subtract result.
18961  * a  A single precision number to subtract from.
18962  * b  A single precision number to subtract.
18963  * m  Mask value to apply.
18964  */
sp_4096_cond_sub_39(sp_digit * r,const sp_digit * a,const sp_digit * b,const sp_digit m)18965 static void sp_4096_cond_sub_39(sp_digit* r, const sp_digit* a,
18966         const sp_digit* b, const sp_digit m)
18967 {
18968     int i;
18969 
18970     for (i = 0; i < 32; i += 8) {
18971         r[i + 0] = a[i + 0] - (b[i + 0] & m);
18972         r[i + 1] = a[i + 1] - (b[i + 1] & m);
18973         r[i + 2] = a[i + 2] - (b[i + 2] & m);
18974         r[i + 3] = a[i + 3] - (b[i + 3] & m);
18975         r[i + 4] = a[i + 4] - (b[i + 4] & m);
18976         r[i + 5] = a[i + 5] - (b[i + 5] & m);
18977         r[i + 6] = a[i + 6] - (b[i + 6] & m);
18978         r[i + 7] = a[i + 7] - (b[i + 7] & m);
18979     }
18980     r[32] = a[32] - (b[32] & m);
18981     r[33] = a[33] - (b[33] & m);
18982     r[34] = a[34] - (b[34] & m);
18983     r[35] = a[35] - (b[35] & m);
18984     r[36] = a[36] - (b[36] & m);
18985     r[37] = a[37] - (b[37] & m);
18986     r[38] = a[38] - (b[38] & m);
18987 }
18988 
18989 /* Mul a by scalar b and add into r. (r += a * b)
18990  *
18991  * r  A single precision integer.
18992  * a  A single precision integer.
18993  * b  A scalar.
18994  */
sp_4096_mul_add_39(sp_digit * r,const sp_digit * a,const sp_digit b)18995 SP_NOINLINE static void sp_4096_mul_add_39(sp_digit* r, const sp_digit* a,
18996         const sp_digit b)
18997 {
18998     sp_int128 tb = b;
18999     sp_int128 t[8];
19000     int i;
19001 
19002     t[0] = tb * a[0]; r[0] += (sp_digit)(t[0] & 0x1fffffffffffffL);
19003     for (i = 0; i < 32; i += 8) {
19004         t[1] = tb * a[i+1];
19005         r[i+1] += (sp_digit)((t[0] >> 53) + (t[1] & 0x1fffffffffffffL));
19006         t[2] = tb * a[i+2];
19007         r[i+2] += (sp_digit)((t[1] >> 53) + (t[2] & 0x1fffffffffffffL));
19008         t[3] = tb * a[i+3];
19009         r[i+3] += (sp_digit)((t[2] >> 53) + (t[3] & 0x1fffffffffffffL));
19010         t[4] = tb * a[i+4];
19011         r[i+4] += (sp_digit)((t[3] >> 53) + (t[4] & 0x1fffffffffffffL));
19012         t[5] = tb * a[i+5];
19013         r[i+5] += (sp_digit)((t[4] >> 53) + (t[5] & 0x1fffffffffffffL));
19014         t[6] = tb * a[i+6];
19015         r[i+6] += (sp_digit)((t[5] >> 53) + (t[6] & 0x1fffffffffffffL));
19016         t[7] = tb * a[i+7];
19017         r[i+7] += (sp_digit)((t[6] >> 53) + (t[7] & 0x1fffffffffffffL));
19018         t[0] = tb * a[i+8];
19019         r[i+8] += (sp_digit)((t[7] >> 53) + (t[0] & 0x1fffffffffffffL));
19020     }
19021     t[1] = tb * a[33];
19022     r[33] += (sp_digit)((t[0] >> 53) + (t[1] & 0x1fffffffffffffL));
19023     t[2] = tb * a[34];
19024     r[34] += (sp_digit)((t[1] >> 53) + (t[2] & 0x1fffffffffffffL));
19025     t[3] = tb * a[35];
19026     r[35] += (sp_digit)((t[2] >> 53) + (t[3] & 0x1fffffffffffffL));
19027     t[4] = tb * a[36];
19028     r[36] += (sp_digit)((t[3] >> 53) + (t[4] & 0x1fffffffffffffL));
19029     t[5] = tb * a[37];
19030     r[37] += (sp_digit)((t[4] >> 53) + (t[5] & 0x1fffffffffffffL));
19031     t[6] = tb * a[38];
19032     r[38] += (sp_digit)((t[5] >> 53) + (t[6] & 0x1fffffffffffffL));
19033     r[39] +=  (sp_digit)(t[6] >> 53);
19034 }
19035 
19036 /* Shift the result in the high 2048 bits down to the bottom.
19037  *
19038  * r  A single precision number.
19039  * a  A single precision number.
19040  */
sp_4096_mont_shift_39(sp_digit * r,const sp_digit * a)19041 static void sp_4096_mont_shift_39(sp_digit* r, const sp_digit* a)
19042 {
19043     int i;
19044     sp_int128 n = a[38] >> 34;
19045     n += ((sp_int128)a[39]) << 19;
19046     for (i = 0; i < 32; i += 8) {
19047         r[i + 0] = n & 0x1fffffffffffffL;
19048         n >>= 53; n += ((sp_int128)a[i + 40]) << 19;
19049         r[i + 1] = n & 0x1fffffffffffffL;
19050         n >>= 53; n += ((sp_int128)a[i + 41]) << 19;
19051         r[i + 2] = n & 0x1fffffffffffffL;
19052         n >>= 53; n += ((sp_int128)a[i + 42]) << 19;
19053         r[i + 3] = n & 0x1fffffffffffffL;
19054         n >>= 53; n += ((sp_int128)a[i + 43]) << 19;
19055         r[i + 4] = n & 0x1fffffffffffffL;
19056         n >>= 53; n += ((sp_int128)a[i + 44]) << 19;
19057         r[i + 5] = n & 0x1fffffffffffffL;
19058         n >>= 53; n += ((sp_int128)a[i + 45]) << 19;
19059         r[i + 6] = n & 0x1fffffffffffffL;
19060         n >>= 53; n += ((sp_int128)a[i + 46]) << 19;
19061         r[i + 7] = n & 0x1fffffffffffffL;
19062         n >>= 53; n += ((sp_int128)a[i + 47]) << 19;
19063     }
19064     r[32] = n & 0x1fffffffffffffL; n >>= 53; n += ((sp_int128)a[72]) << 19;
19065     r[33] = n & 0x1fffffffffffffL; n >>= 53; n += ((sp_int128)a[73]) << 19;
19066     r[34] = n & 0x1fffffffffffffL; n >>= 53; n += ((sp_int128)a[74]) << 19;
19067     r[35] = n & 0x1fffffffffffffL; n >>= 53; n += ((sp_int128)a[75]) << 19;
19068     r[36] = n & 0x1fffffffffffffL; n >>= 53; n += ((sp_int128)a[76]) << 19;
19069     r[37] = n & 0x1fffffffffffffL; n >>= 53; n += ((sp_int128)a[77]) << 19;
19070     r[38] = (sp_digit)n;
19071     XMEMSET(&r[39], 0, sizeof(*r) * 39U);
19072 }
19073 
19074 /* Reduce the number back to 4096 bits using Montgomery reduction.
19075  *
19076  * a   A single precision number to reduce in place.
19077  * m   The single precision number representing the modulus.
19078  * mp  The digit representing the negative inverse of m mod 2^n.
19079  */
sp_4096_mont_reduce_39(sp_digit * a,const sp_digit * m,sp_digit mp)19080 static void sp_4096_mont_reduce_39(sp_digit* a, const sp_digit* m, sp_digit mp)
19081 {
19082     int i;
19083     sp_digit mu;
19084 
19085     sp_4096_norm_39(a + 39);
19086 
19087     for (i=0; i<38; i++) {
19088         mu = (a[i] * mp) & 0x1fffffffffffffL;
19089         sp_4096_mul_add_39(a+i, m, mu);
19090         a[i+1] += a[i] >> 53;
19091     }
19092     mu = (a[i] * mp) & 0x3ffffffffL;
19093     sp_4096_mul_add_39(a+i, m, mu);
19094     a[i+1] += a[i] >> 53;
19095     a[i] &= 0x1fffffffffffffL;
19096     sp_4096_mont_shift_39(a, a);
19097     sp_4096_cond_sub_39(a, a, m, 0 - (((a[38] - m[38]) > 0) ?
19098             (sp_digit)1 : (sp_digit)0));
19099     sp_4096_norm_39(a);
19100 }
19101 
19102 /* Multiply two Montgomery form numbers mod the modulus (prime).
19103  * (r = a * b mod m)
19104  *
19105  * r   Result of multiplication.
19106  * a   First number to multiply in Montgomery form.
19107  * b   Second number to multiply in Montgomery form.
19108  * m   Modulus (prime).
19109  * mp  Montgomery mulitplier.
19110  */
sp_4096_mont_mul_39(sp_digit * r,const sp_digit * a,const sp_digit * b,const sp_digit * m,sp_digit mp)19111 static void sp_4096_mont_mul_39(sp_digit* r, const sp_digit* a,
19112         const sp_digit* b, const sp_digit* m, sp_digit mp)
19113 {
19114     sp_4096_mul_39(r, a, b);
19115     sp_4096_mont_reduce_39(r, m, mp);
19116 }
19117 
19118 /* Square the Montgomery form number. (r = a * a mod m)
19119  *
19120  * r   Result of squaring.
19121  * a   Number to square in Montgomery form.
19122  * m   Modulus (prime).
19123  * mp  Montgomery mulitplier.
19124  */
sp_4096_mont_sqr_39(sp_digit * r,const sp_digit * a,const sp_digit * m,sp_digit mp)19125 static void sp_4096_mont_sqr_39(sp_digit* r, const sp_digit* a,
19126         const sp_digit* m, sp_digit mp)
19127 {
19128     sp_4096_sqr_39(r, a);
19129     sp_4096_mont_reduce_39(r, m, mp);
19130 }
19131 
19132 /* Multiply a by scalar b into r. (r = a * b)
19133  *
19134  * r  A single precision integer.
19135  * a  A single precision integer.
19136  * b  A scalar.
19137  */
sp_4096_mul_d_39(sp_digit * r,const sp_digit * a,sp_digit b)19138 SP_NOINLINE static void sp_4096_mul_d_39(sp_digit* r, const sp_digit* a,
19139     sp_digit b)
19140 {
19141     sp_int128 tb = b;
19142     sp_int128 t = 0;
19143     sp_digit t2;
19144     sp_int128 p[4];
19145     int i;
19146 
19147     for (i = 0; i < 36; i += 4) {
19148         p[0] = tb * a[i + 0];
19149         p[1] = tb * a[i + 1];
19150         p[2] = tb * a[i + 2];
19151         p[3] = tb * a[i + 3];
19152         t += p[0];
19153         t2 = (sp_digit)(t & 0x1fffffffffffffL);
19154         t >>= 53;
19155         r[i + 0] = (sp_digit)t2;
19156         t += p[1];
19157         t2 = (sp_digit)(t & 0x1fffffffffffffL);
19158         t >>= 53;
19159         r[i + 1] = (sp_digit)t2;
19160         t += p[2];
19161         t2 = (sp_digit)(t & 0x1fffffffffffffL);
19162         t >>= 53;
19163         r[i + 2] = (sp_digit)t2;
19164         t += p[3];
19165         t2 = (sp_digit)(t & 0x1fffffffffffffL);
19166         t >>= 53;
19167         r[i + 3] = (sp_digit)t2;
19168     }
19169     t += tb * a[36];
19170     r[36] = (sp_digit)(t & 0x1fffffffffffffL);
19171     t >>= 53;
19172     t += tb * a[37];
19173     r[37] = (sp_digit)(t & 0x1fffffffffffffL);
19174     t >>= 53;
19175     t += tb * a[38];
19176     r[38] = (sp_digit)(t & 0x1fffffffffffffL);
19177     t >>= 53;
19178     r[39] = (sp_digit)(t & 0x1fffffffffffffL);
19179 }
19180 
19181 /* Conditionally add a and b using the mask m.
19182  * m is -1 to add and 0 when not.
19183  *
19184  * r  A single precision number representing conditional add result.
19185  * a  A single precision number to add with.
19186  * b  A single precision number to add.
19187  * m  Mask value to apply.
19188  */
sp_4096_cond_add_39(sp_digit * r,const sp_digit * a,const sp_digit * b,const sp_digit m)19189 static void sp_4096_cond_add_39(sp_digit* r, const sp_digit* a,
19190         const sp_digit* b, const sp_digit m)
19191 {
19192     int i;
19193 
19194     for (i = 0; i < 32; i += 8) {
19195         r[i + 0] = a[i + 0] + (b[i + 0] & m);
19196         r[i + 1] = a[i + 1] + (b[i + 1] & m);
19197         r[i + 2] = a[i + 2] + (b[i + 2] & m);
19198         r[i + 3] = a[i + 3] + (b[i + 3] & m);
19199         r[i + 4] = a[i + 4] + (b[i + 4] & m);
19200         r[i + 5] = a[i + 5] + (b[i + 5] & m);
19201         r[i + 6] = a[i + 6] + (b[i + 6] & m);
19202         r[i + 7] = a[i + 7] + (b[i + 7] & m);
19203     }
19204     r[32] = a[32] + (b[32] & m);
19205     r[33] = a[33] + (b[33] & m);
19206     r[34] = a[34] + (b[34] & m);
19207     r[35] = a[35] + (b[35] & m);
19208     r[36] = a[36] + (b[36] & m);
19209     r[37] = a[37] + (b[37] & m);
19210     r[38] = a[38] + (b[38] & m);
19211 }
19212 
sp_4096_rshift_39(sp_digit * r,const sp_digit * a,byte n)19213 SP_NOINLINE static void sp_4096_rshift_39(sp_digit* r, const sp_digit* a,
19214         byte n)
19215 {
19216     int i;
19217 
19218     for (i=0; i<32; i += 8) {
19219         r[i+0] = (a[i+0] >> n) | ((a[i+1] << (53 - n)) & 0x1fffffffffffffL);
19220         r[i+1] = (a[i+1] >> n) | ((a[i+2] << (53 - n)) & 0x1fffffffffffffL);
19221         r[i+2] = (a[i+2] >> n) | ((a[i+3] << (53 - n)) & 0x1fffffffffffffL);
19222         r[i+3] = (a[i+3] >> n) | ((a[i+4] << (53 - n)) & 0x1fffffffffffffL);
19223         r[i+4] = (a[i+4] >> n) | ((a[i+5] << (53 - n)) & 0x1fffffffffffffL);
19224         r[i+5] = (a[i+5] >> n) | ((a[i+6] << (53 - n)) & 0x1fffffffffffffL);
19225         r[i+6] = (a[i+6] >> n) | ((a[i+7] << (53 - n)) & 0x1fffffffffffffL);
19226         r[i+7] = (a[i+7] >> n) | ((a[i+8] << (53 - n)) & 0x1fffffffffffffL);
19227     }
19228     r[32] = (a[32] >> n) | ((a[33] << (53 - n)) & 0x1fffffffffffffL);
19229     r[33] = (a[33] >> n) | ((a[34] << (53 - n)) & 0x1fffffffffffffL);
19230     r[34] = (a[34] >> n) | ((a[35] << (53 - n)) & 0x1fffffffffffffL);
19231     r[35] = (a[35] >> n) | ((a[36] << (53 - n)) & 0x1fffffffffffffL);
19232     r[36] = (a[36] >> n) | ((a[37] << (53 - n)) & 0x1fffffffffffffL);
19233     r[37] = (a[37] >> n) | ((a[38] << (53 - n)) & 0x1fffffffffffffL);
19234     r[38] = a[38] >> n;
19235 }
19236 
19237 #ifdef WOLFSSL_SP_DIV_64
sp_4096_div_word_39(sp_digit d1,sp_digit d0,sp_digit dv)19238 static WC_INLINE sp_digit sp_4096_div_word_39(sp_digit d1, sp_digit d0,
19239     sp_digit dv)
19240 {
19241     sp_digit d;
19242     sp_digit r;
19243     sp_digit t;
19244 
19245     /* All 53 bits from d1 and top 10 bits from d0. */
19246     d = (d1 << 10) + (d0 >> 43);
19247     r = d / dv;
19248     d -= r * dv;
19249     /* Up to 11 bits in r */
19250     /* Next 10 bits from d0. */
19251     r <<= 10;
19252     d <<= 10;
19253     d += (d0 >> 33) & ((1 << 10) - 1);
19254     t = d / dv;
19255     d -= t * dv;
19256     r += t;
19257     /* Up to 21 bits in r */
19258     /* Next 10 bits from d0. */
19259     r <<= 10;
19260     d <<= 10;
19261     d += (d0 >> 23) & ((1 << 10) - 1);
19262     t = d / dv;
19263     d -= t * dv;
19264     r += t;
19265     /* Up to 31 bits in r */
19266     /* Next 10 bits from d0. */
19267     r <<= 10;
19268     d <<= 10;
19269     d += (d0 >> 13) & ((1 << 10) - 1);
19270     t = d / dv;
19271     d -= t * dv;
19272     r += t;
19273     /* Up to 41 bits in r */
19274     /* Next 10 bits from d0. */
19275     r <<= 10;
19276     d <<= 10;
19277     d += (d0 >> 3) & ((1 << 10) - 1);
19278     t = d / dv;
19279     d -= t * dv;
19280     r += t;
19281     /* Up to 51 bits in r */
19282     /* Remaining 3 bits from d0. */
19283     r <<= 3;
19284     d <<= 3;
19285     d += d0 & ((1 << 3) - 1);
19286     t = d / dv;
19287     r += t;
19288 
19289     /* All 53 bits from d1 and top 10 bits from d0. */
19290     return r;
19291 }
19292 #endif /* WOLFSSL_SP_DIV_64 */
19293 
19294 /* Divide d in a and put remainder into r (m*d + r = a)
19295  * m is not calculated as it is not needed at this time.
19296  *
19297  * Full implementation.
19298  *
19299  * a  Number to be divided.
19300  * d  Number to divide with.
19301  * m  Multiplier result.
19302  * r  Remainder from the division.
19303  * returns MEMORY_E when unable to allocate memory and MP_OKAY otherwise.
19304  */
sp_4096_div_39(const sp_digit * a,const sp_digit * d,const sp_digit * m,sp_digit * r)19305 static int sp_4096_div_39(const sp_digit* a, const sp_digit* d,
19306         const sp_digit* m, sp_digit* r)
19307 {
19308     int i;
19309 #ifndef WOLFSSL_SP_DIV_64
19310     sp_int128 d1;
19311 #endif
19312     sp_digit dv;
19313     sp_digit r1;
19314 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
19315     sp_digit* t1 = NULL;
19316 #else
19317     sp_digit t1[4 * 39 + 3];
19318 #endif
19319     sp_digit* t2 = NULL;
19320     sp_digit* sd = NULL;
19321     int err = MP_OKAY;
19322 
19323     (void)m;
19324 
19325 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
19326     t1 = (sp_digit*)XMALLOC(sizeof(sp_digit) * (4 * 39 + 3), NULL,
19327                                                        DYNAMIC_TYPE_TMP_BUFFER);
19328     if (t1 == NULL)
19329         err = MEMORY_E;
19330 #endif
19331 
19332     (void)m;
19333 
19334     if (err == MP_OKAY) {
19335         t2 = t1 + 78 + 1;
19336         sd = t2 + 39 + 1;
19337 
19338         sp_4096_mul_d_39(sd, d, (sp_digit)1 << 19);
19339         sp_4096_mul_d_78(t1, a, (sp_digit)1 << 19);
19340         dv = sd[38];
19341         t1[39 + 39] += t1[39 + 39 - 1] >> 53;
19342         t1[39 + 39 - 1] &= 0x1fffffffffffffL;
19343         for (i=39; i>=0; i--) {
19344 #ifndef WOLFSSL_SP_DIV_64
19345             d1 = t1[39 + i];
19346             d1 <<= 53;
19347             d1 += t1[39 + i - 1];
19348             r1 = (sp_digit)(d1 / dv);
19349 #else
19350             r1 = sp_4096_div_word_39(t1[39 + i], t1[39 + i - 1], dv);
19351 #endif
19352 
19353             sp_4096_mul_d_39(t2, sd, r1);
19354             (void)sp_4096_sub_39(&t1[i], &t1[i], t2);
19355             sp_4096_norm_39(&t1[i]);
19356             t1[39 + i] -= t2[39];
19357             t1[39 + i] += t1[39 + i - 1] >> 53;
19358             t1[39 + i - 1] &= 0x1fffffffffffffL;
19359 #ifndef WOLFSSL_SP_DIV_64
19360             d1 = -t1[39 + i];
19361             d1 <<= 53;
19362             d1 -= t1[39 + i - 1];
19363             r1 = (sp_digit)(d1 / dv);
19364 #else
19365             r1 = sp_4096_div_word_39(-t1[39 + i], -t1[39 + i - 1], dv);
19366 #endif
19367             r1 -= t1[39 + i];
19368             sp_4096_mul_d_39(t2, sd, r1);
19369             (void)sp_4096_add_39(&t1[i], &t1[i], t2);
19370             t1[39 + i] += t1[39 + i - 1] >> 53;
19371             t1[39 + i - 1] &= 0x1fffffffffffffL;
19372         }
19373         t1[39 - 1] += t1[39 - 2] >> 53;
19374         t1[39 - 2] &= 0x1fffffffffffffL;
19375         r1 = t1[39 - 1] / dv;
19376 
19377         sp_4096_mul_d_39(t2, sd, r1);
19378         sp_4096_sub_39(t1, t1, t2);
19379         XMEMCPY(r, t1, sizeof(*r) * 78U);
19380         for (i=0; i<38; i++) {
19381             r[i+1] += r[i] >> 53;
19382             r[i] &= 0x1fffffffffffffL;
19383         }
19384         sp_4096_cond_add_39(r, r, sd, 0 - ((r[38] < 0) ?
19385                     (sp_digit)1 : (sp_digit)0));
19386 
19387         sp_4096_norm_39(r);
19388         sp_4096_rshift_39(r, r, 19);
19389     }
19390 
19391 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
19392     if (t1 != NULL)
19393         XFREE(t1, NULL, DYNAMIC_TYPE_TMP_BUFFER);
19394 #endif
19395 
19396     return err;
19397 }
19398 
19399 /* Reduce a modulo m into r. (r = a mod m)
19400  *
19401  * r  A single precision number that is the reduced result.
19402  * a  A single precision number that is to be reduced.
19403  * m  A single precision number that is the modulus to reduce with.
19404  * returns MEMORY_E when unable to allocate memory and MP_OKAY otherwise.
19405  */
sp_4096_mod_39(sp_digit * r,const sp_digit * a,const sp_digit * m)19406 static int sp_4096_mod_39(sp_digit* r, const sp_digit* a, const sp_digit* m)
19407 {
19408     return sp_4096_div_39(a, m, NULL, r);
19409 }
19410 
19411 /* Modular exponentiate a to the e mod m. (r = a^e mod m)
19412  *
19413  * r     A single precision number that is the result of the operation.
19414  * a     A single precision number being exponentiated.
19415  * e     A single precision number that is the exponent.
19416  * bits  The number of bits in the exponent.
19417  * m     A single precision number that is the modulus.
19418  * returns  0 on success.
19419  * returns  MEMORY_E on dynamic memory allocation failure.
19420  * returns  MP_VAL when base is even or exponent is 0.
19421  */
sp_4096_mod_exp_39(sp_digit * r,const sp_digit * a,const sp_digit * e,int bits,const sp_digit * m,int reduceA)19422 static int sp_4096_mod_exp_39(sp_digit* r, const sp_digit* a, const sp_digit* e,
19423     int bits, const sp_digit* m, int reduceA)
19424 {
19425 #if defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SP_FAST_MODEXP)
19426 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
19427     sp_digit* td = NULL;
19428 #else
19429     sp_digit td[3 * 78];
19430 #endif
19431     sp_digit* t[3] = {0, 0, 0};
19432     sp_digit* norm = NULL;
19433     sp_digit mp = 1;
19434     sp_digit n;
19435     int i;
19436     int c;
19437     byte y;
19438     int err = MP_OKAY;
19439 
19440     if ((m[0] & 1) == 0) {
19441         err = MP_VAL;
19442     }
19443     else if (bits == 0) {
19444         err = MP_VAL;
19445     }
19446 
19447 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
19448     if (err == MP_OKAY) {
19449         td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 3 * 39 * 2, NULL,
19450                                 DYNAMIC_TYPE_TMP_BUFFER);
19451         if (td == NULL)
19452             err = MEMORY_E;
19453     }
19454 #endif
19455 
19456     if (err == MP_OKAY) {
19457         norm = td;
19458         for (i=0; i<3; i++) {
19459             t[i] = td + (i * 39 * 2);
19460             XMEMSET(t[i], 0, sizeof(sp_digit) * 39U * 2U);
19461         }
19462 
19463         sp_4096_mont_setup(m, &mp);
19464         sp_4096_mont_norm_39(norm, m);
19465 
19466         if (reduceA != 0) {
19467             err = sp_4096_mod_39(t[1], a, m);
19468         }
19469         else {
19470             XMEMCPY(t[1], a, sizeof(sp_digit) * 39U);
19471         }
19472     }
19473     if (err == MP_OKAY) {
19474         sp_4096_mul_39(t[1], t[1], norm);
19475         err = sp_4096_mod_39(t[1], t[1], m);
19476     }
19477 
19478     if (err == MP_OKAY) {
19479         i = bits / 53;
19480         c = bits % 53;
19481         n = e[i--] << (53 - c);
19482         for (; ; c--) {
19483             if (c == 0) {
19484                 if (i == -1) {
19485                     break;
19486                 }
19487 
19488                 n = e[i--];
19489                 c = 53;
19490             }
19491 
19492             y = (int)((n >> 52) & 1);
19493             n <<= 1;
19494 
19495             sp_4096_mont_mul_39(t[y^1], t[0], t[1], m, mp);
19496 
19497             XMEMCPY(t[2], (void*)(((size_t)t[0] & addr_mask[y^1]) +
19498                                   ((size_t)t[1] & addr_mask[y])),
19499                                   sizeof(*t[2]) * 39 * 2);
19500             sp_4096_mont_sqr_39(t[2], t[2], m, mp);
19501             XMEMCPY((void*)(((size_t)t[0] & addr_mask[y^1]) +
19502                             ((size_t)t[1] & addr_mask[y])), t[2],
19503                             sizeof(*t[2]) * 39 * 2);
19504         }
19505 
19506         sp_4096_mont_reduce_39(t[0], m, mp);
19507         n = sp_4096_cmp_39(t[0], m);
19508         sp_4096_cond_sub_39(t[0], t[0], m, ((n < 0) ?
19509                     (sp_digit)1 : (sp_digit)0) - 1);
19510         XMEMCPY(r, t[0], sizeof(*r) * 39 * 2);
19511 
19512     }
19513 
19514 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
19515     if (td != NULL)
19516         XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);
19517 #endif
19518 
19519     return err;
19520 #elif !defined(WC_NO_CACHE_RESISTANT)
19521 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
19522     sp_digit* td = NULL;
19523 #else
19524     sp_digit td[3 * 78];
19525 #endif
19526     sp_digit* t[3] = {0, 0, 0};
19527     sp_digit* norm = NULL;
19528     sp_digit mp = 1;
19529     sp_digit n;
19530     int i;
19531     int c;
19532     byte y;
19533     int err = MP_OKAY;
19534 
19535     if ((m[0] & 1) == 0) {
19536         err = MP_VAL;
19537     }
19538     else if (bits == 0) {
19539         err = MP_VAL;
19540     }
19541 
19542 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
19543     if (err == MP_OKAY) {
19544         td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 3 * 39 * 2, NULL,
19545                                 DYNAMIC_TYPE_TMP_BUFFER);
19546         if (td == NULL)
19547             err = MEMORY_E;
19548     }
19549 #endif
19550 
19551     if (err == MP_OKAY) {
19552         norm = td;
19553         for (i=0; i<3; i++) {
19554             t[i] = td + (i * 39 * 2);
19555         }
19556 
19557         sp_4096_mont_setup(m, &mp);
19558         sp_4096_mont_norm_39(norm, m);
19559 
19560         if (reduceA != 0) {
19561             err = sp_4096_mod_39(t[1], a, m);
19562             if (err == MP_OKAY) {
19563                 sp_4096_mul_39(t[1], t[1], norm);
19564                 err = sp_4096_mod_39(t[1], t[1], m);
19565             }
19566         }
19567         else {
19568             sp_4096_mul_39(t[1], a, norm);
19569             err = sp_4096_mod_39(t[1], t[1], m);
19570         }
19571     }
19572 
19573     if (err == MP_OKAY) {
19574         i = bits / 53;
19575         c = bits % 53;
19576         n = e[i--] << (53 - c);
19577         for (; ; c--) {
19578             if (c == 0) {
19579                 if (i == -1) {
19580                     break;
19581                 }
19582 
19583                 n = e[i--];
19584                 c = 53;
19585             }
19586 
19587             y = (int)((n >> 52) & 1);
19588             n <<= 1;
19589 
19590             sp_4096_mont_mul_39(t[y^1], t[0], t[1], m, mp);
19591 
19592             XMEMCPY(t[2], (void*)(((size_t)t[0] & addr_mask[y^1]) +
19593                                   ((size_t)t[1] & addr_mask[y])),
19594                                   sizeof(*t[2]) * 39 * 2);
19595             sp_4096_mont_sqr_39(t[2], t[2], m, mp);
19596             XMEMCPY((void*)(((size_t)t[0] & addr_mask[y^1]) +
19597                             ((size_t)t[1] & addr_mask[y])), t[2],
19598                             sizeof(*t[2]) * 39 * 2);
19599         }
19600 
19601         sp_4096_mont_reduce_39(t[0], m, mp);
19602         n = sp_4096_cmp_39(t[0], m);
19603         sp_4096_cond_sub_39(t[0], t[0], m, ((n < 0) ?
19604                     (sp_digit)1 : (sp_digit)0) - 1);
19605         XMEMCPY(r, t[0], sizeof(*r) * 39 * 2);
19606     }
19607 
19608 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
19609     if (td != NULL)
19610         XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);
19611 #endif
19612 
19613     return err;
19614 #else
19615 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
19616     sp_digit* td = NULL;
19617 #else
19618     sp_digit td[(32 * 78) + 78];
19619 #endif
19620     sp_digit* t[32];
19621     sp_digit* rt = NULL;
19622     sp_digit* norm = NULL;
19623     sp_digit mp = 1;
19624     sp_digit n;
19625     int i;
19626     int c;
19627     byte y;
19628     int err = MP_OKAY;
19629 
19630     if ((m[0] & 1) == 0) {
19631         err = MP_VAL;
19632     }
19633     else if (bits == 0) {
19634         err = MP_VAL;
19635     }
19636 
19637 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
19638     if (err == MP_OKAY) {
19639         td = (sp_digit*)XMALLOC(sizeof(sp_digit) * ((32 * 78) + 78), NULL,
19640                                 DYNAMIC_TYPE_TMP_BUFFER);
19641         if (td == NULL)
19642             err = MEMORY_E;
19643     }
19644 #endif
19645 
19646     if (err == MP_OKAY) {
19647         norm = td;
19648         for (i=0; i<32; i++)
19649             t[i] = td + i * 78;
19650         rt = td + 2496;
19651 
19652         sp_4096_mont_setup(m, &mp);
19653         sp_4096_mont_norm_39(norm, m);
19654 
19655         if (reduceA != 0) {
19656             err = sp_4096_mod_39(t[1], a, m);
19657             if (err == MP_OKAY) {
19658                 sp_4096_mul_39(t[1], t[1], norm);
19659                 err = sp_4096_mod_39(t[1], t[1], m);
19660             }
19661         }
19662         else {
19663             sp_4096_mul_39(t[1], a, norm);
19664             err = sp_4096_mod_39(t[1], t[1], m);
19665         }
19666     }
19667 
19668     if (err == MP_OKAY) {
19669         sp_4096_mont_sqr_39(t[ 2], t[ 1], m, mp);
19670         sp_4096_mont_mul_39(t[ 3], t[ 2], t[ 1], m, mp);
19671         sp_4096_mont_sqr_39(t[ 4], t[ 2], m, mp);
19672         sp_4096_mont_mul_39(t[ 5], t[ 3], t[ 2], m, mp);
19673         sp_4096_mont_sqr_39(t[ 6], t[ 3], m, mp);
19674         sp_4096_mont_mul_39(t[ 7], t[ 4], t[ 3], m, mp);
19675         sp_4096_mont_sqr_39(t[ 8], t[ 4], m, mp);
19676         sp_4096_mont_mul_39(t[ 9], t[ 5], t[ 4], m, mp);
19677         sp_4096_mont_sqr_39(t[10], t[ 5], m, mp);
19678         sp_4096_mont_mul_39(t[11], t[ 6], t[ 5], m, mp);
19679         sp_4096_mont_sqr_39(t[12], t[ 6], m, mp);
19680         sp_4096_mont_mul_39(t[13], t[ 7], t[ 6], m, mp);
19681         sp_4096_mont_sqr_39(t[14], t[ 7], m, mp);
19682         sp_4096_mont_mul_39(t[15], t[ 8], t[ 7], m, mp);
19683         sp_4096_mont_sqr_39(t[16], t[ 8], m, mp);
19684         sp_4096_mont_mul_39(t[17], t[ 9], t[ 8], m, mp);
19685         sp_4096_mont_sqr_39(t[18], t[ 9], m, mp);
19686         sp_4096_mont_mul_39(t[19], t[10], t[ 9], m, mp);
19687         sp_4096_mont_sqr_39(t[20], t[10], m, mp);
19688         sp_4096_mont_mul_39(t[21], t[11], t[10], m, mp);
19689         sp_4096_mont_sqr_39(t[22], t[11], m, mp);
19690         sp_4096_mont_mul_39(t[23], t[12], t[11], m, mp);
19691         sp_4096_mont_sqr_39(t[24], t[12], m, mp);
19692         sp_4096_mont_mul_39(t[25], t[13], t[12], m, mp);
19693         sp_4096_mont_sqr_39(t[26], t[13], m, mp);
19694         sp_4096_mont_mul_39(t[27], t[14], t[13], m, mp);
19695         sp_4096_mont_sqr_39(t[28], t[14], m, mp);
19696         sp_4096_mont_mul_39(t[29], t[15], t[14], m, mp);
19697         sp_4096_mont_sqr_39(t[30], t[15], m, mp);
19698         sp_4096_mont_mul_39(t[31], t[16], t[15], m, mp);
19699 
19700         bits = ((bits + 4) / 5) * 5;
19701         i = ((bits + 52) / 53) - 1;
19702         c = bits % 53;
19703         if (c == 0) {
19704             c = 53;
19705         }
19706         if (i < 39) {
19707             n = e[i--] << (64 - c);
19708         }
19709         else {
19710             n = 0;
19711             i--;
19712         }
19713         if (c < 5) {
19714             n |= e[i--] << (11 - c);
19715             c += 53;
19716         }
19717         y = (int)((n >> 59) & 0x1f);
19718         n <<= 5;
19719         c -= 5;
19720         XMEMCPY(rt, t[y], sizeof(sp_digit) * 78);
19721         while ((i >= 0) || (c >= 5)) {
19722             if (c >= 5) {
19723                 y = (byte)((n >> 59) & 0x1f);
19724                 n <<= 5;
19725                 c -= 5;
19726             }
19727             else if (c == 0) {
19728                 n = e[i--] << 11;
19729                 y = (byte)((n >> 59) & 0x1f);
19730                 n <<= 5;
19731                 c = 48;
19732             }
19733             else {
19734                 y = (byte)((n >> 59) & 0x1f);
19735                 n = e[i--] << 11;
19736                 c = 5 - c;
19737                 y |= (byte)((n >> (64 - c)) & ((1 << c) - 1));
19738                 n <<= c;
19739                 c = 53 - c;
19740             }
19741 
19742             sp_4096_mont_sqr_39(rt, rt, m, mp);
19743             sp_4096_mont_sqr_39(rt, rt, m, mp);
19744             sp_4096_mont_sqr_39(rt, rt, m, mp);
19745             sp_4096_mont_sqr_39(rt, rt, m, mp);
19746             sp_4096_mont_sqr_39(rt, rt, m, mp);
19747 
19748             sp_4096_mont_mul_39(rt, rt, t[y], m, mp);
19749         }
19750 
19751         sp_4096_mont_reduce_39(rt, m, mp);
19752         n = sp_4096_cmp_39(rt, m);
19753         sp_4096_cond_sub_39(rt, rt, m, ((n < 0) ?
19754                    (sp_digit)1 : (sp_digit)0) - 1);
19755         XMEMCPY(r, rt, sizeof(sp_digit) * 78);
19756     }
19757 
19758 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
19759     if (td != NULL)
19760         XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);
19761 #endif
19762 
19763     return err;
19764 #endif
19765 }
19766 
19767 #endif /* WOLFSSL_HAVE_SP_RSA & !SP_RSA_PRIVATE_EXP_D */
19768 #endif /* (WOLFSSL_HAVE_SP_RSA | WOLFSSL_HAVE_SP_DH) & !WOLFSSL_RSA_PUBLIC_ONLY */
19769 
19770 /* r = 2^n mod m where n is the number of bits to reduce by.
19771  * Given m must be 4096 bits, just need to subtract.
19772  *
19773  * r  A single precision number.
19774  * m  A single precision number.
19775  */
sp_4096_mont_norm_78(sp_digit * r,const sp_digit * m)19776 static void sp_4096_mont_norm_78(sp_digit* r, const sp_digit* m)
19777 {
19778     /* Set r = 2^n - 1. */
19779     int i;
19780 
19781     for (i = 0; i < 72; i += 8) {
19782         r[i + 0] = 0x1fffffffffffffL;
19783         r[i + 1] = 0x1fffffffffffffL;
19784         r[i + 2] = 0x1fffffffffffffL;
19785         r[i + 3] = 0x1fffffffffffffL;
19786         r[i + 4] = 0x1fffffffffffffL;
19787         r[i + 5] = 0x1fffffffffffffL;
19788         r[i + 6] = 0x1fffffffffffffL;
19789         r[i + 7] = 0x1fffffffffffffL;
19790     }
19791     r[72] = 0x1fffffffffffffL;
19792     r[73] = 0x1fffffffffffffL;
19793     r[74] = 0x1fffffffffffffL;
19794     r[75] = 0x1fffffffffffffL;
19795     r[76] = 0x1fffffffffffffL;
19796     r[77] = 0x7fffL;
19797 
19798     /* r = (2^n - 1) mod n */
19799     (void)sp_4096_sub_78(r, r, m);
19800 
19801     /* Add one so r = 2^n mod m */
19802     r[0] += 1;
19803 }
19804 
19805 /* Compare a with b in constant time.
19806  *
19807  * a  A single precision integer.
19808  * b  A single precision integer.
19809  * return -ve, 0 or +ve if a is less than, equal to or greater than b
19810  * respectively.
19811  */
sp_4096_cmp_78(const sp_digit * a,const sp_digit * b)19812 static sp_digit sp_4096_cmp_78(const sp_digit* a, const sp_digit* b)
19813 {
19814     sp_digit r = 0;
19815     int i;
19816 
19817     r |= (a[77] - b[77]) & (0 - (sp_digit)1);
19818     r |= (a[76] - b[76]) & (0 - (sp_digit)((r == 0) ? 1 : 0));
19819     r |= (a[75] - b[75]) & (0 - (sp_digit)((r == 0) ? 1 : 0));
19820     r |= (a[74] - b[74]) & (0 - (sp_digit)((r == 0) ? 1 : 0));
19821     r |= (a[73] - b[73]) & (0 - (sp_digit)((r == 0) ? 1 : 0));
19822     r |= (a[72] - b[72]) & (0 - (sp_digit)((r == 0) ? 1 : 0));
19823     for (i = 64; i >= 0; i -= 8) {
19824         r |= (a[i + 7] - b[i + 7]) & (0 - (sp_digit)((r == 0) ? 1 : 0));
19825         r |= (a[i + 6] - b[i + 6]) & (0 - (sp_digit)((r == 0) ? 1 : 0));
19826         r |= (a[i + 5] - b[i + 5]) & (0 - (sp_digit)((r == 0) ? 1 : 0));
19827         r |= (a[i + 4] - b[i + 4]) & (0 - (sp_digit)((r == 0) ? 1 : 0));
19828         r |= (a[i + 3] - b[i + 3]) & (0 - (sp_digit)((r == 0) ? 1 : 0));
19829         r |= (a[i + 2] - b[i + 2]) & (0 - (sp_digit)((r == 0) ? 1 : 0));
19830         r |= (a[i + 1] - b[i + 1]) & (0 - (sp_digit)((r == 0) ? 1 : 0));
19831         r |= (a[i + 0] - b[i + 0]) & (0 - (sp_digit)((r == 0) ? 1 : 0));
19832     }
19833 
19834     return r;
19835 }
19836 
19837 /* Conditionally subtract b from a using the mask m.
19838  * m is -1 to subtract and 0 when not.
19839  *
19840  * r  A single precision number representing condition subtract result.
19841  * a  A single precision number to subtract from.
19842  * b  A single precision number to subtract.
19843  * m  Mask value to apply.
19844  */
sp_4096_cond_sub_78(sp_digit * r,const sp_digit * a,const sp_digit * b,const sp_digit m)19845 static void sp_4096_cond_sub_78(sp_digit* r, const sp_digit* a,
19846         const sp_digit* b, const sp_digit m)
19847 {
19848     int i;
19849 
19850     for (i = 0; i < 72; i += 8) {
19851         r[i + 0] = a[i + 0] - (b[i + 0] & m);
19852         r[i + 1] = a[i + 1] - (b[i + 1] & m);
19853         r[i + 2] = a[i + 2] - (b[i + 2] & m);
19854         r[i + 3] = a[i + 3] - (b[i + 3] & m);
19855         r[i + 4] = a[i + 4] - (b[i + 4] & m);
19856         r[i + 5] = a[i + 5] - (b[i + 5] & m);
19857         r[i + 6] = a[i + 6] - (b[i + 6] & m);
19858         r[i + 7] = a[i + 7] - (b[i + 7] & m);
19859     }
19860     r[72] = a[72] - (b[72] & m);
19861     r[73] = a[73] - (b[73] & m);
19862     r[74] = a[74] - (b[74] & m);
19863     r[75] = a[75] - (b[75] & m);
19864     r[76] = a[76] - (b[76] & m);
19865     r[77] = a[77] - (b[77] & m);
19866 }
19867 
19868 /* Mul a by scalar b and add into r. (r += a * b)
19869  *
19870  * r  A single precision integer.
19871  * a  A single precision integer.
19872  * b  A scalar.
19873  */
sp_4096_mul_add_78(sp_digit * r,const sp_digit * a,const sp_digit b)19874 SP_NOINLINE static void sp_4096_mul_add_78(sp_digit* r, const sp_digit* a,
19875         const sp_digit b)
19876 {
19877     sp_int128 tb = b;
19878     sp_int128 t[8];
19879     int i;
19880 
19881     t[0] = tb * a[0]; r[0] += (sp_digit)(t[0] & 0x1fffffffffffffL);
19882     for (i = 0; i < 72; i += 8) {
19883         t[1] = tb * a[i+1];
19884         r[i+1] += (sp_digit)((t[0] >> 53) + (t[1] & 0x1fffffffffffffL));
19885         t[2] = tb * a[i+2];
19886         r[i+2] += (sp_digit)((t[1] >> 53) + (t[2] & 0x1fffffffffffffL));
19887         t[3] = tb * a[i+3];
19888         r[i+3] += (sp_digit)((t[2] >> 53) + (t[3] & 0x1fffffffffffffL));
19889         t[4] = tb * a[i+4];
19890         r[i+4] += (sp_digit)((t[3] >> 53) + (t[4] & 0x1fffffffffffffL));
19891         t[5] = tb * a[i+5];
19892         r[i+5] += (sp_digit)((t[4] >> 53) + (t[5] & 0x1fffffffffffffL));
19893         t[6] = tb * a[i+6];
19894         r[i+6] += (sp_digit)((t[5] >> 53) + (t[6] & 0x1fffffffffffffL));
19895         t[7] = tb * a[i+7];
19896         r[i+7] += (sp_digit)((t[6] >> 53) + (t[7] & 0x1fffffffffffffL));
19897         t[0] = tb * a[i+8];
19898         r[i+8] += (sp_digit)((t[7] >> 53) + (t[0] & 0x1fffffffffffffL));
19899     }
19900     t[1] = tb * a[73];
19901     r[73] += (sp_digit)((t[0] >> 53) + (t[1] & 0x1fffffffffffffL));
19902     t[2] = tb * a[74];
19903     r[74] += (sp_digit)((t[1] >> 53) + (t[2] & 0x1fffffffffffffL));
19904     t[3] = tb * a[75];
19905     r[75] += (sp_digit)((t[2] >> 53) + (t[3] & 0x1fffffffffffffL));
19906     t[4] = tb * a[76];
19907     r[76] += (sp_digit)((t[3] >> 53) + (t[4] & 0x1fffffffffffffL));
19908     t[5] = tb * a[77];
19909     r[77] += (sp_digit)((t[4] >> 53) + (t[5] & 0x1fffffffffffffL));
19910     r[78] +=  (sp_digit)(t[5] >> 53);
19911 }
19912 
19913 /* Shift the result in the high 4096 bits down to the bottom.
19914  *
19915  * r  A single precision number.
19916  * a  A single precision number.
19917  */
sp_4096_mont_shift_78(sp_digit * r,const sp_digit * a)19918 static void sp_4096_mont_shift_78(sp_digit* r, const sp_digit* a)
19919 {
19920     int i;
19921     sp_int128 n = a[77] >> 15;
19922     n += ((sp_int128)a[78]) << 38;
19923     for (i = 0; i < 72; i += 8) {
19924         r[i + 0] = n & 0x1fffffffffffffL;
19925         n >>= 53; n += ((sp_int128)a[i + 79]) << 38;
19926         r[i + 1] = n & 0x1fffffffffffffL;
19927         n >>= 53; n += ((sp_int128)a[i + 80]) << 38;
19928         r[i + 2] = n & 0x1fffffffffffffL;
19929         n >>= 53; n += ((sp_int128)a[i + 81]) << 38;
19930         r[i + 3] = n & 0x1fffffffffffffL;
19931         n >>= 53; n += ((sp_int128)a[i + 82]) << 38;
19932         r[i + 4] = n & 0x1fffffffffffffL;
19933         n >>= 53; n += ((sp_int128)a[i + 83]) << 38;
19934         r[i + 5] = n & 0x1fffffffffffffL;
19935         n >>= 53; n += ((sp_int128)a[i + 84]) << 38;
19936         r[i + 6] = n & 0x1fffffffffffffL;
19937         n >>= 53; n += ((sp_int128)a[i + 85]) << 38;
19938         r[i + 7] = n & 0x1fffffffffffffL;
19939         n >>= 53; n += ((sp_int128)a[i + 86]) << 38;
19940     }
19941     r[72] = n & 0x1fffffffffffffL; n >>= 53; n += ((sp_int128)a[151]) << 38;
19942     r[73] = n & 0x1fffffffffffffL; n >>= 53; n += ((sp_int128)a[152]) << 38;
19943     r[74] = n & 0x1fffffffffffffL; n >>= 53; n += ((sp_int128)a[153]) << 38;
19944     r[75] = n & 0x1fffffffffffffL; n >>= 53; n += ((sp_int128)a[154]) << 38;
19945     r[76] = n & 0x1fffffffffffffL; n >>= 53; n += ((sp_int128)a[155]) << 38;
19946     r[77] = (sp_digit)n;
19947     XMEMSET(&r[78], 0, sizeof(*r) * 78U);
19948 }
19949 
19950 /* Reduce the number back to 4096 bits using Montgomery reduction.
19951  *
19952  * a   A single precision number to reduce in place.
19953  * m   The single precision number representing the modulus.
19954  * mp  The digit representing the negative inverse of m mod 2^n.
19955  */
sp_4096_mont_reduce_78(sp_digit * a,const sp_digit * m,sp_digit mp)19956 static void sp_4096_mont_reduce_78(sp_digit* a, const sp_digit* m, sp_digit mp)
19957 {
19958     int i;
19959     sp_digit mu;
19960 
19961     sp_4096_norm_78(a + 78);
19962 
19963 #ifdef WOLFSSL_SP_DH
19964     if (mp != 1) {
19965         for (i=0; i<77; i++) {
19966             mu = (a[i] * mp) & 0x1fffffffffffffL;
19967             sp_4096_mul_add_78(a+i, m, mu);
19968             a[i+1] += a[i] >> 53;
19969         }
19970         mu = (a[i] * mp) & 0x7fffL;
19971         sp_4096_mul_add_78(a+i, m, mu);
19972         a[i+1] += a[i] >> 53;
19973         a[i] &= 0x1fffffffffffffL;
19974     }
19975     else {
19976         for (i=0; i<77; i++) {
19977             mu = a[i] & 0x1fffffffffffffL;
19978             sp_4096_mul_add_78(a+i, m, mu);
19979             a[i+1] += a[i] >> 53;
19980         }
19981         mu = a[i] & 0x7fffL;
19982         sp_4096_mul_add_78(a+i, m, mu);
19983         a[i+1] += a[i] >> 53;
19984         a[i] &= 0x1fffffffffffffL;
19985     }
19986 #else
19987     for (i=0; i<77; i++) {
19988         mu = (a[i] * mp) & 0x1fffffffffffffL;
19989         sp_4096_mul_add_78(a+i, m, mu);
19990         a[i+1] += a[i] >> 53;
19991     }
19992     mu = (a[i] * mp) & 0x7fffL;
19993     sp_4096_mul_add_78(a+i, m, mu);
19994     a[i+1] += a[i] >> 53;
19995     a[i] &= 0x1fffffffffffffL;
19996 #endif
19997     sp_4096_mont_shift_78(a, a);
19998     sp_4096_cond_sub_78(a, a, m, 0 - (((a[77] - m[77]) > 0) ?
19999             (sp_digit)1 : (sp_digit)0));
20000     sp_4096_norm_78(a);
20001 }
20002 
20003 /* Multiply two Montgomery form numbers mod the modulus (prime).
20004  * (r = a * b mod m)
20005  *
20006  * r   Result of multiplication.
20007  * a   First number to multiply in Montgomery form.
20008  * b   Second number to multiply in Montgomery form.
20009  * m   Modulus (prime).
20010  * mp  Montgomery mulitplier.
20011  */
sp_4096_mont_mul_78(sp_digit * r,const sp_digit * a,const sp_digit * b,const sp_digit * m,sp_digit mp)20012 static void sp_4096_mont_mul_78(sp_digit* r, const sp_digit* a,
20013         const sp_digit* b, const sp_digit* m, sp_digit mp)
20014 {
20015     sp_4096_mul_78(r, a, b);
20016     sp_4096_mont_reduce_78(r, m, mp);
20017 }
20018 
20019 /* Square the Montgomery form number. (r = a * a mod m)
20020  *
20021  * r   Result of squaring.
20022  * a   Number to square in Montgomery form.
20023  * m   Modulus (prime).
20024  * mp  Montgomery mulitplier.
20025  */
sp_4096_mont_sqr_78(sp_digit * r,const sp_digit * a,const sp_digit * m,sp_digit mp)20026 static void sp_4096_mont_sqr_78(sp_digit* r, const sp_digit* a,
20027         const sp_digit* m, sp_digit mp)
20028 {
20029     sp_4096_sqr_78(r, a);
20030     sp_4096_mont_reduce_78(r, m, mp);
20031 }
20032 
20033 /* Multiply a by scalar b into r. (r = a * b)
20034  *
20035  * r  A single precision integer.
20036  * a  A single precision integer.
20037  * b  A scalar.
20038  */
sp_4096_mul_d_156(sp_digit * r,const sp_digit * a,sp_digit b)20039 SP_NOINLINE static void sp_4096_mul_d_156(sp_digit* r, const sp_digit* a,
20040     sp_digit b)
20041 {
20042     sp_int128 tb = b;
20043     sp_int128 t = 0;
20044     sp_digit t2;
20045     sp_int128 p[4];
20046     int i;
20047 
20048     for (i = 0; i < 156; i += 4) {
20049         p[0] = tb * a[i + 0];
20050         p[1] = tb * a[i + 1];
20051         p[2] = tb * a[i + 2];
20052         p[3] = tb * a[i + 3];
20053         t += p[0];
20054         t2 = (sp_digit)(t & 0x1fffffffffffffL);
20055         t >>= 53;
20056         r[i + 0] = (sp_digit)t2;
20057         t += p[1];
20058         t2 = (sp_digit)(t & 0x1fffffffffffffL);
20059         t >>= 53;
20060         r[i + 1] = (sp_digit)t2;
20061         t += p[2];
20062         t2 = (sp_digit)(t & 0x1fffffffffffffL);
20063         t >>= 53;
20064         r[i + 2] = (sp_digit)t2;
20065         t += p[3];
20066         t2 = (sp_digit)(t & 0x1fffffffffffffL);
20067         t >>= 53;
20068         r[i + 3] = (sp_digit)t2;
20069     }
20070     r[156] = (sp_digit)(t & 0x1fffffffffffffL);
20071 }
20072 
20073 /* Conditionally add a and b using the mask m.
20074  * m is -1 to add and 0 when not.
20075  *
20076  * r  A single precision number representing conditional add result.
20077  * a  A single precision number to add with.
20078  * b  A single precision number to add.
20079  * m  Mask value to apply.
20080  */
sp_4096_cond_add_78(sp_digit * r,const sp_digit * a,const sp_digit * b,const sp_digit m)20081 static void sp_4096_cond_add_78(sp_digit* r, const sp_digit* a,
20082         const sp_digit* b, const sp_digit m)
20083 {
20084     int i;
20085 
20086     for (i = 0; i < 72; i += 8) {
20087         r[i + 0] = a[i + 0] + (b[i + 0] & m);
20088         r[i + 1] = a[i + 1] + (b[i + 1] & m);
20089         r[i + 2] = a[i + 2] + (b[i + 2] & m);
20090         r[i + 3] = a[i + 3] + (b[i + 3] & m);
20091         r[i + 4] = a[i + 4] + (b[i + 4] & m);
20092         r[i + 5] = a[i + 5] + (b[i + 5] & m);
20093         r[i + 6] = a[i + 6] + (b[i + 6] & m);
20094         r[i + 7] = a[i + 7] + (b[i + 7] & m);
20095     }
20096     r[72] = a[72] + (b[72] & m);
20097     r[73] = a[73] + (b[73] & m);
20098     r[74] = a[74] + (b[74] & m);
20099     r[75] = a[75] + (b[75] & m);
20100     r[76] = a[76] + (b[76] & m);
20101     r[77] = a[77] + (b[77] & m);
20102 }
20103 
sp_4096_rshift_78(sp_digit * r,const sp_digit * a,byte n)20104 SP_NOINLINE static void sp_4096_rshift_78(sp_digit* r, const sp_digit* a,
20105         byte n)
20106 {
20107     int i;
20108 
20109     for (i=0; i<72; i += 8) {
20110         r[i+0] = (a[i+0] >> n) | ((a[i+1] << (53 - n)) & 0x1fffffffffffffL);
20111         r[i+1] = (a[i+1] >> n) | ((a[i+2] << (53 - n)) & 0x1fffffffffffffL);
20112         r[i+2] = (a[i+2] >> n) | ((a[i+3] << (53 - n)) & 0x1fffffffffffffL);
20113         r[i+3] = (a[i+3] >> n) | ((a[i+4] << (53 - n)) & 0x1fffffffffffffL);
20114         r[i+4] = (a[i+4] >> n) | ((a[i+5] << (53 - n)) & 0x1fffffffffffffL);
20115         r[i+5] = (a[i+5] >> n) | ((a[i+6] << (53 - n)) & 0x1fffffffffffffL);
20116         r[i+6] = (a[i+6] >> n) | ((a[i+7] << (53 - n)) & 0x1fffffffffffffL);
20117         r[i+7] = (a[i+7] >> n) | ((a[i+8] << (53 - n)) & 0x1fffffffffffffL);
20118     }
20119     r[72] = (a[72] >> n) | ((a[73] << (53 - n)) & 0x1fffffffffffffL);
20120     r[73] = (a[73] >> n) | ((a[74] << (53 - n)) & 0x1fffffffffffffL);
20121     r[74] = (a[74] >> n) | ((a[75] << (53 - n)) & 0x1fffffffffffffL);
20122     r[75] = (a[75] >> n) | ((a[76] << (53 - n)) & 0x1fffffffffffffL);
20123     r[76] = (a[76] >> n) | ((a[77] << (53 - n)) & 0x1fffffffffffffL);
20124     r[77] = a[77] >> n;
20125 }
20126 
20127 #ifdef WOLFSSL_SP_DIV_64
sp_4096_div_word_78(sp_digit d1,sp_digit d0,sp_digit dv)20128 static WC_INLINE sp_digit sp_4096_div_word_78(sp_digit d1, sp_digit d0,
20129     sp_digit dv)
20130 {
20131     sp_digit d;
20132     sp_digit r;
20133     sp_digit t;
20134 
20135     /* All 53 bits from d1 and top 10 bits from d0. */
20136     d = (d1 << 10) + (d0 >> 43);
20137     r = d / dv;
20138     d -= r * dv;
20139     /* Up to 11 bits in r */
20140     /* Next 10 bits from d0. */
20141     r <<= 10;
20142     d <<= 10;
20143     d += (d0 >> 33) & ((1 << 10) - 1);
20144     t = d / dv;
20145     d -= t * dv;
20146     r += t;
20147     /* Up to 21 bits in r */
20148     /* Next 10 bits from d0. */
20149     r <<= 10;
20150     d <<= 10;
20151     d += (d0 >> 23) & ((1 << 10) - 1);
20152     t = d / dv;
20153     d -= t * dv;
20154     r += t;
20155     /* Up to 31 bits in r */
20156     /* Next 10 bits from d0. */
20157     r <<= 10;
20158     d <<= 10;
20159     d += (d0 >> 13) & ((1 << 10) - 1);
20160     t = d / dv;
20161     d -= t * dv;
20162     r += t;
20163     /* Up to 41 bits in r */
20164     /* Next 10 bits from d0. */
20165     r <<= 10;
20166     d <<= 10;
20167     d += (d0 >> 3) & ((1 << 10) - 1);
20168     t = d / dv;
20169     d -= t * dv;
20170     r += t;
20171     /* Up to 51 bits in r */
20172     /* Remaining 3 bits from d0. */
20173     r <<= 3;
20174     d <<= 3;
20175     d += d0 & ((1 << 3) - 1);
20176     t = d / dv;
20177     r += t;
20178 
20179     /* All 53 bits from d1 and top 10 bits from d0. */
20180     return r;
20181 }
20182 #endif /* WOLFSSL_SP_DIV_64 */
20183 
20184 /* Divide d in a and put remainder into r (m*d + r = a)
20185  * m is not calculated as it is not needed at this time.
20186  *
20187  * Full implementation.
20188  *
20189  * a  Number to be divided.
20190  * d  Number to divide with.
20191  * m  Multiplier result.
20192  * r  Remainder from the division.
20193  * returns MEMORY_E when unable to allocate memory and MP_OKAY otherwise.
20194  */
sp_4096_div_78(const sp_digit * a,const sp_digit * d,const sp_digit * m,sp_digit * r)20195 static int sp_4096_div_78(const sp_digit* a, const sp_digit* d,
20196         const sp_digit* m, sp_digit* r)
20197 {
20198     int i;
20199 #ifndef WOLFSSL_SP_DIV_64
20200     sp_int128 d1;
20201 #endif
20202     sp_digit dv;
20203     sp_digit r1;
20204 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
20205     sp_digit* t1 = NULL;
20206 #else
20207     sp_digit t1[4 * 78 + 3];
20208 #endif
20209     sp_digit* t2 = NULL;
20210     sp_digit* sd = NULL;
20211     int err = MP_OKAY;
20212 
20213     (void)m;
20214 
20215 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
20216     t1 = (sp_digit*)XMALLOC(sizeof(sp_digit) * (4 * 78 + 3), NULL,
20217                                                        DYNAMIC_TYPE_TMP_BUFFER);
20218     if (t1 == NULL)
20219         err = MEMORY_E;
20220 #endif
20221 
20222     (void)m;
20223 
20224     if (err == MP_OKAY) {
20225         t2 = t1 + 156 + 1;
20226         sd = t2 + 78 + 1;
20227 
20228         sp_4096_mul_d_78(sd, d, (sp_digit)1 << 38);
20229         sp_4096_mul_d_156(t1, a, (sp_digit)1 << 38);
20230         dv = sd[77];
20231         t1[78 + 78] += t1[78 + 78 - 1] >> 53;
20232         t1[78 + 78 - 1] &= 0x1fffffffffffffL;
20233         for (i=78; i>=0; i--) {
20234 #ifndef WOLFSSL_SP_DIV_64
20235             d1 = t1[78 + i];
20236             d1 <<= 53;
20237             d1 += t1[78 + i - 1];
20238             r1 = (sp_digit)(d1 / dv);
20239 #else
20240             r1 = sp_4096_div_word_78(t1[78 + i], t1[78 + i - 1], dv);
20241 #endif
20242 
20243             sp_4096_mul_d_78(t2, sd, r1);
20244             (void)sp_4096_sub_78(&t1[i], &t1[i], t2);
20245             sp_4096_norm_78(&t1[i]);
20246             t1[78 + i] -= t2[78];
20247             t1[78 + i] += t1[78 + i - 1] >> 53;
20248             t1[78 + i - 1] &= 0x1fffffffffffffL;
20249 #ifndef WOLFSSL_SP_DIV_64
20250             d1 = -t1[78 + i];
20251             d1 <<= 53;
20252             d1 -= t1[78 + i - 1];
20253             r1 = (sp_digit)(d1 / dv);
20254 #else
20255             r1 = sp_4096_div_word_78(-t1[78 + i], -t1[78 + i - 1], dv);
20256 #endif
20257             r1 -= t1[78 + i];
20258             sp_4096_mul_d_78(t2, sd, r1);
20259             (void)sp_4096_add_78(&t1[i], &t1[i], t2);
20260             t1[78 + i] += t1[78 + i - 1] >> 53;
20261             t1[78 + i - 1] &= 0x1fffffffffffffL;
20262         }
20263         t1[78 - 1] += t1[78 - 2] >> 53;
20264         t1[78 - 2] &= 0x1fffffffffffffL;
20265         r1 = t1[78 - 1] / dv;
20266 
20267         sp_4096_mul_d_78(t2, sd, r1);
20268         sp_4096_sub_78(t1, t1, t2);
20269         XMEMCPY(r, t1, sizeof(*r) * 156U);
20270         for (i=0; i<77; i++) {
20271             r[i+1] += r[i] >> 53;
20272             r[i] &= 0x1fffffffffffffL;
20273         }
20274         sp_4096_cond_add_78(r, r, sd, 0 - ((r[77] < 0) ?
20275                     (sp_digit)1 : (sp_digit)0));
20276 
20277         sp_4096_norm_78(r);
20278         sp_4096_rshift_78(r, r, 38);
20279     }
20280 
20281 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
20282     if (t1 != NULL)
20283         XFREE(t1, NULL, DYNAMIC_TYPE_TMP_BUFFER);
20284 #endif
20285 
20286     return err;
20287 }
20288 
20289 /* Reduce a modulo m into r. (r = a mod m)
20290  *
20291  * r  A single precision number that is the reduced result.
20292  * a  A single precision number that is to be reduced.
20293  * m  A single precision number that is the modulus to reduce with.
20294  * returns MEMORY_E when unable to allocate memory and MP_OKAY otherwise.
20295  */
sp_4096_mod_78(sp_digit * r,const sp_digit * a,const sp_digit * m)20296 static int sp_4096_mod_78(sp_digit* r, const sp_digit* a, const sp_digit* m)
20297 {
20298     return sp_4096_div_78(a, m, NULL, r);
20299 }
20300 
20301 #if (defined(WOLFSSL_HAVE_SP_RSA) && !defined(WOLFSSL_RSA_PUBLIC_ONLY)) || defined(WOLFSSL_HAVE_SP_DH)
20302 #if (defined(WOLFSSL_HAVE_SP_RSA) && !defined(WOLFSSL_RSA_PUBLIC_ONLY)) || \
20303                                                      defined(WOLFSSL_HAVE_SP_DH)
20304 /* Modular exponentiate a to the e mod m. (r = a^e mod m)
20305  *
20306  * r     A single precision number that is the result of the operation.
20307  * a     A single precision number being exponentiated.
20308  * e     A single precision number that is the exponent.
20309  * bits  The number of bits in the exponent.
20310  * m     A single precision number that is the modulus.
20311  * returns  0 on success.
20312  * returns  MEMORY_E on dynamic memory allocation failure.
20313  * returns  MP_VAL when base is even or exponent is 0.
20314  */
sp_4096_mod_exp_78(sp_digit * r,const sp_digit * a,const sp_digit * e,int bits,const sp_digit * m,int reduceA)20315 static int sp_4096_mod_exp_78(sp_digit* r, const sp_digit* a, const sp_digit* e,
20316     int bits, const sp_digit* m, int reduceA)
20317 {
20318 #if defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SP_FAST_MODEXP)
20319 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
20320     sp_digit* td = NULL;
20321 #else
20322     sp_digit td[3 * 156];
20323 #endif
20324     sp_digit* t[3] = {0, 0, 0};
20325     sp_digit* norm = NULL;
20326     sp_digit mp = 1;
20327     sp_digit n;
20328     int i;
20329     int c;
20330     byte y;
20331     int err = MP_OKAY;
20332 
20333     if ((m[0] & 1) == 0) {
20334         err = MP_VAL;
20335     }
20336     else if (bits == 0) {
20337         err = MP_VAL;
20338     }
20339 
20340 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
20341     if (err == MP_OKAY) {
20342         td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 3 * 78 * 2, NULL,
20343                                 DYNAMIC_TYPE_TMP_BUFFER);
20344         if (td == NULL)
20345             err = MEMORY_E;
20346     }
20347 #endif
20348 
20349     if (err == MP_OKAY) {
20350         norm = td;
20351         for (i=0; i<3; i++) {
20352             t[i] = td + (i * 78 * 2);
20353             XMEMSET(t[i], 0, sizeof(sp_digit) * 78U * 2U);
20354         }
20355 
20356         sp_4096_mont_setup(m, &mp);
20357         sp_4096_mont_norm_78(norm, m);
20358 
20359         if (reduceA != 0) {
20360             err = sp_4096_mod_78(t[1], a, m);
20361         }
20362         else {
20363             XMEMCPY(t[1], a, sizeof(sp_digit) * 78U);
20364         }
20365     }
20366     if (err == MP_OKAY) {
20367         sp_4096_mul_78(t[1], t[1], norm);
20368         err = sp_4096_mod_78(t[1], t[1], m);
20369     }
20370 
20371     if (err == MP_OKAY) {
20372         i = bits / 53;
20373         c = bits % 53;
20374         n = e[i--] << (53 - c);
20375         for (; ; c--) {
20376             if (c == 0) {
20377                 if (i == -1) {
20378                     break;
20379                 }
20380 
20381                 n = e[i--];
20382                 c = 53;
20383             }
20384 
20385             y = (int)((n >> 52) & 1);
20386             n <<= 1;
20387 
20388             sp_4096_mont_mul_78(t[y^1], t[0], t[1], m, mp);
20389 
20390             XMEMCPY(t[2], (void*)(((size_t)t[0] & addr_mask[y^1]) +
20391                                   ((size_t)t[1] & addr_mask[y])),
20392                                   sizeof(*t[2]) * 78 * 2);
20393             sp_4096_mont_sqr_78(t[2], t[2], m, mp);
20394             XMEMCPY((void*)(((size_t)t[0] & addr_mask[y^1]) +
20395                             ((size_t)t[1] & addr_mask[y])), t[2],
20396                             sizeof(*t[2]) * 78 * 2);
20397         }
20398 
20399         sp_4096_mont_reduce_78(t[0], m, mp);
20400         n = sp_4096_cmp_78(t[0], m);
20401         sp_4096_cond_sub_78(t[0], t[0], m, ((n < 0) ?
20402                     (sp_digit)1 : (sp_digit)0) - 1);
20403         XMEMCPY(r, t[0], sizeof(*r) * 78 * 2);
20404 
20405     }
20406 
20407 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
20408     if (td != NULL)
20409         XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);
20410 #endif
20411 
20412     return err;
20413 #elif !defined(WC_NO_CACHE_RESISTANT)
20414 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
20415     sp_digit* td = NULL;
20416 #else
20417     sp_digit td[3 * 156];
20418 #endif
20419     sp_digit* t[3] = {0, 0, 0};
20420     sp_digit* norm = NULL;
20421     sp_digit mp = 1;
20422     sp_digit n;
20423     int i;
20424     int c;
20425     byte y;
20426     int err = MP_OKAY;
20427 
20428     if ((m[0] & 1) == 0) {
20429         err = MP_VAL;
20430     }
20431     else if (bits == 0) {
20432         err = MP_VAL;
20433     }
20434 
20435 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
20436     if (err == MP_OKAY) {
20437         td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 3 * 78 * 2, NULL,
20438                                 DYNAMIC_TYPE_TMP_BUFFER);
20439         if (td == NULL)
20440             err = MEMORY_E;
20441     }
20442 #endif
20443 
20444     if (err == MP_OKAY) {
20445         norm = td;
20446         for (i=0; i<3; i++) {
20447             t[i] = td + (i * 78 * 2);
20448         }
20449 
20450         sp_4096_mont_setup(m, &mp);
20451         sp_4096_mont_norm_78(norm, m);
20452 
20453         if (reduceA != 0) {
20454             err = sp_4096_mod_78(t[1], a, m);
20455             if (err == MP_OKAY) {
20456                 sp_4096_mul_78(t[1], t[1], norm);
20457                 err = sp_4096_mod_78(t[1], t[1], m);
20458             }
20459         }
20460         else {
20461             sp_4096_mul_78(t[1], a, norm);
20462             err = sp_4096_mod_78(t[1], t[1], m);
20463         }
20464     }
20465 
20466     if (err == MP_OKAY) {
20467         i = bits / 53;
20468         c = bits % 53;
20469         n = e[i--] << (53 - c);
20470         for (; ; c--) {
20471             if (c == 0) {
20472                 if (i == -1) {
20473                     break;
20474                 }
20475 
20476                 n = e[i--];
20477                 c = 53;
20478             }
20479 
20480             y = (int)((n >> 52) & 1);
20481             n <<= 1;
20482 
20483             sp_4096_mont_mul_78(t[y^1], t[0], t[1], m, mp);
20484 
20485             XMEMCPY(t[2], (void*)(((size_t)t[0] & addr_mask[y^1]) +
20486                                   ((size_t)t[1] & addr_mask[y])),
20487                                   sizeof(*t[2]) * 78 * 2);
20488             sp_4096_mont_sqr_78(t[2], t[2], m, mp);
20489             XMEMCPY((void*)(((size_t)t[0] & addr_mask[y^1]) +
20490                             ((size_t)t[1] & addr_mask[y])), t[2],
20491                             sizeof(*t[2]) * 78 * 2);
20492         }
20493 
20494         sp_4096_mont_reduce_78(t[0], m, mp);
20495         n = sp_4096_cmp_78(t[0], m);
20496         sp_4096_cond_sub_78(t[0], t[0], m, ((n < 0) ?
20497                     (sp_digit)1 : (sp_digit)0) - 1);
20498         XMEMCPY(r, t[0], sizeof(*r) * 78 * 2);
20499     }
20500 
20501 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
20502     if (td != NULL)
20503         XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);
20504 #endif
20505 
20506     return err;
20507 #else
20508 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
20509     sp_digit* td = NULL;
20510 #else
20511     sp_digit td[(16 * 156) + 156];
20512 #endif
20513     sp_digit* t[16];
20514     sp_digit* rt = NULL;
20515     sp_digit* norm = NULL;
20516     sp_digit mp = 1;
20517     sp_digit n;
20518     int i;
20519     int c;
20520     byte y;
20521     int err = MP_OKAY;
20522 
20523     if ((m[0] & 1) == 0) {
20524         err = MP_VAL;
20525     }
20526     else if (bits == 0) {
20527         err = MP_VAL;
20528     }
20529 
20530 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
20531     if (err == MP_OKAY) {
20532         td = (sp_digit*)XMALLOC(sizeof(sp_digit) * ((16 * 156) + 156), NULL,
20533                                 DYNAMIC_TYPE_TMP_BUFFER);
20534         if (td == NULL)
20535             err = MEMORY_E;
20536     }
20537 #endif
20538 
20539     if (err == MP_OKAY) {
20540         norm = td;
20541         for (i=0; i<16; i++)
20542             t[i] = td + i * 156;
20543         rt = td + 2496;
20544 
20545         sp_4096_mont_setup(m, &mp);
20546         sp_4096_mont_norm_78(norm, m);
20547 
20548         if (reduceA != 0) {
20549             err = sp_4096_mod_78(t[1], a, m);
20550             if (err == MP_OKAY) {
20551                 sp_4096_mul_78(t[1], t[1], norm);
20552                 err = sp_4096_mod_78(t[1], t[1], m);
20553             }
20554         }
20555         else {
20556             sp_4096_mul_78(t[1], a, norm);
20557             err = sp_4096_mod_78(t[1], t[1], m);
20558         }
20559     }
20560 
20561     if (err == MP_OKAY) {
20562         sp_4096_mont_sqr_78(t[ 2], t[ 1], m, mp);
20563         sp_4096_mont_mul_78(t[ 3], t[ 2], t[ 1], m, mp);
20564         sp_4096_mont_sqr_78(t[ 4], t[ 2], m, mp);
20565         sp_4096_mont_mul_78(t[ 5], t[ 3], t[ 2], m, mp);
20566         sp_4096_mont_sqr_78(t[ 6], t[ 3], m, mp);
20567         sp_4096_mont_mul_78(t[ 7], t[ 4], t[ 3], m, mp);
20568         sp_4096_mont_sqr_78(t[ 8], t[ 4], m, mp);
20569         sp_4096_mont_mul_78(t[ 9], t[ 5], t[ 4], m, mp);
20570         sp_4096_mont_sqr_78(t[10], t[ 5], m, mp);
20571         sp_4096_mont_mul_78(t[11], t[ 6], t[ 5], m, mp);
20572         sp_4096_mont_sqr_78(t[12], t[ 6], m, mp);
20573         sp_4096_mont_mul_78(t[13], t[ 7], t[ 6], m, mp);
20574         sp_4096_mont_sqr_78(t[14], t[ 7], m, mp);
20575         sp_4096_mont_mul_78(t[15], t[ 8], t[ 7], m, mp);
20576 
20577         bits = ((bits + 3) / 4) * 4;
20578         i = ((bits + 52) / 53) - 1;
20579         c = bits % 53;
20580         if (c == 0) {
20581             c = 53;
20582         }
20583         if (i < 78) {
20584             n = e[i--] << (64 - c);
20585         }
20586         else {
20587             n = 0;
20588             i--;
20589         }
20590         if (c < 4) {
20591             n |= e[i--] << (11 - c);
20592             c += 53;
20593         }
20594         y = (int)((n >> 60) & 0xf);
20595         n <<= 4;
20596         c -= 4;
20597         XMEMCPY(rt, t[y], sizeof(sp_digit) * 156);
20598         while ((i >= 0) || (c >= 4)) {
20599             if (c >= 4) {
20600                 y = (byte)((n >> 60) & 0xf);
20601                 n <<= 4;
20602                 c -= 4;
20603             }
20604             else if (c == 0) {
20605                 n = e[i--] << 11;
20606                 y = (byte)((n >> 60) & 0xf);
20607                 n <<= 4;
20608                 c = 49;
20609             }
20610             else {
20611                 y = (byte)((n >> 60) & 0xf);
20612                 n = e[i--] << 11;
20613                 c = 4 - c;
20614                 y |= (byte)((n >> (64 - c)) & ((1 << c) - 1));
20615                 n <<= c;
20616                 c = 53 - c;
20617             }
20618 
20619             sp_4096_mont_sqr_78(rt, rt, m, mp);
20620             sp_4096_mont_sqr_78(rt, rt, m, mp);
20621             sp_4096_mont_sqr_78(rt, rt, m, mp);
20622             sp_4096_mont_sqr_78(rt, rt, m, mp);
20623 
20624             sp_4096_mont_mul_78(rt, rt, t[y], m, mp);
20625         }
20626 
20627         sp_4096_mont_reduce_78(rt, m, mp);
20628         n = sp_4096_cmp_78(rt, m);
20629         sp_4096_cond_sub_78(rt, rt, m, ((n < 0) ?
20630                    (sp_digit)1 : (sp_digit)0) - 1);
20631         XMEMCPY(r, rt, sizeof(sp_digit) * 156);
20632     }
20633 
20634 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
20635     if (td != NULL)
20636         XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);
20637 #endif
20638 
20639     return err;
20640 #endif
20641 }
20642 #endif /* (WOLFSSL_HAVE_SP_RSA & !WOLFSSL_RSA_PUBLIC_ONLY) || */
20643        /* WOLFSSL_HAVE_SP_DH */
20644 
20645 #endif /* (WOLFSSL_HAVE_SP_RSA && !WOLFSSL_RSA_PUBLIC_ONLY) || WOLFSSL_HAVE_SP_DH */
20646 #ifdef WOLFSSL_HAVE_SP_RSA
20647 /* RSA public key operation.
20648  *
20649  * in      Array of bytes representing the number to exponentiate, base.
20650  * inLen   Number of bytes in base.
20651  * em      Public exponent.
20652  * mm      Modulus.
20653  * out     Buffer to hold big-endian bytes of exponentiation result.
20654  *         Must be at least 512 bytes long.
20655  * outLen  Number of bytes in result.
20656  * returns 0 on success, MP_TO_E when the outLen is too small, MP_READ_E when
20657  * an array is too long and MEMORY_E when dynamic memory allocation fails.
20658  */
sp_RsaPublic_4096(const byte * in,word32 inLen,const mp_int * em,const mp_int * mm,byte * out,word32 * outLen)20659 int sp_RsaPublic_4096(const byte* in, word32 inLen, const mp_int* em,
20660     const mp_int* mm, byte* out, word32* outLen)
20661 {
20662 #ifdef WOLFSSL_SP_SMALL
20663 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
20664     sp_digit* a = NULL;
20665 #else
20666     sp_digit a[78 * 5];
20667 #endif
20668     sp_digit* m = NULL;
20669     sp_digit* r = NULL;
20670     sp_digit* norm = NULL;
20671     sp_digit e[1] = {0};
20672     sp_digit mp;
20673     int i;
20674     int err = MP_OKAY;
20675 
20676     if (*outLen < 512U) {
20677         err = MP_TO_E;
20678     }
20679 
20680     if (err == MP_OKAY) {
20681         if (mp_count_bits(em) > 53) {
20682             err = MP_READ_E;
20683         }
20684         else if (inLen > 512U) {
20685             err = MP_READ_E;
20686         }
20687         else if (mp_count_bits(mm) != 4096) {
20688             err = MP_READ_E;
20689         }
20690         else if (mp_iseven(mm)) {
20691             err = MP_VAL;
20692         }
20693     }
20694 
20695 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
20696     if (err == MP_OKAY) {
20697         a = (sp_digit*)XMALLOC(sizeof(sp_digit) * 78 * 5, NULL,
20698                                                               DYNAMIC_TYPE_RSA);
20699         if (a == NULL)
20700             err = MEMORY_E;
20701     }
20702 #endif
20703 
20704     if (err == MP_OKAY) {
20705         r = a + 78 * 2;
20706         m = r + 78 * 2;
20707         norm = r;
20708 
20709         sp_4096_from_bin(a, 78, in, inLen);
20710 #if DIGIT_BIT >= 53
20711         e[0] = (sp_digit)em->dp[0];
20712 #else
20713         e[0] = (sp_digit)em->dp[0];
20714         if (em->used > 1) {
20715             e[0] |= ((sp_digit)em->dp[1]) << DIGIT_BIT;
20716         }
20717 #endif
20718         if (e[0] == 0) {
20719             err = MP_EXPTMOD_E;
20720         }
20721     }
20722 
20723     if (err == MP_OKAY) {
20724         sp_4096_from_mp(m, 78, mm);
20725 
20726         sp_4096_mont_setup(m, &mp);
20727         sp_4096_mont_norm_78(norm, m);
20728     }
20729     if (err == MP_OKAY) {
20730         sp_4096_mul_78(a, a, norm);
20731         err = sp_4096_mod_78(a, a, m);
20732     }
20733     if (err == MP_OKAY) {
20734         for (i=52; i>=0; i--) {
20735             if ((e[0] >> i) != 0) {
20736                 break;
20737             }
20738         }
20739 
20740         XMEMCPY(r, a, sizeof(sp_digit) * 78 * 2);
20741         for (i--; i>=0; i--) {
20742             sp_4096_mont_sqr_78(r, r, m, mp);
20743 
20744             if (((e[0] >> i) & 1) == 1) {
20745                 sp_4096_mont_mul_78(r, r, a, m, mp);
20746             }
20747         }
20748         sp_4096_mont_reduce_78(r, m, mp);
20749         mp = sp_4096_cmp_78(r, m);
20750         sp_4096_cond_sub_78(r, r, m, ((mp < 0) ?
20751                     (sp_digit)1 : (sp_digit)0)- 1);
20752 
20753         sp_4096_to_bin_78(r, out);
20754         *outLen = 512;
20755     }
20756 
20757 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
20758     if (a != NULL)
20759         XFREE(a, NULL, DYNAMIC_TYPE_RSA);
20760 #endif
20761 
20762     return err;
20763 #else
20764 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
20765     sp_digit* d = NULL;
20766 #else
20767     sp_digit d[78 * 5];
20768 #endif
20769     sp_digit* a = NULL;
20770     sp_digit* m = NULL;
20771     sp_digit* r = NULL;
20772     sp_digit e[1] = {0};
20773     int err = MP_OKAY;
20774 
20775     if (*outLen < 512U) {
20776         err = MP_TO_E;
20777     }
20778     if (err == MP_OKAY) {
20779         if (mp_count_bits(em) > 53) {
20780             err = MP_READ_E;
20781         }
20782         else if (inLen > 512U) {
20783             err = MP_READ_E;
20784         }
20785         else if (mp_count_bits(mm) != 4096) {
20786             err = MP_READ_E;
20787         }
20788         else if (mp_iseven(mm)) {
20789             err = MP_VAL;
20790         }
20791     }
20792 
20793 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
20794     if (err == MP_OKAY) {
20795         d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 78 * 5, NULL,
20796                                                               DYNAMIC_TYPE_RSA);
20797         if (d == NULL)
20798             err = MEMORY_E;
20799     }
20800 #endif
20801 
20802     if (err == MP_OKAY) {
20803         a = d;
20804         r = a + 78 * 2;
20805         m = r + 78 * 2;
20806 
20807         sp_4096_from_bin(a, 78, in, inLen);
20808 #if DIGIT_BIT >= 53
20809         e[0] = (sp_digit)em->dp[0];
20810 #else
20811         e[0] = (sp_digit)em->dp[0];
20812         if (em->used > 1) {
20813             e[0] |= ((sp_digit)em->dp[1]) << DIGIT_BIT;
20814         }
20815 #endif
20816         if (e[0] == 0) {
20817             err = MP_EXPTMOD_E;
20818         }
20819     }
20820     if (err == MP_OKAY) {
20821         sp_4096_from_mp(m, 78, mm);
20822 
20823         if (e[0] == 0x3) {
20824             sp_4096_sqr_78(r, a);
20825             err = sp_4096_mod_78(r, r, m);
20826             if (err == MP_OKAY) {
20827                 sp_4096_mul_78(r, a, r);
20828                 err = sp_4096_mod_78(r, r, m);
20829             }
20830         }
20831         else {
20832             sp_digit* norm = r;
20833             int i;
20834             sp_digit mp;
20835 
20836             sp_4096_mont_setup(m, &mp);
20837             sp_4096_mont_norm_78(norm, m);
20838 
20839             sp_4096_mul_78(a, a, norm);
20840             err = sp_4096_mod_78(a, a, m);
20841 
20842             if (err == MP_OKAY) {
20843                 for (i=52; i>=0; i--) {
20844                     if ((e[0] >> i) != 0) {
20845                         break;
20846                     }
20847                 }
20848 
20849                 XMEMCPY(r, a, sizeof(sp_digit) * 156U);
20850                 for (i--; i>=0; i--) {
20851                     sp_4096_mont_sqr_78(r, r, m, mp);
20852 
20853                     if (((e[0] >> i) & 1) == 1) {
20854                         sp_4096_mont_mul_78(r, r, a, m, mp);
20855                     }
20856                 }
20857                 sp_4096_mont_reduce_78(r, m, mp);
20858                 mp = sp_4096_cmp_78(r, m);
20859                 sp_4096_cond_sub_78(r, r, m, ((mp < 0) ?
20860                            (sp_digit)1 : (sp_digit)0) - 1);
20861             }
20862         }
20863     }
20864 
20865     if (err == MP_OKAY) {
20866         sp_4096_to_bin_78(r, out);
20867         *outLen = 512;
20868     }
20869 
20870 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
20871     if (d != NULL)
20872         XFREE(d, NULL, DYNAMIC_TYPE_RSA);
20873 #endif
20874 
20875     return err;
20876 #endif /* WOLFSSL_SP_SMALL */
20877 }
20878 
20879 #ifndef WOLFSSL_RSA_PUBLIC_ONLY
20880 #if !defined(SP_RSA_PRIVATE_EXP_D) && !defined(RSA_LOW_MEM)
20881 #endif /* !SP_RSA_PRIVATE_EXP_D & !RSA_LOW_MEM */
20882 /* RSA private key operation.
20883  *
20884  * in      Array of bytes representing the number to exponentiate, base.
20885  * inLen   Number of bytes in base.
20886  * dm      Private exponent.
20887  * pm      First prime.
20888  * qm      Second prime.
20889  * dpm     First prime's CRT exponent.
20890  * dqm     Second prime's CRT exponent.
20891  * qim     Inverse of second prime mod p.
20892  * mm      Modulus.
20893  * out     Buffer to hold big-endian bytes of exponentiation result.
20894  *         Must be at least 512 bytes long.
20895  * outLen  Number of bytes in result.
20896  * returns 0 on success, MP_TO_E when the outLen is too small, MP_READ_E when
20897  * an array is too long and MEMORY_E when dynamic memory allocation fails.
20898  */
sp_RsaPrivate_4096(const byte * in,word32 inLen,const mp_int * dm,const mp_int * pm,const mp_int * qm,const mp_int * dpm,const mp_int * dqm,const mp_int * qim,const mp_int * mm,byte * out,word32 * outLen)20899 int sp_RsaPrivate_4096(const byte* in, word32 inLen, const mp_int* dm,
20900     const mp_int* pm, const mp_int* qm, const mp_int* dpm, const mp_int* dqm,
20901     const mp_int* qim, const mp_int* mm, byte* out, word32* outLen)
20902 {
20903 #if defined(SP_RSA_PRIVATE_EXP_D) || defined(RSA_LOW_MEM)
20904 #if defined(WOLFSSL_SP_SMALL)
20905 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
20906     sp_digit* d = NULL;
20907 #else
20908     sp_digit  d[78 * 4];
20909 #endif
20910     sp_digit* a = NULL;
20911     sp_digit* m = NULL;
20912     sp_digit* r = NULL;
20913     int err = MP_OKAY;
20914 
20915     (void)pm;
20916     (void)qm;
20917     (void)dpm;
20918     (void)dqm;
20919     (void)qim;
20920 
20921     if (*outLen < 512U) {
20922         err = MP_TO_E;
20923     }
20924     if (err == MP_OKAY) {
20925         if (mp_count_bits(dm) > 4096) {
20926            err = MP_READ_E;
20927         }
20928         else if (inLen > 512) {
20929             err = MP_READ_E;
20930         }
20931         else if (mp_count_bits(mm) != 4096) {
20932             err = MP_READ_E;
20933         }
20934         else if (mp_iseven(mm)) {
20935             err = MP_VAL;
20936         }
20937     }
20938 
20939 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
20940     if (err == MP_OKAY) {
20941         d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 78 * 4, NULL,
20942                                                               DYNAMIC_TYPE_RSA);
20943         if (d == NULL)
20944             err = MEMORY_E;
20945     }
20946 #endif
20947 
20948     if (err == MP_OKAY) {
20949         a = d + 78;
20950         m = a + 156;
20951         r = a;
20952 
20953         sp_4096_from_bin(a, 78, in, inLen);
20954         sp_4096_from_mp(d, 78, dm);
20955         sp_4096_from_mp(m, 78, mm);
20956         err = sp_4096_mod_exp_78(r, a, d, 4096, m, 0);
20957     }
20958 
20959     if (err == MP_OKAY) {
20960         sp_4096_to_bin_78(r, out);
20961         *outLen = 512;
20962     }
20963 
20964 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
20965     if (d != NULL)
20966 #endif
20967     {
20968         /* only "a" and "r" are sensitive and need zeroized (same pointer) */
20969         if (a != NULL)
20970             ForceZero(a, sizeof(sp_digit) * 78);
20971 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
20972         XFREE(d, NULL, DYNAMIC_TYPE_RSA);
20973 #endif
20974     }
20975 
20976     return err;
20977 #else
20978 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
20979     sp_digit* d = NULL;
20980 #else
20981     sp_digit d[78 * 4];
20982 #endif
20983     sp_digit* a = NULL;
20984     sp_digit* m = NULL;
20985     sp_digit* r = NULL;
20986     int err = MP_OKAY;
20987 
20988     (void)pm;
20989     (void)qm;
20990     (void)dpm;
20991     (void)dqm;
20992     (void)qim;
20993 
20994     if (*outLen < 512U) {
20995         err = MP_TO_E;
20996     }
20997     if (err == MP_OKAY) {
20998         if (mp_count_bits(dm) > 4096) {
20999             err = MP_READ_E;
21000         }
21001         else if (inLen > 512U) {
21002             err = MP_READ_E;
21003         }
21004         else if (mp_count_bits(mm) != 4096) {
21005             err = MP_READ_E;
21006         }
21007         else if (mp_iseven(mm)) {
21008             err = MP_VAL;
21009         }
21010     }
21011 
21012 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
21013     if (err == MP_OKAY) {
21014         d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 78 * 4, NULL,
21015                                                               DYNAMIC_TYPE_RSA);
21016         if (d == NULL)
21017             err = MEMORY_E;
21018     }
21019 #endif
21020 
21021     if (err == MP_OKAY) {
21022         a = d + 78;
21023         m = a + 156;
21024         r = a;
21025 
21026         sp_4096_from_bin(a, 78, in, inLen);
21027         sp_4096_from_mp(d, 78, dm);
21028         sp_4096_from_mp(m, 78, mm);
21029         err = sp_4096_mod_exp_78(r, a, d, 4096, m, 0);
21030     }
21031 
21032     if (err == MP_OKAY) {
21033         sp_4096_to_bin_78(r, out);
21034         *outLen = 512;
21035     }
21036 
21037 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
21038     if (d != NULL)
21039 #endif
21040     {
21041         /* only "a" and "r" are sensitive and need zeroized (same pointer) */
21042         if (a != NULL)
21043             ForceZero(a, sizeof(sp_digit) * 78);
21044 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
21045         XFREE(d, NULL, DYNAMIC_TYPE_RSA);
21046 #endif
21047     }
21048 
21049     return err;
21050 #endif /* WOLFSSL_SP_SMALL */
21051 #else
21052 #if defined(WOLFSSL_SP_SMALL)
21053 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
21054     sp_digit* a = NULL;
21055 #else
21056     sp_digit a[39 * 8];
21057 #endif
21058     sp_digit* p = NULL;
21059     sp_digit* dp = NULL;
21060     sp_digit* dq = NULL;
21061     sp_digit* qi = NULL;
21062     sp_digit* tmpa = NULL;
21063     sp_digit* tmpb = NULL;
21064     sp_digit* r = NULL;
21065     int err = MP_OKAY;
21066 
21067     (void)dm;
21068     (void)mm;
21069 
21070     if (*outLen < 512U) {
21071         err = MP_TO_E;
21072     }
21073     if (err == MP_OKAY) {
21074         if (inLen > 512) {
21075             err = MP_READ_E;
21076         }
21077         else if (mp_count_bits(mm) != 4096) {
21078             err = MP_READ_E;
21079         }
21080         else if (mp_iseven(mm)) {
21081             err = MP_VAL;
21082         }
21083     }
21084 
21085 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
21086     if (err == MP_OKAY) {
21087         a = (sp_digit*)XMALLOC(sizeof(sp_digit) * 39 * 8, NULL,
21088                                                               DYNAMIC_TYPE_RSA);
21089         if (a == NULL)
21090             err = MEMORY_E;
21091     }
21092 #endif
21093     if (err == MP_OKAY) {
21094         p = a + 78;
21095         qi = dq = dp = p + 39;
21096         tmpa = qi + 39;
21097         tmpb = tmpa + 78;
21098         r = a;
21099 
21100         sp_4096_from_bin(a, 78, in, inLen);
21101         sp_4096_from_mp(p, 39, pm);
21102         sp_4096_from_mp(dp, 39, dpm);
21103         err = sp_4096_mod_exp_39(tmpa, a, dp, 2048, p, 1);
21104     }
21105     if (err == MP_OKAY) {
21106         sp_4096_from_mp(p, 39, qm);
21107         sp_4096_from_mp(dq, 39, dqm);
21108         err = sp_4096_mod_exp_39(tmpb, a, dq, 2048, p, 1);
21109     }
21110     if (err == MP_OKAY) {
21111         sp_4096_from_mp(p, 39, pm);
21112         (void)sp_4096_sub_39(tmpa, tmpa, tmpb);
21113         sp_4096_norm_39(tmpa);
21114         sp_4096_cond_add_39(tmpa, tmpa, p, 0 - ((sp_int_digit)tmpa[38] >> 63));
21115         sp_4096_cond_add_39(tmpa, tmpa, p, 0 - ((sp_int_digit)tmpa[38] >> 63));
21116         sp_4096_norm_39(tmpa);
21117 
21118         sp_4096_from_mp(qi, 39, qim);
21119         sp_4096_mul_39(tmpa, tmpa, qi);
21120         err = sp_4096_mod_39(tmpa, tmpa, p);
21121     }
21122 
21123     if (err == MP_OKAY) {
21124         sp_4096_from_mp(p, 39, qm);
21125         sp_4096_mul_39(tmpa, p, tmpa);
21126         (void)sp_4096_add_78(r, tmpb, tmpa);
21127         sp_4096_norm_78(r);
21128 
21129         sp_4096_to_bin_78(r, out);
21130         *outLen = 512;
21131     }
21132 
21133 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
21134     if (a != NULL)
21135 #endif
21136     {
21137         ForceZero(a, sizeof(sp_digit) * 39 * 8);
21138 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
21139         XFREE(a, NULL, DYNAMIC_TYPE_RSA);
21140 #endif
21141     }
21142 
21143     return err;
21144 #else
21145 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
21146     sp_digit* a = NULL;
21147 #else
21148     sp_digit a[39 * 13];
21149 #endif
21150     sp_digit* p = NULL;
21151     sp_digit* q = NULL;
21152     sp_digit* dp = NULL;
21153     sp_digit* dq = NULL;
21154     sp_digit* qi = NULL;
21155     sp_digit* tmpa = NULL;
21156     sp_digit* tmpb = NULL;
21157     sp_digit* r = NULL;
21158     int err = MP_OKAY;
21159 
21160     (void)dm;
21161     (void)mm;
21162 
21163     if (*outLen < 512U) {
21164         err = MP_TO_E;
21165     }
21166     if (err == MP_OKAY) {
21167         if (inLen > 512U) {
21168             err = MP_READ_E;
21169         }
21170         else if (mp_count_bits(mm) != 4096) {
21171             err = MP_READ_E;
21172         }
21173         else if (mp_iseven(mm)) {
21174             err = MP_VAL;
21175         }
21176     }
21177 
21178 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
21179     if (err == MP_OKAY) {
21180         a = (sp_digit*)XMALLOC(sizeof(sp_digit) * 39 * 13, NULL,
21181                                                               DYNAMIC_TYPE_RSA);
21182         if (a == NULL)
21183             err = MEMORY_E;
21184     }
21185 #endif
21186 
21187     if (err == MP_OKAY) {
21188         p = a + 78 * 2;
21189         q = p + 39;
21190         dp = q + 39;
21191         dq = dp + 39;
21192         qi = dq + 39;
21193         tmpa = qi + 39;
21194         tmpb = tmpa + 78;
21195         r = a;
21196 
21197         sp_4096_from_bin(a, 78, in, inLen);
21198         sp_4096_from_mp(p, 39, pm);
21199         sp_4096_from_mp(q, 39, qm);
21200         sp_4096_from_mp(dp, 39, dpm);
21201         sp_4096_from_mp(dq, 39, dqm);
21202         sp_4096_from_mp(qi, 39, qim);
21203 
21204         err = sp_4096_mod_exp_39(tmpa, a, dp, 2048, p, 1);
21205     }
21206     if (err == MP_OKAY) {
21207         err = sp_4096_mod_exp_39(tmpb, a, dq, 2048, q, 1);
21208     }
21209 
21210     if (err == MP_OKAY) {
21211         (void)sp_4096_sub_39(tmpa, tmpa, tmpb);
21212         sp_4096_norm_39(tmpa);
21213         sp_4096_cond_add_39(tmpa, tmpa, p, 0 - ((sp_int_digit)tmpa[38] >> 63));
21214         sp_4096_cond_add_39(tmpa, tmpa, p, 0 - ((sp_int_digit)tmpa[38] >> 63));
21215         sp_4096_norm_39(tmpa);
21216         sp_4096_mul_39(tmpa, tmpa, qi);
21217         err = sp_4096_mod_39(tmpa, tmpa, p);
21218     }
21219 
21220     if (err == MP_OKAY) {
21221         sp_4096_mul_39(tmpa, tmpa, q);
21222         (void)sp_4096_add_78(r, tmpb, tmpa);
21223         sp_4096_norm_78(r);
21224 
21225         sp_4096_to_bin_78(r, out);
21226         *outLen = 512;
21227     }
21228 
21229 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
21230 if (a != NULL)
21231 #endif
21232     {
21233         ForceZero(a, sizeof(sp_digit) * 39 * 13);
21234     #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
21235         XFREE(a, NULL, DYNAMIC_TYPE_RSA);
21236     #endif
21237     }
21238 
21239     return err;
21240 #endif /* WOLFSSL_SP_SMALL */
21241 #endif /* SP_RSA_PRIVATE_EXP_D || RSA_LOW_MEM */
21242 }
21243 
21244 #endif /* !WOLFSSL_RSA_PUBLIC_ONLY */
21245 #endif /* WOLFSSL_HAVE_SP_RSA */
21246 #if defined(WOLFSSL_HAVE_SP_DH) || (defined(WOLFSSL_HAVE_SP_RSA) && \
21247                                               !defined(WOLFSSL_RSA_PUBLIC_ONLY))
21248 /* Convert an array of sp_digit to an mp_int.
21249  *
21250  * a  A single precision integer.
21251  * r  A multi-precision integer.
21252  */
sp_4096_to_mp(const sp_digit * a,mp_int * r)21253 static int sp_4096_to_mp(const sp_digit* a, mp_int* r)
21254 {
21255     int err;
21256 
21257     err = mp_grow(r, (4096 + DIGIT_BIT - 1) / DIGIT_BIT);
21258     if (err == MP_OKAY) { /*lint !e774 case where err is always MP_OKAY*/
21259 #if DIGIT_BIT == 53
21260         XMEMCPY(r->dp, a, sizeof(sp_digit) * 78);
21261         r->used = 78;
21262         mp_clamp(r);
21263 #elif DIGIT_BIT < 53
21264         int i;
21265         int j = 0;
21266         int s = 0;
21267 
21268         r->dp[0] = 0;
21269         for (i = 0; i < 78; i++) {
21270             r->dp[j] |= (mp_digit)(a[i] << s);
21271             r->dp[j] &= ((sp_digit)1 << DIGIT_BIT) - 1;
21272             s = DIGIT_BIT - s;
21273             r->dp[++j] = (mp_digit)(a[i] >> s);
21274             while (s + DIGIT_BIT <= 53) {
21275                 s += DIGIT_BIT;
21276                 r->dp[j++] &= ((sp_digit)1 << DIGIT_BIT) - 1;
21277                 if (s == SP_WORD_SIZE) {
21278                     r->dp[j] = 0;
21279                 }
21280                 else {
21281                     r->dp[j] = (mp_digit)(a[i] >> s);
21282                 }
21283             }
21284             s = 53 - s;
21285         }
21286         r->used = (4096 + DIGIT_BIT - 1) / DIGIT_BIT;
21287         mp_clamp(r);
21288 #else
21289         int i;
21290         int j = 0;
21291         int s = 0;
21292 
21293         r->dp[0] = 0;
21294         for (i = 0; i < 78; i++) {
21295             r->dp[j] |= ((mp_digit)a[i]) << s;
21296             if (s + 53 >= DIGIT_BIT) {
21297     #if DIGIT_BIT != 32 && DIGIT_BIT != 64
21298                 r->dp[j] &= ((sp_digit)1 << DIGIT_BIT) - 1;
21299     #endif
21300                 s = DIGIT_BIT - s;
21301                 r->dp[++j] = a[i] >> s;
21302                 s = 53 - s;
21303             }
21304             else {
21305                 s += 53;
21306             }
21307         }
21308         r->used = (4096 + DIGIT_BIT - 1) / DIGIT_BIT;
21309         mp_clamp(r);
21310 #endif
21311     }
21312 
21313     return err;
21314 }
21315 
21316 /* Perform the modular exponentiation for Diffie-Hellman.
21317  *
21318  * base  Base. MP integer.
21319  * exp   Exponent. MP integer.
21320  * mod   Modulus. MP integer.
21321  * res   Result. MP integer.
21322  * returns 0 on success, MP_READ_E if there are too many bytes in an array
21323  * and MEMORY_E if memory allocation fails.
21324  */
sp_ModExp_4096(const mp_int * base,const mp_int * exp,const mp_int * mod,mp_int * res)21325 int sp_ModExp_4096(const mp_int* base, const mp_int* exp, const mp_int* mod,
21326     mp_int* res)
21327 {
21328 #ifdef WOLFSSL_SP_SMALL
21329     int err = MP_OKAY;
21330 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
21331     sp_digit* b = NULL;
21332 #else
21333     sp_digit b[78 * 4];
21334 #endif
21335     sp_digit* e = NULL;
21336     sp_digit* m = NULL;
21337     sp_digit* r = NULL;
21338     int expBits = mp_count_bits(exp);
21339 
21340     if (mp_count_bits(base) > 4096) {
21341         err = MP_READ_E;
21342     }
21343     else if (expBits > 4096) {
21344         err = MP_READ_E;
21345     }
21346     else if (mp_count_bits(mod) != 4096) {
21347         err = MP_READ_E;
21348     }
21349     else if (mp_iseven(mod)) {
21350         err = MP_VAL;
21351     }
21352 
21353 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
21354     if (err == MP_OKAY) {
21355         b = (sp_digit*)XMALLOC(sizeof(sp_digit) * 78 * 4, NULL,
21356             DYNAMIC_TYPE_DH);
21357         if (b == NULL)
21358             err = MEMORY_E;
21359     }
21360 #endif
21361 
21362     if (err == MP_OKAY) {
21363         e = b + 78 * 2;
21364         m = e + 78;
21365         r = b;
21366 
21367         sp_4096_from_mp(b, 78, base);
21368         sp_4096_from_mp(e, 78, exp);
21369         sp_4096_from_mp(m, 78, mod);
21370 
21371         err = sp_4096_mod_exp_78(r, b, e, mp_count_bits(exp), m, 0);
21372     }
21373 
21374     if (err == MP_OKAY) {
21375         err = sp_4096_to_mp(r, res);
21376     }
21377 
21378 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
21379     if (b != NULL)
21380 #endif
21381     {
21382         /* only "e" is sensitive and needs zeroized */
21383         if (e != NULL)
21384             ForceZero(e, sizeof(sp_digit) * 78U);
21385     #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
21386         XFREE(b, NULL, DYNAMIC_TYPE_DH);
21387     #endif
21388     }
21389     return err;
21390 #else
21391 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
21392     sp_digit* b = NULL;
21393 #else
21394     sp_digit b[78 * 4];
21395 #endif
21396     sp_digit* e = NULL;
21397     sp_digit* m = NULL;
21398     sp_digit* r = NULL;
21399     int err = MP_OKAY;
21400     int expBits = mp_count_bits(exp);
21401 
21402     if (mp_count_bits(base) > 4096) {
21403         err = MP_READ_E;
21404     }
21405     else if (expBits > 4096) {
21406         err = MP_READ_E;
21407     }
21408     else if (mp_count_bits(mod) != 4096) {
21409         err = MP_READ_E;
21410     }
21411     else if (mp_iseven(mod)) {
21412         err = MP_VAL;
21413     }
21414 
21415 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
21416     if (err == MP_OKAY) {
21417         b = (sp_digit*)XMALLOC(sizeof(sp_digit) * 78 * 4, NULL, DYNAMIC_TYPE_DH);
21418         if (b == NULL)
21419             err = MEMORY_E;
21420     }
21421 #endif
21422 
21423     if (err == MP_OKAY) {
21424         e = b + 78 * 2;
21425         m = e + 78;
21426         r = b;
21427 
21428         sp_4096_from_mp(b, 78, base);
21429         sp_4096_from_mp(e, 78, exp);
21430         sp_4096_from_mp(m, 78, mod);
21431 
21432         err = sp_4096_mod_exp_78(r, b, e, expBits, m, 0);
21433     }
21434 
21435     if (err == MP_OKAY) {
21436         err = sp_4096_to_mp(r, res);
21437     }
21438 
21439 
21440 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
21441     if (b != NULL)
21442 #endif
21443     {
21444         /* only "e" is sensitive and needs zeroized */
21445         if (e != NULL)
21446             ForceZero(e, sizeof(sp_digit) * 78U);
21447     #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
21448         XFREE(b, NULL, DYNAMIC_TYPE_DH);
21449     #endif
21450     }
21451 
21452     return err;
21453 #endif
21454 }
21455 
21456 #ifdef WOLFSSL_HAVE_SP_DH
21457 
21458 #ifdef HAVE_FFDHE_4096
sp_4096_lshift_78(sp_digit * r,const sp_digit * a,byte n)21459 SP_NOINLINE static void sp_4096_lshift_78(sp_digit* r, const sp_digit* a,
21460         byte n)
21461 {
21462     sp_int_digit s;
21463     sp_int_digit t;
21464 
21465     s = (sp_int_digit)a[77];
21466     r[78] = s >> (53U - n);
21467     s = (sp_int_digit)(a[77]); t = (sp_int_digit)(a[76]);
21468     r[77] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;
21469     s = (sp_int_digit)(a[76]); t = (sp_int_digit)(a[75]);
21470     r[76] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;
21471     s = (sp_int_digit)(a[75]); t = (sp_int_digit)(a[74]);
21472     r[75] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;
21473     s = (sp_int_digit)(a[74]); t = (sp_int_digit)(a[73]);
21474     r[74] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;
21475     s = (sp_int_digit)(a[73]); t = (sp_int_digit)(a[72]);
21476     r[73] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;
21477     s = (sp_int_digit)(a[72]); t = (sp_int_digit)(a[71]);
21478     r[72] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;
21479     s = (sp_int_digit)(a[71]); t = (sp_int_digit)(a[70]);
21480     r[71] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;
21481     s = (sp_int_digit)(a[70]); t = (sp_int_digit)(a[69]);
21482     r[70] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;
21483     s = (sp_int_digit)(a[69]); t = (sp_int_digit)(a[68]);
21484     r[69] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;
21485     s = (sp_int_digit)(a[68]); t = (sp_int_digit)(a[67]);
21486     r[68] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;
21487     s = (sp_int_digit)(a[67]); t = (sp_int_digit)(a[66]);
21488     r[67] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;
21489     s = (sp_int_digit)(a[66]); t = (sp_int_digit)(a[65]);
21490     r[66] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;
21491     s = (sp_int_digit)(a[65]); t = (sp_int_digit)(a[64]);
21492     r[65] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;
21493     s = (sp_int_digit)(a[64]); t = (sp_int_digit)(a[63]);
21494     r[64] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;
21495     s = (sp_int_digit)(a[63]); t = (sp_int_digit)(a[62]);
21496     r[63] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;
21497     s = (sp_int_digit)(a[62]); t = (sp_int_digit)(a[61]);
21498     r[62] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;
21499     s = (sp_int_digit)(a[61]); t = (sp_int_digit)(a[60]);
21500     r[61] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;
21501     s = (sp_int_digit)(a[60]); t = (sp_int_digit)(a[59]);
21502     r[60] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;
21503     s = (sp_int_digit)(a[59]); t = (sp_int_digit)(a[58]);
21504     r[59] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;
21505     s = (sp_int_digit)(a[58]); t = (sp_int_digit)(a[57]);
21506     r[58] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;
21507     s = (sp_int_digit)(a[57]); t = (sp_int_digit)(a[56]);
21508     r[57] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;
21509     s = (sp_int_digit)(a[56]); t = (sp_int_digit)(a[55]);
21510     r[56] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;
21511     s = (sp_int_digit)(a[55]); t = (sp_int_digit)(a[54]);
21512     r[55] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;
21513     s = (sp_int_digit)(a[54]); t = (sp_int_digit)(a[53]);
21514     r[54] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;
21515     s = (sp_int_digit)(a[53]); t = (sp_int_digit)(a[52]);
21516     r[53] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;
21517     s = (sp_int_digit)(a[52]); t = (sp_int_digit)(a[51]);
21518     r[52] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;
21519     s = (sp_int_digit)(a[51]); t = (sp_int_digit)(a[50]);
21520     r[51] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;
21521     s = (sp_int_digit)(a[50]); t = (sp_int_digit)(a[49]);
21522     r[50] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;
21523     s = (sp_int_digit)(a[49]); t = (sp_int_digit)(a[48]);
21524     r[49] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;
21525     s = (sp_int_digit)(a[48]); t = (sp_int_digit)(a[47]);
21526     r[48] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;
21527     s = (sp_int_digit)(a[47]); t = (sp_int_digit)(a[46]);
21528     r[47] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;
21529     s = (sp_int_digit)(a[46]); t = (sp_int_digit)(a[45]);
21530     r[46] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;
21531     s = (sp_int_digit)(a[45]); t = (sp_int_digit)(a[44]);
21532     r[45] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;
21533     s = (sp_int_digit)(a[44]); t = (sp_int_digit)(a[43]);
21534     r[44] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;
21535     s = (sp_int_digit)(a[43]); t = (sp_int_digit)(a[42]);
21536     r[43] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;
21537     s = (sp_int_digit)(a[42]); t = (sp_int_digit)(a[41]);
21538     r[42] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;
21539     s = (sp_int_digit)(a[41]); t = (sp_int_digit)(a[40]);
21540     r[41] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;
21541     s = (sp_int_digit)(a[40]); t = (sp_int_digit)(a[39]);
21542     r[40] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;
21543     s = (sp_int_digit)(a[39]); t = (sp_int_digit)(a[38]);
21544     r[39] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;
21545     s = (sp_int_digit)(a[38]); t = (sp_int_digit)(a[37]);
21546     r[38] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;
21547     s = (sp_int_digit)(a[37]); t = (sp_int_digit)(a[36]);
21548     r[37] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;
21549     s = (sp_int_digit)(a[36]); t = (sp_int_digit)(a[35]);
21550     r[36] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;
21551     s = (sp_int_digit)(a[35]); t = (sp_int_digit)(a[34]);
21552     r[35] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;
21553     s = (sp_int_digit)(a[34]); t = (sp_int_digit)(a[33]);
21554     r[34] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;
21555     s = (sp_int_digit)(a[33]); t = (sp_int_digit)(a[32]);
21556     r[33] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;
21557     s = (sp_int_digit)(a[32]); t = (sp_int_digit)(a[31]);
21558     r[32] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;
21559     s = (sp_int_digit)(a[31]); t = (sp_int_digit)(a[30]);
21560     r[31] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;
21561     s = (sp_int_digit)(a[30]); t = (sp_int_digit)(a[29]);
21562     r[30] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;
21563     s = (sp_int_digit)(a[29]); t = (sp_int_digit)(a[28]);
21564     r[29] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;
21565     s = (sp_int_digit)(a[28]); t = (sp_int_digit)(a[27]);
21566     r[28] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;
21567     s = (sp_int_digit)(a[27]); t = (sp_int_digit)(a[26]);
21568     r[27] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;
21569     s = (sp_int_digit)(a[26]); t = (sp_int_digit)(a[25]);
21570     r[26] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;
21571     s = (sp_int_digit)(a[25]); t = (sp_int_digit)(a[24]);
21572     r[25] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;
21573     s = (sp_int_digit)(a[24]); t = (sp_int_digit)(a[23]);
21574     r[24] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;
21575     s = (sp_int_digit)(a[23]); t = (sp_int_digit)(a[22]);
21576     r[23] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;
21577     s = (sp_int_digit)(a[22]); t = (sp_int_digit)(a[21]);
21578     r[22] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;
21579     s = (sp_int_digit)(a[21]); t = (sp_int_digit)(a[20]);
21580     r[21] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;
21581     s = (sp_int_digit)(a[20]); t = (sp_int_digit)(a[19]);
21582     r[20] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;
21583     s = (sp_int_digit)(a[19]); t = (sp_int_digit)(a[18]);
21584     r[19] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;
21585     s = (sp_int_digit)(a[18]); t = (sp_int_digit)(a[17]);
21586     r[18] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;
21587     s = (sp_int_digit)(a[17]); t = (sp_int_digit)(a[16]);
21588     r[17] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;
21589     s = (sp_int_digit)(a[16]); t = (sp_int_digit)(a[15]);
21590     r[16] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;
21591     s = (sp_int_digit)(a[15]); t = (sp_int_digit)(a[14]);
21592     r[15] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;
21593     s = (sp_int_digit)(a[14]); t = (sp_int_digit)(a[13]);
21594     r[14] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;
21595     s = (sp_int_digit)(a[13]); t = (sp_int_digit)(a[12]);
21596     r[13] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;
21597     s = (sp_int_digit)(a[12]); t = (sp_int_digit)(a[11]);
21598     r[12] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;
21599     s = (sp_int_digit)(a[11]); t = (sp_int_digit)(a[10]);
21600     r[11] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;
21601     s = (sp_int_digit)(a[10]); t = (sp_int_digit)(a[9]);
21602     r[10] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;
21603     s = (sp_int_digit)(a[9]); t = (sp_int_digit)(a[8]);
21604     r[9] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;
21605     s = (sp_int_digit)(a[8]); t = (sp_int_digit)(a[7]);
21606     r[8] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;
21607     s = (sp_int_digit)(a[7]); t = (sp_int_digit)(a[6]);
21608     r[7] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;
21609     s = (sp_int_digit)(a[6]); t = (sp_int_digit)(a[5]);
21610     r[6] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;
21611     s = (sp_int_digit)(a[5]); t = (sp_int_digit)(a[4]);
21612     r[5] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;
21613     s = (sp_int_digit)(a[4]); t = (sp_int_digit)(a[3]);
21614     r[4] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;
21615     s = (sp_int_digit)(a[3]); t = (sp_int_digit)(a[2]);
21616     r[3] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;
21617     s = (sp_int_digit)(a[2]); t = (sp_int_digit)(a[1]);
21618     r[2] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;
21619     s = (sp_int_digit)(a[1]); t = (sp_int_digit)(a[0]);
21620     r[1] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;
21621     r[0] = (a[0] << n) & 0x1fffffffffffffL;
21622 }
21623 
21624 /* Modular exponentiate 2 to the e mod m. (r = 2^e mod m)
21625  *
21626  * r     A single precision number that is the result of the operation.
21627  * e     A single precision number that is the exponent.
21628  * bits  The number of bits in the exponent.
21629  * m     A single precision number that is the modulus.
21630  * returns  0 on success.
21631  * returns  MEMORY_E on dynamic memory allocation failure.
21632  * returns  MP_VAL when base is even.
21633  */
sp_4096_mod_exp_2_78(sp_digit * r,const sp_digit * e,int bits,const sp_digit * m)21634 static int sp_4096_mod_exp_2_78(sp_digit* r, const sp_digit* e, int bits, const sp_digit* m)
21635 {
21636 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
21637     sp_digit* td = NULL;
21638 #else
21639     sp_digit td[235];
21640 #endif
21641     sp_digit* norm = NULL;
21642     sp_digit* tmp = NULL;
21643     sp_digit mp = 1;
21644     sp_digit n;
21645     sp_digit o;
21646     int i;
21647     int c;
21648     byte y;
21649     int err = MP_OKAY;
21650 
21651     if ((m[0] & 1) == 0) {
21652         err = MP_VAL;
21653     }
21654 
21655 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
21656     if (err == MP_OKAY) {
21657         td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 235, NULL,
21658                                 DYNAMIC_TYPE_TMP_BUFFER);
21659         if (td == NULL)
21660             err = MEMORY_E;
21661     }
21662 #endif
21663 
21664     if (err == MP_OKAY) {
21665         norm = td;
21666         tmp  = td + 156;
21667         XMEMSET(td, 0, sizeof(sp_digit) * 235);
21668 
21669         sp_4096_mont_setup(m, &mp);
21670         sp_4096_mont_norm_78(norm, m);
21671 
21672         bits = ((bits + 4) / 5) * 5;
21673         i = ((bits + 52) / 53) - 1;
21674         c = bits % 53;
21675         if (c == 0) {
21676             c = 53;
21677         }
21678         if (i < 78) {
21679             n = e[i--] << (64 - c);
21680         }
21681         else {
21682             n = 0;
21683             i--;
21684         }
21685         if (c < 5) {
21686             n |= e[i--] << (11 - c);
21687             c += 53;
21688         }
21689         y = (int)((n >> 59) & 0x1f);
21690         n <<= 5;
21691         c -= 5;
21692         sp_4096_lshift_78(r, norm, (byte)y);
21693         while ((i >= 0) || (c >= 5)) {
21694             if (c >= 5) {
21695                 y = (byte)((n >> 59) & 0x1f);
21696                 n <<= 5;
21697                 c -= 5;
21698             }
21699             else if (c == 0) {
21700                 n = e[i--] << 11;
21701                 y = (byte)((n >> 59) & 0x1f);
21702                 n <<= 5;
21703                 c = 48;
21704             }
21705             else {
21706                 y = (byte)((n >> 59) & 0x1f);
21707                 n = e[i--] << 11;
21708                 c = 5 - c;
21709                 y |= (byte)((n >> (64 - c)) & ((1 << c) - 1));
21710                 n <<= c;
21711                 c = 53 - c;
21712             }
21713 
21714             sp_4096_mont_sqr_78(r, r, m, mp);
21715             sp_4096_mont_sqr_78(r, r, m, mp);
21716             sp_4096_mont_sqr_78(r, r, m, mp);
21717             sp_4096_mont_sqr_78(r, r, m, mp);
21718             sp_4096_mont_sqr_78(r, r, m, mp);
21719 
21720             sp_4096_lshift_78(r, r, (byte)y);
21721             sp_4096_mul_d_78(tmp, norm, (r[78] << 38) + (r[77] >> 15));
21722             r[78] = 0;
21723             r[77] &= 0x7fffL;
21724             (void)sp_4096_add_78(r, r, tmp);
21725             sp_4096_norm_78(r);
21726             o = sp_4096_cmp_78(r, m);
21727             sp_4096_cond_sub_78(r, r, m, ((o < 0) ?
21728                                           (sp_digit)1 : (sp_digit)0) - 1);
21729         }
21730 
21731         sp_4096_mont_reduce_78(r, m, mp);
21732         n = sp_4096_cmp_78(r, m);
21733         sp_4096_cond_sub_78(r, r, m, ((n < 0) ?
21734                                                 (sp_digit)1 : (sp_digit)0) - 1);
21735     }
21736 
21737 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
21738     if (td != NULL)
21739         XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);
21740 #endif
21741 
21742     return err;
21743 }
21744 
21745 #endif /* HAVE_FFDHE_4096 */
21746 
21747 /* Perform the modular exponentiation for Diffie-Hellman.
21748  *
21749  * base     Base.
21750  * exp      Array of bytes that is the exponent.
21751  * expLen   Length of data, in bytes, in exponent.
21752  * mod      Modulus.
21753  * out      Buffer to hold big-endian bytes of exponentiation result.
21754  *          Must be at least 512 bytes long.
21755  * outLen   Length, in bytes, of exponentiation result.
21756  * returns 0 on success, MP_READ_E if there are too many bytes in an array
21757  * and MEMORY_E if memory allocation fails.
21758  */
sp_DhExp_4096(const mp_int * base,const byte * exp,word32 expLen,const mp_int * mod,byte * out,word32 * outLen)21759 int sp_DhExp_4096(const mp_int* base, const byte* exp, word32 expLen,
21760     const mp_int* mod, byte* out, word32* outLen)
21761 {
21762 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
21763     sp_digit* b = NULL;
21764 #else
21765     sp_digit b[78 * 4];
21766 #endif
21767     sp_digit* e = NULL;
21768     sp_digit* m = NULL;
21769     sp_digit* r = NULL;
21770     word32 i;
21771     int err = MP_OKAY;
21772 
21773     if (mp_count_bits(base) > 4096) {
21774         err = MP_READ_E;
21775     }
21776     else if (expLen > 512U) {
21777         err = MP_READ_E;
21778     }
21779     else if (mp_count_bits(mod) != 4096) {
21780         err = MP_READ_E;
21781     }
21782     else if (mp_iseven(mod)) {
21783         err = MP_VAL;
21784     }
21785 
21786 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
21787     if (err == MP_OKAY) {
21788         b = (sp_digit*)XMALLOC(sizeof(sp_digit) * 78 * 4, NULL,
21789             DYNAMIC_TYPE_DH);
21790         if (b == NULL)
21791             err = MEMORY_E;
21792     }
21793 #endif
21794 
21795     if (err == MP_OKAY) {
21796         e = b + 78 * 2;
21797         m = e + 78;
21798         r = b;
21799 
21800         sp_4096_from_mp(b, 78, base);
21801         sp_4096_from_bin(e, 78, exp, expLen);
21802         sp_4096_from_mp(m, 78, mod);
21803 
21804     #ifdef HAVE_FFDHE_4096
21805         if (base->used == 1 && base->dp[0] == 2U &&
21806                 ((m[77] << 17) | (m[76] >> 36)) == 0xffffffffL) {
21807             err = sp_4096_mod_exp_2_78(r, e, expLen * 8U, m);
21808         }
21809         else {
21810     #endif
21811             err = sp_4096_mod_exp_78(r, b, e, expLen * 8U, m, 0);
21812     #ifdef HAVE_FFDHE_4096
21813         }
21814     #endif
21815     }
21816 
21817     if (err == MP_OKAY) {
21818         sp_4096_to_bin_78(r, out);
21819         *outLen = 512;
21820         for (i=0; i<512U && out[i] == 0U; i++) {
21821             /* Search for first non-zero. */
21822         }
21823         *outLen -= i;
21824         XMEMMOVE(out, out + i, *outLen);
21825     }
21826 
21827 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
21828     if (b != NULL)
21829 #endif
21830     {
21831         /* only "e" is sensitive and needs zeroized */
21832         if (e != NULL)
21833             ForceZero(e, sizeof(sp_digit) * 78U);
21834     #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
21835         XFREE(b, NULL, DYNAMIC_TYPE_DH);
21836     #endif
21837     }
21838 
21839     return err;
21840 }
21841 #endif /* WOLFSSL_HAVE_SP_DH */
21842 
21843 #endif /* WOLFSSL_HAVE_SP_DH | (WOLFSSL_HAVE_SP_RSA & !WOLFSSL_RSA_PUBLIC_ONLY) */
21844 
21845 #endif /* WOLFSSL_SP_SMALL */
21846 #endif /* WOLFSSL_SP_4096 */
21847 
21848 #endif /* WOLFSSL_HAVE_SP_RSA | WOLFSSL_HAVE_SP_DH */
21849 #ifdef WOLFSSL_HAVE_SP_ECC
21850 #ifndef WOLFSSL_SP_NO_256
21851 
21852 /* Point structure to use. */
21853 typedef struct sp_point_256 {
21854     /* X ordinate of point. */
21855     sp_digit x[2 * 5];
21856     /* Y ordinate of point. */
21857     sp_digit y[2 * 5];
21858     /* Z ordinate of point. */
21859     sp_digit z[2 * 5];
21860     /* Indicates point is at infinity. */
21861     int infinity;
21862 } sp_point_256;
21863 
21864 /* The modulus (prime) of the curve P256. */
21865 static const sp_digit p256_mod[5] = {
21866     0xfffffffffffffL,0x00fffffffffffL,0x0000000000000L,0x0001000000000L,
21867     0x0ffffffff0000L
21868 };
21869 /* The Montgomery normalizer for modulus of the curve P256. */
21870 static const sp_digit p256_norm_mod[5] = {
21871     0x0000000000001L,0xff00000000000L,0xfffffffffffffL,0xfffefffffffffL,
21872     0x000000000ffffL
21873 };
21874 /* The Montgomery multiplier for modulus of the curve P256. */
21875 static const sp_digit p256_mp_mod = 0x0000000000001;
21876 #if defined(WOLFSSL_VALIDATE_ECC_KEYGEN) || defined(HAVE_ECC_SIGN) || \
21877                                             defined(HAVE_ECC_VERIFY)
21878 /* The order of the curve P256. */
21879 static const sp_digit p256_order[5] = {
21880     0x9cac2fc632551L,0xada7179e84f3bL,0xfffffffbce6faL,0x0000fffffffffL,
21881     0x0ffffffff0000L
21882 };
21883 #endif
21884 /* The order of the curve P256 minus 2. */
21885 static const sp_digit p256_order2[5] = {
21886     0x9cac2fc63254fL,0xada7179e84f3bL,0xfffffffbce6faL,0x0000fffffffffL,
21887     0x0ffffffff0000L
21888 };
21889 #if defined(HAVE_ECC_SIGN) || defined(HAVE_ECC_VERIFY)
21890 /* The Montgomery normalizer for order of the curve P256. */
21891 static const sp_digit p256_norm_order[5] = {
21892     0x6353d039cdaafL,0x5258e8617b0c4L,0x0000000431905L,0xffff000000000L,
21893     0x000000000ffffL
21894 };
21895 #endif
21896 #if defined(HAVE_ECC_SIGN) || defined(HAVE_ECC_VERIFY)
21897 /* The Montgomery multiplier for order of the curve P256. */
21898 static const sp_digit p256_mp_order = 0x1c8aaee00bc4fL;
21899 #endif
21900 /* The base point of curve P256. */
21901 static const sp_point_256 p256_base = {
21902     /* X ordinate */
21903     {
21904         0x13945d898c296L,0x812deb33a0f4aL,0x3a440f277037dL,0x4247f8bce6e56L,
21905         0x06b17d1f2e12cL,
21906         (sp_digit)0, (sp_digit)0, (sp_digit)0, (sp_digit)0, (sp_digit)0
21907     },
21908     /* Y ordinate */
21909     {
21910         0x6406837bf51f5L,0x576b315ececbbL,0xc0f9e162bce33L,0x7f9b8ee7eb4a7L,
21911         0x04fe342e2fe1aL,
21912         (sp_digit)0, (sp_digit)0, (sp_digit)0, (sp_digit)0, (sp_digit)0
21913     },
21914     /* Z ordinate */
21915     {
21916         0x0000000000001L,0x0000000000000L,0x0000000000000L,0x0000000000000L,
21917         0x0000000000000L,
21918         (sp_digit)0, (sp_digit)0, (sp_digit)0, (sp_digit)0, (sp_digit)0
21919     },
21920     /* infinity */
21921     0
21922 };
21923 #if defined(HAVE_ECC_CHECK_KEY) || defined(HAVE_COMP_KEY)
21924 static const sp_digit p256_b[5] = {
21925     0xe3c3e27d2604bL,0xb0cc53b0f63bcL,0x69886bc651d06L,0x93e7b3ebbd557L,
21926     0x05ac635d8aa3aL
21927 };
21928 #endif
21929 
21930 #ifdef WOLFSSL_SP_SMALL
21931 /* Multiply a and b into r. (r = a * b)
21932  *
21933  * r  A single precision integer.
21934  * a  A single precision integer.
21935  * b  A single precision integer.
21936  */
sp_256_mul_5(sp_digit * r,const sp_digit * a,const sp_digit * b)21937 SP_NOINLINE static void sp_256_mul_5(sp_digit* r, const sp_digit* a,
21938     const sp_digit* b)
21939 {
21940     int i;
21941     int imax;
21942     int k;
21943     sp_uint128 c;
21944     sp_uint128 lo;
21945 
21946     c = ((sp_uint128)a[4]) * b[4];
21947     r[9] = (sp_digit)(c >> 52);
21948     c &= 0xfffffffffffffL;
21949     for (k = 7; k >= 0; k--) {
21950         if (k >= 5) {
21951             i = k - 4;
21952             imax = 4;
21953         }
21954         else {
21955             i = 0;
21956             imax = k;
21957         }
21958         lo = 0;
21959         for (; i <= imax; i++) {
21960             lo += ((sp_uint128)a[i]) * b[k - i];
21961         }
21962         c += lo >> 52;
21963         r[k + 2] += (sp_digit)(c >> 52);
21964         r[k + 1]  = (sp_digit)(c & 0xfffffffffffffL);
21965         c = lo & 0xfffffffffffffL;
21966     }
21967     r[0] = (sp_digit)c;
21968 }
21969 
21970 #else
21971 /* Multiply a and b into r. (r = a * b)
21972  *
21973  * r  A single precision integer.
21974  * a  A single precision integer.
21975  * b  A single precision integer.
21976  */
sp_256_mul_5(sp_digit * r,const sp_digit * a,const sp_digit * b)21977 SP_NOINLINE static void sp_256_mul_5(sp_digit* r, const sp_digit* a,
21978     const sp_digit* b)
21979 {
21980     sp_int128 t0   = ((sp_int128)a[ 0]) * b[ 0];
21981     sp_int128 t1   = ((sp_int128)a[ 0]) * b[ 1]
21982                  + ((sp_int128)a[ 1]) * b[ 0];
21983     sp_int128 t2   = ((sp_int128)a[ 0]) * b[ 2]
21984                  + ((sp_int128)a[ 1]) * b[ 1]
21985                  + ((sp_int128)a[ 2]) * b[ 0];
21986     sp_int128 t3   = ((sp_int128)a[ 0]) * b[ 3]
21987                  + ((sp_int128)a[ 1]) * b[ 2]
21988                  + ((sp_int128)a[ 2]) * b[ 1]
21989                  + ((sp_int128)a[ 3]) * b[ 0];
21990     sp_int128 t4   = ((sp_int128)a[ 0]) * b[ 4]
21991                  + ((sp_int128)a[ 1]) * b[ 3]
21992                  + ((sp_int128)a[ 2]) * b[ 2]
21993                  + ((sp_int128)a[ 3]) * b[ 1]
21994                  + ((sp_int128)a[ 4]) * b[ 0];
21995     sp_int128 t5   = ((sp_int128)a[ 1]) * b[ 4]
21996                  + ((sp_int128)a[ 2]) * b[ 3]
21997                  + ((sp_int128)a[ 3]) * b[ 2]
21998                  + ((sp_int128)a[ 4]) * b[ 1];
21999     sp_int128 t6   = ((sp_int128)a[ 2]) * b[ 4]
22000                  + ((sp_int128)a[ 3]) * b[ 3]
22001                  + ((sp_int128)a[ 4]) * b[ 2];
22002     sp_int128 t7   = ((sp_int128)a[ 3]) * b[ 4]
22003                  + ((sp_int128)a[ 4]) * b[ 3];
22004     sp_int128 t8   = ((sp_int128)a[ 4]) * b[ 4];
22005 
22006     t1   += t0  >> 52; r[ 0] = t0  & 0xfffffffffffffL;
22007     t2   += t1  >> 52; r[ 1] = t1  & 0xfffffffffffffL;
22008     t3   += t2  >> 52; r[ 2] = t2  & 0xfffffffffffffL;
22009     t4   += t3  >> 52; r[ 3] = t3  & 0xfffffffffffffL;
22010     t5   += t4  >> 52; r[ 4] = t4  & 0xfffffffffffffL;
22011     t6   += t5  >> 52; r[ 5] = t5  & 0xfffffffffffffL;
22012     t7   += t6  >> 52; r[ 6] = t6  & 0xfffffffffffffL;
22013     t8   += t7  >> 52; r[ 7] = t7  & 0xfffffffffffffL;
22014     r[9] = (sp_digit)(t8 >> 52);
22015                        r[8] = t8 & 0xfffffffffffffL;
22016 }
22017 
22018 #endif /* WOLFSSL_SP_SMALL */
22019 #ifdef WOLFSSL_SP_SMALL
22020 /* Square a and put result in r. (r = a * a)
22021  *
22022  * r  A single precision integer.
22023  * a  A single precision integer.
22024  */
sp_256_sqr_5(sp_digit * r,const sp_digit * a)22025 SP_NOINLINE static void sp_256_sqr_5(sp_digit* r, const sp_digit* a)
22026 {
22027     int i;
22028     int imax;
22029     int k;
22030     sp_uint128 c;
22031     sp_uint128 t;
22032 
22033     c = ((sp_uint128)a[4]) * a[4];
22034     r[9] = (sp_digit)(c >> 52);
22035     c = (c & 0xfffffffffffffL) << 52;
22036     for (k = 7; k >= 0; k--) {
22037         i = (k + 1) / 2;
22038         if ((k & 1) == 0) {
22039            c += ((sp_uint128)a[i]) * a[i];
22040            i++;
22041         }
22042         if (k < 4) {
22043             imax = k;
22044         }
22045         else {
22046             imax = 4;
22047         }
22048         t = 0;
22049         for (; i <= imax; i++) {
22050             t += ((sp_uint128)a[i]) * a[k - i];
22051         }
22052         c += t * 2;
22053 
22054         r[k + 2] += (sp_digit) (c >> 104);
22055         r[k + 1]  = (sp_digit)((c >> 52) & 0xfffffffffffffL);
22056         c = (c & 0xfffffffffffffL) << 52;
22057     }
22058     r[0] = (sp_digit)(c >> 52);
22059 }
22060 
22061 #else
22062 /* Square a and put result in r. (r = a * a)
22063  *
22064  * r  A single precision integer.
22065  * a  A single precision integer.
22066  */
sp_256_sqr_5(sp_digit * r,const sp_digit * a)22067 SP_NOINLINE static void sp_256_sqr_5(sp_digit* r, const sp_digit* a)
22068 {
22069     sp_int128 t0   =  ((sp_int128)a[ 0]) * a[ 0];
22070     sp_int128 t1   = (((sp_int128)a[ 0]) * a[ 1]) * 2;
22071     sp_int128 t2   = (((sp_int128)a[ 0]) * a[ 2]) * 2
22072                  +  ((sp_int128)a[ 1]) * a[ 1];
22073     sp_int128 t3   = (((sp_int128)a[ 0]) * a[ 3]
22074                  +  ((sp_int128)a[ 1]) * a[ 2]) * 2;
22075     sp_int128 t4   = (((sp_int128)a[ 0]) * a[ 4]
22076                  +  ((sp_int128)a[ 1]) * a[ 3]) * 2
22077                  +  ((sp_int128)a[ 2]) * a[ 2];
22078     sp_int128 t5   = (((sp_int128)a[ 1]) * a[ 4]
22079                  +  ((sp_int128)a[ 2]) * a[ 3]) * 2;
22080     sp_int128 t6   = (((sp_int128)a[ 2]) * a[ 4]) * 2
22081                  +  ((sp_int128)a[ 3]) * a[ 3];
22082     sp_int128 t7   = (((sp_int128)a[ 3]) * a[ 4]) * 2;
22083     sp_int128 t8   =  ((sp_int128)a[ 4]) * a[ 4];
22084 
22085     t1   += t0  >> 52; r[ 0] = t0  & 0xfffffffffffffL;
22086     t2   += t1  >> 52; r[ 1] = t1  & 0xfffffffffffffL;
22087     t3   += t2  >> 52; r[ 2] = t2  & 0xfffffffffffffL;
22088     t4   += t3  >> 52; r[ 3] = t3  & 0xfffffffffffffL;
22089     t5   += t4  >> 52; r[ 4] = t4  & 0xfffffffffffffL;
22090     t6   += t5  >> 52; r[ 5] = t5  & 0xfffffffffffffL;
22091     t7   += t6  >> 52; r[ 6] = t6  & 0xfffffffffffffL;
22092     t8   += t7  >> 52; r[ 7] = t7  & 0xfffffffffffffL;
22093     r[9] = (sp_digit)(t8 >> 52);
22094                        r[8] = t8 & 0xfffffffffffffL;
22095 }
22096 
22097 #endif /* WOLFSSL_SP_SMALL */
22098 #ifdef WOLFSSL_SP_SMALL
22099 /* Add b to a into r. (r = a + b)
22100  *
22101  * r  A single precision integer.
22102  * a  A single precision integer.
22103  * b  A single precision integer.
22104  */
sp_256_add_5(sp_digit * r,const sp_digit * a,const sp_digit * b)22105 SP_NOINLINE static int sp_256_add_5(sp_digit* r, const sp_digit* a,
22106         const sp_digit* b)
22107 {
22108     int i;
22109 
22110     for (i = 0; i < 5; i++) {
22111         r[i] = a[i] + b[i];
22112     }
22113 
22114     return 0;
22115 }
22116 #else
22117 /* Add b to a into r. (r = a + b)
22118  *
22119  * r  A single precision integer.
22120  * a  A single precision integer.
22121  * b  A single precision integer.
22122  */
sp_256_add_5(sp_digit * r,const sp_digit * a,const sp_digit * b)22123 SP_NOINLINE static int sp_256_add_5(sp_digit* r, const sp_digit* a,
22124         const sp_digit* b)
22125 {
22126     r[ 0] = a[ 0] + b[ 0];
22127     r[ 1] = a[ 1] + b[ 1];
22128     r[ 2] = a[ 2] + b[ 2];
22129     r[ 3] = a[ 3] + b[ 3];
22130     r[ 4] = a[ 4] + b[ 4];
22131 
22132     return 0;
22133 }
22134 
22135 #endif /* WOLFSSL_SP_SMALL */
22136 #ifdef WOLFSSL_SP_SMALL
22137 /* Sub b from a into r. (r = a - b)
22138  *
22139  * r  A single precision integer.
22140  * a  A single precision integer.
22141  * b  A single precision integer.
22142  */
sp_256_sub_5(sp_digit * r,const sp_digit * a,const sp_digit * b)22143 SP_NOINLINE static int sp_256_sub_5(sp_digit* r, const sp_digit* a,
22144         const sp_digit* b)
22145 {
22146     int i;
22147 
22148     for (i = 0; i < 5; i++) {
22149         r[i] = a[i] - b[i];
22150     }
22151 
22152     return 0;
22153 }
22154 
22155 #else
22156 /* Sub b from a into r. (r = a - b)
22157  *
22158  * r  A single precision integer.
22159  * a  A single precision integer.
22160  * b  A single precision integer.
22161  */
sp_256_sub_5(sp_digit * r,const sp_digit * a,const sp_digit * b)22162 SP_NOINLINE static int sp_256_sub_5(sp_digit* r, const sp_digit* a,
22163         const sp_digit* b)
22164 {
22165     r[ 0] = a[ 0] - b[ 0];
22166     r[ 1] = a[ 1] - b[ 1];
22167     r[ 2] = a[ 2] - b[ 2];
22168     r[ 3] = a[ 3] - b[ 3];
22169     r[ 4] = a[ 4] - b[ 4];
22170 
22171     return 0;
22172 }
22173 
22174 #endif /* WOLFSSL_SP_SMALL */
22175 /* Convert an mp_int to an array of sp_digit.
22176  *
22177  * r  A single precision integer.
22178  * size  Maximum number of bytes to convert
22179  * a  A multi-precision integer.
22180  */
sp_256_from_mp(sp_digit * r,int size,const mp_int * a)22181 static void sp_256_from_mp(sp_digit* r, int size, const mp_int* a)
22182 {
22183 #if DIGIT_BIT == 52
22184     int j;
22185 
22186     XMEMCPY(r, a->dp, sizeof(sp_digit) * a->used);
22187 
22188     for (j = a->used; j < size; j++) {
22189         r[j] = 0;
22190     }
22191 #elif DIGIT_BIT > 52
22192     int i;
22193     int j = 0;
22194     word32 s = 0;
22195 
22196     r[0] = 0;
22197     for (i = 0; i < a->used && j < size; i++) {
22198         r[j] |= ((sp_digit)a->dp[i] << s);
22199         r[j] &= 0xfffffffffffffL;
22200         s = 52U - s;
22201         if (j + 1 >= size) {
22202             break;
22203         }
22204         /* lint allow cast of mismatch word32 and mp_digit */
22205         r[++j] = (sp_digit)(a->dp[i] >> s); /*lint !e9033*/
22206         while ((s + 52U) <= (word32)DIGIT_BIT) {
22207             s += 52U;
22208             r[j] &= 0xfffffffffffffL;
22209             if (j + 1 >= size) {
22210                 break;
22211             }
22212             if (s < (word32)DIGIT_BIT) {
22213                 /* lint allow cast of mismatch word32 and mp_digit */
22214                 r[++j] = (sp_digit)(a->dp[i] >> s); /*lint !e9033*/
22215             }
22216             else {
22217                 r[++j] = (sp_digit)0;
22218             }
22219         }
22220         s = (word32)DIGIT_BIT - s;
22221     }
22222 
22223     for (j++; j < size; j++) {
22224         r[j] = 0;
22225     }
22226 #else
22227     int i;
22228     int j = 0;
22229     int s = 0;
22230 
22231     r[0] = 0;
22232     for (i = 0; i < a->used && j < size; i++) {
22233         r[j] |= ((sp_digit)a->dp[i]) << s;
22234         if (s + DIGIT_BIT >= 52) {
22235             r[j] &= 0xfffffffffffffL;
22236             if (j + 1 >= size) {
22237                 break;
22238             }
22239             s = 52 - s;
22240             if (s == DIGIT_BIT) {
22241                 r[++j] = 0;
22242                 s = 0;
22243             }
22244             else {
22245                 r[++j] = a->dp[i] >> s;
22246                 s = DIGIT_BIT - s;
22247             }
22248         }
22249         else {
22250             s += DIGIT_BIT;
22251         }
22252     }
22253 
22254     for (j++; j < size; j++) {
22255         r[j] = 0;
22256     }
22257 #endif
22258 }
22259 
22260 /* Convert a point of type ecc_point to type sp_point_256.
22261  *
22262  * p   Point of type sp_point_256 (result).
22263  * pm  Point of type ecc_point.
22264  */
sp_256_point_from_ecc_point_5(sp_point_256 * p,const ecc_point * pm)22265 static void sp_256_point_from_ecc_point_5(sp_point_256* p,
22266         const ecc_point* pm)
22267 {
22268     XMEMSET(p->x, 0, sizeof(p->x));
22269     XMEMSET(p->y, 0, sizeof(p->y));
22270     XMEMSET(p->z, 0, sizeof(p->z));
22271     sp_256_from_mp(p->x, 5, pm->x);
22272     sp_256_from_mp(p->y, 5, pm->y);
22273     sp_256_from_mp(p->z, 5, pm->z);
22274     p->infinity = 0;
22275 }
22276 
22277 /* Convert an array of sp_digit to an mp_int.
22278  *
22279  * a  A single precision integer.
22280  * r  A multi-precision integer.
22281  */
sp_256_to_mp(const sp_digit * a,mp_int * r)22282 static int sp_256_to_mp(const sp_digit* a, mp_int* r)
22283 {
22284     int err;
22285 
22286     err = mp_grow(r, (256 + DIGIT_BIT - 1) / DIGIT_BIT);
22287     if (err == MP_OKAY) { /*lint !e774 case where err is always MP_OKAY*/
22288 #if DIGIT_BIT == 52
22289         XMEMCPY(r->dp, a, sizeof(sp_digit) * 5);
22290         r->used = 5;
22291         mp_clamp(r);
22292 #elif DIGIT_BIT < 52
22293         int i;
22294         int j = 0;
22295         int s = 0;
22296 
22297         r->dp[0] = 0;
22298         for (i = 0; i < 5; i++) {
22299             r->dp[j] |= (mp_digit)(a[i] << s);
22300             r->dp[j] &= ((sp_digit)1 << DIGIT_BIT) - 1;
22301             s = DIGIT_BIT - s;
22302             r->dp[++j] = (mp_digit)(a[i] >> s);
22303             while (s + DIGIT_BIT <= 52) {
22304                 s += DIGIT_BIT;
22305                 r->dp[j++] &= ((sp_digit)1 << DIGIT_BIT) - 1;
22306                 if (s == SP_WORD_SIZE) {
22307                     r->dp[j] = 0;
22308                 }
22309                 else {
22310                     r->dp[j] = (mp_digit)(a[i] >> s);
22311                 }
22312             }
22313             s = 52 - s;
22314         }
22315         r->used = (256 + DIGIT_BIT - 1) / DIGIT_BIT;
22316         mp_clamp(r);
22317 #else
22318         int i;
22319         int j = 0;
22320         int s = 0;
22321 
22322         r->dp[0] = 0;
22323         for (i = 0; i < 5; i++) {
22324             r->dp[j] |= ((mp_digit)a[i]) << s;
22325             if (s + 52 >= DIGIT_BIT) {
22326     #if DIGIT_BIT != 32 && DIGIT_BIT != 64
22327                 r->dp[j] &= ((sp_digit)1 << DIGIT_BIT) - 1;
22328     #endif
22329                 s = DIGIT_BIT - s;
22330                 r->dp[++j] = a[i] >> s;
22331                 s = 52 - s;
22332             }
22333             else {
22334                 s += 52;
22335             }
22336         }
22337         r->used = (256 + DIGIT_BIT - 1) / DIGIT_BIT;
22338         mp_clamp(r);
22339 #endif
22340     }
22341 
22342     return err;
22343 }
22344 
22345 /* Convert a point of type sp_point_256 to type ecc_point.
22346  *
22347  * p   Point of type sp_point_256.
22348  * pm  Point of type ecc_point (result).
22349  * returns MEMORY_E when allocation of memory in ecc_point fails otherwise
22350  * MP_OKAY.
22351  */
sp_256_point_to_ecc_point_5(const sp_point_256 * p,ecc_point * pm)22352 static int sp_256_point_to_ecc_point_5(const sp_point_256* p, ecc_point* pm)
22353 {
22354     int err;
22355 
22356     err = sp_256_to_mp(p->x, pm->x);
22357     if (err == MP_OKAY) {
22358         err = sp_256_to_mp(p->y, pm->y);
22359     }
22360     if (err == MP_OKAY) {
22361         err = sp_256_to_mp(p->z, pm->z);
22362     }
22363 
22364     return err;
22365 }
22366 
22367 /* Compare a with b in constant time.
22368  *
22369  * a  A single precision integer.
22370  * b  A single precision integer.
22371  * return -ve, 0 or +ve if a is less than, equal to or greater than b
22372  * respectively.
22373  */
sp_256_cmp_5(const sp_digit * a,const sp_digit * b)22374 static sp_digit sp_256_cmp_5(const sp_digit* a, const sp_digit* b)
22375 {
22376     sp_digit r = 0;
22377 #ifdef WOLFSSL_SP_SMALL
22378     int i;
22379 
22380     for (i=4; i>=0; i--) {
22381         r |= (a[i] - b[i]) & (0 - (sp_digit)((r == 0) ? 1 : 0));
22382     }
22383 #else
22384     r |= (a[ 4] - b[ 4]) & (0 - (sp_digit)1);
22385     r |= (a[ 3] - b[ 3]) & (0 - (sp_digit)((r == 0) ? 1 : 0));
22386     r |= (a[ 2] - b[ 2]) & (0 - (sp_digit)((r == 0) ? 1 : 0));
22387     r |= (a[ 1] - b[ 1]) & (0 - (sp_digit)((r == 0) ? 1 : 0));
22388     r |= (a[ 0] - b[ 0]) & (0 - (sp_digit)((r == 0) ? 1 : 0));
22389 #endif /* WOLFSSL_SP_SMALL */
22390 
22391     return r;
22392 }
22393 
22394 /* Conditionally subtract b from a using the mask m.
22395  * m is -1 to subtract and 0 when not.
22396  *
22397  * r  A single precision number representing condition subtract result.
22398  * a  A single precision number to subtract from.
22399  * b  A single precision number to subtract.
22400  * m  Mask value to apply.
22401  */
sp_256_cond_sub_5(sp_digit * r,const sp_digit * a,const sp_digit * b,const sp_digit m)22402 static void sp_256_cond_sub_5(sp_digit* r, const sp_digit* a,
22403         const sp_digit* b, const sp_digit m)
22404 {
22405 #ifdef WOLFSSL_SP_SMALL
22406     int i;
22407 
22408     for (i = 0; i < 5; i++) {
22409         r[i] = a[i] - (b[i] & m);
22410     }
22411 #else
22412     r[ 0] = a[ 0] - (b[ 0] & m);
22413     r[ 1] = a[ 1] - (b[ 1] & m);
22414     r[ 2] = a[ 2] - (b[ 2] & m);
22415     r[ 3] = a[ 3] - (b[ 3] & m);
22416     r[ 4] = a[ 4] - (b[ 4] & m);
22417 #endif /* WOLFSSL_SP_SMALL */
22418 }
22419 
22420 /* Mul a by scalar b and add into r. (r += a * b)
22421  *
22422  * r  A single precision integer.
22423  * a  A single precision integer.
22424  * b  A scalar.
22425  */
sp_256_mul_add_5(sp_digit * r,const sp_digit * a,const sp_digit b)22426 SP_NOINLINE static void sp_256_mul_add_5(sp_digit* r, const sp_digit* a,
22427         const sp_digit b)
22428 {
22429 #ifdef WOLFSSL_SP_SMALL
22430     sp_int128 tb = b;
22431     sp_int128 t[4];
22432     int i;
22433 
22434     t[0] = 0;
22435     for (i = 0; i < 4; i += 4) {
22436         t[0] += (tb * a[i+0]) + r[i+0];
22437         t[1]  = (tb * a[i+1]) + r[i+1];
22438         t[2]  = (tb * a[i+2]) + r[i+2];
22439         t[3]  = (tb * a[i+3]) + r[i+3];
22440         r[i+0] = t[0] & 0xfffffffffffffL;
22441         t[1] += t[0] >> 52;
22442         r[i+1] = t[1] & 0xfffffffffffffL;
22443         t[2] += t[1] >> 52;
22444         r[i+2] = t[2] & 0xfffffffffffffL;
22445         t[3] += t[2] >> 52;
22446         r[i+3] = t[3] & 0xfffffffffffffL;
22447         t[0]  = t[3] >> 52;
22448     }
22449     t[0] += (tb * a[4]) + r[4];
22450     r[4] = t[0] & 0xfffffffffffffL;
22451     r[5] +=  (sp_digit)(t[0] >> 52);
22452 #else
22453     sp_int128 tb = b;
22454     sp_int128 t[5];
22455 
22456     t[ 0] = tb * a[ 0];
22457     t[ 1] = tb * a[ 1];
22458     t[ 2] = tb * a[ 2];
22459     t[ 3] = tb * a[ 3];
22460     t[ 4] = tb * a[ 4];
22461     r[ 0] += (sp_digit)                 (t[ 0] & 0xfffffffffffffL);
22462     r[ 1] += (sp_digit)((t[ 0] >> 52) + (t[ 1] & 0xfffffffffffffL));
22463     r[ 2] += (sp_digit)((t[ 1] >> 52) + (t[ 2] & 0xfffffffffffffL));
22464     r[ 3] += (sp_digit)((t[ 2] >> 52) + (t[ 3] & 0xfffffffffffffL));
22465     r[ 4] += (sp_digit)((t[ 3] >> 52) + (t[ 4] & 0xfffffffffffffL));
22466     r[ 5] += (sp_digit) (t[ 4] >> 52);
22467 #endif /* WOLFSSL_SP_SMALL */
22468 }
22469 
22470 /* Normalize the values in each word to 52 bits.
22471  *
22472  * a  Array of sp_digit to normalize.
22473  */
sp_256_norm_5(sp_digit * a)22474 static void sp_256_norm_5(sp_digit* a)
22475 {
22476 #ifdef WOLFSSL_SP_SMALL
22477     int i;
22478     for (i = 0; i < 4; i++) {
22479         a[i+1] += a[i] >> 52;
22480         a[i] &= 0xfffffffffffffL;
22481     }
22482 #else
22483     a[1] += a[0] >> 52; a[0] &= 0xfffffffffffffL;
22484     a[2] += a[1] >> 52; a[1] &= 0xfffffffffffffL;
22485     a[3] += a[2] >> 52; a[2] &= 0xfffffffffffffL;
22486     a[4] += a[3] >> 52; a[3] &= 0xfffffffffffffL;
22487 #endif /* WOLFSSL_SP_SMALL */
22488 }
22489 
22490 /* Shift the result in the high 256 bits down to the bottom.
22491  *
22492  * r  A single precision number.
22493  * a  A single precision number.
22494  */
sp_256_mont_shift_5(sp_digit * r,const sp_digit * a)22495 static void sp_256_mont_shift_5(sp_digit* r, const sp_digit* a)
22496 {
22497 #ifdef WOLFSSL_SP_SMALL
22498     int i;
22499     sp_uint64 n;
22500 
22501     n = a[4] >> 48;
22502     for (i = 0; i < 4; i++) {
22503         n += (sp_uint64)a[5 + i] << 4;
22504         r[i] = n & 0xfffffffffffffL;
22505         n >>= 52;
22506     }
22507     n += (sp_uint64)a[9] << 4;
22508     r[4] = n;
22509 #else
22510     sp_uint64 n;
22511 
22512     n  = a[4] >> 48;
22513     n += (sp_uint64)a[ 5] << 4U; r[ 0] = n & 0xfffffffffffffUL; n >>= 52U;
22514     n += (sp_uint64)a[ 6] << 4U; r[ 1] = n & 0xfffffffffffffUL; n >>= 52U;
22515     n += (sp_uint64)a[ 7] << 4U; r[ 2] = n & 0xfffffffffffffUL; n >>= 52U;
22516     n += (sp_uint64)a[ 8] << 4U; r[ 3] = n & 0xfffffffffffffUL; n >>= 52U;
22517     n += (sp_uint64)a[ 9] << 4U; r[ 4] = n;
22518 #endif /* WOLFSSL_SP_SMALL */
22519     XMEMSET(&r[5], 0, sizeof(*r) * 5U);
22520 }
22521 
22522 /* Reduce the number back to 256 bits using Montgomery reduction.
22523  *
22524  * a   A single precision number to reduce in place.
22525  * m   The single precision number representing the modulus.
22526  * mp  The digit representing the negative inverse of m mod 2^n.
22527  */
sp_256_mont_reduce_order_5(sp_digit * a,const sp_digit * m,sp_digit mp)22528 static void sp_256_mont_reduce_order_5(sp_digit* a, const sp_digit* m, sp_digit mp)
22529 {
22530     int i;
22531     sp_digit mu;
22532 
22533     sp_256_norm_5(a + 5);
22534 
22535     for (i=0; i<4; i++) {
22536         mu = (a[i] * mp) & 0xfffffffffffffL;
22537         sp_256_mul_add_5(a+i, m, mu);
22538         a[i+1] += a[i] >> 52;
22539     }
22540     mu = (a[i] * mp) & 0xffffffffffffL;
22541     sp_256_mul_add_5(a+i, m, mu);
22542     a[i+1] += a[i] >> 52;
22543     a[i] &= 0xfffffffffffffL;
22544     sp_256_mont_shift_5(a, a);
22545     sp_256_cond_sub_5(a, a, m, 0 - (((a[4] >> 48) > 0) ?
22546             (sp_digit)1 : (sp_digit)0));
22547     sp_256_norm_5(a);
22548 }
22549 
22550 /* Reduce the number back to 256 bits using Montgomery reduction.
22551  *
22552  * a   A single precision number to reduce in place.
22553  * m   The single precision number representing the modulus.
22554  * mp  The digit representing the negative inverse of m mod 2^n.
22555  */
sp_256_mont_reduce_5(sp_digit * a,const sp_digit * m,sp_digit mp)22556 static void sp_256_mont_reduce_5(sp_digit* a, const sp_digit* m, sp_digit mp)
22557 {
22558     int i;
22559     sp_int128 t;
22560     sp_digit am;
22561 
22562     (void)m;
22563     (void)mp;
22564 
22565     for (i = 0; i < 4; i++) {
22566         am = a[i] & 0xfffffffffffffL;
22567         /* Fifth word of modulus word */
22568         t = am; t *= 0x0ffffffff0000L;
22569 
22570         a[i+1] += (am << 44) & 0xfffffffffffffL;
22571         a[i+2] += am >> 8;
22572         a[i+3] += (am << 36) & 0xfffffffffffffL;
22573         a[i+4] += (am >> 16) + (t & 0xfffffffffffffL);
22574         a[i+5] +=  t >> 52;
22575 
22576         a[i+1] += a[i] >> 52;
22577     }
22578     am = a[4] & 0xffffffffffff;
22579     /* Fifth word of modulus word */
22580     t = am; t *= 0x0ffffffff0000L;
22581 
22582     a[4+1] += (am << 44) & 0xfffffffffffffL;
22583     a[4+2] += am >> 8;
22584     a[4+3] += (am << 36) & 0xfffffffffffffL;
22585     a[4+4] += (am >> 16) + (t & 0xfffffffffffffL);
22586     a[4+5] +=  t >> 52;
22587 
22588     a[0] = (a[4] >> 48) + ((a[5] << 4) & 0xfffffffffffffL);
22589     a[1] = (a[5] >> 48) + ((a[6] << 4) & 0xfffffffffffffL);
22590     a[2] = (a[6] >> 48) + ((a[7] << 4) & 0xfffffffffffffL);
22591     a[3] = (a[7] >> 48) + ((a[8] << 4) & 0xfffffffffffffL);
22592     a[4] = (a[8] >> 48) +  (a[9] << 4);
22593 
22594     /* Get the bit over, if any. */
22595     am = a[4] >> 48;
22596     /* Create mask. */
22597     am = 0 - am;
22598 
22599     a[0] -= 0x000fffffffffffffL & am;
22600     a[1] -= 0x00000fffffffffffL & am;
22601     /* p256_mod[2] is zero */
22602     a[3] -= 0x0000001000000000L & am;
22603     a[4] -= 0x0000ffffffff0000L & am;
22604 
22605     sp_256_norm_5(a);
22606 }
22607 
22608 /* Multiply two Montgomery form numbers mod the modulus (prime).
22609  * (r = a * b mod m)
22610  *
22611  * r   Result of multiplication.
22612  * a   First number to multiply in Montgomery form.
22613  * b   Second number to multiply in Montgomery form.
22614  * m   Modulus (prime).
22615  * mp  Montgomery mulitplier.
22616  */
sp_256_mont_mul_5(sp_digit * r,const sp_digit * a,const sp_digit * b,const sp_digit * m,sp_digit mp)22617 static void sp_256_mont_mul_5(sp_digit* r, const sp_digit* a,
22618         const sp_digit* b, const sp_digit* m, sp_digit mp)
22619 {
22620     sp_256_mul_5(r, a, b);
22621     sp_256_mont_reduce_5(r, m, mp);
22622 }
22623 
22624 /* Square the Montgomery form number. (r = a * a mod m)
22625  *
22626  * r   Result of squaring.
22627  * a   Number to square in Montgomery form.
22628  * m   Modulus (prime).
22629  * mp  Montgomery mulitplier.
22630  */
sp_256_mont_sqr_5(sp_digit * r,const sp_digit * a,const sp_digit * m,sp_digit mp)22631 static void sp_256_mont_sqr_5(sp_digit* r, const sp_digit* a,
22632         const sp_digit* m, sp_digit mp)
22633 {
22634     sp_256_sqr_5(r, a);
22635     sp_256_mont_reduce_5(r, m, mp);
22636 }
22637 
22638 #if !defined(WOLFSSL_SP_SMALL) || defined(HAVE_COMP_KEY)
22639 /* Square the Montgomery form number a number of times. (r = a ^ n mod m)
22640  *
22641  * r   Result of squaring.
22642  * a   Number to square in Montgomery form.
22643  * n   Number of times to square.
22644  * m   Modulus (prime).
22645  * mp  Montgomery mulitplier.
22646  */
sp_256_mont_sqr_n_5(sp_digit * r,const sp_digit * a,int n,const sp_digit * m,sp_digit mp)22647 static void sp_256_mont_sqr_n_5(sp_digit* r, const sp_digit* a, int n,
22648         const sp_digit* m, sp_digit mp)
22649 {
22650     sp_256_mont_sqr_5(r, a, m, mp);
22651     for (; n > 1; n--) {
22652         sp_256_mont_sqr_5(r, r, m, mp);
22653     }
22654 }
22655 
22656 #endif /* !WOLFSSL_SP_SMALL | HAVE_COMP_KEY */
22657 #ifdef WOLFSSL_SP_SMALL
22658 /* Mod-2 for the P256 curve. */
22659 static const uint64_t p256_mod_minus_2[4] = {
22660     0xfffffffffffffffdU,0x00000000ffffffffU,0x0000000000000000U,
22661     0xffffffff00000001U
22662 };
22663 #endif /* !WOLFSSL_SP_SMALL */
22664 
22665 /* Invert the number, in Montgomery form, modulo the modulus (prime) of the
22666  * P256 curve. (r = 1 / a mod m)
22667  *
22668  * r   Inverse result.
22669  * a   Number to invert.
22670  * td  Temporary data.
22671  */
sp_256_mont_inv_5(sp_digit * r,const sp_digit * a,sp_digit * td)22672 static void sp_256_mont_inv_5(sp_digit* r, const sp_digit* a, sp_digit* td)
22673 {
22674 #ifdef WOLFSSL_SP_SMALL
22675     sp_digit* t = td;
22676     int i;
22677 
22678     XMEMCPY(t, a, sizeof(sp_digit) * 5);
22679     for (i=254; i>=0; i--) {
22680         sp_256_mont_sqr_5(t, t, p256_mod, p256_mp_mod);
22681         if (p256_mod_minus_2[i / 64] & ((sp_digit)1 << (i % 64)))
22682             sp_256_mont_mul_5(t, t, a, p256_mod, p256_mp_mod);
22683     }
22684     XMEMCPY(r, t, sizeof(sp_digit) * 5);
22685 #else
22686     sp_digit* t1 = td;
22687     sp_digit* t2 = td + 2 * 5;
22688     sp_digit* t3 = td + 4 * 5;
22689     /* 0x2 */
22690     sp_256_mont_sqr_5(t1, a, p256_mod, p256_mp_mod);
22691     /* 0x3 */
22692     sp_256_mont_mul_5(t2, t1, a, p256_mod, p256_mp_mod);
22693     /* 0xc */
22694     sp_256_mont_sqr_n_5(t1, t2, 2, p256_mod, p256_mp_mod);
22695     /* 0xd */
22696     sp_256_mont_mul_5(t3, t1, a, p256_mod, p256_mp_mod);
22697     /* 0xf */
22698     sp_256_mont_mul_5(t2, t2, t1, p256_mod, p256_mp_mod);
22699     /* 0xf0 */
22700     sp_256_mont_sqr_n_5(t1, t2, 4, p256_mod, p256_mp_mod);
22701     /* 0xfd */
22702     sp_256_mont_mul_5(t3, t3, t1, p256_mod, p256_mp_mod);
22703     /* 0xff */
22704     sp_256_mont_mul_5(t2, t2, t1, p256_mod, p256_mp_mod);
22705     /* 0xff00 */
22706     sp_256_mont_sqr_n_5(t1, t2, 8, p256_mod, p256_mp_mod);
22707     /* 0xfffd */
22708     sp_256_mont_mul_5(t3, t3, t1, p256_mod, p256_mp_mod);
22709     /* 0xffff */
22710     sp_256_mont_mul_5(t2, t2, t1, p256_mod, p256_mp_mod);
22711     /* 0xffff0000 */
22712     sp_256_mont_sqr_n_5(t1, t2, 16, p256_mod, p256_mp_mod);
22713     /* 0xfffffffd */
22714     sp_256_mont_mul_5(t3, t3, t1, p256_mod, p256_mp_mod);
22715     /* 0xffffffff */
22716     sp_256_mont_mul_5(t2, t2, t1, p256_mod, p256_mp_mod);
22717     /* 0xffffffff00000000 */
22718     sp_256_mont_sqr_n_5(t1, t2, 32, p256_mod, p256_mp_mod);
22719     /* 0xffffffffffffffff */
22720     sp_256_mont_mul_5(t2, t2, t1, p256_mod, p256_mp_mod);
22721     /* 0xffffffff00000001 */
22722     sp_256_mont_mul_5(r, t1, a, p256_mod, p256_mp_mod);
22723     /* 0xffffffff000000010000000000000000000000000000000000000000 */
22724     sp_256_mont_sqr_n_5(r, r, 160, p256_mod, p256_mp_mod);
22725     /* 0xffffffff00000001000000000000000000000000ffffffffffffffff */
22726     sp_256_mont_mul_5(r, r, t2, p256_mod, p256_mp_mod);
22727     /* 0xffffffff00000001000000000000000000000000ffffffffffffffff00000000 */
22728     sp_256_mont_sqr_n_5(r, r, 32, p256_mod, p256_mp_mod);
22729     /* 0xffffffff00000001000000000000000000000000fffffffffffffffffffffffd */
22730     sp_256_mont_mul_5(r, r, t3, p256_mod, p256_mp_mod);
22731 #endif /* WOLFSSL_SP_SMALL */
22732 }
22733 
22734 /* Map the Montgomery form projective coordinate point to an affine point.
22735  *
22736  * r  Resulting affine coordinate point.
22737  * p  Montgomery form projective coordinate point.
22738  * t  Temporary ordinate data.
22739  */
sp_256_map_5(sp_point_256 * r,const sp_point_256 * p,sp_digit * t)22740 static void sp_256_map_5(sp_point_256* r, const sp_point_256* p,
22741     sp_digit* t)
22742 {
22743     sp_digit* t1 = t;
22744     sp_digit* t2 = t + 2*5;
22745     sp_int64 n;
22746 
22747     sp_256_mont_inv_5(t1, p->z, t + 2*5);
22748 
22749     sp_256_mont_sqr_5(t2, t1, p256_mod, p256_mp_mod);
22750     sp_256_mont_mul_5(t1, t2, t1, p256_mod, p256_mp_mod);
22751 
22752     /* x /= z^2 */
22753     sp_256_mont_mul_5(r->x, p->x, t2, p256_mod, p256_mp_mod);
22754     XMEMSET(r->x + 5, 0, sizeof(r->x) / 2U);
22755     sp_256_mont_reduce_5(r->x, p256_mod, p256_mp_mod);
22756     /* Reduce x to less than modulus */
22757     n = sp_256_cmp_5(r->x, p256_mod);
22758     sp_256_cond_sub_5(r->x, r->x, p256_mod, 0 - ((n >= 0) ?
22759                 (sp_digit)1 : (sp_digit)0));
22760     sp_256_norm_5(r->x);
22761 
22762     /* y /= z^3 */
22763     sp_256_mont_mul_5(r->y, p->y, t1, p256_mod, p256_mp_mod);
22764     XMEMSET(r->y + 5, 0, sizeof(r->y) / 2U);
22765     sp_256_mont_reduce_5(r->y, p256_mod, p256_mp_mod);
22766     /* Reduce y to less than modulus */
22767     n = sp_256_cmp_5(r->y, p256_mod);
22768     sp_256_cond_sub_5(r->y, r->y, p256_mod, 0 - ((n >= 0) ?
22769                 (sp_digit)1 : (sp_digit)0));
22770     sp_256_norm_5(r->y);
22771 
22772     XMEMSET(r->z, 0, sizeof(r->z));
22773     r->z[0] = 1;
22774 
22775 }
22776 
22777 /* Add two Montgomery form numbers (r = a + b % m).
22778  *
22779  * r   Result of addition.
22780  * a   First number to add in Montgomery form.
22781  * b   Second number to add in Montgomery form.
22782  * m   Modulus (prime).
22783  */
sp_256_mont_add_5(sp_digit * r,const sp_digit * a,const sp_digit * b,const sp_digit * m)22784 static void sp_256_mont_add_5(sp_digit* r, const sp_digit* a, const sp_digit* b,
22785         const sp_digit* m)
22786 {
22787     (void)sp_256_add_5(r, a, b);
22788     sp_256_norm_5(r);
22789     sp_256_cond_sub_5(r, r, m, 0 - (((r[4] >> 48) > 0) ?
22790                 (sp_digit)1 : (sp_digit)0));
22791     sp_256_norm_5(r);
22792 }
22793 
22794 /* Double a Montgomery form number (r = a + a % m).
22795  *
22796  * r   Result of doubling.
22797  * a   Number to double in Montgomery form.
22798  * m   Modulus (prime).
22799  */
sp_256_mont_dbl_5(sp_digit * r,const sp_digit * a,const sp_digit * m)22800 static void sp_256_mont_dbl_5(sp_digit* r, const sp_digit* a, const sp_digit* m)
22801 {
22802     (void)sp_256_add_5(r, a, a);
22803     sp_256_norm_5(r);
22804     sp_256_cond_sub_5(r, r, m, 0 - (((r[4] >> 48) > 0) ?
22805                 (sp_digit)1 : (sp_digit)0));
22806     sp_256_norm_5(r);
22807 }
22808 
22809 /* Triple a Montgomery form number (r = a + a + a % m).
22810  *
22811  * r   Result of Tripling.
22812  * a   Number to triple in Montgomery form.
22813  * m   Modulus (prime).
22814  */
sp_256_mont_tpl_5(sp_digit * r,const sp_digit * a,const sp_digit * m)22815 static void sp_256_mont_tpl_5(sp_digit* r, const sp_digit* a, const sp_digit* m)
22816 {
22817     (void)sp_256_add_5(r, a, a);
22818     sp_256_norm_5(r);
22819     sp_256_cond_sub_5(r, r, m, 0 - (((r[4] >> 48) > 0) ?
22820                 (sp_digit)1 : (sp_digit)0));
22821     sp_256_norm_5(r);
22822     (void)sp_256_add_5(r, r, a);
22823     sp_256_norm_5(r);
22824     sp_256_cond_sub_5(r, r, m, 0 - (((r[4] >> 48) > 0) ?
22825                 (sp_digit)1 : (sp_digit)0));
22826     sp_256_norm_5(r);
22827 }
22828 
22829 /* Conditionally add a and b using the mask m.
22830  * m is -1 to add and 0 when not.
22831  *
22832  * r  A single precision number representing conditional add result.
22833  * a  A single precision number to add with.
22834  * b  A single precision number to add.
22835  * m  Mask value to apply.
22836  */
sp_256_cond_add_5(sp_digit * r,const sp_digit * a,const sp_digit * b,const sp_digit m)22837 static void sp_256_cond_add_5(sp_digit* r, const sp_digit* a,
22838         const sp_digit* b, const sp_digit m)
22839 {
22840 #ifdef WOLFSSL_SP_SMALL
22841     int i;
22842 
22843     for (i = 0; i < 5; i++) {
22844         r[i] = a[i] + (b[i] & m);
22845     }
22846 #else
22847     r[ 0] = a[ 0] + (b[ 0] & m);
22848     r[ 1] = a[ 1] + (b[ 1] & m);
22849     r[ 2] = a[ 2] + (b[ 2] & m);
22850     r[ 3] = a[ 3] + (b[ 3] & m);
22851     r[ 4] = a[ 4] + (b[ 4] & m);
22852 #endif /* WOLFSSL_SP_SMALL */
22853 }
22854 
22855 /* Subtract two Montgomery form numbers (r = a - b % m).
22856  *
22857  * r   Result of subtration.
22858  * a   Number to subtract from in Montgomery form.
22859  * b   Number to subtract with in Montgomery form.
22860  * m   Modulus (prime).
22861  */
sp_256_mont_sub_5(sp_digit * r,const sp_digit * a,const sp_digit * b,const sp_digit * m)22862 static void sp_256_mont_sub_5(sp_digit* r, const sp_digit* a, const sp_digit* b,
22863         const sp_digit* m)
22864 {
22865     (void)sp_256_sub_5(r, a, b);
22866     sp_256_norm_5(r);
22867     sp_256_cond_add_5(r, r, m, r[4] >> 48);
22868     sp_256_norm_5(r);
22869 }
22870 
22871 /* Shift number left one bit.
22872  * Bottom bit is lost.
22873  *
22874  * r  Result of shift.
22875  * a  Number to shift.
22876  */
sp_256_rshift1_5(sp_digit * r,const sp_digit * a)22877 SP_NOINLINE static void sp_256_rshift1_5(sp_digit* r, const sp_digit* a)
22878 {
22879 #ifdef WOLFSSL_SP_SMALL
22880     int i;
22881 
22882     for (i=0; i<4; i++) {
22883         r[i] = (a[i] >> 1) + ((a[i + 1] << 51) & 0xfffffffffffffL);
22884     }
22885 #else
22886     r[0] = (a[0] >> 1) + ((a[1] << 51) & 0xfffffffffffffL);
22887     r[1] = (a[1] >> 1) + ((a[2] << 51) & 0xfffffffffffffL);
22888     r[2] = (a[2] >> 1) + ((a[3] << 51) & 0xfffffffffffffL);
22889     r[3] = (a[3] >> 1) + ((a[4] << 51) & 0xfffffffffffffL);
22890 #endif
22891     r[4] = a[4] >> 1;
22892 }
22893 
22894 /* Divide the number by 2 mod the modulus (prime). (r = a / 2 % m)
22895  *
22896  * r  Result of division by 2.
22897  * a  Number to divide.
22898  * m  Modulus (prime).
22899  */
sp_256_div2_5(sp_digit * r,const sp_digit * a,const sp_digit * m)22900 static void sp_256_div2_5(sp_digit* r, const sp_digit* a, const sp_digit* m)
22901 {
22902     sp_256_cond_add_5(r, a, m, 0 - (a[0] & 1));
22903     sp_256_norm_5(r);
22904     sp_256_rshift1_5(r, r);
22905 }
22906 
22907 /* Double the Montgomery form projective point p.
22908  *
22909  * r  Result of doubling point.
22910  * p  Point to double.
22911  * t  Temporary ordinate data.
22912  */
22913 #ifdef WOLFSSL_SP_NONBLOCK
22914 typedef struct sp_256_proj_point_dbl_5_ctx {
22915     int state;
22916     sp_digit* t1;
22917     sp_digit* t2;
22918     sp_digit* x;
22919     sp_digit* y;
22920     sp_digit* z;
22921 } sp_256_proj_point_dbl_5_ctx;
22922 
sp_256_proj_point_dbl_5_nb(sp_ecc_ctx_t * sp_ctx,sp_point_256 * r,const sp_point_256 * p,sp_digit * t)22923 static int sp_256_proj_point_dbl_5_nb(sp_ecc_ctx_t* sp_ctx, sp_point_256* r, const sp_point_256* p, sp_digit* t)
22924 {
22925     int err = FP_WOULDBLOCK;
22926     sp_256_proj_point_dbl_5_ctx* ctx = (sp_256_proj_point_dbl_5_ctx*)sp_ctx->data;
22927 
22928     typedef char ctx_size_test[sizeof(sp_256_proj_point_dbl_5_ctx) >= sizeof(*sp_ctx) ? -1 : 1];
22929     (void)sizeof(ctx_size_test);
22930 
22931     switch (ctx->state) {
22932     case 0:
22933         ctx->t1 = t;
22934         ctx->t2 = t + 2*5;
22935         ctx->x = r->x;
22936         ctx->y = r->y;
22937         ctx->z = r->z;
22938 
22939         /* Put infinity into result. */
22940         if (r != p) {
22941             r->infinity = p->infinity;
22942         }
22943         ctx->state = 1;
22944         break;
22945     case 1:
22946         /* T1 = Z * Z */
22947         sp_256_mont_sqr_5(ctx->t1, p->z, p256_mod, p256_mp_mod);
22948         ctx->state = 2;
22949         break;
22950     case 2:
22951         /* Z = Y * Z */
22952         sp_256_mont_mul_5(ctx->z, p->y, p->z, p256_mod, p256_mp_mod);
22953         ctx->state = 3;
22954         break;
22955     case 3:
22956         /* Z = 2Z */
22957         sp_256_mont_dbl_5(ctx->z, ctx->z, p256_mod);
22958         ctx->state = 4;
22959         break;
22960     case 4:
22961         /* T2 = X - T1 */
22962         sp_256_mont_sub_5(ctx->t2, p->x, ctx->t1, p256_mod);
22963         ctx->state = 5;
22964         break;
22965     case 5:
22966         /* T1 = X + T1 */
22967         sp_256_mont_add_5(ctx->t1, p->x, ctx->t1, p256_mod);
22968         ctx->state = 6;
22969         break;
22970     case 6:
22971         /* T2 = T1 * T2 */
22972         sp_256_mont_mul_5(ctx->t2, ctx->t1, ctx->t2, p256_mod, p256_mp_mod);
22973         ctx->state = 7;
22974         break;
22975     case 7:
22976         /* T1 = 3T2 */
22977         sp_256_mont_tpl_5(ctx->t1, ctx->t2, p256_mod);
22978         ctx->state = 8;
22979         break;
22980     case 8:
22981         /* Y = 2Y */
22982         sp_256_mont_dbl_5(ctx->y, p->y, p256_mod);
22983         ctx->state = 9;
22984         break;
22985     case 9:
22986         /* Y = Y * Y */
22987         sp_256_mont_sqr_5(ctx->y, ctx->y, p256_mod, p256_mp_mod);
22988         ctx->state = 10;
22989         break;
22990     case 10:
22991         /* T2 = Y * Y */
22992         sp_256_mont_sqr_5(ctx->t2, ctx->y, p256_mod, p256_mp_mod);
22993         ctx->state = 11;
22994         break;
22995     case 11:
22996         /* T2 = T2/2 */
22997         sp_256_div2_5(ctx->t2, ctx->t2, p256_mod);
22998         ctx->state = 12;
22999         break;
23000     case 12:
23001         /* Y = Y * X */
23002         sp_256_mont_mul_5(ctx->y, ctx->y, p->x, p256_mod, p256_mp_mod);
23003         ctx->state = 13;
23004         break;
23005     case 13:
23006         /* X = T1 * T1 */
23007         sp_256_mont_sqr_5(ctx->x, ctx->t1, p256_mod, p256_mp_mod);
23008         ctx->state = 14;
23009         break;
23010     case 14:
23011         /* X = X - Y */
23012         sp_256_mont_sub_5(ctx->x, ctx->x, ctx->y, p256_mod);
23013         ctx->state = 15;
23014         break;
23015     case 15:
23016         /* X = X - Y */
23017         sp_256_mont_sub_5(ctx->x, ctx->x, ctx->y, p256_mod);
23018         ctx->state = 16;
23019         break;
23020     case 16:
23021         /* Y = Y - X */
23022         sp_256_mont_sub_5(ctx->y, ctx->y, ctx->x, p256_mod);
23023         ctx->state = 17;
23024         break;
23025     case 17:
23026         /* Y = Y * T1 */
23027         sp_256_mont_mul_5(ctx->y, ctx->y, ctx->t1, p256_mod, p256_mp_mod);
23028         ctx->state = 18;
23029         break;
23030     case 18:
23031         /* Y = Y - T2 */
23032         sp_256_mont_sub_5(ctx->y, ctx->y, ctx->t2, p256_mod);
23033         ctx->state = 19;
23034         /* fall-through */
23035     case 19:
23036         err = MP_OKAY;
23037         break;
23038     }
23039 
23040     if (err == MP_OKAY && ctx->state != 19) {
23041         err = FP_WOULDBLOCK;
23042     }
23043 
23044     return err;
23045 }
23046 #endif /* WOLFSSL_SP_NONBLOCK */
23047 
sp_256_proj_point_dbl_5(sp_point_256 * r,const sp_point_256 * p,sp_digit * t)23048 static void sp_256_proj_point_dbl_5(sp_point_256* r, const sp_point_256* p, sp_digit* t)
23049 {
23050     sp_digit* t1 = t;
23051     sp_digit* t2 = t + 2*5;
23052     sp_digit* x;
23053     sp_digit* y;
23054     sp_digit* z;
23055 
23056     x = r->x;
23057     y = r->y;
23058     z = r->z;
23059     /* Put infinity into result. */
23060     if (r != p) {
23061         r->infinity = p->infinity;
23062     }
23063 
23064     /* T1 = Z * Z */
23065     sp_256_mont_sqr_5(t1, p->z, p256_mod, p256_mp_mod);
23066     /* Z = Y * Z */
23067     sp_256_mont_mul_5(z, p->y, p->z, p256_mod, p256_mp_mod);
23068     /* Z = 2Z */
23069     sp_256_mont_dbl_5(z, z, p256_mod);
23070     /* T2 = X - T1 */
23071     sp_256_mont_sub_5(t2, p->x, t1, p256_mod);
23072     /* T1 = X + T1 */
23073     sp_256_mont_add_5(t1, p->x, t1, p256_mod);
23074     /* T2 = T1 * T2 */
23075     sp_256_mont_mul_5(t2, t1, t2, p256_mod, p256_mp_mod);
23076     /* T1 = 3T2 */
23077     sp_256_mont_tpl_5(t1, t2, p256_mod);
23078     /* Y = 2Y */
23079     sp_256_mont_dbl_5(y, p->y, p256_mod);
23080     /* Y = Y * Y */
23081     sp_256_mont_sqr_5(y, y, p256_mod, p256_mp_mod);
23082     /* T2 = Y * Y */
23083     sp_256_mont_sqr_5(t2, y, p256_mod, p256_mp_mod);
23084     /* T2 = T2/2 */
23085     sp_256_div2_5(t2, t2, p256_mod);
23086     /* Y = Y * X */
23087     sp_256_mont_mul_5(y, y, p->x, p256_mod, p256_mp_mod);
23088     /* X = T1 * T1 */
23089     sp_256_mont_sqr_5(x, t1, p256_mod, p256_mp_mod);
23090     /* X = X - Y */
23091     sp_256_mont_sub_5(x, x, y, p256_mod);
23092     /* X = X - Y */
23093     sp_256_mont_sub_5(x, x, y, p256_mod);
23094     /* Y = Y - X */
23095     sp_256_mont_sub_5(y, y, x, p256_mod);
23096     /* Y = Y * T1 */
23097     sp_256_mont_mul_5(y, y, t1, p256_mod, p256_mp_mod);
23098     /* Y = Y - T2 */
23099     sp_256_mont_sub_5(y, y, t2, p256_mod);
23100 }
23101 
23102 /* Compare two numbers to determine if they are equal.
23103  * Constant time implementation.
23104  *
23105  * a  First number to compare.
23106  * b  Second number to compare.
23107  * returns 1 when equal and 0 otherwise.
23108  */
sp_256_cmp_equal_5(const sp_digit * a,const sp_digit * b)23109 static int sp_256_cmp_equal_5(const sp_digit* a, const sp_digit* b)
23110 {
23111     return ((a[0] ^ b[0]) | (a[1] ^ b[1]) | (a[2] ^ b[2]) |
23112             (a[3] ^ b[3]) | (a[4] ^ b[4])) == 0;
23113 }
23114 
23115 /* Add two Montgomery form projective points.
23116  *
23117  * r  Result of addition.
23118  * p  First point to add.
23119  * q  Second point to add.
23120  * t  Temporary ordinate data.
23121  */
23122 
23123 #ifdef WOLFSSL_SP_NONBLOCK
23124 typedef struct sp_256_proj_point_add_5_ctx {
23125     int state;
23126     sp_256_proj_point_dbl_5_ctx dbl_ctx;
23127     const sp_point_256* ap[2];
23128     sp_point_256* rp[2];
23129     sp_digit* t1;
23130     sp_digit* t2;
23131     sp_digit* t3;
23132     sp_digit* t4;
23133     sp_digit* t5;
23134     sp_digit* x;
23135     sp_digit* y;
23136     sp_digit* z;
23137 } sp_256_proj_point_add_5_ctx;
23138 
sp_256_proj_point_add_5_nb(sp_ecc_ctx_t * sp_ctx,sp_point_256 * r,const sp_point_256 * p,const sp_point_256 * q,sp_digit * t)23139 static int sp_256_proj_point_add_5_nb(sp_ecc_ctx_t* sp_ctx, sp_point_256* r,
23140     const sp_point_256* p, const sp_point_256* q, sp_digit* t)
23141 {
23142     int err = FP_WOULDBLOCK;
23143     sp_256_proj_point_add_5_ctx* ctx = (sp_256_proj_point_add_5_ctx*)sp_ctx->data;
23144 
23145     /* Ensure only the first point is the same as the result. */
23146     if (q == r) {
23147         const sp_point_256* a = p;
23148         p = q;
23149         q = a;
23150     }
23151 
23152     typedef char ctx_size_test[sizeof(sp_256_proj_point_add_5_ctx) >= sizeof(*sp_ctx) ? -1 : 1];
23153     (void)sizeof(ctx_size_test);
23154 
23155     switch (ctx->state) {
23156     case 0: /* INIT */
23157         ctx->t1 = t;
23158         ctx->t2 = t + 2*5;
23159         ctx->t3 = t + 4*5;
23160         ctx->t4 = t + 6*5;
23161         ctx->t5 = t + 8*5;
23162 
23163         ctx->state = 1;
23164         break;
23165     case 1:
23166         /* Check double */
23167         (void)sp_256_sub_5(ctx->t1, p256_mod, q->y);
23168         sp_256_norm_5(ctx->t1);
23169         if ((sp_256_cmp_equal_5(p->x, q->x) & sp_256_cmp_equal_5(p->z, q->z) &
23170             (sp_256_cmp_equal_5(p->y, q->y) | sp_256_cmp_equal_5(p->y, ctx->t1))) != 0)
23171         {
23172             XMEMSET(&ctx->dbl_ctx, 0, sizeof(ctx->dbl_ctx));
23173             ctx->state = 2;
23174         }
23175         else {
23176             ctx->state = 3;
23177         }
23178         break;
23179     case 2:
23180         err = sp_256_proj_point_dbl_5_nb((sp_ecc_ctx_t*)&ctx->dbl_ctx, r, p, t);
23181         if (err == MP_OKAY)
23182             ctx->state = 27; /* done */
23183         break;
23184     case 3:
23185     {
23186         int i;
23187         ctx->rp[0] = r;
23188 
23189         /*lint allow cast to different type of pointer*/
23190         ctx->rp[1] = (sp_point_256*)t; /*lint !e9087 !e740*/
23191         XMEMSET(ctx->rp[1], 0, sizeof(sp_point_256));
23192         ctx->x = ctx->rp[p->infinity | q->infinity]->x;
23193         ctx->y = ctx->rp[p->infinity | q->infinity]->y;
23194         ctx->z = ctx->rp[p->infinity | q->infinity]->z;
23195 
23196         ctx->ap[0] = p;
23197         ctx->ap[1] = q;
23198         for (i=0; i<5; i++) {
23199             r->x[i] = ctx->ap[p->infinity]->x[i];
23200         }
23201         for (i=0; i<5; i++) {
23202             r->y[i] = ctx->ap[p->infinity]->y[i];
23203         }
23204         for (i=0; i<5; i++) {
23205             r->z[i] = ctx->ap[p->infinity]->z[i];
23206         }
23207         r->infinity = ctx->ap[p->infinity]->infinity;
23208 
23209         ctx->state = 4;
23210         break;
23211     }
23212     case 4:
23213         /* U1 = X1*Z2^2 */
23214         sp_256_mont_sqr_5(ctx->t1, q->z, p256_mod, p256_mp_mod);
23215         ctx->state = 5;
23216         break;
23217     case 5:
23218         sp_256_mont_mul_5(ctx->t3, ctx->t1, q->z, p256_mod, p256_mp_mod);
23219         ctx->state = 6;
23220         break;
23221     case 6:
23222         sp_256_mont_mul_5(ctx->t1, ctx->t1, ctx->x, p256_mod, p256_mp_mod);
23223         ctx->state = 7;
23224         break;
23225     case 7:
23226         /* U2 = X2*Z1^2 */
23227         sp_256_mont_sqr_5(ctx->t2, ctx->z, p256_mod, p256_mp_mod);
23228         ctx->state = 8;
23229         break;
23230     case 8:
23231         sp_256_mont_mul_5(ctx->t4, ctx->t2, ctx->z, p256_mod, p256_mp_mod);
23232         ctx->state = 9;
23233         break;
23234     case 9:
23235         sp_256_mont_mul_5(ctx->t2, ctx->t2, q->x, p256_mod, p256_mp_mod);
23236         ctx->state = 10;
23237         break;
23238     case 10:
23239         /* S1 = Y1*Z2^3 */
23240         sp_256_mont_mul_5(ctx->t3, ctx->t3, ctx->y, p256_mod, p256_mp_mod);
23241         ctx->state = 11;
23242         break;
23243     case 11:
23244         /* S2 = Y2*Z1^3 */
23245         sp_256_mont_mul_5(ctx->t4, ctx->t4, q->y, p256_mod, p256_mp_mod);
23246         ctx->state = 12;
23247         break;
23248     case 12:
23249         /* H = U2 - U1 */
23250         sp_256_mont_sub_5(ctx->t2, ctx->t2, ctx->t1, p256_mod);
23251         ctx->state = 13;
23252         break;
23253     case 13:
23254         /* R = S2 - S1 */
23255         sp_256_mont_sub_5(ctx->t4, ctx->t4, ctx->t3, p256_mod);
23256         ctx->state = 14;
23257         break;
23258     case 14:
23259         /* Z3 = H*Z1*Z2 */
23260         sp_256_mont_mul_5(ctx->z, ctx->z, q->z, p256_mod, p256_mp_mod);
23261         ctx->state = 15;
23262         break;
23263     case 15:
23264         sp_256_mont_mul_5(ctx->z, ctx->z, ctx->t2, p256_mod, p256_mp_mod);
23265         ctx->state = 16;
23266         break;
23267     case 16:
23268         /* X3 = R^2 - H^3 - 2*U1*H^2 */
23269         sp_256_mont_sqr_5(ctx->x, ctx->t4, p256_mod, p256_mp_mod);
23270         ctx->state = 17;
23271         break;
23272     case 17:
23273         sp_256_mont_sqr_5(ctx->t5, ctx->t2, p256_mod, p256_mp_mod);
23274         ctx->state = 18;
23275         break;
23276     case 18:
23277         sp_256_mont_mul_5(ctx->y, ctx->t1, ctx->t5, p256_mod, p256_mp_mod);
23278         ctx->state = 19;
23279         break;
23280     case 19:
23281         sp_256_mont_mul_5(ctx->t5, ctx->t5, ctx->t2, p256_mod, p256_mp_mod);
23282         ctx->state = 20;
23283         break;
23284     case 20:
23285         sp_256_mont_sub_5(ctx->x, ctx->x, ctx->t5, p256_mod);
23286         ctx->state = 21;
23287         break;
23288     case 21:
23289         sp_256_mont_dbl_5(ctx->t1, ctx->y, p256_mod);
23290         ctx->state = 22;
23291         break;
23292     case 22:
23293         sp_256_mont_sub_5(ctx->x, ctx->x, ctx->t1, p256_mod);
23294         ctx->state = 23;
23295         break;
23296     case 23:
23297         /* Y3 = R*(U1*H^2 - X3) - S1*H^3 */
23298         sp_256_mont_sub_5(ctx->y, ctx->y, ctx->x, p256_mod);
23299         ctx->state = 24;
23300         break;
23301     case 24:
23302         sp_256_mont_mul_5(ctx->y, ctx->y, ctx->t4, p256_mod, p256_mp_mod);
23303         ctx->state = 25;
23304         break;
23305     case 25:
23306         sp_256_mont_mul_5(ctx->t5, ctx->t5, ctx->t3, p256_mod, p256_mp_mod);
23307         ctx->state = 26;
23308         break;
23309     case 26:
23310         sp_256_mont_sub_5(ctx->y, ctx->y, ctx->t5, p256_mod);
23311         ctx->state = 27;
23312         /* fall-through */
23313     case 27:
23314         err = MP_OKAY;
23315         break;
23316     }
23317 
23318     if (err == MP_OKAY && ctx->state != 27) {
23319         err = FP_WOULDBLOCK;
23320     }
23321     return err;
23322 }
23323 #endif /* WOLFSSL_SP_NONBLOCK */
23324 
sp_256_proj_point_add_5(sp_point_256 * r,const sp_point_256 * p,const sp_point_256 * q,sp_digit * t)23325 static void sp_256_proj_point_add_5(sp_point_256* r,
23326         const sp_point_256* p, const sp_point_256* q, sp_digit* t)
23327 {
23328     const sp_point_256* ap[2];
23329     sp_point_256* rp[2];
23330     sp_digit* t1 = t;
23331     sp_digit* t2 = t + 2*5;
23332     sp_digit* t3 = t + 4*5;
23333     sp_digit* t4 = t + 6*5;
23334     sp_digit* t5 = t + 8*5;
23335     sp_digit* x;
23336     sp_digit* y;
23337     sp_digit* z;
23338     int i;
23339 
23340     /* Ensure only the first point is the same as the result. */
23341     if (q == r) {
23342         const sp_point_256* a = p;
23343         p = q;
23344         q = a;
23345     }
23346 
23347     /* Check double */
23348     (void)sp_256_sub_5(t1, p256_mod, q->y);
23349     sp_256_norm_5(t1);
23350     if ((sp_256_cmp_equal_5(p->x, q->x) & sp_256_cmp_equal_5(p->z, q->z) &
23351         (sp_256_cmp_equal_5(p->y, q->y) | sp_256_cmp_equal_5(p->y, t1))) != 0) {
23352         sp_256_proj_point_dbl_5(r, p, t);
23353     }
23354     else {
23355         rp[0] = r;
23356 
23357         /*lint allow cast to different type of pointer*/
23358         rp[1] = (sp_point_256*)t; /*lint !e9087 !e740*/
23359         XMEMSET(rp[1], 0, sizeof(sp_point_256));
23360         x = rp[p->infinity | q->infinity]->x;
23361         y = rp[p->infinity | q->infinity]->y;
23362         z = rp[p->infinity | q->infinity]->z;
23363 
23364         ap[0] = p;
23365         ap[1] = q;
23366         for (i=0; i<5; i++) {
23367             r->x[i] = ap[p->infinity]->x[i];
23368         }
23369         for (i=0; i<5; i++) {
23370             r->y[i] = ap[p->infinity]->y[i];
23371         }
23372         for (i=0; i<5; i++) {
23373             r->z[i] = ap[p->infinity]->z[i];
23374         }
23375         r->infinity = ap[p->infinity]->infinity;
23376 
23377         /* U1 = X1*Z2^2 */
23378         sp_256_mont_sqr_5(t1, q->z, p256_mod, p256_mp_mod);
23379         sp_256_mont_mul_5(t3, t1, q->z, p256_mod, p256_mp_mod);
23380         sp_256_mont_mul_5(t1, t1, x, p256_mod, p256_mp_mod);
23381         /* U2 = X2*Z1^2 */
23382         sp_256_mont_sqr_5(t2, z, p256_mod, p256_mp_mod);
23383         sp_256_mont_mul_5(t4, t2, z, p256_mod, p256_mp_mod);
23384         sp_256_mont_mul_5(t2, t2, q->x, p256_mod, p256_mp_mod);
23385         /* S1 = Y1*Z2^3 */
23386         sp_256_mont_mul_5(t3, t3, y, p256_mod, p256_mp_mod);
23387         /* S2 = Y2*Z1^3 */
23388         sp_256_mont_mul_5(t4, t4, q->y, p256_mod, p256_mp_mod);
23389         /* H = U2 - U1 */
23390         sp_256_mont_sub_5(t2, t2, t1, p256_mod);
23391         /* R = S2 - S1 */
23392         sp_256_mont_sub_5(t4, t4, t3, p256_mod);
23393         /* Z3 = H*Z1*Z2 */
23394         sp_256_mont_mul_5(z, z, q->z, p256_mod, p256_mp_mod);
23395         sp_256_mont_mul_5(z, z, t2, p256_mod, p256_mp_mod);
23396         /* X3 = R^2 - H^3 - 2*U1*H^2 */
23397         sp_256_mont_sqr_5(x, t4, p256_mod, p256_mp_mod);
23398         sp_256_mont_sqr_5(t5, t2, p256_mod, p256_mp_mod);
23399         sp_256_mont_mul_5(y, t1, t5, p256_mod, p256_mp_mod);
23400         sp_256_mont_mul_5(t5, t5, t2, p256_mod, p256_mp_mod);
23401         sp_256_mont_sub_5(x, x, t5, p256_mod);
23402         sp_256_mont_dbl_5(t1, y, p256_mod);
23403         sp_256_mont_sub_5(x, x, t1, p256_mod);
23404         /* Y3 = R*(U1*H^2 - X3) - S1*H^3 */
23405         sp_256_mont_sub_5(y, y, x, p256_mod);
23406         sp_256_mont_mul_5(y, y, t4, p256_mod, p256_mp_mod);
23407         sp_256_mont_mul_5(t5, t5, t3, p256_mod, p256_mp_mod);
23408         sp_256_mont_sub_5(y, y, t5, p256_mod);
23409     }
23410 }
23411 
23412 /* Multiply a number by Montgomery normalizer mod modulus (prime).
23413  *
23414  * r  The resulting Montgomery form number.
23415  * a  The number to convert.
23416  * m  The modulus (prime).
23417  * returns MEMORY_E when memory allocation fails and MP_OKAY otherwise.
23418  */
sp_256_mod_mul_norm_5(sp_digit * r,const sp_digit * a,const sp_digit * m)23419 static int sp_256_mod_mul_norm_5(sp_digit* r, const sp_digit* a, const sp_digit* m)
23420 {
23421 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
23422     int64_t* t = NULL;
23423 #else
23424     int64_t t[2 * 8];
23425 #endif
23426     int64_t* a32 = NULL;
23427     int64_t o;
23428     int err = MP_OKAY;
23429 
23430     (void)m;
23431 
23432 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
23433     t = (int64_t*)XMALLOC(sizeof(int64_t) * 2 * 8, NULL, DYNAMIC_TYPE_ECC);
23434     if (t == NULL)
23435         return MEMORY_E;
23436 #endif
23437 
23438     if (err == MP_OKAY) {
23439         a32 = t + 8;
23440 
23441         a32[0] = (sp_digit)(a[0]) & 0xffffffffL;
23442         a32[1] = (sp_digit)(a[0] >> 32U);
23443         a32[1] |= (sp_digit)(a[1] << 20U);
23444         a32[1] &= 0xffffffffL;
23445         a32[2] = (sp_digit)(a[1] >> 12U) & 0xffffffffL;
23446         a32[3] = (sp_digit)(a[1] >> 44U);
23447         a32[3] |= (sp_digit)(a[2] << 8U);
23448         a32[3] &= 0xffffffffL;
23449         a32[4] = (sp_digit)(a[2] >> 24U);
23450         a32[4] |= (sp_digit)(a[3] << 28U);
23451         a32[4] &= 0xffffffffL;
23452         a32[5] = (sp_digit)(a[3] >> 4U) & 0xffffffffL;
23453         a32[6] = (sp_digit)(a[3] >> 36U);
23454         a32[6] |= (sp_digit)(a[4] << 16U);
23455         a32[6] &= 0xffffffffL;
23456         a32[7] = (sp_digit)(a[4] >> 16U) & 0xffffffffL;
23457 
23458         /*  1  1  0 -1 -1 -1 -1  0 */
23459         t[0] = 0 + a32[0] + a32[1] - a32[3] - a32[4] - a32[5] - a32[6];
23460         /*  0  1  1  0 -1 -1 -1 -1 */
23461         t[1] = 0 + a32[1] + a32[2] - a32[4] - a32[5] - a32[6] - a32[7];
23462         /*  0  0  1  1  0 -1 -1 -1 */
23463         t[2] = 0 + a32[2] + a32[3] - a32[5] - a32[6] - a32[7];
23464         /* -1 -1  0  2  2  1  0 -1 */
23465         t[3] = 0 - a32[0] - a32[1] + 2 * a32[3] + 2 * a32[4] + a32[5] - a32[7];
23466         /*  0 -1 -1  0  2  2  1  0 */
23467         t[4] = 0 - a32[1] - a32[2] + 2 * a32[4] + 2 * a32[5] + a32[6];
23468         /*  0  0 -1 -1  0  2  2  1 */
23469         t[5] = 0 - a32[2] - a32[3] + 2 * a32[5] + 2 * a32[6] + a32[7];
23470         /* -1 -1  0  0  0  1  3  2 */
23471         t[6] = 0 - a32[0] - a32[1] + a32[5] + 3 * a32[6] + 2 * a32[7];
23472         /*  1  0 -1 -1 -1 -1  0  3 */
23473         t[7] = 0 + a32[0] - a32[2] - a32[3] - a32[4] - a32[5] + 3 * a32[7];
23474 
23475         t[1] += t[0] >> 32U; t[0] &= 0xffffffffL;
23476         t[2] += t[1] >> 32U; t[1] &= 0xffffffffL;
23477         t[3] += t[2] >> 32U; t[2] &= 0xffffffffL;
23478         t[4] += t[3] >> 32U; t[3] &= 0xffffffffL;
23479         t[5] += t[4] >> 32U; t[4] &= 0xffffffffL;
23480         t[6] += t[5] >> 32U; t[5] &= 0xffffffffL;
23481         t[7] += t[6] >> 32U; t[6] &= 0xffffffffL;
23482         o     = t[7] >> 32U; t[7] &= 0xffffffffL;
23483         t[0] += o;
23484         t[3] -= o;
23485         t[6] -= o;
23486         t[7] += o;
23487         t[1] += t[0] >> 32U; t[0] &= 0xffffffffL;
23488         t[2] += t[1] >> 32U; t[1] &= 0xffffffffL;
23489         t[3] += t[2] >> 32U; t[2] &= 0xffffffffL;
23490         t[4] += t[3] >> 32U; t[3] &= 0xffffffffL;
23491         t[5] += t[4] >> 32U; t[4] &= 0xffffffffL;
23492         t[6] += t[5] >> 32U; t[5] &= 0xffffffffL;
23493         t[7] += t[6] >> 32U; t[6] &= 0xffffffffL;
23494 
23495         r[0] = t[0];
23496         r[0] |= t[1] << 32U;
23497         r[0] &= 0xfffffffffffffLL;
23498         r[1] = (t[1] >> 20);
23499         r[1] |= t[2] << 12U;
23500         r[1] |= t[3] << 44U;
23501         r[1] &= 0xfffffffffffffLL;
23502         r[2] = (t[3] >> 8);
23503         r[2] |= t[4] << 24U;
23504         r[2] &= 0xfffffffffffffLL;
23505         r[3] = (t[4] >> 28);
23506         r[3] |= t[5] << 4U;
23507         r[3] |= t[6] << 36U;
23508         r[3] &= 0xfffffffffffffLL;
23509         r[4] = (t[6] >> 16);
23510         r[4] |= t[7] << 16U;
23511     }
23512 
23513 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
23514     if (t != NULL)
23515         XFREE(t, NULL, DYNAMIC_TYPE_ECC);
23516 #endif
23517 
23518     return err;
23519 }
23520 
23521 #ifdef WOLFSSL_SP_SMALL
23522 /* Multiply the point by the scalar and return the result.
23523  * If map is true then convert result to affine coordinates.
23524  *
23525  * Small implementation using add and double that is cache attack resistant but
23526  * allocates memory rather than use large stacks.
23527  * 256 adds and doubles.
23528  *
23529  * r     Resulting point.
23530  * g     Point to multiply.
23531  * k     Scalar to multiply by.
23532  * map   Indicates whether to convert result to affine.
23533  * ct    Constant time required.
23534  * heap  Heap to use for allocation.
23535  * returns MEMORY_E when memory allocation fails and MP_OKAY on success.
23536  */
23537 
23538 #ifdef WOLFSSL_SP_NONBLOCK
23539 typedef struct sp_256_ecc_mulmod_5_ctx {
23540     int state;
23541     union {
23542         sp_256_proj_point_dbl_5_ctx dbl_ctx;
23543         sp_256_proj_point_add_5_ctx add_ctx;
23544     };
23545     sp_point_256 t[3];
23546     sp_digit tmp[2 * 5 * 5];
23547     sp_digit n;
23548     int i;
23549     int c;
23550     int y;
23551 } sp_256_ecc_mulmod_5_ctx;
23552 
sp_256_ecc_mulmod_5_nb(sp_ecc_ctx_t * sp_ctx,sp_point_256 * r,const sp_point_256 * g,const sp_digit * k,int map,int ct,void * heap)23553 static int sp_256_ecc_mulmod_5_nb(sp_ecc_ctx_t* sp_ctx, sp_point_256* r,
23554     const sp_point_256* g, const sp_digit* k, int map, int ct, void* heap)
23555 {
23556     int err = FP_WOULDBLOCK;
23557     sp_256_ecc_mulmod_5_ctx* ctx = (sp_256_ecc_mulmod_5_ctx*)sp_ctx->data;
23558 
23559     typedef char ctx_size_test[sizeof(sp_256_ecc_mulmod_5_ctx) >= sizeof(*sp_ctx) ? -1 : 1];
23560     (void)sizeof(ctx_size_test);
23561 
23562     /* Implementation is constant time. */
23563     (void)ct;
23564 
23565     switch (ctx->state) {
23566     case 0: /* INIT */
23567         XMEMSET(ctx->t, 0, sizeof(sp_point_256) * 3);
23568         ctx->i = 4;
23569         ctx->c = 48;
23570         ctx->n = k[ctx->i--] << (52 - ctx->c);
23571 
23572         /* t[0] = {0, 0, 1} * norm */
23573         ctx->t[0].infinity = 1;
23574         ctx->state = 1;
23575         break;
23576     case 1: /* T1X */
23577         /* t[1] = {g->x, g->y, g->z} * norm */
23578         err = sp_256_mod_mul_norm_5(ctx->t[1].x, g->x, p256_mod);
23579         ctx->state = 2;
23580         break;
23581     case 2: /* T1Y */
23582         err = sp_256_mod_mul_norm_5(ctx->t[1].y, g->y, p256_mod);
23583         ctx->state = 3;
23584         break;
23585     case 3: /* T1Z */
23586         err = sp_256_mod_mul_norm_5(ctx->t[1].z, g->z, p256_mod);
23587         ctx->state = 4;
23588         break;
23589     case 4: /* ADDPREP */
23590         if (ctx->c == 0) {
23591             if (ctx->i == -1) {
23592                 ctx->state = 7;
23593                 break;
23594             }
23595 
23596             ctx->n = k[ctx->i--];
23597             ctx->c = 52;
23598         }
23599         ctx->y = (ctx->n >> 51) & 1;
23600         ctx->n <<= 1;
23601         XMEMSET(&ctx->add_ctx, 0, sizeof(ctx->add_ctx));
23602         ctx->state = 5;
23603         break;
23604     case 5: /* ADD */
23605         err = sp_256_proj_point_add_5_nb((sp_ecc_ctx_t*)&ctx->add_ctx,
23606             &ctx->t[ctx->y^1], &ctx->t[0], &ctx->t[1], ctx->tmp);
23607         if (err == MP_OKAY) {
23608             XMEMCPY(&ctx->t[2], (void*)(((size_t)&ctx->t[0] & addr_mask[ctx->y^1]) +
23609                                         ((size_t)&ctx->t[1] & addr_mask[ctx->y])),
23610                     sizeof(sp_point_256));
23611             XMEMSET(&ctx->dbl_ctx, 0, sizeof(ctx->dbl_ctx));
23612             ctx->state = 6;
23613         }
23614         break;
23615     case 6: /* DBL */
23616         err = sp_256_proj_point_dbl_5_nb((sp_ecc_ctx_t*)&ctx->dbl_ctx, &ctx->t[2],
23617             &ctx->t[2], ctx->tmp);
23618         if (err == MP_OKAY) {
23619             XMEMCPY((void*)(((size_t)&ctx->t[0] & addr_mask[ctx->y^1]) +
23620                             ((size_t)&ctx->t[1] & addr_mask[ctx->y])), &ctx->t[2],
23621                     sizeof(sp_point_256));
23622             ctx->state = 4;
23623             ctx->c--;
23624         }
23625         break;
23626     case 7: /* MAP */
23627         if (map != 0) {
23628             sp_256_map_5(r, &ctx->t[0], ctx->tmp);
23629         }
23630         else {
23631             XMEMCPY(r, &ctx->t[0], sizeof(sp_point_256));
23632         }
23633         err = MP_OKAY;
23634         break;
23635     }
23636 
23637     if (err == MP_OKAY && ctx->state != 7) {
23638         err = FP_WOULDBLOCK;
23639     }
23640     if (err != FP_WOULDBLOCK) {
23641         ForceZero(ctx->tmp, sizeof(ctx->tmp));
23642         ForceZero(ctx->t, sizeof(ctx->t));
23643     }
23644 
23645     (void)heap;
23646 
23647     return err;
23648 }
23649 
23650 #endif /* WOLFSSL_SP_NONBLOCK */
23651 
sp_256_ecc_mulmod_5(sp_point_256 * r,const sp_point_256 * g,const sp_digit * k,int map,int ct,void * heap)23652 static int sp_256_ecc_mulmod_5(sp_point_256* r, const sp_point_256* g,
23653         const sp_digit* k, int map, int ct, void* heap)
23654 {
23655 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
23656     sp_point_256* t = NULL;
23657     sp_digit* tmp = NULL;
23658 #else
23659     sp_point_256 t[3];
23660     sp_digit tmp[2 * 5 * 5];
23661 #endif
23662     sp_digit n;
23663     int i;
23664     int c;
23665     int y;
23666     int err = MP_OKAY;
23667 
23668     /* Implementation is constant time. */
23669     (void)ct;
23670     (void)heap;
23671 
23672 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
23673     t = (sp_point_256*)XMALLOC(sizeof(sp_point_256) * 3, heap,
23674                                      DYNAMIC_TYPE_ECC);
23675     if (t == NULL)
23676         err = MEMORY_E;
23677     if (err == MP_OKAY) {
23678         tmp = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 5 * 5, heap,
23679                                  DYNAMIC_TYPE_ECC);
23680         if (tmp == NULL)
23681             err = MEMORY_E;
23682     }
23683 #endif
23684 
23685     if (err == MP_OKAY) {
23686         XMEMSET(t, 0, sizeof(sp_point_256) * 3);
23687 
23688         /* t[0] = {0, 0, 1} * norm */
23689         t[0].infinity = 1;
23690         /* t[1] = {g->x, g->y, g->z} * norm */
23691         err = sp_256_mod_mul_norm_5(t[1].x, g->x, p256_mod);
23692     }
23693     if (err == MP_OKAY)
23694         err = sp_256_mod_mul_norm_5(t[1].y, g->y, p256_mod);
23695     if (err == MP_OKAY)
23696         err = sp_256_mod_mul_norm_5(t[1].z, g->z, p256_mod);
23697 
23698     if (err == MP_OKAY) {
23699         i = 4;
23700         c = 48;
23701         n = k[i--] << (52 - c);
23702         for (; ; c--) {
23703             if (c == 0) {
23704                 if (i == -1)
23705                     break;
23706 
23707                 n = k[i--];
23708                 c = 52;
23709             }
23710 
23711             y = (n >> 51) & 1;
23712             n <<= 1;
23713 
23714             sp_256_proj_point_add_5(&t[y^1], &t[0], &t[1], tmp);
23715 
23716             XMEMCPY(&t[2], (void*)(((size_t)&t[0] & addr_mask[y^1]) +
23717                                    ((size_t)&t[1] & addr_mask[y])),
23718                     sizeof(sp_point_256));
23719             sp_256_proj_point_dbl_5(&t[2], &t[2], tmp);
23720             XMEMCPY((void*)(((size_t)&t[0] & addr_mask[y^1]) +
23721                             ((size_t)&t[1] & addr_mask[y])), &t[2],
23722                     sizeof(sp_point_256));
23723         }
23724 
23725         if (map != 0) {
23726             sp_256_map_5(r, &t[0], tmp);
23727         }
23728         else {
23729             XMEMCPY(r, &t[0], sizeof(sp_point_256));
23730         }
23731     }
23732 
23733 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
23734     if (tmp != NULL)
23735 #endif
23736     {
23737         ForceZero(tmp, sizeof(sp_digit) * 2 * 5 * 5);
23738     #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
23739         XFREE(tmp, heap, DYNAMIC_TYPE_ECC);
23740     #endif
23741     }
23742 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
23743     if (t != NULL)
23744 #endif
23745     {
23746         ForceZero(t, sizeof(sp_point_256) * 3);
23747     #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
23748         XFREE(t, heap, DYNAMIC_TYPE_ECC);
23749     #endif
23750     }
23751 
23752     return err;
23753 }
23754 
23755 #else
23756 /* A table entry for pre-computed points. */
23757 typedef struct sp_table_entry_256 {
23758     sp_digit x[5];
23759     sp_digit y[5];
23760 } sp_table_entry_256;
23761 
23762 /* Conditionally copy a into r using the mask m.
23763  * m is -1 to copy and 0 when not.
23764  *
23765  * r  A single precision number to copy over.
23766  * a  A single precision number to copy.
23767  * m  Mask value to apply.
23768  */
sp_256_cond_copy_5(sp_digit * r,const sp_digit * a,const sp_digit m)23769 static void sp_256_cond_copy_5(sp_digit* r, const sp_digit* a, const sp_digit m)
23770 {
23771     sp_digit t[5];
23772 #ifdef WOLFSSL_SP_SMALL
23773     int i;
23774 
23775     for (i = 0; i < 5; i++) {
23776         t[i] = r[i] ^ a[i];
23777     }
23778     for (i = 0; i < 5; i++) {
23779         r[i] ^= t[i] & m;
23780     }
23781 #else
23782     t[ 0] = r[ 0] ^ a[ 0];
23783     t[ 1] = r[ 1] ^ a[ 1];
23784     t[ 2] = r[ 2] ^ a[ 2];
23785     t[ 3] = r[ 3] ^ a[ 3];
23786     t[ 4] = r[ 4] ^ a[ 4];
23787     r[ 0] ^= t[ 0] & m;
23788     r[ 1] ^= t[ 1] & m;
23789     r[ 2] ^= t[ 2] & m;
23790     r[ 3] ^= t[ 3] & m;
23791     r[ 4] ^= t[ 4] & m;
23792 #endif /* WOLFSSL_SP_SMALL */
23793 }
23794 
23795 /* Double the Montgomery form projective point p a number of times.
23796  *
23797  * r  Result of repeated doubling of point.
23798  * p  Point to double.
23799  * n  Number of times to double
23800  * t  Temporary ordinate data.
23801  */
sp_256_proj_point_dbl_n_5(sp_point_256 * p,int n,sp_digit * t)23802 static void sp_256_proj_point_dbl_n_5(sp_point_256* p, int n,
23803     sp_digit* t)
23804 {
23805     sp_digit* w = t;
23806     sp_digit* a = t + 2*5;
23807     sp_digit* b = t + 4*5;
23808     sp_digit* t1 = t + 6*5;
23809     sp_digit* t2 = t + 8*5;
23810     sp_digit* x;
23811     sp_digit* y;
23812     sp_digit* z;
23813 
23814     x = p->x;
23815     y = p->y;
23816     z = p->z;
23817 
23818     /* Y = 2*Y */
23819     sp_256_mont_dbl_5(y, y, p256_mod);
23820     /* W = Z^4 */
23821     sp_256_mont_sqr_5(w, z, p256_mod, p256_mp_mod);
23822     sp_256_mont_sqr_5(w, w, p256_mod, p256_mp_mod);
23823 
23824 #ifndef WOLFSSL_SP_SMALL
23825     while (--n > 0)
23826 #else
23827     while (--n >= 0)
23828 #endif
23829     {
23830         /* A = 3*(X^2 - W) */
23831         sp_256_mont_sqr_5(t1, x, p256_mod, p256_mp_mod);
23832         sp_256_mont_sub_5(t1, t1, w, p256_mod);
23833         sp_256_mont_tpl_5(a, t1, p256_mod);
23834         /* B = X*Y^2 */
23835         sp_256_mont_sqr_5(t1, y, p256_mod, p256_mp_mod);
23836         sp_256_mont_mul_5(b, t1, x, p256_mod, p256_mp_mod);
23837         /* X = A^2 - 2B */
23838         sp_256_mont_sqr_5(x, a, p256_mod, p256_mp_mod);
23839         sp_256_mont_dbl_5(t2, b, p256_mod);
23840         sp_256_mont_sub_5(x, x, t2, p256_mod);
23841         /* Z = Z*Y */
23842         sp_256_mont_mul_5(z, z, y, p256_mod, p256_mp_mod);
23843         /* t2 = Y^4 */
23844         sp_256_mont_sqr_5(t1, t1, p256_mod, p256_mp_mod);
23845 #ifdef WOLFSSL_SP_SMALL
23846         if (n != 0)
23847 #endif
23848         {
23849             /* W = W*Y^4 */
23850             sp_256_mont_mul_5(w, w, t1, p256_mod, p256_mp_mod);
23851         }
23852         /* y = 2*A*(B - X) - Y^4 */
23853         sp_256_mont_sub_5(y, b, x, p256_mod);
23854         sp_256_mont_mul_5(y, y, a, p256_mod, p256_mp_mod);
23855         sp_256_mont_dbl_5(y, y, p256_mod);
23856         sp_256_mont_sub_5(y, y, t1, p256_mod);
23857     }
23858 #ifndef WOLFSSL_SP_SMALL
23859     /* A = 3*(X^2 - W) */
23860     sp_256_mont_sqr_5(t1, x, p256_mod, p256_mp_mod);
23861     sp_256_mont_sub_5(t1, t1, w, p256_mod);
23862     sp_256_mont_tpl_5(a, t1, p256_mod);
23863     /* B = X*Y^2 */
23864     sp_256_mont_sqr_5(t1, y, p256_mod, p256_mp_mod);
23865     sp_256_mont_mul_5(b, t1, x, p256_mod, p256_mp_mod);
23866     /* X = A^2 - 2B */
23867     sp_256_mont_sqr_5(x, a, p256_mod, p256_mp_mod);
23868     sp_256_mont_dbl_5(t2, b, p256_mod);
23869     sp_256_mont_sub_5(x, x, t2, p256_mod);
23870     /* Z = Z*Y */
23871     sp_256_mont_mul_5(z, z, y, p256_mod, p256_mp_mod);
23872     /* t2 = Y^4 */
23873     sp_256_mont_sqr_5(t1, t1, p256_mod, p256_mp_mod);
23874     /* y = 2*A*(B - X) - Y^4 */
23875     sp_256_mont_sub_5(y, b, x, p256_mod);
23876     sp_256_mont_mul_5(y, y, a, p256_mod, p256_mp_mod);
23877     sp_256_mont_dbl_5(y, y, p256_mod);
23878     sp_256_mont_sub_5(y, y, t1, p256_mod);
23879 #endif
23880     /* Y = Y/2 */
23881     sp_256_div2_5(y, y, p256_mod);
23882 }
23883 
23884 /* Double the Montgomery form projective point p a number of times.
23885  *
23886  * r  Result of repeated doubling of point.
23887  * p  Point to double.
23888  * n  Number of times to double
23889  * t  Temporary ordinate data.
23890  */
sp_256_proj_point_dbl_n_store_5(sp_point_256 * r,const sp_point_256 * p,int n,int m,sp_digit * t)23891 static void sp_256_proj_point_dbl_n_store_5(sp_point_256* r,
23892         const sp_point_256* p, int n, int m, sp_digit* t)
23893 {
23894     sp_digit* w = t;
23895     sp_digit* a = t + 2*5;
23896     sp_digit* b = t + 4*5;
23897     sp_digit* t1 = t + 6*5;
23898     sp_digit* t2 = t + 8*5;
23899     sp_digit* x = r[2*m].x;
23900     sp_digit* y = r[(1<<n)*m].y;
23901     sp_digit* z = r[2*m].z;
23902     int i;
23903     int j;
23904 
23905     for (i=0; i<5; i++) {
23906         x[i] = p->x[i];
23907     }
23908     for (i=0; i<5; i++) {
23909         y[i] = p->y[i];
23910     }
23911     for (i=0; i<5; i++) {
23912         z[i] = p->z[i];
23913     }
23914 
23915     /* Y = 2*Y */
23916     sp_256_mont_dbl_5(y, y, p256_mod);
23917     /* W = Z^4 */
23918     sp_256_mont_sqr_5(w, z, p256_mod, p256_mp_mod);
23919     sp_256_mont_sqr_5(w, w, p256_mod, p256_mp_mod);
23920     j = m;
23921     for (i=1; i<=n; i++) {
23922         j *= 2;
23923 
23924         /* A = 3*(X^2 - W) */
23925         sp_256_mont_sqr_5(t1, x, p256_mod, p256_mp_mod);
23926         sp_256_mont_sub_5(t1, t1, w, p256_mod);
23927         sp_256_mont_tpl_5(a, t1, p256_mod);
23928         /* B = X*Y^2 */
23929         sp_256_mont_sqr_5(t2, y, p256_mod, p256_mp_mod);
23930         sp_256_mont_mul_5(b, t2, x, p256_mod, p256_mp_mod);
23931         x = r[j].x;
23932         /* X = A^2 - 2B */
23933         sp_256_mont_sqr_5(x, a, p256_mod, p256_mp_mod);
23934         sp_256_mont_dbl_5(t1, b, p256_mod);
23935         sp_256_mont_sub_5(x, x, t1, p256_mod);
23936         /* Z = Z*Y */
23937         sp_256_mont_mul_5(r[j].z, z, y, p256_mod, p256_mp_mod);
23938         z = r[j].z;
23939         /* t2 = Y^4 */
23940         sp_256_mont_sqr_5(t2, t2, p256_mod, p256_mp_mod);
23941         if (i != n) {
23942             /* W = W*Y^4 */
23943             sp_256_mont_mul_5(w, w, t2, p256_mod, p256_mp_mod);
23944         }
23945         /* y = 2*A*(B - X) - Y^4 */
23946         sp_256_mont_sub_5(y, b, x, p256_mod);
23947         sp_256_mont_mul_5(y, y, a, p256_mod, p256_mp_mod);
23948         sp_256_mont_dbl_5(y, y, p256_mod);
23949         sp_256_mont_sub_5(y, y, t2, p256_mod);
23950 
23951         /* Y = Y/2 */
23952         sp_256_div2_5(r[j].y, y, p256_mod);
23953         r[j].infinity = 0;
23954     }
23955 }
23956 
23957 /* Add two Montgomery form projective points.
23958  *
23959  * ra  Result of addition.
23960  * rs  Result of subtraction.
23961  * p   First point to add.
23962  * q   Second point to add.
23963  * t   Temporary ordinate data.
23964  */
sp_256_proj_point_add_sub_5(sp_point_256 * ra,sp_point_256 * rs,const sp_point_256 * p,const sp_point_256 * q,sp_digit * t)23965 static void sp_256_proj_point_add_sub_5(sp_point_256* ra,
23966         sp_point_256* rs, const sp_point_256* p, const sp_point_256* q,
23967         sp_digit* t)
23968 {
23969     sp_digit* t1 = t;
23970     sp_digit* t2 = t + 2*5;
23971     sp_digit* t3 = t + 4*5;
23972     sp_digit* t4 = t + 6*5;
23973     sp_digit* t5 = t + 8*5;
23974     sp_digit* t6 = t + 10*5;
23975     sp_digit* x = ra->x;
23976     sp_digit* y = ra->y;
23977     sp_digit* z = ra->z;
23978     sp_digit* xs = rs->x;
23979     sp_digit* ys = rs->y;
23980     sp_digit* zs = rs->z;
23981 
23982 
23983     XMEMCPY(x, p->x, sizeof(p->x) / 2);
23984     XMEMCPY(y, p->y, sizeof(p->y) / 2);
23985     XMEMCPY(z, p->z, sizeof(p->z) / 2);
23986     ra->infinity = 0;
23987     rs->infinity = 0;
23988 
23989     /* U1 = X1*Z2^2 */
23990     sp_256_mont_sqr_5(t1, q->z, p256_mod, p256_mp_mod);
23991     sp_256_mont_mul_5(t3, t1, q->z, p256_mod, p256_mp_mod);
23992     sp_256_mont_mul_5(t1, t1, x, p256_mod, p256_mp_mod);
23993     /* U2 = X2*Z1^2 */
23994     sp_256_mont_sqr_5(t2, z, p256_mod, p256_mp_mod);
23995     sp_256_mont_mul_5(t4, t2, z, p256_mod, p256_mp_mod);
23996     sp_256_mont_mul_5(t2, t2, q->x, p256_mod, p256_mp_mod);
23997     /* S1 = Y1*Z2^3 */
23998     sp_256_mont_mul_5(t3, t3, y, p256_mod, p256_mp_mod);
23999     /* S2 = Y2*Z1^3 */
24000     sp_256_mont_mul_5(t4, t4, q->y, p256_mod, p256_mp_mod);
24001     /* H = U2 - U1 */
24002     sp_256_mont_sub_5(t2, t2, t1, p256_mod);
24003     /* RS = S2 + S1 */
24004     sp_256_mont_add_5(t6, t4, t3, p256_mod);
24005     /* R = S2 - S1 */
24006     sp_256_mont_sub_5(t4, t4, t3, p256_mod);
24007     /* Z3 = H*Z1*Z2 */
24008     /* ZS = H*Z1*Z2 */
24009     sp_256_mont_mul_5(z, z, q->z, p256_mod, p256_mp_mod);
24010     sp_256_mont_mul_5(z, z, t2, p256_mod, p256_mp_mod);
24011     XMEMCPY(zs, z, sizeof(p->z)/2);
24012     /* X3 = R^2 - H^3 - 2*U1*H^2 */
24013     /* XS = RS^2 - H^3 - 2*U1*H^2 */
24014     sp_256_mont_sqr_5(x, t4, p256_mod, p256_mp_mod);
24015     sp_256_mont_sqr_5(xs, t6, p256_mod, p256_mp_mod);
24016     sp_256_mont_sqr_5(t5, t2, p256_mod, p256_mp_mod);
24017     sp_256_mont_mul_5(y, t1, t5, p256_mod, p256_mp_mod);
24018     sp_256_mont_mul_5(t5, t5, t2, p256_mod, p256_mp_mod);
24019     sp_256_mont_sub_5(x, x, t5, p256_mod);
24020     sp_256_mont_sub_5(xs, xs, t5, p256_mod);
24021     sp_256_mont_dbl_5(t1, y, p256_mod);
24022     sp_256_mont_sub_5(x, x, t1, p256_mod);
24023     sp_256_mont_sub_5(xs, xs, t1, p256_mod);
24024     /* Y3 = R*(U1*H^2 - X3) - S1*H^3 */
24025     /* YS = -RS*(U1*H^2 - XS) - S1*H^3 */
24026     sp_256_mont_sub_5(ys, y, xs, p256_mod);
24027     sp_256_mont_sub_5(y, y, x, p256_mod);
24028     sp_256_mont_mul_5(y, y, t4, p256_mod, p256_mp_mod);
24029     sp_256_sub_5(t6, p256_mod, t6);
24030     sp_256_mont_mul_5(ys, ys, t6, p256_mod, p256_mp_mod);
24031     sp_256_mont_mul_5(t5, t5, t3, p256_mod, p256_mp_mod);
24032     sp_256_mont_sub_5(y, y, t5, p256_mod);
24033     sp_256_mont_sub_5(ys, ys, t5, p256_mod);
24034 }
24035 
24036 /* Structure used to describe recoding of scalar multiplication. */
24037 typedef struct ecc_recode_256 {
24038     /* Index into pre-computation table. */
24039     uint8_t i;
24040     /* Use the negative of the point. */
24041     uint8_t neg;
24042 } ecc_recode_256;
24043 
24044 /* The index into pre-computation table to use. */
24045 static const uint8_t recode_index_5_6[66] = {
24046      0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15,
24047     16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
24048     32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17,
24049     16, 15, 14, 13, 12, 11, 10,  9,  8,  7,  6,  5,  4,  3,  2,  1,
24050      0,  1,
24051 };
24052 
24053 /* Whether to negate y-ordinate. */
24054 static const uint8_t recode_neg_5_6[66] = {
24055      0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
24056      0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
24057      1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
24058      1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
24059      0,  0,
24060 };
24061 
24062 /* Recode the scalar for multiplication using pre-computed values and
24063  * subtraction.
24064  *
24065  * k  Scalar to multiply by.
24066  * v  Vector of operations to perform.
24067  */
sp_256_ecc_recode_6_5(const sp_digit * k,ecc_recode_256 * v)24068 static void sp_256_ecc_recode_6_5(const sp_digit* k, ecc_recode_256* v)
24069 {
24070     int i;
24071     int j;
24072     uint8_t y;
24073     int carry = 0;
24074     int o;
24075     sp_digit n;
24076 
24077     j = 0;
24078     n = k[j];
24079     o = 0;
24080     for (i=0; i<43; i++) {
24081         y = (int8_t)n;
24082         if (o + 6 < 52) {
24083             y &= 0x3f;
24084             n >>= 6;
24085             o += 6;
24086         }
24087         else if (o + 6 == 52) {
24088             n >>= 6;
24089             if (++j < 5)
24090                 n = k[j];
24091             o = 0;
24092         }
24093         else if (++j < 5) {
24094             n = k[j];
24095             y |= (uint8_t)((n << (52 - o)) & 0x3f);
24096             o -= 46;
24097             n >>= o;
24098         }
24099 
24100         y += (uint8_t)carry;
24101         v[i].i = recode_index_5_6[y];
24102         v[i].neg = recode_neg_5_6[y];
24103         carry = (y >> 6) + v[i].neg;
24104     }
24105 }
24106 
24107 #ifndef WC_NO_CACHE_RESISTANT
24108 /* Touch each possible point that could be being copied.
24109  *
24110  * r      Point to copy into.
24111  * table  Table - start of the entires to access
24112  * idx    Index of entry to retrieve.
24113  */
sp_256_get_point_33_5(sp_point_256 * r,const sp_point_256 * table,int idx)24114 static void sp_256_get_point_33_5(sp_point_256* r, const sp_point_256* table,
24115     int idx)
24116 {
24117     int i;
24118     sp_digit mask;
24119 
24120     r->x[0] = 0;
24121     r->x[1] = 0;
24122     r->x[2] = 0;
24123     r->x[3] = 0;
24124     r->x[4] = 0;
24125     r->y[0] = 0;
24126     r->y[1] = 0;
24127     r->y[2] = 0;
24128     r->y[3] = 0;
24129     r->y[4] = 0;
24130     r->z[0] = 0;
24131     r->z[1] = 0;
24132     r->z[2] = 0;
24133     r->z[3] = 0;
24134     r->z[4] = 0;
24135     for (i = 1; i < 33; i++) {
24136         mask = 0 - (i == idx);
24137         r->x[0] |= mask & table[i].x[0];
24138         r->x[1] |= mask & table[i].x[1];
24139         r->x[2] |= mask & table[i].x[2];
24140         r->x[3] |= mask & table[i].x[3];
24141         r->x[4] |= mask & table[i].x[4];
24142         r->y[0] |= mask & table[i].y[0];
24143         r->y[1] |= mask & table[i].y[1];
24144         r->y[2] |= mask & table[i].y[2];
24145         r->y[3] |= mask & table[i].y[3];
24146         r->y[4] |= mask & table[i].y[4];
24147         r->z[0] |= mask & table[i].z[0];
24148         r->z[1] |= mask & table[i].z[1];
24149         r->z[2] |= mask & table[i].z[2];
24150         r->z[3] |= mask & table[i].z[3];
24151         r->z[4] |= mask & table[i].z[4];
24152     }
24153 }
24154 #endif /* !WC_NO_CACHE_RESISTANT */
24155 /* Multiply the point by the scalar and return the result.
24156  * If map is true then convert result to affine coordinates.
24157  *
24158  * Window technique of 6 bits. (Add-Sub variation.)
24159  * Calculate 0..32 times the point. Use function that adds and
24160  * subtracts the same two points.
24161  * Recode to add or subtract one of the computed points.
24162  * Double to push up.
24163  * NOT a sliding window.
24164  *
24165  * r     Resulting point.
24166  * g     Point to multiply.
24167  * k     Scalar to multiply by.
24168  * map   Indicates whether to convert result to affine.
24169  * ct    Constant time required.
24170  * heap  Heap to use for allocation.
24171  * returns MEMORY_E when memory allocation fails and MP_OKAY on success.
24172  */
sp_256_ecc_mulmod_win_add_sub_5(sp_point_256 * r,const sp_point_256 * g,const sp_digit * k,int map,int ct,void * heap)24173 static int sp_256_ecc_mulmod_win_add_sub_5(sp_point_256* r, const sp_point_256* g,
24174         const sp_digit* k, int map, int ct, void* heap)
24175 {
24176 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
24177     sp_point_256* t = NULL;
24178     sp_digit* tmp = NULL;
24179 #else
24180     sp_point_256 t[33+2];
24181     sp_digit tmp[2 * 5 * 6];
24182 #endif
24183     sp_point_256* rt = NULL;
24184     sp_point_256* p = NULL;
24185     sp_digit* negy;
24186     int i;
24187     ecc_recode_256 v[43];
24188     int err = MP_OKAY;
24189 
24190     /* Constant time used for cache attack resistance implementation. */
24191     (void)ct;
24192     (void)heap;
24193 
24194 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
24195     t = (sp_point_256*)XMALLOC(sizeof(sp_point_256) *
24196         (33+2), heap, DYNAMIC_TYPE_ECC);
24197     if (t == NULL)
24198         err = MEMORY_E;
24199     if (err == MP_OKAY) {
24200         tmp = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 5 * 6,
24201                                  heap, DYNAMIC_TYPE_ECC);
24202         if (tmp == NULL)
24203             err = MEMORY_E;
24204     }
24205 #endif
24206 
24207     if (err == MP_OKAY) {
24208         rt = t + 33;
24209         p  = t + 33+1;
24210 
24211         /* t[0] = {0, 0, 1} * norm */
24212         XMEMSET(&t[0], 0, sizeof(t[0]));
24213         t[0].infinity = 1;
24214         /* t[1] = {g->x, g->y, g->z} * norm */
24215         err = sp_256_mod_mul_norm_5(t[1].x, g->x, p256_mod);
24216     }
24217     if (err == MP_OKAY) {
24218         err = sp_256_mod_mul_norm_5(t[1].y, g->y, p256_mod);
24219     }
24220     if (err == MP_OKAY) {
24221         err = sp_256_mod_mul_norm_5(t[1].z, g->z, p256_mod);
24222     }
24223 
24224     if (err == MP_OKAY) {
24225         t[1].infinity = 0;
24226         /* t[2] ... t[32]  */
24227         sp_256_proj_point_dbl_n_store_5(t, &t[ 1], 5, 1, tmp);
24228         sp_256_proj_point_add_5(&t[ 3], &t[ 2], &t[ 1], tmp);
24229         sp_256_proj_point_dbl_5(&t[ 6], &t[ 3], tmp);
24230         sp_256_proj_point_add_sub_5(&t[ 7], &t[ 5], &t[ 6], &t[ 1], tmp);
24231         sp_256_proj_point_dbl_5(&t[10], &t[ 5], tmp);
24232         sp_256_proj_point_add_sub_5(&t[11], &t[ 9], &t[10], &t[ 1], tmp);
24233         sp_256_proj_point_dbl_5(&t[12], &t[ 6], tmp);
24234         sp_256_proj_point_dbl_5(&t[14], &t[ 7], tmp);
24235         sp_256_proj_point_add_sub_5(&t[15], &t[13], &t[14], &t[ 1], tmp);
24236         sp_256_proj_point_dbl_5(&t[18], &t[ 9], tmp);
24237         sp_256_proj_point_add_sub_5(&t[19], &t[17], &t[18], &t[ 1], tmp);
24238         sp_256_proj_point_dbl_5(&t[20], &t[10], tmp);
24239         sp_256_proj_point_dbl_5(&t[22], &t[11], tmp);
24240         sp_256_proj_point_add_sub_5(&t[23], &t[21], &t[22], &t[ 1], tmp);
24241         sp_256_proj_point_dbl_5(&t[24], &t[12], tmp);
24242         sp_256_proj_point_dbl_5(&t[26], &t[13], tmp);
24243         sp_256_proj_point_add_sub_5(&t[27], &t[25], &t[26], &t[ 1], tmp);
24244         sp_256_proj_point_dbl_5(&t[28], &t[14], tmp);
24245         sp_256_proj_point_dbl_5(&t[30], &t[15], tmp);
24246         sp_256_proj_point_add_sub_5(&t[31], &t[29], &t[30], &t[ 1], tmp);
24247 
24248         negy = t[0].y;
24249 
24250         sp_256_ecc_recode_6_5(k, v);
24251 
24252         i = 42;
24253     #ifndef WC_NO_CACHE_RESISTANT
24254         if (ct) {
24255             sp_256_get_point_33_5(rt, t, v[i].i);
24256             rt->infinity = !v[i].i;
24257         }
24258         else
24259     #endif
24260         {
24261             XMEMCPY(rt, &t[v[i].i], sizeof(sp_point_256));
24262         }
24263         for (--i; i>=0; i--) {
24264             sp_256_proj_point_dbl_n_5(rt, 6, tmp);
24265 
24266         #ifndef WC_NO_CACHE_RESISTANT
24267             if (ct) {
24268                 sp_256_get_point_33_5(p, t, v[i].i);
24269                 p->infinity = !v[i].i;
24270             }
24271             else
24272         #endif
24273             {
24274                 XMEMCPY(p, &t[v[i].i], sizeof(sp_point_256));
24275             }
24276             sp_256_sub_5(negy, p256_mod, p->y);
24277             sp_256_norm_5(negy);
24278             sp_256_cond_copy_5(p->y, negy, (sp_digit)0 - v[i].neg);
24279             sp_256_proj_point_add_5(rt, rt, p, tmp);
24280         }
24281 
24282         if (map != 0) {
24283             sp_256_map_5(r, rt, tmp);
24284         }
24285         else {
24286             XMEMCPY(r, rt, sizeof(sp_point_256));
24287         }
24288     }
24289 
24290 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
24291     if (t != NULL)
24292         XFREE(t, heap, DYNAMIC_TYPE_ECC);
24293     if (tmp != NULL)
24294         XFREE(tmp, heap, DYNAMIC_TYPE_ECC);
24295 #endif
24296 
24297     return err;
24298 }
24299 
24300 #ifdef FP_ECC
24301 #endif /* FP_ECC */
24302 /* Add two Montgomery form projective points. The second point has a q value of
24303  * one.
24304  * Only the first point can be the same pointer as the result point.
24305  *
24306  * r  Result of addition.
24307  * p  First point to add.
24308  * q  Second point to add.
24309  * t  Temporary ordinate data.
24310  */
sp_256_proj_point_add_qz1_5(sp_point_256 * r,const sp_point_256 * p,const sp_point_256 * q,sp_digit * t)24311 static void sp_256_proj_point_add_qz1_5(sp_point_256* r, const sp_point_256* p,
24312         const sp_point_256* q, sp_digit* t)
24313 {
24314     const sp_point_256* ap[2];
24315     sp_point_256* rp[2];
24316     sp_digit* t1 = t;
24317     sp_digit* t2 = t + 2*5;
24318     sp_digit* t3 = t + 4*5;
24319     sp_digit* t4 = t + 6*5;
24320     sp_digit* t5 = t + 8*5;
24321     sp_digit* x;
24322     sp_digit* y;
24323     sp_digit* z;
24324     int i;
24325 
24326     /* Check double */
24327     (void)sp_256_sub_5(t1, p256_mod, q->y);
24328     sp_256_norm_5(t1);
24329     if ((sp_256_cmp_equal_5(p->x, q->x) & sp_256_cmp_equal_5(p->z, q->z) &
24330         (sp_256_cmp_equal_5(p->y, q->y) | sp_256_cmp_equal_5(p->y, t1))) != 0) {
24331         sp_256_proj_point_dbl_5(r, p, t);
24332     }
24333     else {
24334         rp[0] = r;
24335 
24336         /*lint allow cast to different type of pointer*/
24337         rp[1] = (sp_point_256*)t; /*lint !e9087 !e740*/
24338         XMEMSET(rp[1], 0, sizeof(sp_point_256));
24339         x = rp[p->infinity | q->infinity]->x;
24340         y = rp[p->infinity | q->infinity]->y;
24341         z = rp[p->infinity | q->infinity]->z;
24342 
24343         ap[0] = p;
24344         ap[1] = q;
24345         for (i=0; i<5; i++) {
24346             r->x[i] = ap[p->infinity]->x[i];
24347         }
24348         for (i=0; i<5; i++) {
24349             r->y[i] = ap[p->infinity]->y[i];
24350         }
24351         for (i=0; i<5; i++) {
24352             r->z[i] = ap[p->infinity]->z[i];
24353         }
24354         r->infinity = ap[p->infinity]->infinity;
24355 
24356         /* U2 = X2*Z1^2 */
24357         sp_256_mont_sqr_5(t2, z, p256_mod, p256_mp_mod);
24358         sp_256_mont_mul_5(t4, t2, z, p256_mod, p256_mp_mod);
24359         sp_256_mont_mul_5(t2, t2, q->x, p256_mod, p256_mp_mod);
24360         /* S2 = Y2*Z1^3 */
24361         sp_256_mont_mul_5(t4, t4, q->y, p256_mod, p256_mp_mod);
24362         /* H = U2 - X1 */
24363         sp_256_mont_sub_5(t2, t2, x, p256_mod);
24364         /* R = S2 - Y1 */
24365         sp_256_mont_sub_5(t4, t4, y, p256_mod);
24366         /* Z3 = H*Z1 */
24367         sp_256_mont_mul_5(z, z, t2, p256_mod, p256_mp_mod);
24368         /* X3 = R^2 - H^3 - 2*X1*H^2 */
24369         sp_256_mont_sqr_5(t1, t4, p256_mod, p256_mp_mod);
24370         sp_256_mont_sqr_5(t5, t2, p256_mod, p256_mp_mod);
24371         sp_256_mont_mul_5(t3, x, t5, p256_mod, p256_mp_mod);
24372         sp_256_mont_mul_5(t5, t5, t2, p256_mod, p256_mp_mod);
24373         sp_256_mont_sub_5(x, t1, t5, p256_mod);
24374         sp_256_mont_dbl_5(t1, t3, p256_mod);
24375         sp_256_mont_sub_5(x, x, t1, p256_mod);
24376         /* Y3 = R*(X1*H^2 - X3) - Y1*H^3 */
24377         sp_256_mont_sub_5(t3, t3, x, p256_mod);
24378         sp_256_mont_mul_5(t3, t3, t4, p256_mod, p256_mp_mod);
24379         sp_256_mont_mul_5(t5, t5, y, p256_mod, p256_mp_mod);
24380         sp_256_mont_sub_5(y, t3, t5, p256_mod);
24381     }
24382 }
24383 
24384 #ifdef FP_ECC
24385 /* Convert the projective point to affine.
24386  * Ordinates are in Montgomery form.
24387  *
24388  * a  Point to convert.
24389  * t  Temporary data.
24390  */
sp_256_proj_to_affine_5(sp_point_256 * a,sp_digit * t)24391 static void sp_256_proj_to_affine_5(sp_point_256* a, sp_digit* t)
24392 {
24393     sp_digit* t1 = t;
24394     sp_digit* t2 = t + 2 * 5;
24395     sp_digit* tmp = t + 4 * 5;
24396 
24397     sp_256_mont_inv_5(t1, a->z, tmp);
24398 
24399     sp_256_mont_sqr_5(t2, t1, p256_mod, p256_mp_mod);
24400     sp_256_mont_mul_5(t1, t2, t1, p256_mod, p256_mp_mod);
24401 
24402     sp_256_mont_mul_5(a->x, a->x, t2, p256_mod, p256_mp_mod);
24403     sp_256_mont_mul_5(a->y, a->y, t1, p256_mod, p256_mp_mod);
24404     XMEMCPY(a->z, p256_norm_mod, sizeof(p256_norm_mod));
24405 }
24406 
24407 /* Generate the pre-computed table of points for the base point.
24408  *
24409  * width = 8
24410  * 256 entries
24411  * 32 bits between
24412  *
24413  * a      The base point.
24414  * table  Place to store generated point data.
24415  * tmp    Temporary data.
24416  * heap  Heap to use for allocation.
24417  */
sp_256_gen_stripe_table_5(const sp_point_256 * a,sp_table_entry_256 * table,sp_digit * tmp,void * heap)24418 static int sp_256_gen_stripe_table_5(const sp_point_256* a,
24419         sp_table_entry_256* table, sp_digit* tmp, void* heap)
24420 {
24421 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
24422     sp_point_256* t = NULL;
24423 #else
24424     sp_point_256 t[3];
24425 #endif
24426     sp_point_256* s1 = NULL;
24427     sp_point_256* s2 = NULL;
24428     int i;
24429     int j;
24430     int err = MP_OKAY;
24431 
24432     (void)heap;
24433 
24434 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
24435     t = (sp_point_256*)XMALLOC(sizeof(sp_point_256) * 3, heap,
24436                                      DYNAMIC_TYPE_ECC);
24437     if (t == NULL)
24438         err = MEMORY_E;
24439 #endif
24440 
24441     if (err == MP_OKAY) {
24442         s1 = t + 1;
24443         s2 = t + 2;
24444 
24445         err = sp_256_mod_mul_norm_5(t->x, a->x, p256_mod);
24446     }
24447     if (err == MP_OKAY) {
24448         err = sp_256_mod_mul_norm_5(t->y, a->y, p256_mod);
24449     }
24450     if (err == MP_OKAY) {
24451         err = sp_256_mod_mul_norm_5(t->z, a->z, p256_mod);
24452     }
24453     if (err == MP_OKAY) {
24454         t->infinity = 0;
24455         sp_256_proj_to_affine_5(t, tmp);
24456 
24457         XMEMCPY(s1->z, p256_norm_mod, sizeof(p256_norm_mod));
24458         s1->infinity = 0;
24459         XMEMCPY(s2->z, p256_norm_mod, sizeof(p256_norm_mod));
24460         s2->infinity = 0;
24461 
24462         /* table[0] = {0, 0, infinity} */
24463         XMEMSET(&table[0], 0, sizeof(sp_table_entry_256));
24464         /* table[1] = Affine version of 'a' in Montgomery form */
24465         XMEMCPY(table[1].x, t->x, sizeof(table->x));
24466         XMEMCPY(table[1].y, t->y, sizeof(table->y));
24467 
24468         for (i=1; i<8; i++) {
24469             sp_256_proj_point_dbl_n_5(t, 32, tmp);
24470             sp_256_proj_to_affine_5(t, tmp);
24471             XMEMCPY(table[1<<i].x, t->x, sizeof(table->x));
24472             XMEMCPY(table[1<<i].y, t->y, sizeof(table->y));
24473         }
24474 
24475         for (i=1; i<8; i++) {
24476             XMEMCPY(s1->x, table[1<<i].x, sizeof(table->x));
24477             XMEMCPY(s1->y, table[1<<i].y, sizeof(table->y));
24478             for (j=(1<<i)+1; j<(1<<(i+1)); j++) {
24479                 XMEMCPY(s2->x, table[j-(1<<i)].x, sizeof(table->x));
24480                 XMEMCPY(s2->y, table[j-(1<<i)].y, sizeof(table->y));
24481                 sp_256_proj_point_add_qz1_5(t, s1, s2, tmp);
24482                 sp_256_proj_to_affine_5(t, tmp);
24483                 XMEMCPY(table[j].x, t->x, sizeof(table->x));
24484                 XMEMCPY(table[j].y, t->y, sizeof(table->y));
24485             }
24486         }
24487     }
24488 
24489 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
24490     if (t != NULL)
24491         XFREE(t, heap, DYNAMIC_TYPE_ECC);
24492 #endif
24493 
24494     return err;
24495 }
24496 
24497 #endif /* FP_ECC */
24498 #ifndef WC_NO_CACHE_RESISTANT
24499 /* Touch each possible entry that could be being copied.
24500  *
24501  * r      Point to copy into.
24502  * table  Table - start of the entires to access
24503  * idx    Index of entry to retrieve.
24504  */
sp_256_get_entry_256_5(sp_point_256 * r,const sp_table_entry_256 * table,int idx)24505 static void sp_256_get_entry_256_5(sp_point_256* r,
24506     const sp_table_entry_256* table, int idx)
24507 {
24508     int i;
24509     sp_digit mask;
24510 
24511     r->x[0] = 0;
24512     r->x[1] = 0;
24513     r->x[2] = 0;
24514     r->x[3] = 0;
24515     r->x[4] = 0;
24516     r->y[0] = 0;
24517     r->y[1] = 0;
24518     r->y[2] = 0;
24519     r->y[3] = 0;
24520     r->y[4] = 0;
24521     for (i = 1; i < 256; i++) {
24522         mask = 0 - (i == idx);
24523         r->x[0] |= mask & table[i].x[0];
24524         r->x[1] |= mask & table[i].x[1];
24525         r->x[2] |= mask & table[i].x[2];
24526         r->x[3] |= mask & table[i].x[3];
24527         r->x[4] |= mask & table[i].x[4];
24528         r->y[0] |= mask & table[i].y[0];
24529         r->y[1] |= mask & table[i].y[1];
24530         r->y[2] |= mask & table[i].y[2];
24531         r->y[3] |= mask & table[i].y[3];
24532         r->y[4] |= mask & table[i].y[4];
24533     }
24534 }
24535 #endif /* !WC_NO_CACHE_RESISTANT */
24536 /* Multiply the point by the scalar and return the result.
24537  * If map is true then convert result to affine coordinates.
24538  *
24539  * Stripe implementation.
24540  * Pre-generated: 2^0, 2^32, ...
24541  * Pre-generated: products of all combinations of above.
24542  * 8 doubles and adds (with qz=1)
24543  *
24544  * r      Resulting point.
24545  * k      Scalar to multiply by.
24546  * table  Pre-computed table.
24547  * map    Indicates whether to convert result to affine.
24548  * ct     Constant time required.
24549  * heap   Heap to use for allocation.
24550  * returns MEMORY_E when memory allocation fails and MP_OKAY on success.
24551  */
sp_256_ecc_mulmod_stripe_5(sp_point_256 * r,const sp_point_256 * g,const sp_table_entry_256 * table,const sp_digit * k,int map,int ct,void * heap)24552 static int sp_256_ecc_mulmod_stripe_5(sp_point_256* r, const sp_point_256* g,
24553         const sp_table_entry_256* table, const sp_digit* k, int map,
24554         int ct, void* heap)
24555 {
24556 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
24557     sp_point_256* rt = NULL;
24558     sp_digit* t = NULL;
24559 #else
24560     sp_point_256 rt[2];
24561     sp_digit t[2 * 5 * 5];
24562 #endif
24563     sp_point_256* p = NULL;
24564     int i;
24565     int j;
24566     int y;
24567     int x;
24568     int err = MP_OKAY;
24569 
24570     (void)g;
24571     /* Constant time used for cache attack resistance implementation. */
24572     (void)ct;
24573     (void)heap;
24574 
24575 
24576 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
24577     rt = (sp_point_256*)XMALLOC(sizeof(sp_point_256) * 2, heap,
24578                                       DYNAMIC_TYPE_ECC);
24579     if (rt == NULL)
24580         err = MEMORY_E;
24581     if (err == MP_OKAY) {
24582         t = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 5 * 5, heap,
24583                                DYNAMIC_TYPE_ECC);
24584         if (t == NULL)
24585             err = MEMORY_E;
24586     }
24587 #endif
24588 
24589     if (err == MP_OKAY) {
24590         p = rt + 1;
24591 
24592         XMEMCPY(p->z, p256_norm_mod, sizeof(p256_norm_mod));
24593         XMEMCPY(rt->z, p256_norm_mod, sizeof(p256_norm_mod));
24594 
24595         y = 0;
24596         x = 31;
24597         for (j=0; j<8; j++) {
24598             y |= (int)(((k[x / 52] >> (x % 52)) & 1) << j);
24599             x += 32;
24600         }
24601     #ifndef WC_NO_CACHE_RESISTANT
24602         if (ct) {
24603             sp_256_get_entry_256_5(rt, table, y);
24604         } else
24605     #endif
24606         {
24607             XMEMCPY(rt->x, table[y].x, sizeof(table[y].x));
24608             XMEMCPY(rt->y, table[y].y, sizeof(table[y].y));
24609         }
24610         rt->infinity = !y;
24611         for (i=30; i>=0; i--) {
24612             y = 0;
24613             x = i;
24614             for (j=0; j<8; j++) {
24615                 y |= (int)(((k[x / 52] >> (x % 52)) & 1) << j);
24616                 x += 32;
24617             }
24618 
24619             sp_256_proj_point_dbl_5(rt, rt, t);
24620         #ifndef WC_NO_CACHE_RESISTANT
24621             if (ct) {
24622                 sp_256_get_entry_256_5(p, table, y);
24623             }
24624             else
24625         #endif
24626             {
24627                 XMEMCPY(p->x, table[y].x, sizeof(table[y].x));
24628                 XMEMCPY(p->y, table[y].y, sizeof(table[y].y));
24629             }
24630             p->infinity = !y;
24631             sp_256_proj_point_add_qz1_5(rt, rt, p, t);
24632         }
24633 
24634         if (map != 0) {
24635             sp_256_map_5(r, rt, t);
24636         }
24637         else {
24638             XMEMCPY(r, rt, sizeof(sp_point_256));
24639         }
24640     }
24641 
24642 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
24643     if (t != NULL)
24644         XFREE(t, heap, DYNAMIC_TYPE_ECC);
24645     if (rt != NULL)
24646         XFREE(rt, heap, DYNAMIC_TYPE_ECC);
24647 #endif
24648 
24649     return err;
24650 }
24651 
24652 #ifdef FP_ECC
24653 #ifndef FP_ENTRIES
24654     #define FP_ENTRIES 16
24655 #endif
24656 
24657 /* Cache entry - holds precomputation tables for a point. */
24658 typedef struct sp_cache_256_t {
24659     /* X ordinate of point that table was generated from. */
24660     sp_digit x[5];
24661     /* Y ordinate of point that table was generated from. */
24662     sp_digit y[5];
24663     /* Precomputation table for point. */
24664     sp_table_entry_256 table[256];
24665     /* Count of entries in table. */
24666     uint32_t cnt;
24667     /* Point and table set in entry. */
24668     int set;
24669 } sp_cache_256_t;
24670 
24671 /* Cache of tables. */
24672 static THREAD_LS_T sp_cache_256_t sp_cache_256[FP_ENTRIES];
24673 /* Index of last entry in cache. */
24674 static THREAD_LS_T int sp_cache_256_last = -1;
24675 /* Cache has been initialized. */
24676 static THREAD_LS_T int sp_cache_256_inited = 0;
24677 
24678 #ifndef HAVE_THREAD_LS
24679     static volatile int initCacheMutex_256 = 0;
24680     static wolfSSL_Mutex sp_cache_256_lock;
24681 #endif
24682 
24683 /* Get the cache entry for the point.
24684  *
24685  * g      [in]   Point scalar multipling.
24686  * cache  [out]  Cache table to use.
24687  */
sp_ecc_get_cache_256(const sp_point_256 * g,sp_cache_256_t ** cache)24688 static void sp_ecc_get_cache_256(const sp_point_256* g, sp_cache_256_t** cache)
24689 {
24690     int i;
24691     int j;
24692     uint32_t least;
24693 
24694     if (sp_cache_256_inited == 0) {
24695         for (i=0; i<FP_ENTRIES; i++) {
24696             sp_cache_256[i].set = 0;
24697         }
24698         sp_cache_256_inited = 1;
24699     }
24700 
24701     /* Compare point with those in cache. */
24702     for (i=0; i<FP_ENTRIES; i++) {
24703         if (!sp_cache_256[i].set)
24704             continue;
24705 
24706         if (sp_256_cmp_equal_5(g->x, sp_cache_256[i].x) &
24707                            sp_256_cmp_equal_5(g->y, sp_cache_256[i].y)) {
24708             sp_cache_256[i].cnt++;
24709             break;
24710         }
24711     }
24712 
24713     /* No match. */
24714     if (i == FP_ENTRIES) {
24715         /* Find empty entry. */
24716         i = (sp_cache_256_last + 1) % FP_ENTRIES;
24717         for (; i != sp_cache_256_last; i=(i+1)%FP_ENTRIES) {
24718             if (!sp_cache_256[i].set) {
24719                 break;
24720             }
24721         }
24722 
24723         /* Evict least used. */
24724         if (i == sp_cache_256_last) {
24725             least = sp_cache_256[0].cnt;
24726             for (j=1; j<FP_ENTRIES; j++) {
24727                 if (sp_cache_256[j].cnt < least) {
24728                     i = j;
24729                     least = sp_cache_256[i].cnt;
24730                 }
24731             }
24732         }
24733 
24734         XMEMCPY(sp_cache_256[i].x, g->x, sizeof(sp_cache_256[i].x));
24735         XMEMCPY(sp_cache_256[i].y, g->y, sizeof(sp_cache_256[i].y));
24736         sp_cache_256[i].set = 1;
24737         sp_cache_256[i].cnt = 1;
24738     }
24739 
24740     *cache = &sp_cache_256[i];
24741     sp_cache_256_last = i;
24742 }
24743 #endif /* FP_ECC */
24744 
24745 /* Multiply the base point of P256 by the scalar and return the result.
24746  * If map is true then convert result to affine coordinates.
24747  *
24748  * r     Resulting point.
24749  * g     Point to multiply.
24750  * k     Scalar to multiply by.
24751  * map   Indicates whether to convert result to affine.
24752  * ct    Constant time required.
24753  * heap  Heap to use for allocation.
24754  * returns MEMORY_E when memory allocation fails and MP_OKAY on success.
24755  */
sp_256_ecc_mulmod_5(sp_point_256 * r,const sp_point_256 * g,const sp_digit * k,int map,int ct,void * heap)24756 static int sp_256_ecc_mulmod_5(sp_point_256* r, const sp_point_256* g, const sp_digit* k,
24757         int map, int ct, void* heap)
24758 {
24759 #ifndef FP_ECC
24760     return sp_256_ecc_mulmod_win_add_sub_5(r, g, k, map, ct, heap);
24761 #else
24762     sp_digit tmp[2 * 5 * 5];
24763     sp_cache_256_t* cache;
24764     int err = MP_OKAY;
24765 
24766 #ifndef HAVE_THREAD_LS
24767     if (initCacheMutex_256 == 0) {
24768          wc_InitMutex(&sp_cache_256_lock);
24769          initCacheMutex_256 = 1;
24770     }
24771     if (wc_LockMutex(&sp_cache_256_lock) != 0)
24772        err = BAD_MUTEX_E;
24773 #endif /* HAVE_THREAD_LS */
24774 
24775     if (err == MP_OKAY) {
24776         sp_ecc_get_cache_256(g, &cache);
24777         if (cache->cnt == 2)
24778             sp_256_gen_stripe_table_5(g, cache->table, tmp, heap);
24779 
24780 #ifndef HAVE_THREAD_LS
24781         wc_UnLockMutex(&sp_cache_256_lock);
24782 #endif /* HAVE_THREAD_LS */
24783 
24784         if (cache->cnt < 2) {
24785             err = sp_256_ecc_mulmod_win_add_sub_5(r, g, k, map, ct, heap);
24786         }
24787         else {
24788             err = sp_256_ecc_mulmod_stripe_5(r, g, cache->table, k,
24789                     map, ct, heap);
24790         }
24791     }
24792 
24793     return err;
24794 #endif
24795 }
24796 
24797 #endif
24798 /* Multiply the point by the scalar and return the result.
24799  * If map is true then convert result to affine coordinates.
24800  *
24801  * km    Scalar to multiply by.
24802  * p     Point to multiply.
24803  * r     Resulting point.
24804  * map   Indicates whether to convert result to affine.
24805  * heap  Heap to use for allocation.
24806  * returns MEMORY_E when memory allocation fails and MP_OKAY on success.
24807  */
sp_ecc_mulmod_256(const mp_int * km,const ecc_point * gm,ecc_point * r,int map,void * heap)24808 int sp_ecc_mulmod_256(const mp_int* km, const ecc_point* gm, ecc_point* r,
24809         int map, void* heap)
24810 {
24811 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
24812     sp_point_256* point = NULL;
24813     sp_digit* k = NULL;
24814 #else
24815     sp_point_256 point[1];
24816     sp_digit k[5];
24817 #endif
24818     int err = MP_OKAY;
24819 
24820 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
24821     point = (sp_point_256*)XMALLOC(sizeof(sp_point_256), heap,
24822                                          DYNAMIC_TYPE_ECC);
24823     if (point == NULL)
24824         err = MEMORY_E;
24825     if (err == MP_OKAY) {
24826         k = (sp_digit*)XMALLOC(sizeof(sp_digit) * 5, heap,
24827                                DYNAMIC_TYPE_ECC);
24828         if (k == NULL)
24829             err = MEMORY_E;
24830     }
24831 #endif
24832 
24833     if (err == MP_OKAY) {
24834         sp_256_from_mp(k, 5, km);
24835         sp_256_point_from_ecc_point_5(point, gm);
24836 
24837             err = sp_256_ecc_mulmod_5(point, point, k, map, 1, heap);
24838     }
24839     if (err == MP_OKAY) {
24840         err = sp_256_point_to_ecc_point_5(point, r);
24841     }
24842 
24843 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
24844     if (k != NULL)
24845         XFREE(k, heap, DYNAMIC_TYPE_ECC);
24846     if (point != NULL)
24847         XFREE(point, heap, DYNAMIC_TYPE_ECC);
24848 #endif
24849 
24850     return err;
24851 }
24852 
24853 /* Multiply the point by the scalar, add point a and return the result.
24854  * If map is true then convert result to affine coordinates.
24855  *
24856  * km      Scalar to multiply by.
24857  * p       Point to multiply.
24858  * am      Point to add to scalar mulitply result.
24859  * inMont  Point to add is in montgomery form.
24860  * r       Resulting point.
24861  * map     Indicates whether to convert result to affine.
24862  * heap    Heap to use for allocation.
24863  * returns MEMORY_E when memory allocation fails and MP_OKAY on success.
24864  */
sp_ecc_mulmod_add_256(const mp_int * km,const ecc_point * gm,const ecc_point * am,int inMont,ecc_point * r,int map,void * heap)24865 int sp_ecc_mulmod_add_256(const mp_int* km, const ecc_point* gm,
24866     const ecc_point* am, int inMont, ecc_point* r, int map, void* heap)
24867 {
24868 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
24869     sp_point_256* point = NULL;
24870     sp_digit* k = NULL;
24871 #else
24872     sp_point_256 point[2];
24873     sp_digit k[5 + 5 * 2 * 5];
24874 #endif
24875     sp_point_256* addP = NULL;
24876     sp_digit* tmp = NULL;
24877     int err = MP_OKAY;
24878 
24879 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
24880     point = (sp_point_256*)XMALLOC(sizeof(sp_point_256) * 2, heap,
24881                                          DYNAMIC_TYPE_ECC);
24882     if (point == NULL)
24883         err = MEMORY_E;
24884     if (err == MP_OKAY) {
24885         k = (sp_digit*)XMALLOC(
24886             sizeof(sp_digit) * (5 + 5 * 2 * 5), heap,
24887             DYNAMIC_TYPE_ECC);
24888         if (k == NULL)
24889             err = MEMORY_E;
24890     }
24891 #endif
24892 
24893     if (err == MP_OKAY) {
24894         addP = point + 1;
24895         tmp = k + 5;
24896 
24897         sp_256_from_mp(k, 5, km);
24898         sp_256_point_from_ecc_point_5(point, gm);
24899         sp_256_point_from_ecc_point_5(addP, am);
24900     }
24901     if ((err == MP_OKAY) && (!inMont)) {
24902         err = sp_256_mod_mul_norm_5(addP->x, addP->x, p256_mod);
24903     }
24904     if ((err == MP_OKAY) && (!inMont)) {
24905         err = sp_256_mod_mul_norm_5(addP->y, addP->y, p256_mod);
24906     }
24907     if ((err == MP_OKAY) && (!inMont)) {
24908         err = sp_256_mod_mul_norm_5(addP->z, addP->z, p256_mod);
24909     }
24910     if (err == MP_OKAY) {
24911             err = sp_256_ecc_mulmod_5(point, point, k, 0, 0, heap);
24912     }
24913     if (err == MP_OKAY) {
24914             sp_256_proj_point_add_5(point, point, addP, tmp);
24915 
24916         if (map) {
24917                 sp_256_map_5(point, point, tmp);
24918         }
24919 
24920         err = sp_256_point_to_ecc_point_5(point, r);
24921     }
24922 
24923 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
24924     if (k != NULL)
24925         XFREE(k, heap, DYNAMIC_TYPE_ECC);
24926     if (point != NULL)
24927         XFREE(point, heap, DYNAMIC_TYPE_ECC);
24928 #endif
24929 
24930     return err;
24931 }
24932 
24933 #ifdef WOLFSSL_SP_SMALL
24934 /* Multiply the base point of P256 by the scalar and return the result.
24935  * If map is true then convert result to affine coordinates.
24936  *
24937  * r     Resulting point.
24938  * k     Scalar to multiply by.
24939  * map   Indicates whether to convert result to affine.
24940  * heap  Heap to use for allocation.
24941  * returns MEMORY_E when memory allocation fails and MP_OKAY on success.
24942  */
sp_256_ecc_mulmod_base_5(sp_point_256 * r,const sp_digit * k,int map,int ct,void * heap)24943 static int sp_256_ecc_mulmod_base_5(sp_point_256* r, const sp_digit* k,
24944         int map, int ct, void* heap)
24945 {
24946     /* No pre-computed values. */
24947     return sp_256_ecc_mulmod_5(r, &p256_base, k, map, ct, heap);
24948 }
24949 
24950 #else
24951 /* Striping precomputation table.
24952  * 8 points combined into a table of 256 points.
24953  * Distance of 32 between points.
24954  */
24955 static const sp_table_entry_256 p256_table[256] = {
24956     /* 0 */
24957     { { 0x00, 0x00, 0x00, 0x00, 0x00 },
24958       { 0x00, 0x00, 0x00, 0x00, 0x00 } },
24959     /* 1 */
24960     { { 0x730d418a9143cL,0xfc5fedb60179eL,0x762251075ba95L,0x55c679fb732b7L,
24961         0x018905f76a537L },
24962       { 0x25357ce95560aL,0xe4ba19e45cddfL,0xd21f3258b4ab8L,0x5d85d2e88688dL,
24963         0x08571ff182588L } },
24964     /* 2 */
24965     { { 0x886024147519aL,0xac26b372f0202L,0x785ebc8d0981eL,0x58e9a9d4a7caaL,
24966         0x0d953c50ddbdfL },
24967       { 0x361ccfd590f8fL,0x6b44e6c9179d6L,0x2eb64cf72e962L,0x88f37fd961102L,
24968         0x0863ebb7e9eb2L } },
24969     /* 3 */
24970     { { 0x6b6235cdb6485L,0xa22f0a2f97785L,0xf7e300b808f0eL,0x80a03e68d9544L,
24971         0x000076055b5ffL },
24972       { 0x4eb9b838d2010L,0xbb3243708a763L,0x42a660654014fL,0x3ee0e0e47d398L,
24973         0x0830877613437L } },
24974     /* 4 */
24975     { { 0x22fc516a0d2bbL,0x6c1a6234994f9L,0x7c62c8b0d5cc1L,0x667f9241cf3a5L,
24976         0x02f5e6961fd1bL },
24977       { 0x5c70bf5a01797L,0x4d609561925c1L,0x71fdb523d20b4L,0x0f7b04911b370L,
24978         0x0f648f9168d6fL } },
24979     /* 5 */
24980     { { 0x66847e137bbbcL,0x9e8a6a0bec9e5L,0x9d73463e43446L,0x0015b1c427617L,
24981         0x05abe0285133dL },
24982       { 0xa837cc04c7dabL,0x4c43260c0792aL,0x8e6cc37573d9fL,0x73830c9315627L,
24983         0x094bb725b6b6fL } },
24984     /* 6 */
24985     { { 0x9b48f720f141cL,0xcd2df5bc74bbfL,0x11045c46199b3L,0xc4efdc3f61294L,
24986         0x0cdd6bbcb2f7dL },
24987       { 0x6700beaf436fdL,0x6db99326beccaL,0x14f25226f647fL,0xe5f60c0fa7920L,
24988         0x0a361bebd4bdaL } },
24989     /* 7 */
24990     { { 0xa2558597c13c7L,0x5f50b7c3e128aL,0x3c09d1dc38d63L,0x292c07039aecfL,
24991         0x0ba12ca09c4b5L },
24992       { 0x08fa459f91dfdL,0x66ceea07fb9e4L,0xd780b293af43bL,0xef4b1eceb0899L,
24993         0x053ebb99d701fL } },
24994     /* 8 */
24995     { { 0x7ee31b0e63d34L,0x72a9e54fab4feL,0x5e7b5a4f46005L,0x4831c0493334dL,
24996         0x08589fb9206d5L },
24997       { 0x0f5cc6583553aL,0x4ae25649e5aa7L,0x0044652087909L,0x1c4fcc9045071L,
24998         0x0ebb0696d0254L } },
24999     /* 9 */
25000     { { 0x6ca15ac1647c5L,0x47c4cf5799461L,0x64dfbacb8127dL,0x7da3dc666aa37L,
25001         0x0eb2820cbd1b2L },
25002       { 0x6f8d86a87e008L,0x9d922378f3940L,0x0ccecb2d87dfaL,0xda1d56ed2e428L,
25003         0x01f28289b55a7L } },
25004     /* 10 */
25005     { { 0xaa0c03b89da99L,0x9eb8284022abbL,0x81c05e8a6f2d7L,0x4d6327847862bL,
25006         0x0337a4b5905e5L },
25007       { 0x7500d21f7794aL,0xb77d6d7f613c6L,0x4cfd6e8207005L,0xfbd60a5a37810L,
25008         0x00d65e0d5f4c2L } },
25009     /* 11 */
25010     { { 0x09bbeb5275d38L,0x450be0a358d9dL,0x73eb2654268a7L,0xa232f0762ff49L,
25011         0x0c23da24252f4L },
25012       { 0x1b84f0b94520cL,0x63b05bd78e5daL,0x4d29ea1096667L,0xcff13a4dcb869L,
25013         0x019de3b8cc790L } },
25014     /* 12 */
25015     { { 0xa716c26c5fe04L,0x0b3bba1bdb183L,0x4cb712c3b28deL,0xcbfd7432c586aL,
25016         0x0e34dcbd491fcL },
25017       { 0x8d46baaa58403L,0x8682e97a53b40L,0x6aaa8af9a6974L,0x0f7f9e3901273L,
25018         0x0e7641f447b4eL } },
25019     /* 13 */
25020     { { 0x53941df64ba59L,0xec0b0242fc7d7L,0x1581859d33f10L,0x57bf4f06dfc6aL,
25021         0x04a12df57052aL },
25022       { 0x6338f9439dbd0L,0xd4bde53e1fbfaL,0x1f1b314d3c24bL,0xea46fd5e4ffa2L,
25023         0x06af5aa93bb5bL } },
25024     /* 14 */
25025     { { 0x0b69910c91999L,0x402a580491da1L,0x8cc20900a24b4L,0x40133e0094b4bL,
25026         0x05fe3475a66a4L },
25027       { 0x8cabdf93e7b4bL,0x1a7c23f91ab0fL,0xd1e6263292b50L,0xa91642e889aecL,
25028         0x0b544e308ecfeL } },
25029     /* 15 */
25030     { { 0x8c6e916ddfdceL,0x66f89179e6647L,0xd4e67e12c3291L,0xc20b4e8d6e764L,
25031         0x0e0b6b2bda6b0L },
25032       { 0x12df2bb7efb57L,0xde790c40070d3L,0x79bc9441aac0dL,0x3774f90336ad6L,
25033         0x071c023de25a6L } },
25034     /* 16 */
25035     { { 0x8c244bfe20925L,0xc38fdce86762aL,0xd38706391c19aL,0x24f65a96a5d5dL,
25036         0x061d587d421d3L },
25037       { 0x673a2a37173eaL,0x0853778b65e87L,0x5bab43e238480L,0xefbe10f8441e0L,
25038         0x0fa11fe124621L } },
25039     /* 17 */
25040     { { 0x91f2b2cb19ffdL,0x5bb1923c231c8L,0xac5ca8e01ba8dL,0xbedcb6d03d678L,
25041         0x0586eb04c1f13L },
25042       { 0x5c6e527e8ed09L,0x3c1819ede20c3L,0x6c652fa1e81a3L,0x4f11278fd6c05L,
25043         0x019d5ac087086L } },
25044     /* 18 */
25045     { { 0x9f581309a4e1fL,0x1be92700741e9L,0xfd28d20ab7de7L,0x563f26a5ef0beL,
25046         0x0e7c0073f7f9cL },
25047       { 0xd663a0ef59f76L,0x5420fcb0501f6L,0xa6602d4669b3bL,0x3c0ac08c1f7a7L,
25048         0x0e08504fec65bL } },
25049     /* 19 */
25050     { { 0x8f68da031b3caL,0x9ee6da6d66f09L,0x4f246e86d1cabL,0x96b45bfd81fa9L,
25051         0x078f018825b09L },
25052       { 0xefde43a25787fL,0x0d1dccac9bb7eL,0x35bfc368016f8L,0x747a0cea4877bL,
25053         0x043a773b87e94L } },
25054     /* 20 */
25055     { { 0x77734d2b533d5L,0xf6a1bdddc0625L,0x79ec293673b8aL,0x66b1577e7c9aaL,
25056         0x0bb6de651c3b2L },
25057       { 0x9303ab65259b3L,0xd3d03a7480e7eL,0xb3cfc27d6a0afL,0xb99bc5ac83d19L,
25058         0x060b4619a5d18L } },
25059     /* 21 */
25060     { { 0xa38e11ae5aa1cL,0x2b49e73658bd6L,0xe5f87edb8b765L,0xffcd0b130014eL,
25061         0x09d0f27b2aeebL },
25062       { 0x246317a730a55L,0x2fddbbc83aca9L,0xc019a719c955bL,0xc48d07c1dfe0aL,
25063         0x0244a566d356eL } },
25064     /* 22 */
25065     { { 0x0394aeacf1f96L,0xa9024c271c6dbL,0x2cbd3b99f2122L,0xef692626ac1b8L,
25066         0x045e58c873581L },
25067       { 0xf479da38f9dbcL,0x46e888a040d3fL,0x6e0bed7a8aaf1L,0xb7a4945adfb24L,
25068         0x0c040e21cc1e4L } },
25069     /* 23 */
25070     { { 0xaf0006f8117b6L,0xff73a35433847L,0xd9475eb651969L,0x6ec7482b35761L,
25071         0x01cdf5c97682cL },
25072       { 0x775b411f04839L,0xf448de16987dbL,0x70b32197dbeacL,0xff3db2921dd1bL,
25073         0x0046755f8a92dL } },
25074     /* 24 */
25075     { { 0xac5d2bce8ffcdL,0x8b2fe61a82cc8L,0x202d6c70d53c4L,0xa5f3f6f161727L,
25076         0x0046e5e113b83L },
25077       { 0x8ff64d8007f01L,0x125af43183e7bL,0x5e1a03c7fb1efL,0x005b045c5ea63L,
25078         0x06e0106c3303dL } },
25079     /* 25 */
25080     { { 0x7358488dd73b1L,0x8f995ed0d948cL,0x56a2ab7767070L,0xcf1f38385ea8cL,
25081         0x0442594ede901L },
25082       { 0xaa2c912d4b65bL,0x3b96c90c37f8fL,0xe978d1f94c234L,0xe68ed326e4a15L,
25083         0x0a796fa514c2eL } },
25084     /* 26 */
25085     { { 0xfb604823addd7L,0x83e56693b3359L,0xcbf3c809e2a61L,0x66e9f885b78e3L,
25086         0x0e4ad2da9c697L },
25087       { 0xf7f428e048a61L,0x8cc092d9a0357L,0x03ed8ef082d19L,0x5143fc3a1af4cL,
25088         0x0c5e94046c37bL } },
25089     /* 27 */
25090     { { 0xa538c2be75f9eL,0xe8cb123a78476L,0x109c04b6fd1a9L,0x4747d85e4df0bL,
25091         0x063283dafdb46L },
25092       { 0x28cf7baf2df15L,0x550ad9a7f4ce7L,0x834bcc3e592c4L,0xa938fab226adeL,
25093         0x068bd19ab1981L } },
25094     /* 28 */
25095     { { 0xead511887d659L,0xf4b359305ac08L,0xfe74fe33374d5L,0xdfd696986981cL,
25096         0x0495292f53c6fL },
25097       { 0x78c9e1acec896L,0x10ec5b44844a8L,0x64d60a7d964b2L,0x68376696f7e26L,
25098         0x00ec7530d2603L } },
25099     /* 29 */
25100     { { 0x13a05ad2687bbL,0x6af32e21fa2daL,0xdd4607ba1f83bL,0x3f0b390f5ef51L,
25101         0x00f6207a66486L },
25102       { 0x7e3bb0f138233L,0x6c272aa718bd6L,0x6ec88aedd66b9L,0x6dcf8ed004072L,
25103         0x0ff0db07208edL } },
25104     /* 30 */
25105     { { 0xfa1014c95d553L,0xfd5d680a8a749L,0xf3b566fa44052L,0x0ea3183b4317fL,
25106         0x0313b513c8874L },
25107       { 0x2e2ac08d11549L,0x0bb4dee21cb40L,0x7f2320e071ee1L,0x9f8126b987dd4L,
25108         0x02d3abcf986f1L } },
25109     /* 31 */
25110     { { 0x88501815581a2L,0x56632211af4c2L,0xcab2e999a0a6dL,0x8cdf19ba7a0f0L,
25111         0x0c036fa10ded9L },
25112       { 0xe08bac1fbd009L,0x9006d1581629aL,0xb9e0d8f0b68b1L,0x0194c2eb32779L,
25113         0x0a6b2a2c4b6d4L } },
25114     /* 32 */
25115     { { 0x3e50f6d3549cfL,0x6ffacd665ed43L,0xe11fcb46f3369L,0x9860695bfdaccL,
25116         0x0810ee252af7cL },
25117       { 0x50fe17159bb2cL,0xbe758b357b654L,0x69fea72f7dfbeL,0x17452b057e74dL,
25118         0x0d485717a9273L } },
25119     /* 33 */
25120     { { 0x41a8af0cb5a98L,0x931f3110bf117L,0xb382adfd3da8fL,0x604e1994e2cbaL,
25121         0x06a6045a72f9aL },
25122       { 0xc0d3fa2b2411dL,0x3e510e96e0170L,0x865b3ccbe0eb8L,0x57903bcc9f738L,
25123         0x0d3e45cfaf9e1L } },
25124     /* 34 */
25125     { { 0xf69bbe83f7669L,0x8272877d6bce1L,0x244278d09f8aeL,0xc19c9548ae543L,
25126         0x0207755dee3c2L },
25127       { 0xd61d96fef1945L,0xefb12d28c387bL,0x2df64aa18813cL,0xb00d9fbcd1d67L,
25128         0x048dc5ee57154L } },
25129     /* 35 */
25130     { { 0x790bff7e5a199L,0xcf989ccbb7123L,0xa519c79e0efb8L,0xf445c27a2bfe0L,
25131         0x0f2fb0aeddff6L },
25132       { 0x09575f0b5025fL,0xd740fa9f2241cL,0x80bfbd0550543L,0xd5258fa3c8ad3L,
25133         0x0a13e9015db28L } },
25134     /* 36 */
25135     { { 0x7a350a2b65cbcL,0x722a464226f9fL,0x23f07a10b04b9L,0x526f265ce241eL,
25136         0x02bf0d6b01497L },
25137       { 0x4dd3f4b216fb7L,0x67fbdda26ad3dL,0x708505cf7d7b8L,0xe89faeb7b83f6L,
25138         0x042a94a5a162fL } },
25139     /* 37 */
25140     { { 0x6ad0beaadf191L,0x9025a268d7584L,0x94dc1f60f8a48L,0xde3de86030504L,
25141         0x02c2dd969c65eL },
25142       { 0x2171d93849c17L,0xba1da250dd6d0L,0xc3a5485460488L,0x6dbc4810c7063L,
25143         0x0f437fa1f42c5L } },
25144     /* 38 */
25145     { { 0x0d7144a0f7dabL,0x931776e9ac6aaL,0x5f397860f0497L,0x7aa852c0a050fL,
25146         0x0aaf45b335470L },
25147       { 0x37c33c18d364aL,0x063e49716585eL,0x5ec5444d40b9bL,0x72bcf41716811L,
25148         0x0cdf6310df4f2L } },
25149     /* 39 */
25150     { { 0x3c6238ea8b7efL,0x1885bc2287747L,0xbda8e3408e935L,0x2ff2419567722L,
25151         0x0f0d008bada9eL },
25152       { 0x2671d2414d3b1L,0x85b019ea76291L,0x53bcbdbb37549L,0x7b8b5c61b96d4L,
25153         0x05bd5c2f5ca88L } },
25154     /* 40 */
25155     { { 0xf469ef49a3154L,0x956e2b2e9aef0L,0xa924a9c3e85a5L,0x471945aaec1eaL,
25156         0x0aa12dfc8a09eL },
25157       { 0x272274df69f1dL,0x2ca2ff5e7326fL,0x7a9dd44e0e4c8L,0xa901b9d8ce73bL,
25158         0x06c036e73e48cL } },
25159     /* 41 */
25160     { { 0xae12a0f6e3138L,0x0025ad345a5cfL,0x5672bc56966efL,0xbe248993c64b4L,
25161         0x0292ff65896afL },
25162       { 0x50d445e213402L,0x274392c9fed52L,0xa1c72e8f6580eL,0x7276097b397fdL,
25163         0x0644e0c90311bL } },
25164     /* 42 */
25165     { { 0x421e1a47153f0L,0x79920418c9e1eL,0x05d7672b86c3bL,0x9a7793bdce877L,
25166         0x0f25ae793cab7L },
25167       { 0x194a36d869d0cL,0x824986c2641f3L,0x96e945e9d55c8L,0x0a3e49fb5ea30L,
25168         0x039b8e65313dbL } },
25169     /* 43 */
25170     { { 0x54200b6fd2e59L,0x669255c98f377L,0xe2a573935e2c0L,0xdb06d9dab21a0L,
25171         0x039122f2f0f19L },
25172       { 0xce1e003cad53cL,0x0fe65c17e3cfbL,0xaa13877225b2cL,0xff8d72baf1d29L,
25173         0x08de80af8ce80L } },
25174     /* 44 */
25175     { { 0xea8d9207bbb76L,0x7c21782758afbL,0xc0436b1921c7eL,0x8c04dfa2b74b1L,
25176         0x0871949062e36L },
25177       { 0x928bba3993df5L,0xb5f3b3d26ab5fL,0x5b55050639d75L,0xfde1011aa78a8L,
25178         0x0fc315e6a5b74L } },
25179     /* 45 */
25180     { { 0xfd41ae8d6ecfaL,0xf61aec7f86561L,0x924741d5f8c44L,0x908898452a7b4L,
25181         0x0e6d4a7adee38L },
25182       { 0x52ed14593c75dL,0xa4dd271162605L,0xba2c7db70a70dL,0xae57d2aede937L,
25183         0x035dfaf9a9be2L } },
25184     /* 46 */
25185     { { 0x56fcdaa736636L,0x97ae2cab7e6b9L,0xf34996609f51dL,0x0d2bfb10bf410L,
25186         0x01da5c7d71c83L },
25187       { 0x1e4833cce6825L,0x8ff9573c3b5c4L,0x23036b815ad11L,0xb9d6a28552c7fL,
25188         0x07077c0fddbf4L } },
25189     /* 47 */
25190     { { 0x3ff8d46b9661cL,0x6b0d2cfd71bf6L,0x847f8f7a1dfd3L,0xfe440373e140aL,
25191         0x053a8632ee50eL },
25192       { 0x6ff68696d8051L,0x95c74f468a097L,0xe4e26bddaec0cL,0xfcc162994dc35L,
25193         0x0028ca76d34e1L } },
25194     /* 48 */
25195     { { 0xd47dcfc9877eeL,0x10801d0002d11L,0x4c260b6c8b362L,0xf046d002c1175L,
25196         0x004c17cd86962L },
25197       { 0xbd094b0daddf5L,0x7524ce55c06d9L,0x2da03b5bea235L,0x7474663356e67L,
25198         0x0f7ba4de9fed9L } },
25199     /* 49 */
25200     { { 0xbfa34ebe1263fL,0x3571ae7ce6d0dL,0x2a6f523557637L,0x1c41d24405538L,
25201         0x0e31f96005213L },
25202       { 0xb9216ea6b6ec6L,0x2e73c2fc44d1bL,0x9d0a29437a1d1L,0xd47bc10e7eac8L,
25203         0x0aa3a6259ce34L } },
25204     /* 50 */
25205     { { 0xf9df536f3dcd3L,0x50d2bf7360fbcL,0xf504f5b6cededL,0xdaee491710fadL,
25206         0x02398dd627e79L },
25207       { 0x705a36d09569eL,0xbb5149f769cf4L,0x5f6034cea0619L,0x6210ff9c03773L,
25208         0x05717f5b21c04L } },
25209     /* 51 */
25210     { { 0x229c921dd895eL,0x0040c284519feL,0xd637ecd8e5185L,0x28defa13d2391L,
25211         0x0660a2c560e3cL },
25212       { 0xa88aed67fcbd0L,0x780ea9f0969ccL,0x2e92b4dc84724L,0x245332b2f4817L,
25213         0x0624ee54c4f52L } },
25214     /* 52 */
25215     { { 0x49ce4d897ecccL,0xd93f9880aa095L,0x43a7c204d49d1L,0xfbc0723c24230L,
25216         0x04f392afb92bdL },
25217       { 0x9f8fa7de44fd9L,0xe457b32156696L,0x68ebc3cb66cfbL,0x399cdb2fa8033L,
25218         0x08a3e7977ccdbL } },
25219     /* 53 */
25220     { { 0x1881f06c4b125L,0x00f6e3ca8cddeL,0xc7a13e9ae34e3L,0x4404ef6999de5L,
25221         0x03888d02370c2L },
25222       { 0x8035644f91081L,0x615f015504762L,0x32cd36e3d9fcfL,0x23361827edc86L,
25223         0x0a5e62e471810L } },
25224     /* 54 */
25225     { { 0x25ee32facd6c8L,0x5454bcbc661a8L,0x8df9931699c63L,0x5adc0ce3edf79L,
25226         0x02c4768e6466aL },
25227       { 0x6ff8c90a64bc9L,0x20e4779f5cb34L,0xc05e884630a60L,0x52a0d949d064bL,
25228         0x07b5e6441f9e6L } },
25229     /* 55 */
25230     { { 0x9422c1d28444aL,0xd8be136a39216L,0xb0c7fcee996c5L,0x744a2387afe5fL,
25231         0x0b8af73cb0c8dL },
25232       { 0xe83aa338b86fdL,0x58a58a5cff5fdL,0x0ac9433fee3f1L,0x0895c9ee8f6f2L,
25233         0x0a036395f7f3fL } },
25234     /* 56 */
25235     { { 0x3c6bba10f7770L,0x81a12a0e248c7L,0x1bc2b9fa6f16dL,0xb533100df6825L,
25236         0x04be36b01875fL },
25237       { 0x6086e9fb56dbbL,0x8b07e7a4f8922L,0x6d52f20306fefL,0x00c0eeaccc056L,
25238         0x08cbc9a871bdcL } },
25239     /* 57 */
25240     { { 0x1895cc0dac4abL,0x40712ff112e13L,0xa1cee57a874a4L,0x35f86332ae7c6L,
25241         0x044e7553e0c08L },
25242       { 0x03fff7734002dL,0x8b0b34425c6d5L,0xe8738b59d35cbL,0xfc1895f702760L,
25243         0x0470a683a5eb8L } },
25244     /* 58 */
25245     { { 0x761dc90513482L,0x2a01e9276a81bL,0xce73083028720L,0xc6efcda441ee0L,
25246         0x016410690c63dL },
25247       { 0x34a066d06a2edL,0x45189b100bf50L,0xb8218c9dd4d77L,0xbb4fd914ae72aL,
25248         0x0d73479fd7abcL } },
25249     /* 59 */
25250     { { 0xefb165ad4c6e5L,0x8f5b06d04d7edL,0x575cb14262cf0L,0x666b12ed5bb18L,
25251         0x0816469e30771L },
25252       { 0xb9d79561e291eL,0x22c1de1661d7aL,0x35e0513eb9dafL,0x3f9cf49827eb1L,
25253         0x00a36dd23f0ddL } },
25254     /* 60 */
25255     { { 0xd32c741d5533cL,0x9e8684628f098L,0x349bd117c5f5aL,0xb11839a228adeL,
25256         0x0e331dfd6fdbaL },
25257       { 0x0ab686bcc6ed8L,0xbdef7a260e510L,0xce850d77160c3L,0x33899063d9a7bL,
25258         0x0d3b4782a492eL } },
25259     /* 61 */
25260     { { 0x9b6e8f3821f90L,0xed66eb7aada14L,0xa01311692edd9L,0xa5bd0bb669531L,
25261         0x07281275a4c86L },
25262       { 0x858f7d3ff47e5L,0xbc61016441503L,0xdfd9bb15e1616L,0x505962b0f11a7L,
25263         0x02c062e7ece14L } },
25264     /* 62 */
25265     { { 0xf996f0159ac2eL,0x36cbdb2713a76L,0x8e46047281e77L,0x7ef12ad6d2880L,
25266         0x0282a35f92c4eL },
25267       { 0x54b1ec0ce5cd2L,0xc91379c2299c3L,0xe82c11ecf99efL,0x2abd992caf383L,
25268         0x0c71cd513554dL } },
25269     /* 63 */
25270     { { 0x5de9c09b578f4L,0x58e3affa7a488L,0x9182f1f1884e2L,0xf3a38f76b1b75L,
25271         0x0c50f6740cf47L },
25272       { 0x4adf3374b68eaL,0x2369965fe2a9cL,0x5a53050a406f3L,0x58dc2f86a2228L,
25273         0x0b9ecb3a72129L } },
25274     /* 64 */
25275     { { 0x8410ef4f8b16aL,0xfec47b266a56fL,0xd9c87c197241aL,0xab1b0a406b8e6L,
25276         0x0803f3e02cd42L },
25277       { 0x309a804dbec69L,0xf73bbad05f7f0L,0xd8e197fa83b85L,0xadc1c6097273aL,
25278         0x0c097440e5067L } },
25279     /* 65 */
25280     { { 0xa56f2c379ab34L,0x8b841df8d1846L,0x76c68efa8ee06L,0x1f30203144591L,
25281         0x0f1af32d5915fL },
25282       { 0x375315d75bd50L,0xbaf72f67bc99cL,0x8d7723f837cffL,0x1c8b0613a4184L,
25283         0x023d0f130e2d4L } },
25284     /* 66 */
25285     { { 0xab6edf41500d9L,0xe5fcbeada8857L,0x97259510d890aL,0xfadd52fe86488L,
25286         0x0b0288dd6c0a3L },
25287       { 0x20f30650bcb08L,0x13695d6e16853L,0x989aa7671af63L,0xc8d231f520a7bL,
25288         0x0ffd3724ff408L } },
25289     /* 67 */
25290     { { 0x68e64b458e6cbL,0x20317a5d28539L,0xaa75f56992dadL,0x26df3814ae0b7L,
25291         0x0f5590f4ad78cL },
25292       { 0x24bd3cf0ba55aL,0x4a0c778bae0fcL,0x83b674a0fc472L,0x4a201ce9864f6L,
25293         0x018d6da54f6f7L } },
25294     /* 68 */
25295     { { 0x3e225d5be5a2bL,0x835934f3c6ed9L,0x2626ffc6fe799L,0x216a431409262L,
25296         0x050bbb4d97990L },
25297       { 0x191c6e57ec63eL,0x40181dcdb2378L,0x236e0f665422cL,0x49c341a8099b0L,
25298         0x02b10011801feL } },
25299     /* 69 */
25300     { { 0x8b5c59b391593L,0xa2598270fcfc6L,0x19adcbbc385f5L,0xae0c7144f3aadL,
25301         0x0dd55899983fbL },
25302       { 0x88b8e74b82ff4L,0x4071e734c993bL,0x3c0322ad2e03cL,0x60419a7a9eaf4L,
25303         0x0e6e4c551149dL } },
25304     /* 70 */
25305     { { 0x655bb1e9af288L,0x64f7ada93155fL,0xb2820e5647e1aL,0x56ff43697e4bcL,
25306         0x051e00db107edL },
25307       { 0x169b8771c327eL,0x0b4a96c2ad43dL,0xdeb477929cdb2L,0x9177c07d51f53L,
25308         0x0e22f42414982L } },
25309     /* 71 */
25310     { { 0x5e8f4635f1abbL,0xb568538874cd4L,0x5a8034d7edc0cL,0x48c9c9472c1fbL,
25311         0x0f709373d52dcL },
25312       { 0x966bba8af30d6L,0x4af137b69c401L,0x361c47e95bf5fL,0x5b113966162a9L,
25313         0x0bd52d288e727L } },
25314     /* 72 */
25315     { { 0x55c7a9c5fa877L,0x727d3a3d48ab1L,0x3d189d817dad6L,0x77a643f43f9e7L,
25316         0x0a0d0f8e4c8aaL },
25317       { 0xeafd8cc94f92dL,0xbe0c4ddb3a0bbL,0x82eba14d818c8L,0x6a0022cc65f8bL,
25318         0x0a56c78c7946dL } },
25319     /* 73 */
25320     { { 0x2391b0dd09529L,0xa63daddfcf296L,0xb5bf481803e0eL,0x367a2c77351f5L,
25321         0x0d8befdf8731aL },
25322       { 0x19d42fc0157f4L,0xd7fec8e650ab9L,0x2d48b0af51caeL,0x6478cdf9cb400L,
25323         0x0854a68a5ce9fL } },
25324     /* 74 */
25325     { { 0x5f67b63506ea5L,0x89a4fe0d66dc3L,0xe95cd4d9286c4L,0x6a953f101d3bfL,
25326         0x05cacea0b9884L },
25327       { 0xdf60c9ceac44dL,0xf4354d1c3aa90L,0xd5dbabe3db29aL,0xefa908dd3de8aL,
25328         0x0e4982d1235e4L } },
25329     /* 75 */
25330     { { 0x04a22c34cd55eL,0xb32680d132231L,0xfa1d94358695bL,0x0499fb345afa1L,
25331         0x08046b7f616b2L },
25332       { 0x3581e38e7d098L,0x8df46f0b70b53L,0x4cb78c4d7f61eL,0xaf5530dea9ea4L,
25333         0x0eb17ca7b9082L } },
25334     /* 76 */
25335     { { 0x1b59876a145b9L,0x0fc1bc71ec175L,0x92715bba5cf6bL,0xe131d3e035653L,
25336         0x0097b00bafab5L },
25337       { 0x6c8e9565f69e1L,0x5ab5be5199aa6L,0xa4fd98477e8f7L,0xcc9e6033ba11dL,
25338         0x0f95c747bafdbL } },
25339     /* 77 */
25340     { { 0xf01d3bebae45eL,0xf0c4bc6955558L,0xbc64fc6a8ebe9L,0xd837aeb705b1dL,
25341         0x03512601e566eL },
25342       { 0x6f1e1fa1161cdL,0xd54c65ef87933L,0x24f21e5328ab8L,0xab6b4757eee27L,
25343         0x00ef971236068L } },
25344     /* 78 */
25345     { { 0x98cf754ca4226L,0x38f8642c8e025L,0x68e17905eede1L,0xbc9548963f744L,
25346         0x0fc16d9333b4fL },
25347       { 0x6fb31e7c800caL,0x312678adaabe9L,0xff3e8b5138063L,0x7a173d6244976L,
25348         0x014ca4af1b95dL } },
25349     /* 79 */
25350     { { 0x771babd2f81d5L,0x6901f7d1967a4L,0xad9c9071a5f9dL,0x231dd898bef7cL,
25351         0x04057b063f59cL },
25352       { 0xd82fe89c05c0aL,0x6f1dc0df85bffL,0x35a16dbe4911cL,0x0b133befccaeaL,
25353         0x01c3b5d64f133L } },
25354     /* 80 */
25355     { { 0x14bfe80ec21feL,0x6ac255be825feL,0xf4a5d67f6ce11L,0x63af98bc5a072L,
25356         0x0fad27148db7eL },
25357       { 0x0b6ac29ab05b3L,0x3c4e251ae690cL,0x2aade7d37a9a8L,0x1a840a7dc875cL,
25358         0x077387de39f0eL } },
25359     /* 81 */
25360     { { 0xecc49a56c0dd7L,0xd846086c741e9L,0x505aecea5cffcL,0xc47e8f7a1408fL,
25361         0x0b37b85c0bef0L },
25362       { 0x6b6e4cc0e6a8fL,0xbf6b388f23359L,0x39cef4efd6d4bL,0x28d5aba453facL,
25363         0x09c135ac8f9f6L } },
25364     /* 82 */
25365     { { 0xa320284e35743L,0xb185a3cdef32aL,0xdf19819320d6aL,0x851fb821b1761L,
25366         0x05721361fc433L },
25367       { 0xdb36a71fc9168L,0x735e5c403c1f0L,0x7bcd8f55f98baL,0x11bdf64ca87e3L,
25368         0x0dcbac3c9e6bbL } },
25369     /* 83 */
25370     { { 0xd99684518cbe2L,0x189c9eb04ef01L,0x47feebfd242fcL,0x6862727663c7eL,
25371         0x0b8c1c89e2d62L },
25372       { 0x58bddc8e1d569L,0xc8b7d88cd051aL,0x11f31eb563809L,0x22d426c27fd9fL,
25373         0x05d23bbda2f94L } },
25374     /* 84 */
25375     { { 0xc729495c8f8beL,0x803bf362bf0a1L,0xf63d4ac2961c4L,0xe9009e418403dL,
25376         0x0c109f9cb91ecL },
25377       { 0x095d058945705L,0x96ddeb85c0c2dL,0xa40449bb9083dL,0x1ee184692b8d7L,
25378         0x09bc3344f2eeeL } },
25379     /* 85 */
25380     { { 0xae35642913074L,0x2748a542b10d5L,0x310732a55491bL,0x4cc1469ca665bL,
25381         0x029591d525f1aL },
25382       { 0xf5b6bb84f983fL,0x419f5f84e1e76L,0x0baa189be7eefL,0x332c1200d4968L,
25383         0x06376551f18efL } },
25384     /* 86 */
25385     { { 0x5f14e562976ccL,0xe60ef12c38bdaL,0xcca985222bca3L,0x987abbfa30646L,
25386         0x0bdb79dc808e2L },
25387       { 0xcb5c9cb06a772L,0xaafe536dcefd2L,0xc2b5db838f475L,0xc14ac2a3e0227L,
25388         0x08ee86001add3L } },
25389     /* 87 */
25390     { { 0x96981a4ade873L,0x4dc4fba48ccbeL,0xa054ba57ee9aaL,0xaa4b2cee28995L,
25391         0x092e51d7a6f77L },
25392       { 0xbafa87190a34dL,0x5bf6bd1ed1948L,0xcaf1144d698f7L,0xaaaad00ee6e30L,
25393         0x05182f86f0a56L } },
25394     /* 88 */
25395     { { 0x6212c7a4cc99cL,0x683e6d9ca1fbaL,0xac98c5aff609bL,0xa6f25dbb27cb5L,
25396         0x091dcab5d4073L },
25397       { 0x6cc3d5f575a70L,0x396f8d87fa01bL,0x99817360cb361L,0x4f2b165d4e8c8L,
25398         0x017a0cedb9797L } },
25399     /* 89 */
25400     { { 0x61e2a076c8d3aL,0x39210f924b388L,0x3a835d9701aadL,0xdf4194d0eae41L,
25401         0x02e8ce36c7f4cL },
25402       { 0x73dab037a862bL,0xb760e4c8fa912L,0x3baf2dd01ba9bL,0x68f3f96453883L,
25403         0x0f4ccc6cb34f6L } },
25404     /* 90 */
25405     { { 0xf525cf1f79687L,0x9592efa81544eL,0x5c78d297c5954L,0xf3c9e1231741aL,
25406         0x0ac0db4889a0dL },
25407       { 0xfc711df01747fL,0x58ef17df1386bL,0xccb6bb5592b93L,0x74a2e5880e4f5L,
25408         0x095a64a6194c9L } },
25409     /* 91 */
25410     { { 0x1efdac15a4c93L,0x738258514172cL,0x6cb0bad40269bL,0x06776a8dfb1c1L,
25411         0x0231e54ba2921L },
25412       { 0xdf9178ae6d2dcL,0x3f39112918a70L,0xe5b72234d6aa6L,0x31e1f627726b5L,
25413         0x0ab0be032d8a7L } },
25414     /* 92 */
25415     { { 0xad0e98d131f2dL,0xe33b04f101097L,0x5e9a748637f09L,0xa6791ac86196dL,
25416         0x0f1bcc8802cf6L },
25417       { 0x69140e8daacb4L,0x5560f6500925cL,0x77937a63c4e40L,0xb271591cc8fc4L,
25418         0x0851694695aebL } },
25419     /* 93 */
25420     { { 0x5c143f1dcf593L,0x29b018be3bde3L,0xbdd9d3d78202bL,0x55d8e9cdadc29L,
25421         0x08f67d9d2daadL },
25422       { 0x116567481ea5fL,0xe9e34c590c841L,0x5053fa8e7d2ddL,0x8b5dffdd43f40L,
25423         0x0f84572b9c072L } },
25424     /* 94 */
25425     { { 0xa7a7197af71c9L,0x447a7365655e1L,0xe1d5063a14494L,0x2c19a1b4ae070L,
25426         0x0edee2710616bL },
25427       { 0x034f511734121L,0x554a25e9f0b2fL,0x40c2ecf1cac6eL,0xd7f48dc148f3aL,
25428         0x09fd27e9b44ebL } },
25429     /* 95 */
25430     { { 0x7658af6e2cb16L,0x2cfe5919b63ccL,0x68d5583e3eb7dL,0xf3875a8c58161L,
25431         0x0a40c2fb6958fL },
25432       { 0xec560fedcc158L,0xc655f230568c9L,0xa307e127ad804L,0xdecfd93967049L,
25433         0x099bc9bb87dc6L } },
25434     /* 96 */
25435     { { 0x9521d927dafc6L,0x695c09cd1984aL,0x9366dde52c1fbL,0x7e649d9581a0fL,
25436         0x09abe210ba16dL },
25437       { 0xaf84a48915220L,0x6a4dd816c6480L,0x681ca5afa7317L,0x44b0c7d539871L,
25438         0x07881c25787f3L } },
25439     /* 97 */
25440     { { 0x99b51e0bcf3ffL,0xc5127f74f6933L,0xd01d9680d02cbL,0x89408fb465a2dL,
25441         0x015e6e319a30eL },
25442       { 0xd6e0d3e0e05f4L,0xdc43588404646L,0x4f850d3fad7bdL,0x72cebe61c7d1cL,
25443         0x00e55facf1911L } },
25444     /* 98 */
25445     { { 0xd9806f8787564L,0x2131e85ce67e9L,0x819e8d61a3317L,0x65776b0158cabL,
25446         0x0d73d09766fe9L },
25447       { 0x834251eb7206eL,0x0fc618bb42424L,0xe30a520a51929L,0xa50b5dcbb8595L,
25448         0x09250a3748f15L } },
25449     /* 99 */
25450     { { 0xf08f8be577410L,0x035077a8c6cafL,0xc0a63a4fd408aL,0x8c0bf1f63289eL,
25451         0x077414082c1ccL },
25452       { 0x40fa6eb0991cdL,0x6649fdc29605aL,0x324fd40c1ca08L,0x20b93a68a3c7bL,
25453         0x08cb04f4d12ebL } },
25454     /* 100 */
25455     { { 0x2d0556906171cL,0xcdb0240c3fb1cL,0x89068419073e9L,0x3b51db8e6b4fdL,
25456         0x0e4e429ef4712L },
25457       { 0xdd53c38ec36f4L,0x01ff4b6a270b8L,0x79a9a48f9d2dcL,0x65525d066e078L,
25458         0x037bca2ff3c6eL } },
25459     /* 101 */
25460     { { 0x2e3c7df562470L,0xa2c0964ac94cdL,0x0c793be44f272L,0xb22a7c6d5df98L,
25461         0x059913edc3002L },
25462       { 0x39a835750592aL,0x80e783de027a1L,0xa05d64f99e01dL,0xe226cf8c0375eL,
25463         0x043786e4ab013L } },
25464     /* 102 */
25465     { { 0x2b0ed9e56b5a6L,0xa6d9fc68f9ff3L,0x97846a70750d9L,0x9e7aec15e8455L,
25466         0x08638ca98b7e7L },
25467       { 0xae0960afc24b2L,0xaf4dace8f22f5L,0xecba78f05398eL,0xa6f03b765dd0aL,
25468         0x01ecdd36a7b3aL } },
25469     /* 103 */
25470     { { 0xacd626c5ff2f3L,0xc02873a9785d3L,0x2110d54a2d516L,0xf32dad94c9fadL,
25471         0x0d85d0f85d459L },
25472       { 0x00b8d10b11da3L,0x30a78318c49f7L,0x208decdd2c22cL,0x3c62556988f49L,
25473         0x0a04f19c3b4edL } },
25474     /* 104 */
25475     { { 0x924c8ed7f93bdL,0x5d392f51f6087L,0x21b71afcb64acL,0x50b07cae330a8L,
25476         0x092b2eeea5c09L },
25477       { 0xc4c9485b6e235L,0xa92936c0f085aL,0x0508891ab2ca4L,0x276c80faa6b3eL,
25478         0x01ee782215834L } },
25479     /* 105 */
25480     { { 0xa2e00e63e79f7L,0xb2f399d906a60L,0x607c09df590e7L,0xe1509021054a6L,
25481         0x0f3f2ced857a6L },
25482       { 0x510f3f10d9b55L,0xacd8642648200L,0x8bd0e7c9d2fcfL,0xe210e5631aa7eL,
25483         0x00f56a4543da3L } },
25484     /* 106 */
25485     { { 0x1bffa1043e0dfL,0xcc9c007e6d5b2L,0x4a8517a6c74b6L,0xe2631a656ec0dL,
25486         0x0bd8f17411969L },
25487       { 0xbbb86beb7494aL,0x6f45f3b8388a9L,0x4e5a79a1567d4L,0xfa09df7a12a7aL,
25488         0x02d1a1c3530ccL } },
25489     /* 107 */
25490     { { 0xe3813506508daL,0xc4a1d795a7192L,0xa9944b3336180L,0xba46cddb59497L,
25491         0x0a107a65eb91fL },
25492       { 0x1d1c50f94d639L,0x758a58b7d7e6dL,0xd37ca1c8b4af3L,0x9af21a7c5584bL,
25493         0x0183d760af87aL } },
25494     /* 108 */
25495     { { 0x697110dde59a4L,0x070e8bef8729dL,0xf2ebe78f1ad8dL,0xd754229b49634L,
25496         0x01d44179dc269L },
25497       { 0xdc0cf8390d30eL,0x530de8110cb32L,0xbc0339a0a3b27L,0xd26231af1dc52L,
25498         0x0771f9cc29606L } },
25499     /* 109 */
25500     { { 0x93e7785040739L,0xb98026a939999L,0x5f8fc2644539dL,0x718ecf40f6f2fL,
25501         0x064427a310362L },
25502       { 0xf2d8785428aa8L,0x3febfb49a84f4L,0x23d01ac7b7adcL,0x0d6d201b2c6dfL,
25503         0x049d9b7496ae9L } },
25504     /* 110 */
25505     { { 0x8d8bc435d1099L,0x4e8e8d1a08cc7L,0xcb68a412adbcdL,0x544502c2e2a02L,
25506         0x09037d81b3f60L },
25507       { 0xbac27074c7b61L,0xab57bfd72e7cdL,0x96d5352fe2031L,0x639c61ccec965L,
25508         0x008c3de6a7cc0L } },
25509     /* 111 */
25510     { { 0xdd020f6d552abL,0x9805cd81f120fL,0x135129156baffL,0x6b2f06fb7c3e9L,
25511         0x0c69094424579L },
25512       { 0x3ae9c41231bd1L,0x875cc5820517bL,0x9d6a1221eac6eL,0x3ac0208837abfL,
25513         0x03fa3db02cafeL } },
25514     /* 112 */
25515     { { 0xa3e6505058880L,0xef643943f2d75L,0xab249257da365L,0x08ff4147861cfL,
25516         0x0c5c4bdb0fdb8L },
25517       { 0x13e34b272b56bL,0x9511b9043a735L,0x8844969c8327eL,0xb6b5fd8ce37dfL,
25518         0x02d56db9446c2L } },
25519     /* 113 */
25520     { { 0x1782fff46ac6bL,0x2607a2e425246L,0x9a48de1d19f79L,0xba42fafea3c40L,
25521         0x00f56bd9de503L },
25522       { 0xd4ed1345cda49L,0xfc816f299d137L,0xeb43402821158L,0xb5f1e7c6a54aaL,
25523         0x04003bb9d1173L } },
25524     /* 114 */
25525     { { 0xe8189a0803387L,0xf539cbd4043b8L,0x2877f21ece115L,0x2f9e4297208ddL,
25526         0x053765522a07fL },
25527       { 0x80a21a8a4182dL,0x7a3219df79a49L,0xa19a2d4a2bbd0L,0x4549674d0a2e1L,
25528         0x07a056f586c5dL } },
25529     /* 115 */
25530     { { 0xb25589d8a2a47L,0x48c3df2773646L,0xbf0d5395b5829L,0x267551ec000eaL,
25531         0x077d482f17a1aL },
25532       { 0x1bd9587853948L,0xbd6cfbffeeb8aL,0x0681e47a6f817L,0xb0e4ab6ec0578L,
25533         0x04115012b2b38L } },
25534     /* 116 */
25535     { { 0x3f0f46de28cedL,0x609b13ec473c7L,0xe5c63921d5da7L,0x094661b8ce9e6L,
25536         0x0cdf04572fbeaL },
25537       { 0x3c58b6c53c3b0L,0x10447b843c1cbL,0xcb9780e97fe3cL,0x3109fb2b8ae12L,
25538         0x0ee703dda9738L } },
25539     /* 117 */
25540     { { 0x15140ff57e43aL,0xd3b1b811b8345L,0xf42b986d44660L,0xce212b3b5dff8L,
25541         0x02a0ad89da162L },
25542       { 0x4a6946bc277baL,0x54c141c27664eL,0xabf6274c788c9L,0x4659141aa64ccL,
25543         0x0d62d0b67ac2bL } },
25544     /* 118 */
25545     { { 0x5d87b2c054ac4L,0x59f27df78839cL,0x18128d6570058L,0x2426edf7cbf3bL,
25546         0x0b39a23f2991cL },
25547       { 0x84a15f0b16ae5L,0xb1a136f51b952L,0x27007830c6a05L,0x4cc51d63c137fL,
25548         0x004ed0092c067L } },
25549     /* 119 */
25550     { { 0x185d19ae90393L,0x294a3d64e61f4L,0x854fc143047b4L,0xc387ae0001a69L,
25551         0x0a0a91fc10177L },
25552       { 0xa3f01ae2c831eL,0x822b727e16ff0L,0xa3075b4bb76aeL,0x0c418f12c8a15L,
25553         0x0084cf9889ed2L } },
25554     /* 120 */
25555     { { 0x509defca6becfL,0x807dffb328d98L,0x778e8b92fceaeL,0xf77e5d8a15c44L,
25556         0x0d57955b273abL },
25557       { 0xda79e31b5d4f1L,0x4b3cfa7a1c210L,0xc27c20baa52f0L,0x41f1d4d12089dL,
25558         0x08e14ea4202d1L } },
25559     /* 121 */
25560     { { 0x50345f2897042L,0x1f43402c4aeedL,0x8bdfb218d0533L,0xd158c8d9c194cL,
25561         0x0597e1a372aa4L },
25562       { 0x7ec1acf0bd68cL,0xdcab024945032L,0x9fe3e846d4be0L,0x4dea5b9c8d7acL,
25563         0x0ca3f0236199bL } },
25564     /* 122 */
25565     { { 0xa10b56170bd20L,0xf16d3f5de7592L,0x4b2ade20ea897L,0x07e4a3363ff14L,
25566         0x0bde7fd7e309cL },
25567       { 0xbb6d2b8f5432cL,0xcbe043444b516L,0x8f95b5a210dc1L,0xd1983db01e6ffL,
25568         0x0b623ad0e0a7dL } },
25569     /* 123 */
25570     { { 0xbd67560c7b65bL,0x9023a4a289a75L,0x7b26795ab8c55L,0x137bf8220fd0dL,
25571         0x0d6aa2e4658ecL },
25572       { 0xbc00b5138bb85L,0x21d833a95c10aL,0x702a32e8c31d1L,0x513ab24ff00b1L,
25573         0x0111662e02dccL } },
25574     /* 124 */
25575     { { 0x14015efb42b87L,0x701b6c4dff781L,0x7d7c129bd9f5dL,0x50f866ecccd7aL,
25576         0x0db3ee1cb94b7L },
25577       { 0xf3db0f34837cfL,0x8bb9578d4fb26L,0xc56657de7eed1L,0x6a595d2cdf937L,
25578         0x0886a64425220L } },
25579     /* 125 */
25580     { { 0x34cfb65b569eaL,0x41f72119c13c2L,0x15a619e200111L,0x17bc8badc85daL,
25581         0x0a70cf4eb018aL },
25582       { 0xf97ae8c4a6a65L,0x270134378f224L,0xf7e096036e5cfL,0x7b77be3a609e4L,
25583         0x0aa4772abd174L } },
25584     /* 126 */
25585     { { 0x761317aa60cc0L,0x610368115f676L,0xbc1bb5ac79163L,0xf974ded98bb4bL,
25586         0x0611a6ddc30faL },
25587       { 0x78cbcc15ee47aL,0x824e0d96a530eL,0xdd9ed882e8962L,0x9c8836f35adf3L,
25588         0x05cfffaf81642L } },
25589     /* 127 */
25590     { { 0x54cff9b7a99cdL,0x9d843c45a1c0dL,0x2c739e17bf3b9L,0x994c038a908f6L,
25591         0x06e5a6b237dc1L },
25592       { 0xb454e0ba5db77L,0x7facf60d63ef8L,0x6608378b7b880L,0xabcce591c0c67L,
25593         0x0481a238d242dL } },
25594     /* 128 */
25595     { { 0x17bc035d0b34aL,0x6b8327c0a7e34L,0xc0362d1440b38L,0xf9438fb7262daL,
25596         0x02c41114ce0cdL },
25597       { 0x5cef1ad95a0b1L,0xa867d543622baL,0x1e486c9c09b37L,0x929726d6cdd20L,
25598         0x020477abf42ffL } },
25599     /* 129 */
25600     { { 0x5173c18d65dbfL,0x0e339edad82f7L,0xcf1001c77bf94L,0x96b67022d26bdL,
25601         0x0ac66409ac773L },
25602       { 0xbb36fc6261cc3L,0xc9190e7e908b0L,0x45e6c10213f7bL,0x2f856541cebaaL,
25603         0x0ce8e6975cc12L } },
25604     /* 130 */
25605     { { 0x21b41bc0a67d2L,0x0a444d248a0f1L,0x59b473762d476L,0xb4a80e044f1d6L,
25606         0x008fde365250bL },
25607       { 0xec3da848bf287L,0x82d3369d6eaceL,0x2449482c2a621L,0x6cd73582dfdc9L,
25608         0x02f7e2fd2565dL } },
25609     /* 131 */
25610     { { 0xb92dbc3770fa7L,0x5c379043f9ae4L,0x7761171095e8dL,0x02ae54f34e9d1L,
25611         0x0c65be92e9077L },
25612       { 0x8a303f6fd0a40L,0xe3bcce784b275L,0xf9767bfe7d822L,0x3b3a7ae4f5854L,
25613         0x04bff8e47d119L } },
25614     /* 132 */
25615     { { 0x1d21f00ff1480L,0x7d0754db16cd4L,0xbe0f3ea2ab8fbL,0x967dac81d2efbL,
25616         0x03e4e4ae65772L },
25617       { 0x8f36d3c5303e6L,0x4b922623977e1L,0x324c3c03bd999L,0x60289ed70e261L,
25618         0x05388aefd58ecL } },
25619     /* 133 */
25620     { { 0x317eb5e5d7713L,0xee75de49daad1L,0x74fb26109b985L,0xbe0e32f5bc4fcL,
25621         0x05cf908d14f75L },
25622       { 0x435108e657b12L,0xa5b96ed9e6760L,0x970ccc2bfd421L,0x0ce20e29f51f8L,
25623         0x0a698ba4060f0L } },
25624     /* 134 */
25625     { { 0xb1686ef748fecL,0xa27e9d2cf973dL,0xe265effe6e755L,0xad8d630b6544cL,
25626         0x0b142ef8a7aebL },
25627       { 0x1af9f17d5770aL,0x672cb3412fad3L,0xf3359de66af3bL,0x50756bd60d1bdL,
25628         0x0d1896a965851L } },
25629     /* 135 */
25630     { { 0x957ab33c41c08L,0xac5468e2e1ec5L,0xc472f6c87de94L,0xda3918816b73aL,
25631         0x0267b0e0b7981L },
25632       { 0x54e5d8e62b988L,0x55116d21e76e5L,0xd2a6f99d8ddc7L,0x93934610faf03L,
25633         0x0b54e287aa111L } },
25634     /* 136 */
25635     { { 0x122b5178a876bL,0xff085104b40a0L,0x4f29f7651ff96L,0xd4e6050b31ab1L,
25636         0x084abb28b5f87L },
25637       { 0xd439f8270790aL,0x9d85e3f46bd5eL,0xc1e22122d6cb5L,0x564075f55c1b6L,
25638         0x0e5436f671765L } },
25639     /* 137 */
25640     { { 0x9025e2286e8d5L,0xb4864453be53fL,0x408e3a0353c95L,0xe99ed832f5bdeL,
25641         0x00404f68b5b9cL },
25642       { 0x33bdea781e8e5L,0x18163c2f5bcadL,0x119caa33cdf50L,0xc701575769600L,
25643         0x03a4263df0ac1L } },
25644     /* 138 */
25645     { { 0x65ecc9aeb596dL,0xe7023c92b4c29L,0xe01396101ea03L,0xa3674704b4b62L,
25646         0x00ca8fd3f905eL },
25647       { 0x23a42551b2b61L,0x9c390fcd06925L,0x392a63e1eb7a8L,0x0c33e7f1d2be0L,
25648         0x096dca2644ddbL } },
25649     /* 139 */
25650     { { 0xbb43a387510afL,0xa8a9a36a01203L,0xf950378846feaL,0x59dcd23a57702L,
25651         0x04363e2123aadL },
25652       { 0x3a1c740246a47L,0xd2e55dd24dca4L,0xd8faf96b362b8L,0x98c4f9b086045L,
25653         0x0840e115cd8bbL } },
25654     /* 140 */
25655     { { 0x205e21023e8a7L,0xcdd8dc7a0bf12L,0x63a5ddfc808a8L,0xd6d4e292a2721L,
25656         0x05e0d6abd30deL },
25657       { 0x721c27cfc0f64L,0x1d0e55ed8807aL,0xd1f9db242eec0L,0xa25a26a7bef91L,
25658         0x07dea48f42945L } },
25659     /* 141 */
25660     { { 0xf6f1ce5060a81L,0x72f8f95615abdL,0x6ac268be79f9cL,0x16d1cfd36c540L,
25661         0x0abc2a2beebfdL },
25662       { 0x66f91d3e2eac7L,0x63d2dd04668acL,0x282d31b6f10baL,0xefc16790e3770L,
25663         0x04ea353946c7eL } },
25664     /* 142 */
25665     { { 0xa2f8d5266309dL,0xc081945a3eed8L,0x78c5dc10a51c6L,0xffc3cecaf45a5L,
25666         0x03a76e6891c94L },
25667       { 0xce8a47d7b0d0fL,0x968f584a5f9aaL,0xe697fbe963aceL,0x646451a30c724L,
25668         0x08212a10a465eL } },
25669     /* 143 */
25670     { { 0xc61c3cfab8caaL,0x840e142390ef7L,0xe9733ca18eb8eL,0xb164cd1dff677L,
25671         0x0aa7cab71599cL },
25672       { 0xc9273bc837bd1L,0xd0c36af5d702fL,0x423da49c06407L,0x17c317621292fL,
25673         0x040e38073fe06L } },
25674     /* 144 */
25675     { { 0x80824a7bf9b7cL,0x203fbe30d0f4fL,0x7cf9ce3365d23L,0x5526bfbe53209L,
25676         0x0e3604700b305L },
25677       { 0xb99116cc6c2c7L,0x08ba4cbee64dcL,0x37ad9ec726837L,0xe15fdcded4346L,
25678         0x06542d677a3deL } },
25679     /* 145 */
25680     { { 0x2b6d07b6c377aL,0x47903448be3f3L,0x0da8af76cb038L,0x6f21d6fdd3a82L,
25681         0x0a6534aee09bbL },
25682       { 0x1780d1035facfL,0x339dcb47e630aL,0x447f39335e55aL,0xef226ea50fe1cL,
25683         0x0f3cb672fdc9aL } },
25684     /* 146 */
25685     { { 0x719fe3b55fd83L,0x6c875ddd10eb3L,0x5cea784e0d7a4L,0x70e733ac9fa90L,
25686         0x07cafaa2eaae8L },
25687       { 0x14d041d53b338L,0xa0ef87e6c69b8L,0x1672b0fe0acc0L,0x522efb93d1081L,
25688         0x00aab13c1b9bdL } },
25689     /* 147 */
25690     { { 0xce278d2681297L,0xb1b509546addcL,0x661aaf2cb350eL,0x12e92dc431737L,
25691         0x04b91a6028470L },
25692       { 0xf109572f8ddcfL,0x1e9a911af4dcfL,0x372430e08ebf6L,0x1cab48f4360acL,
25693         0x049534c537232L } },
25694     /* 148 */
25695     { { 0xf7d71f07b7e9dL,0xa313cd516f83dL,0xc047ee3a478efL,0xc5ee78ef264b6L,
25696         0x0caf46c4fd65aL },
25697       { 0xd0c7792aa8266L,0x66913684bba04L,0xe4b16b0edf454L,0x770f56e65168aL,
25698         0x014ce9e5704c6L } },
25699     /* 149 */
25700     { { 0x45e3e965e8f91L,0xbacb0f2492994L,0x0c8a0a0d3aca1L,0x9a71d31cc70f9L,
25701         0x01bb708a53e4cL },
25702       { 0xa9e69558bdd7aL,0x08018a26b1d5cL,0xc9cf1ec734a05L,0x0102b093aa714L,
25703         0x0f9d126f2da30L } },
25704     /* 150 */
25705     { { 0xbca7aaff9563eL,0xfeb49914a0749L,0xf5f1671dd077aL,0xcc69e27a0311bL,
25706         0x0807afcb9729eL },
25707       { 0xa9337c9b08b77L,0x85443c7e387f8L,0x76fd8ba86c3a7L,0xcd8c85fafa594L,
25708         0x0751adcd16568L } },
25709     /* 151 */
25710     { { 0xa38b410715c0dL,0x718f7697f78aeL,0x3fbf06dd113eaL,0x743f665eab149L,
25711         0x029ec44682537L },
25712       { 0x4719cb50bebbcL,0xbfe45054223d9L,0xd2dedb1399ee5L,0x077d90cd5b3a8L,
25713         0x0ff9370e392a4L } },
25714     /* 152 */
25715     { { 0x2d69bc6b75b65L,0xd5266651c559aL,0xde9d7d24188f8L,0xd01a28a9f33e3L,
25716         0x09776478ba2a9L },
25717       { 0x2622d929af2c7L,0x6d4e690923885L,0x89a51e9334f5dL,0x82face6cc7e5aL,
25718         0x074a6313fac2fL } },
25719     /* 153 */
25720     { { 0x4dfddb75f079cL,0x9518e36fbbb2fL,0x7cd36dd85b07cL,0x863d1b6cfcf0eL,
25721         0x0ab75be150ff4L },
25722       { 0x367c0173fc9b7L,0x20d2594fd081bL,0x4091236b90a74L,0x59f615fdbf03cL,
25723         0x04ebeac2e0b44L } },
25724     /* 154 */
25725     { { 0xc5fe75c9f2c53L,0x118eae9411eb6L,0x95ac5d8d25220L,0xaffcc8887633fL,
25726         0x0df99887b2c1bL },
25727       { 0x8eed2850aaecbL,0x1b01d6a272bb7L,0x1cdbcac9d4918L,0x4058978dd511bL,
25728         0x027b040a7779fL } },
25729     /* 155 */
25730     { { 0x05db7f73b2eb2L,0x088e1b2118904L,0x962327ee0df85L,0xa3f5501b71525L,
25731         0x0b393dd37e4cfL },
25732       { 0x30e7b3fd75165L,0xc2bcd33554a12L,0xf7b5022d66344L,0x34196c36f1be0L,
25733         0x009588c12d046L } },
25734     /* 156 */
25735     { { 0x6093f02601c3bL,0xf8cf5c335fe08L,0x94aff28fb0252L,0x648b955cf2808L,
25736         0x081c879a9db9fL },
25737       { 0xe687cc6f56c51L,0x693f17618c040L,0x059353bfed471L,0x1bc444f88a419L,
25738         0x0fa0d48f55fc1L } },
25739     /* 157 */
25740     { { 0xe1c9de1608e4dL,0x113582822cbc6L,0x57ec2d7010ddaL,0x67d6f6b7ddc11L,
25741         0x08ea0e156b6a3L },
25742       { 0x4e02f2383b3b4L,0x943f01f53ca35L,0xde03ca569966bL,0xb5ac4ff6632b2L,
25743         0x03f5ab924fa00L } },
25744     /* 158 */
25745     { { 0xbb0d959739efbL,0xf4e7ebec0d337L,0x11a67d1c751b0L,0x256e2da52dd64L,
25746         0x08bc768872b74L },
25747       { 0xe3b7282d3d253L,0xa1f58d779fa5bL,0x16767bba9f679L,0xf34fa1cac168eL,
25748         0x0b386f19060fcL } },
25749     /* 159 */
25750     { { 0x3c1352fedcfc2L,0x6262f8af0d31fL,0x57288c25396bfL,0x9c4d9a02b4eaeL,
25751         0x04cb460f71b06L },
25752       { 0x7b4d35b8095eaL,0x596fc07603ae6L,0x614a16592bbf8L,0x5223e1475f66bL,
25753         0x052c0d50895efL } },
25754     /* 160 */
25755     { { 0xc210e15339848L,0xe870778c8d231L,0x956e170e87a28L,0x9c0b9d1de6616L,
25756         0x04ac3c9382bb0L },
25757       { 0xe05516998987dL,0xc4ae09f4d619bL,0xa3f933d8b2376L,0x05f41de0b7651L,
25758         0x0380d94c7e397L } },
25759     /* 161 */
25760     { { 0x355aa81542e75L,0xa1ee01b9b701aL,0x24d708796c724L,0x37af6b3a29776L,
25761         0x02ce3e171de26L },
25762       { 0xfeb49f5d5bc1aL,0x7e2777e2b5cfeL,0x513756ca65560L,0x4e4d4feaac2f9L,
25763         0x02e6cd8520b62L } },
25764     /* 162 */
25765     { { 0x5954b8c31c31dL,0x005bf21a0c368L,0x5c79ec968533dL,0x9d540bd7626e7L,
25766         0x0ca17754742c6L },
25767       { 0xedafff6d2dbb2L,0xbd174a9d18cc6L,0xa4578e8fd0d8cL,0x2ce6875e8793aL,
25768         0x0a976a7139cabL } },
25769     /* 163 */
25770     { { 0x51f1b93fb353dL,0x8b57fcfa720a6L,0x1b15281d75cabL,0x4999aa88cfa73L,
25771         0x08720a7170a1fL },
25772       { 0xe8d37693e1b90L,0x0b16f6dfc38c3L,0x52a8742d345dcL,0x893c8ea8d00abL,
25773         0x09719ef29c769L } },
25774     /* 164 */
25775     { { 0xeed8d58e35909L,0xdc33ddc116820L,0xe2050269366d8L,0x04c1d7f999d06L,
25776         0x0a5072976e157L },
25777       { 0xa37eac4e70b2eL,0x576890aa8a002L,0x45b2a5c84dcf6L,0x7725cd71bf186L,
25778         0x099389c9df7b7L } },
25779     /* 165 */
25780     { { 0xc08f27ada7a4bL,0x03fd389366238L,0x66f512c3abe9dL,0x82e46b672e897L,
25781         0x0a88806aa202cL },
25782       { 0x2044ad380184eL,0xc4126a8b85660L,0xd844f17a8cb78L,0xdcfe79d670c0aL,
25783         0x00043bffb4738L } },
25784     /* 166 */
25785     { { 0x9b5dc36d5192eL,0xd34590b2af8d5L,0x1601781acf885L,0x486683566d0a1L,
25786         0x052f3ef01ba6cL },
25787       { 0x6732a0edcb64dL,0x238068379f398L,0x040f3090a482cL,0x7e7516cbe5fa7L,
25788         0x03296bd899ef2L } },
25789     /* 167 */
25790     { { 0xaba89454d81d7L,0xef51eb9b3c476L,0x1c579869eade7L,0x71e9619a21cd8L,
25791         0x03b90febfaee5L },
25792       { 0x3023e5496f7cbL,0xd87fb51bc4939L,0x9beb5ce55be41L,0x0b1803f1dd489L,
25793         0x06e88069d9f81L } },
25794     /* 168 */
25795     { { 0x7ab11b43ea1dbL,0xa95259d292ce3L,0xf84f1860a7ff1L,0xad13851b02218L,
25796         0x0a7222beadefaL },
25797       { 0xc78ec2b0a9144L,0x51f2fa59c5a2aL,0x147ce385a0240L,0xc69091d1eca56L,
25798         0x0be94d523bc2aL } },
25799     /* 169 */
25800     { { 0x4945e0b226ce7L,0x47967e8b7072fL,0x5a6c63eb8afd7L,0xc766edea46f18L,
25801         0x07782defe9be8L },
25802       { 0xd2aa43db38626L,0x8776f67ad1760L,0x4499cdb460ae7L,0x2e4b341b86fc5L,
25803         0x003838567a289L } },
25804     /* 170 */
25805     { { 0xdaefd79ec1a0fL,0xfdceb39c972d8L,0x8f61a953bbcd6L,0xb420f5575ffc5L,
25806         0x0dbd986c4adf7L },
25807       { 0xa881415f39eb7L,0xf5b98d976c81aL,0xf2f717d6ee2fcL,0xbbd05465475dcL,
25808         0x08e24d3c46860L } },
25809     /* 171 */
25810     { { 0xd8e549a587390L,0x4f0cbec588749L,0x25983c612bb19L,0xafc846e07da4bL,
25811         0x0541a99c4407bL },
25812       { 0x41692624c8842L,0x2ad86c05ffdb2L,0xf7fcf626044c1L,0x35d1c59d14b44L,
25813         0x0c0092c49f57dL } },
25814     /* 172 */
25815     { { 0xc75c3df2e61efL,0xc82e1b35cad3cL,0x09f29f47e8841L,0x944dc62d30d19L,
25816         0x075e406347286L },
25817       { 0x41fc5bbc237d0L,0xf0ec4f01c9e7dL,0x82bd534c9537bL,0x858691c51a162L,
25818         0x05b7cb658c784L } },
25819     /* 173 */
25820     { { 0xa70848a28ead1L,0x08fd3b47f6964L,0x67e5b39802dc5L,0x97a19ae4bfd17L,
25821         0x07ae13eba8df0L },
25822       { 0x16ef8eadd384eL,0xd9b6b2ff06fd2L,0xbcdb5f30361a2L,0xe3fd204b98784L,
25823         0x0787d8074e2a8L } },
25824     /* 174 */
25825     { { 0x25d6b757fbb1cL,0xb2ca201debc5eL,0xd2233ffe47bddL,0x84844a55e9a36L,
25826         0x05c2228199ef2L },
25827       { 0xd4a8588315250L,0x2b827097c1773L,0xef5d33f21b21aL,0xf2b0ab7c4ea1dL,
25828         0x0e45d37abbaf0L } },
25829     /* 175 */
25830     { { 0xf1e3428511c8aL,0xc8bdca6cd3d2dL,0x27c39a7ebb229L,0xb9d3578a71a76L,
25831         0x0ed7bc12284dfL },
25832       { 0x2a6df93dea561L,0x8dd48f0ed1cf2L,0xbad23e85443f1L,0x6d27d8b861405L,
25833         0x0aac97cc945caL } },
25834     /* 176 */
25835     { { 0x4ea74a16bd00aL,0xadf5c0bcc1eb5L,0xf9bfc06d839e9L,0xdc4e092bb7f11L,
25836         0x0318f97b31163L },
25837       { 0x0c5bec30d7138L,0x23abc30220eccL,0x022360644e8dfL,0xff4d2bb7972fbL,
25838         0x0fa41faa19a84L } },
25839     /* 177 */
25840     { { 0x2d974a6642269L,0xce9bb783bd440L,0x941e60bc81814L,0xe9e2398d38e47L,
25841         0x038bb6b2c1d26L },
25842       { 0xe4a256a577f87L,0x53dc11fe1cc64L,0x22807288b52d2L,0x01a5ff336abf6L,
25843         0x094dd0905ce76L } },
25844     /* 178 */
25845     { { 0xcf7dcde93f92aL,0xcb89b5f315156L,0x995e750a01333L,0x2ae902404df9cL,
25846         0x092077867d25cL },
25847       { 0x71e010bf39d44L,0x2096bb53d7e24L,0xc9c3d8f5f2c90L,0xeb514c44b7b35L,
25848         0x081e8428bd29bL } },
25849     /* 179 */
25850     { { 0x9c2bac477199fL,0xee6b5ecdd96ddL,0xe40fd0e8cb8eeL,0xa4b18af7db3feL,
25851         0x01b94ab62dbbfL },
25852       { 0x0d8b3ce47f143L,0xfc63f4616344fL,0xc59938351e623L,0x90eef18f270fcL,
25853         0x006a38e280555L } },
25854     /* 180 */
25855     { { 0xb0139b3355b49L,0x60b4ebf99b2e5L,0x269f3dc20e265L,0xd4f8c08ffa6bdL,
25856         0x0a7b36c2083d9L },
25857       { 0x15c3a1b3e8830L,0xe1a89f9c0b64dL,0x2d16930d5fceaL,0x2a20cfeee4a2eL,
25858         0x0be54c6b4a282L } },
25859     /* 181 */
25860     { { 0xdb3df8d91167cL,0x79e7a6625ed6cL,0x46ac7f4517c3fL,0x22bb7105648f3L,
25861         0x0bf30a5abeae0L },
25862       { 0x785be93828a68L,0x327f3ef0368e7L,0x92146b25161c3L,0xd13ae11b5feb5L,
25863         0x0d1c820de2732L } },
25864     /* 182 */
25865     { { 0xe13479038b363L,0x546b05e519043L,0x026cad158c11fL,0x8da34fe57abe6L,
25866         0x0b7d17bed68a1L },
25867       { 0xa5891e29c2559L,0x765bfffd8444cL,0x4e469484f7a03L,0xcc64498de4af7L,
25868         0x03997fd5e6412L } },
25869     /* 183 */
25870     { { 0x746828bd61507L,0xd534a64d2af20L,0xa8a15e329e132L,0x13e8ffeddfb08L,
25871         0x00eeb89293c6cL },
25872       { 0x69a3ea7e259f8L,0xe6d13e7e67e9bL,0xd1fa685ce1db7L,0xb6ef277318f6aL,
25873         0x0228916f8c922L } },
25874     /* 184 */
25875     { { 0xae25b0a12ab5bL,0x1f957bc136959L,0x16e2b0ccc1117L,0x097e8058429edL,
25876         0x0ec05ad1d6e93L },
25877       { 0xba5beac3f3708L,0x3530b59d77157L,0x18234e531baf9L,0x1b3747b552371L,
25878         0x07d3141567ff1L } },
25879     /* 185 */
25880     { { 0x9c05cf6dfefabL,0x68dcb377077bdL,0xa38bb95be2f22L,0xd7a3e53ead973L,
25881         0x0e9ce66fc9bc1L },
25882       { 0xa15766f6a02a1L,0xdf60e600ed75aL,0x8cdc1b938c087L,0x0651f8947f346L,
25883         0x0d9650b017228L } },
25884     /* 186 */
25885     { { 0xb4c4a5a057e60L,0xbe8def25e4504L,0x7c1ccbdcbccc3L,0xb7a2a63532081L,
25886         0x014d6699a804eL },
25887       { 0xa8415db1f411aL,0x0bf80d769c2c8L,0xc2f77ad09fbafL,0x598ab4deef901L,
25888         0x06f4c68410d43L } },
25889     /* 187 */
25890     { { 0x6df4e96c24a96L,0x85fcbd99a3872L,0xb2ae30a534dbcL,0x9abb3c466ef28L,
25891         0x04c4350fd6118L },
25892       { 0x7f716f855b8daL,0x94463c38a1296L,0xae9334341a423L,0x18b5c37e1413eL,
25893         0x0a726d2425a31L } },
25894     /* 188 */
25895     { { 0x6b3ee948c1086L,0x3dcbd3a2e1daeL,0x3d022f3f1de50L,0xf3923f35ed3f0L,
25896         0x013639e82cc6cL },
25897       { 0x938fbcdafaa86L,0xfb2654a2589acL,0x5051329f45bc5L,0x35a31963b26e4L,
25898         0x0ca9365e1c1a3L } },
25899     /* 189 */
25900     { { 0x5ac754c3b2d20L,0x17904e241b361L,0xc9d071d742a54L,0x72a5b08521c4cL,
25901         0x09ce29c34970bL },
25902       { 0x81f736d3e0ad6L,0x9ef2f8434c8ccL,0xce862d98060daL,0xaf9835ed1d1a6L,
25903         0x048c4abd7ab42L } },
25904     /* 190 */
25905     { { 0x1b0cc40c7485aL,0xbbe5274dbfd22L,0x263d2e8ead455L,0x33cb493c76989L,
25906         0x078017c32f67bL },
25907       { 0x35769930cb5eeL,0x940c408ed2b9dL,0x72f1a4dc0d14eL,0x1c04f8b7bf552L,
25908         0x053cd0454de5cL } },
25909     /* 191 */
25910     { { 0x585fa5d28ccacL,0x56005b746ebcdL,0xd0123aa5f823eL,0xfa8f7c79f0a1cL,
25911         0x0eea465c1d3d7L },
25912       { 0x0659f0551803bL,0x9f7ce6af70781L,0x9288e706c0b59L,0x91934195a7702L,
25913         0x01b6e42a47ae6L } },
25914     /* 192 */
25915     { { 0x0937cf67d04c3L,0xe289eeb8112e8L,0x2594d601e312bL,0xbd3d56b5d8879L,
25916         0x00224da14187fL },
25917       { 0xbb8630c5fe36fL,0x604ef51f5f87aL,0x3b429ec580f3cL,0xff33964fb1bfbL,
25918         0x060838ef042bfL } },
25919     /* 193 */
25920     { { 0xcb2f27e0bbe99L,0xf304aa39ee432L,0xfa939037bda44L,0x16435f497c7a9L,
25921         0x0636eb2022d33L },
25922       { 0xd0e6193ae00aaL,0xfe31ae6d2ffcfL,0xf93901c875a00L,0x8bacf43658a29L,
25923         0x08844eeb63921L } },
25924     /* 194 */
25925     { { 0x171d26b3bae58L,0x7117e39f3e114L,0x1a8eada7db3dfL,0x789ecd37bc7f8L,
25926         0x027ba83dc51fbL },
25927       { 0xf439ffbf54de5L,0x0bb5fe1a71a7dL,0xb297a48727703L,0xa4ab42ee8e35dL,
25928         0x0adb62d3487f3L } },
25929     /* 195 */
25930     { { 0x168a2a175df2aL,0x4f618c32e99b1L,0x46b0916082aa0L,0xc8b2c9e4f2e71L,
25931         0x0b990fd7675e7L },
25932       { 0x9d96b4df37313L,0x79d0b40789082L,0x80877111c2055L,0xd18d66c9ae4a7L,
25933         0x081707ef94d10L } },
25934     /* 196 */
25935     { { 0x7cab203d6ff96L,0xfc0d84336097dL,0x042db4b5b851bL,0xaa5c268823c4dL,
25936         0x03792daead5a8L },
25937       { 0x18865941afa0bL,0x4142d83671528L,0xbe4e0a7f3e9e7L,0x01ba17c825275L,
25938         0x05abd635e94b0L } },
25939     /* 197 */
25940     { { 0xfa84e0ac4927cL,0x35a7c8cf23727L,0xadca0dfe38860L,0xb610a4bcd5ea4L,
25941         0x05995bf21846aL },
25942       { 0xf860b829dfa33L,0xae958fc18be90L,0x8630366caafe2L,0x411e9b3baf447L,
25943         0x044c32ca2d483L } },
25944     /* 198 */
25945     { { 0xa97f1e40ed80cL,0xb131d2ca82a74L,0xc2d6ad95f938cL,0xa54c53f2124b7L,
25946         0x01f2162fb8082L },
25947       { 0x67cc5720b173eL,0x66085f12f97e4L,0xc9d65dc40e8a6L,0x07c98cebc20e4L,
25948         0x08f1d402bc3e9L } },
25949     /* 199 */
25950     { { 0x92f9cfbc4058aL,0xb6292f56704f5L,0xc1d8c57b15e14L,0xdbf9c55cfe37bL,
25951         0x0b1980f43926eL },
25952       { 0x33e0932c76b09L,0x9d33b07f7898cL,0x63bb4611df527L,0x8e456f08ead48L,
25953         0x02828ad9b3744L } },
25954     /* 200 */
25955     { { 0x722c4c4cf4ac5L,0x3fdde64afb696L,0x0890832f5ac1aL,0xb3900551baa2eL,
25956         0x04973f1275a14L },
25957       { 0xd8335322eac5dL,0xf50bd9b568e59L,0x25883935e07eeL,0x8ac7ab36720faL,
25958         0x06dac8ed0db16L } },
25959     /* 201 */
25960     { { 0x545aeeda835efL,0xd21d10ed51f7bL,0x3741b094aa113L,0xde4c035a65e01L,
25961         0x04b23ef5920b9L },
25962       { 0xbb6803c4c7341L,0x6d3f58bc37e82L,0x51e3ee8d45770L,0x9a4e73527863aL,
25963         0x04dd71534ddf4L } },
25964     /* 202 */
25965     { { 0x4467295476cd9L,0x2fe31a725bbf9L,0xc4b67e0648d07L,0x4dbb1441c8b8fL,
25966         0x0fd3170002f4aL },
25967       { 0x43ff48995d0e1L,0xd10ef729aa1cbL,0x179898276e695L,0xf365e0d5f9764L,
25968         0x014fac58c9569L } },
25969     /* 203 */
25970     { { 0xa0065f312ae18L,0xc0fcc93fc9ad9L,0xa7d284651958dL,0xda50d9a142408L,
25971         0x0ed7c765136abL },
25972       { 0x70f1a25d4abbcL,0xf3f1a113ea462L,0xb51952f9b5dd8L,0x9f53c609b0755L,
25973         0x0fefcb7f74d2eL } },
25974     /* 204 */
25975     { { 0x9497aba119185L,0x30aac45ba4bd0L,0xa521179d54e8cL,0xd80b492479deaL,
25976         0x01801a57e87e0L },
25977       { 0xd3f8dfcafffb0L,0x0bae255240073L,0xb5fdfbc6cf33cL,0x1064781d763b5L,
25978         0x09f8fc11e1eadL } },
25979     /* 205 */
25980     { { 0x3a1715e69544cL,0x67f04b7813158L,0x78a4c320eaf85L,0x69a91e22a8fd2L,
25981         0x0a9d3809d3d3aL },
25982       { 0xc2c2c59a2da3bL,0xf61895c847936L,0x3d5086938ccbcL,0x8ef75e65244e6L,
25983         0x03006b9aee117L } },
25984     /* 206 */
25985     { { 0x1f2b0c9eead28L,0x5d89f4dfbc0bbL,0x2ce89397eef63L,0xf761074757fdbL,
25986         0x00ab85fd745f8L },
25987       { 0xa7c933e5b4549L,0x5c97922f21ecdL,0x43b80404be2bbL,0x42c2261a1274bL,
25988         0x0b122d67511e9L } },
25989     /* 207 */
25990     { { 0x607be66a5ae7aL,0xfa76adcbe33beL,0xeb6e5c501e703L,0xbaecaf9043014L,
25991         0x09f599dc1097dL },
25992       { 0x5b7180ff250edL,0x74349a20dc6d7L,0x0b227a38eb915L,0x4b78425605a41L,
25993         0x07d5528e08a29L } },
25994     /* 208 */
25995     { { 0x58f6620c26defL,0xea582b2d1ef0fL,0x1ce3881025585L,0x1730fbe7d79b0L,
25996         0x028ccea01303fL },
25997       { 0xabcd179644ba5L,0xe806fff0b8d1dL,0x6b3e17b1fc643L,0x13bfa60a76fc6L,
25998         0x0c18baf48a1d0L } },
25999     /* 209 */
26000     { { 0x638c85dc4216dL,0x67206142ac34eL,0x5f5064a00c010L,0x596bd453a1719L,
26001         0x09def809db7a9L },
26002       { 0x8642e67ab8d2cL,0x336237a2b641eL,0x4c4218bb42404L,0x8ce57d506a6d6L,
26003         0x00357f8b06880L } },
26004     /* 210 */
26005     { { 0xdbe644cd2cc88L,0x8df0b8f39d8e9L,0xd30a0c8cc61c2L,0x98874a309874cL,
26006         0x0e4a01add1b48L },
26007       { 0x1eeacf57cd8f9L,0x3ebd594c482edL,0xbd2f7871b767dL,0xcc30a7295c717L,
26008         0x0466d7d79ce10L } },
26009     /* 211 */
26010     { { 0x318929dada2c7L,0xc38f9aa27d47dL,0x20a59e14fa0a6L,0xad1a90e4fd288L,
26011         0x0c672a522451eL },
26012       { 0x07cc85d86b655L,0x3bf9ad4af1306L,0x71172a6f0235dL,0x751399a086805L,
26013         0x05e3d64faf2a6L } },
26014     /* 212 */
26015     { { 0x410c79b3b4416L,0x85eab26d99aa6L,0xb656a74cd8fcfL,0x42fc5ebff74adL,
26016         0x06c8a7a95eb8eL },
26017       { 0x60ba7b02a63bdL,0x038b8f004710cL,0x12d90b06b2f23L,0xca918c6c37383L,
26018         0x0348ae422ad82L } },
26019     /* 213 */
26020     { { 0x746635ccda2fbL,0xa18e0726d27f4L,0x92b1f2022accaL,0x2d2e85adf7824L,
26021         0x0c1074de0d9efL },
26022       { 0x3ce44ae9a65b3L,0xac05d7151bfcfL,0xe6a9788fd71e4L,0x4ffcd4711f50cL,
26023         0x0fbadfbdbc9e5L } },
26024     /* 214 */
26025     { { 0x3f1cd20a99363L,0x8f6cf22775171L,0x4d359b2b91565L,0x6fcd968175cd2L,
26026         0x0b7f976b48371L },
26027       { 0x8e24d5d6dbf74L,0xfd71c3af36575L,0x243dfe38d23baL,0xc80548f477600L,
26028         0x0f4d41b2ecafcL } },
26029     /* 215 */
26030     { { 0x1cf28fdabd48dL,0x3632c078a451fL,0x17146e9ce81beL,0x0f106ace29741L,
26031         0x0180824eae016L },
26032       { 0x7698b66e58358L,0x52ce6ca358038L,0xe41e6c5635687L,0x6d2582380e345L,
26033         0x067e5f63983cfL } },
26034     /* 216 */
26035     { { 0xccb8dcf4899efL,0xf09ebb44c0f89L,0x2598ec9949015L,0x1fc6546f9276bL,
26036         0x09fef789a04c1L },
26037       { 0x67ecf53d2a071L,0x7fa4519b096d3L,0x11e2eefb10e1aL,0x4e20ca6b3fb06L,
26038         0x0bc80c181a99cL } },
26039     /* 217 */
26040     { { 0x536f8e5eb82e6L,0xc7f56cb920972L,0x0b5da5e1a484fL,0xdf10c78e21715L,
26041         0x049270e629f8cL },
26042       { 0x9b7bbea6b50adL,0xc1a2388ffc1a3L,0x107197b9a0284L,0x2f7f5403eb178L,
26043         0x0d2ee52f96137L } },
26044     /* 218 */
26045     { { 0xcd28588e0362aL,0xa78fa5d94dd37L,0x434a526442fa8L,0xb733aff836e5aL,
26046         0x0dfb478bee5abL },
26047       { 0xf1ce7673eede6L,0xd42b5b2f04a91L,0x530da2fa5390aL,0x473a5e66f7bf5L,
26048         0x0d9a140b408dfL } },
26049     /* 219 */
26050     { { 0x221b56e8ea498L,0x293563ee090e0L,0x35d2ade623478L,0x4b1ae06b83913L,
26051         0x0760c058d623fL },
26052       { 0x9b58cc198aa79L,0xd2f07aba7f0b8L,0xde2556af74890L,0x04094e204110fL,
26053         0x07141982d8f19L } },
26054     /* 220 */
26055     { { 0xa0e334d4b0f45L,0x38392a94e16f0L,0x3c61d5ed9280bL,0x4e473af324c6bL,
26056         0x03af9d1ce89d5L },
26057       { 0xf798120930371L,0x4c21c17097fd8L,0xc42309beda266L,0x7dd60e9545dcdL,
26058         0x0b1f815c37395L } },
26059     /* 221 */
26060     { { 0xaa78e89fec44aL,0x473caa4caf84fL,0x1b6a624c8c2aeL,0xf052691c807dcL,
26061         0x0a41aed141543L },
26062       { 0x353997d5ffe04L,0xdf625b6e20424L,0x78177758bacb2L,0x60ef85d660be8L,
26063         0x0d6e9c1dd86fbL } },
26064     /* 222 */
26065     { { 0x2e97ec6853264L,0xb7e2304a0b3aaL,0x8eae9be771533L,0xf8c21b912bb7bL,
26066         0x09c9c6e10ae9bL },
26067       { 0x09a59e030b74cL,0x4d6a631e90a23L,0x49b79f24ed749L,0x61b689f44b23aL,
26068         0x0566bd59640faL } },
26069     /* 223 */
26070     { { 0xc0118c18061f3L,0xd37c83fc70066L,0x7273245190b25L,0x345ef05fc8e02L,
26071         0x0cf2c7390f525L },
26072       { 0xbceb410eb30cfL,0xba0d77703aa09L,0x50ff255cfd2ebL,0x0979e842c43a1L,
26073         0x002f517558aa2L } },
26074     /* 224 */
26075     { { 0xef794addb7d07L,0x4224455500396L,0x78aa3ce0b4fc7L,0xd97dfaff8eaccL,
26076         0x014e9ada5e8d4L },
26077       { 0x480a12f7079e2L,0xcde4b0800edaaL,0x838157d45baa3L,0x9ae801765e2d7L,
26078         0x0a0ad4fab8e9dL } },
26079     /* 225 */
26080     { { 0xb76214a653618L,0x3c31eaaa5f0bfL,0x4949d5e187281L,0xed1e1553e7374L,
26081         0x0bcd530b86e56L },
26082       { 0xbe85332e9c47bL,0xfeb50059ab169L,0x92bfbb4dc2776L,0x341dcdba97611L,
26083         0x0909283cf6979L } },
26084     /* 226 */
26085     { { 0x0032476e81a13L,0x996217123967bL,0x32e19d69bee1aL,0x549a08ed361bdL,
26086         0x035eeb7c9ace1L },
26087       { 0x0ae5a7e4e5bdcL,0xd3b6ceec6e128L,0xe266bc12dcd2cL,0xe86452e4224c6L,
26088         0x09a8b2cf4448aL } },
26089     /* 227 */
26090     { { 0x71bf209d03b59L,0xa3b65af2abf64L,0xbd5eec9c90e62L,0x1379ff7ff168eL,
26091         0x06bdb60f4d449L },
26092       { 0xafebc8a55bc30L,0x1610097fe0dadL,0xc1e3bddc79eadL,0x08a942e197414L,
26093         0x001ec3cfd94baL } },
26094     /* 228 */
26095     { { 0x277ebdc9485c2L,0x7922fb10c7ba6L,0x0a28d8a48cc9aL,0x64f64f61d60f7L,
26096         0x0d1acb1c04754L },
26097       { 0x902b126f36612L,0x4ee0618d8bd26L,0x08357ee59c3a4L,0x26c24df8a8133L,
26098         0x07dcd079d4056L } },
26099     /* 229 */
26100     { { 0x7d4d3f05a4b48L,0x52372307725ceL,0x12a915aadcd29L,0x19b8d18f79718L,
26101         0x00bf53589377dL },
26102       { 0xcd95a6c68ea73L,0xca823a584d35eL,0x473a723c7f3bbL,0x86fc9fb674c6fL,
26103         0x0d28be4d9e166L } },
26104     /* 230 */
26105     { { 0xb990638fa8e4bL,0x6e893fd8fc5d2L,0x36fb6fc559f18L,0x88ce3a6de2aa4L,
26106         0x0d76007aa510fL },
26107       { 0x0aab6523a4988L,0x4474dd02732d1L,0x3407278b455cfL,0xbb017f467082aL,
26108         0x0f2b52f68b303L } },
26109     /* 231 */
26110     { { 0x7eafa9835b4caL,0xfcbb669cbc0d5L,0x66431982d2232L,0xed3a8eeeb680cL,
26111         0x0d8dbe98ecc5aL },
26112       { 0x9be3fc5a02709L,0xe5f5ba1fa8cbaL,0x10ea85230be68L,0x9705febd43cdfL,
26113         0x0e01593a3ee55L } },
26114     /* 232 */
26115     { { 0x5af50ea75a0a6L,0xac57858033d3eL,0x0176406512226L,0xef066fe6d50fdL,
26116         0x0afec07b1aeb8L },
26117       { 0x9956780bb0a31L,0xcc37309aae7fbL,0x1abf3896f1af3L,0xbfdd9153a15a0L,
26118         0x0a71b93546e2dL } },
26119     /* 233 */
26120     { { 0xe12e018f593d2L,0x28a078122bbf8L,0xba4f2add1a904L,0x23d9150505db0L,
26121         0x053a2005c6285L },
26122       { 0x8b639e7f2b935L,0x5ac182961a07cL,0x518ca2c2bff97L,0x8e3d86bceea77L,
26123         0x0bf47d19b3d58L } },
26124     /* 234 */
26125     { { 0x967a7dd7665d5L,0x572f2f4de5672L,0x0d4903f4e3030L,0xa1b6144005ae8L,
26126         0x0001c2c7f39c9L },
26127       { 0xa801469efc6d6L,0xaa7bc7a724143L,0x78150a4c810bdL,0xb99b5f65670baL,
26128         0x0fdadf8e786ffL } },
26129     /* 235 */
26130     { { 0x8cb88ffc00785L,0x913b48eb67fd3L,0xf368fbc77fa75L,0x3c940454d055bL,
26131         0x03a838e4d5aa4L },
26132       { 0x663293e97bb9aL,0x63441d94d9561L,0xadb2a839eb933L,0x1da3515591a60L,
26133         0x03cdb8257873eL } },
26134     /* 236 */
26135     { { 0x140a97de77eabL,0x0d41648109137L,0xeb1d0dff7e1c5L,0x7fba762dcad2cL,
26136         0x05a60cc89f1f5L },
26137       { 0x3638240d45673L,0x195913c65580bL,0xd64b7411b82beL,0x8fc0057284b8dL,
26138         0x0922ff56fdbfdL } },
26139     /* 237 */
26140     { { 0x65deec9a129a1L,0x57cc284e041b2L,0xebfbe3ca5b1ceL,0xcd6204380c46cL,
26141         0x072919a7df6c5L },
26142       { 0xf453a8fb90f9aL,0x0b88e4031b298L,0x96f1856d719c0L,0x089ae32c0e777L,
26143         0x05e7917803624L } },
26144     /* 238 */
26145     { { 0x6ec557f63cdfbL,0x71f1cae4fd5c1L,0x60597ca8e6a35L,0x2fabfce26bea5L,
26146         0x04e0a5371e24cL },
26147       { 0xa40d3a5765357L,0x440d73a2b4276L,0x1d11a323c89afL,0x04eeb8f370ae4L,
26148         0x0f5ff7818d566L } },
26149     /* 239 */
26150     { { 0x3e3fe1a09df21L,0x8ee66e8e47fbfL,0x9c8901526d5d2L,0x5e642096bd0a2L,
26151         0x0e41df0e9533fL },
26152       { 0xfda40b3ba9e3fL,0xeb2604d895305L,0xf0367c7f2340cL,0x155f0866e1927L,
26153         0x08edd7d6eac4fL } },
26154     /* 240 */
26155     { { 0x1dc0e0bfc8ff3L,0x2be936f42fc9aL,0xca381ef14efd8L,0xee9667016f7ccL,
26156         0x01432c1caed8aL },
26157       { 0x8482970b23c26L,0x730735b273ec6L,0xaef0f5aa64fe8L,0xd2c6e389f6e5eL,
26158         0x0caef480b5ac8L } },
26159     /* 241 */
26160     { { 0x5c97875315922L,0x713063cca5524L,0x64ef2cbd82951L,0xe236f3ce60d0bL,
26161         0x0d0ba177e8efaL },
26162       { 0x9ae8fb1b3af60L,0xe53d2da20e53aL,0xf9eef281a796aL,0xae1601d63605dL,
26163         0x0f31c957c1c54L } },
26164     /* 242 */
26165     { { 0x58d5249cc4597L,0xb0bae0a028c0fL,0x34a814adc5015L,0x7c3aefc5fc557L,
26166         0x0013404cb96e1L },
26167       { 0xe2585c9a824bfL,0x5e001eaed7b29L,0x1ef68acd59318L,0x3e6c8d6ee6826L,
26168         0x06f377c4b9193L } },
26169     /* 243 */
26170     { { 0x3bad1a8333fd2L,0x025a2a95b89f9L,0xaf75acea89302L,0x9506211e5037eL,
26171         0x06dba3e4ed2d0L },
26172       { 0xef98cd04399cdL,0x6ee6b73adea48L,0x17ecaf31811c6L,0xf4a772f60752cL,
26173         0x0f13cf3423becL } },
26174     /* 244 */
26175     { { 0xb9ec0a919e2ebL,0x95f62c0f68ceeL,0xaba229983a9a1L,0xbad3cfba3bb67L,
26176         0x0c83fa9a9274bL },
26177       { 0xd1b0b62fa1ce0L,0xf53418efbf0d7L,0x2706f04e58b60L,0x2683bfa8ef9e5L,
26178         0x0b49d70f45d70L } },
26179     /* 245 */
26180     { { 0xc7510fad5513bL,0xecb1751e2d914L,0x9fb9d5905f32eL,0xf1cf6d850418dL,
26181         0x059cfadbb0c30L },
26182       { 0x7ac2355cb7fd6L,0xb8820426a3e16L,0x0a78864249367L,0x4b67eaeec58c9L,
26183         0x05babf362354aL } },
26184     /* 246 */
26185     { { 0x981d1ee424865L,0x78f2e5577f37cL,0x9e0c0588b0028L,0xc8f0702970f1bL,
26186         0x06188c6a79026L },
26187       { 0x9a19bd0f244daL,0x5cfb08087306fL,0xf2136371eccedL,0xb9d935470f9b9L,
26188         0x0993fe475df50L } },
26189     /* 247 */
26190     { { 0x31cdf9b2c3609L,0xc02c46d4ea68eL,0xa77510184eb19L,0x616b7ac9ec1a9L,
26191         0x081f764664c80L },
26192       { 0xc2a5a75fbe978L,0xd3f183b3561d7L,0x01dd2bf6743feL,0x060d838d1f045L,
26193         0x0564a812a5fe9L } },
26194     /* 248 */
26195     { { 0xa64f4fa817d1dL,0x44bea82e0f7a5L,0xd57f9aa55f968L,0x1d6cb5ff5a0fcL,
26196         0x0226bf3cf00e5L },
26197       { 0x1a9f92f2833cfL,0x5a4f4f89a8d6dL,0xf3f7f7720a0a3L,0x783611536c498L,
26198         0x068779f47ff25L } },
26199     /* 249 */
26200     { { 0x0c1c173043d08L,0x741fc020fa79bL,0xa6d26d0a54467L,0x2e0bd3767e289L,
26201         0x097bcb0d1eb09L },
26202       { 0x6eaa8f32ed3c3L,0x51b281bc482abL,0xfa178f3c8a4f1L,0x46554d1bf4f3bL,
26203         0x0a872ffe80a78L } },
26204     /* 250 */
26205     { { 0xb7935a32b2086L,0x0e8160f486b1aL,0xb6ae6bee1eb71L,0xa36a9bd0cd913L,
26206         0x002812bfcb732L },
26207       { 0xfd7cacf605318L,0x50fdfd6d1da63L,0x102d619646e5dL,0x96afa1d683982L,
26208         0x007391cc9fe53L } },
26209     /* 251 */
26210     { { 0x157f08b80d02bL,0xd162877f7fc50L,0x8d542ae6b8333L,0x2a087aca1af87L,
26211         0x0355d2adc7e6dL },
26212       { 0xf335a287386e1L,0x94f8e43275b41L,0x79989eafd272aL,0x3a79286ca2cdeL,
26213         0x03dc2b1e37c2aL } },
26214     /* 252 */
26215     { { 0x9d21c04581352L,0x25376782bed68L,0xfed701f0a00c8L,0x846b203bd5909L,
26216         0x0c47869103ccdL },
26217       { 0xa770824c768edL,0x026841f6575dbL,0xaccce0e72feeaL,0x4d3273313ed56L,
26218         0x0ccc42968d5bbL } },
26219     /* 253 */
26220     { { 0x50de13d7620b9L,0x8a5992a56a94eL,0x75487c9d89a5cL,0x71cfdc0076406L,
26221         0x0e147eb42aa48L },
26222       { 0xab4eeacf3ae46L,0xfb50350fbe274L,0x8c840eafd4936L,0x96e3df2afe474L,
26223         0x0239ac047080eL } },
26224     /* 254 */
26225     { { 0xd1f352bfee8d4L,0xcffa7b0fec481L,0xce9af3cce80b5L,0xe59d105c4c9e2L,
26226         0x0c55fa1a3f5f7L },
26227       { 0x6f14e8257c227L,0x3f342be00b318L,0xa904fb2c5b165L,0xb69909afc998aL,
26228         0x0094cd99cd4f4L } },
26229     /* 255 */
26230     { { 0x81c84d703bebaL,0x5032ceb2918a9L,0x3bd49ec8631d1L,0xad33a445f2c9eL,
26231         0x0b90a30b642abL },
26232       { 0x5404fb4a5abf9L,0xc375db7603b46L,0xa35d89f004750L,0x24f76f9a42cccL,
26233         0x0019f8b9a1b79L } },
26234 };
26235 
26236 /* Multiply the base point of P256 by the scalar and return the result.
26237  * If map is true then convert result to affine coordinates.
26238  *
26239  * Stripe implementation.
26240  * Pre-generated: 2^0, 2^32, ...
26241  * Pre-generated: products of all combinations of above.
26242  * 8 doubles and adds (with qz=1)
26243  *
26244  * r     Resulting point.
26245  * k     Scalar to multiply by.
26246  * map   Indicates whether to convert result to affine.
26247  * ct    Constant time required.
26248  * heap  Heap to use for allocation.
26249  * returns MEMORY_E when memory allocation fails and MP_OKAY on success.
26250  */
sp_256_ecc_mulmod_base_5(sp_point_256 * r,const sp_digit * k,int map,int ct,void * heap)26251 static int sp_256_ecc_mulmod_base_5(sp_point_256* r, const sp_digit* k,
26252         int map, int ct, void* heap)
26253 {
26254     return sp_256_ecc_mulmod_stripe_5(r, &p256_base, p256_table,
26255                                       k, map, ct, heap);
26256 }
26257 
26258 #endif
26259 
26260 /* Multiply the base point of P256 by the scalar and return the result.
26261  * If map is true then convert result to affine coordinates.
26262  *
26263  * km    Scalar to multiply by.
26264  * r     Resulting point.
26265  * map   Indicates whether to convert result to affine.
26266  * heap  Heap to use for allocation.
26267  * returns MEMORY_E when memory allocation fails and MP_OKAY on success.
26268  */
sp_ecc_mulmod_base_256(const mp_int * km,ecc_point * r,int map,void * heap)26269 int sp_ecc_mulmod_base_256(const mp_int* km, ecc_point* r, int map, void* heap)
26270 {
26271 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
26272     sp_point_256* point = NULL;
26273     sp_digit* k = NULL;
26274 #else
26275     sp_point_256  point[1];
26276     sp_digit k[5];
26277 #endif
26278     int err = MP_OKAY;
26279 
26280 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
26281     point = (sp_point_256*)XMALLOC(sizeof(sp_point_256), heap,
26282                                          DYNAMIC_TYPE_ECC);
26283     if (point == NULL)
26284         err = MEMORY_E;
26285     if (err == MP_OKAY) {
26286         k = (sp_digit*)XMALLOC(sizeof(sp_digit) * 5, heap,
26287                                DYNAMIC_TYPE_ECC);
26288         if (k == NULL)
26289             err = MEMORY_E;
26290     }
26291 #endif
26292 
26293     if (err == MP_OKAY) {
26294         sp_256_from_mp(k, 5, km);
26295 
26296             err = sp_256_ecc_mulmod_base_5(point, k, map, 1, heap);
26297     }
26298     if (err == MP_OKAY) {
26299         err = sp_256_point_to_ecc_point_5(point, r);
26300     }
26301 
26302 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
26303     if (k != NULL)
26304         XFREE(k, heap, DYNAMIC_TYPE_ECC);
26305     if (point != NULL)
26306         XFREE(point, heap, DYNAMIC_TYPE_ECC);
26307 #endif
26308 
26309     return err;
26310 }
26311 
26312 /* Multiply the base point of P256 by the scalar, add point a and return
26313  * the result. If map is true then convert result to affine coordinates.
26314  *
26315  * km      Scalar to multiply by.
26316  * am      Point to add to scalar mulitply result.
26317  * inMont  Point to add is in montgomery form.
26318  * r       Resulting point.
26319  * map     Indicates whether to convert result to affine.
26320  * heap    Heap to use for allocation.
26321  * returns MEMORY_E when memory allocation fails and MP_OKAY on success.
26322  */
sp_ecc_mulmod_base_add_256(const mp_int * km,const ecc_point * am,int inMont,ecc_point * r,int map,void * heap)26323 int sp_ecc_mulmod_base_add_256(const mp_int* km, const ecc_point* am,
26324         int inMont, ecc_point* r, int map, void* heap)
26325 {
26326 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
26327     sp_point_256* point = NULL;
26328     sp_digit* k = NULL;
26329 #else
26330     sp_point_256 point[2];
26331     sp_digit k[5 + 5 * 2 * 5];
26332 #endif
26333     sp_point_256* addP = NULL;
26334     sp_digit* tmp = NULL;
26335     int err = MP_OKAY;
26336 
26337 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
26338     point = (sp_point_256*)XMALLOC(sizeof(sp_point_256) * 2, heap,
26339                                          DYNAMIC_TYPE_ECC);
26340     if (point == NULL)
26341         err = MEMORY_E;
26342     if (err == MP_OKAY) {
26343         k = (sp_digit*)XMALLOC(
26344             sizeof(sp_digit) * (5 + 5 * 2 * 5),
26345             heap, DYNAMIC_TYPE_ECC);
26346         if (k == NULL)
26347             err = MEMORY_E;
26348     }
26349 #endif
26350 
26351     if (err == MP_OKAY) {
26352         addP = point + 1;
26353         tmp = k + 5;
26354 
26355         sp_256_from_mp(k, 5, km);
26356         sp_256_point_from_ecc_point_5(addP, am);
26357     }
26358     if ((err == MP_OKAY) && (!inMont)) {
26359         err = sp_256_mod_mul_norm_5(addP->x, addP->x, p256_mod);
26360     }
26361     if ((err == MP_OKAY) && (!inMont)) {
26362         err = sp_256_mod_mul_norm_5(addP->y, addP->y, p256_mod);
26363     }
26364     if ((err == MP_OKAY) && (!inMont)) {
26365         err = sp_256_mod_mul_norm_5(addP->z, addP->z, p256_mod);
26366     }
26367     if (err == MP_OKAY) {
26368             err = sp_256_ecc_mulmod_base_5(point, k, 0, 0, heap);
26369     }
26370     if (err == MP_OKAY) {
26371             sp_256_proj_point_add_5(point, point, addP, tmp);
26372 
26373         if (map) {
26374                 sp_256_map_5(point, point, tmp);
26375         }
26376 
26377         err = sp_256_point_to_ecc_point_5(point, r);
26378     }
26379 
26380 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
26381     if (k != NULL)
26382         XFREE(k, heap, DYNAMIC_TYPE_ECC);
26383     if (point)
26384         XFREE(point, heap, DYNAMIC_TYPE_ECC);
26385 #endif
26386 
26387     return err;
26388 }
26389 
26390 #if defined(WOLFSSL_VALIDATE_ECC_KEYGEN) || defined(HAVE_ECC_SIGN) || \
26391                                                         defined(HAVE_ECC_VERIFY)
26392 /* Returns 1 if the number of zero.
26393  * Implementation is constant time.
26394  *
26395  * a  Number to check.
26396  * returns 1 if the number is zero and 0 otherwise.
26397  */
sp_256_iszero_5(const sp_digit * a)26398 static int sp_256_iszero_5(const sp_digit* a)
26399 {
26400     return (a[0] | a[1] | a[2] | a[3] | a[4]) == 0;
26401 }
26402 
26403 #endif /* WOLFSSL_VALIDATE_ECC_KEYGEN | HAVE_ECC_SIGN | HAVE_ECC_VERIFY */
26404 /* Add 1 to a. (a = a + 1)
26405  *
26406  * r  A single precision integer.
26407  * a  A single precision integer.
26408  */
sp_256_add_one_5(sp_digit * a)26409 SP_NOINLINE static void sp_256_add_one_5(sp_digit* a)
26410 {
26411     a[0]++;
26412     sp_256_norm_5(a);
26413 }
26414 
26415 /* Read big endian unsigned byte array into r.
26416  *
26417  * r  A single precision integer.
26418  * size  Maximum number of bytes to convert
26419  * a  Byte array.
26420  * n  Number of bytes in array to read.
26421  */
sp_256_from_bin(sp_digit * r,int size,const byte * a,int n)26422 static void sp_256_from_bin(sp_digit* r, int size, const byte* a, int n)
26423 {
26424     int i;
26425     int j = 0;
26426     word32 s = 0;
26427 
26428     r[0] = 0;
26429     for (i = n-1; i >= 0; i--) {
26430         r[j] |= (((sp_digit)a[i]) << s);
26431         if (s >= 44U) {
26432             r[j] &= 0xfffffffffffffL;
26433             s = 52U - s;
26434             if (j + 1 >= size) {
26435                 break;
26436             }
26437             r[++j] = (sp_digit)a[i] >> s;
26438             s = 8U - s;
26439         }
26440         else {
26441             s += 8U;
26442         }
26443     }
26444 
26445     for (j++; j < size; j++) {
26446         r[j] = 0;
26447     }
26448 }
26449 
26450 /* Generates a scalar that is in the range 1..order-1.
26451  *
26452  * rng  Random number generator.
26453  * k    Scalar value.
26454  * returns RNG failures, MEMORY_E when memory allocation fails and
26455  * MP_OKAY on success.
26456  */
sp_256_ecc_gen_k_5(WC_RNG * rng,sp_digit * k)26457 static int sp_256_ecc_gen_k_5(WC_RNG* rng, sp_digit* k)
26458 {
26459     int err;
26460     byte buf[32];
26461 
26462     do {
26463         err = wc_RNG_GenerateBlock(rng, buf, sizeof(buf));
26464         if (err == 0) {
26465             sp_256_from_bin(k, 5, buf, (int)sizeof(buf));
26466             if (sp_256_cmp_5(k, p256_order2) <= 0) {
26467                 sp_256_add_one_5(k);
26468                 break;
26469             }
26470         }
26471     }
26472     while (err == 0);
26473 
26474     return err;
26475 }
26476 
26477 /* Makes a random EC key pair.
26478  *
26479  * rng   Random number generator.
26480  * priv  Generated private value.
26481  * pub   Generated public point.
26482  * heap  Heap to use for allocation.
26483  * returns ECC_INF_E when the point does not have the correct order, RNG
26484  * failures, MEMORY_E when memory allocation fails and MP_OKAY on success.
26485  */
sp_ecc_make_key_256(WC_RNG * rng,mp_int * priv,ecc_point * pub,void * heap)26486 int sp_ecc_make_key_256(WC_RNG* rng, mp_int* priv, ecc_point* pub, void* heap)
26487 {
26488 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
26489     sp_point_256* point = NULL;
26490     sp_digit* k = NULL;
26491 #else
26492     #ifdef WOLFSSL_VALIDATE_ECC_KEYGEN
26493     sp_point_256 point[2];
26494     #else
26495     sp_point_256 point[1];
26496     #endif
26497     sp_digit k[5];
26498 #endif
26499 #ifdef WOLFSSL_VALIDATE_ECC_KEYGEN
26500     sp_point_256* infinity = NULL;
26501 #endif
26502     int err = MP_OKAY;
26503 
26504 
26505     (void)heap;
26506 
26507 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
26508     #ifdef WOLFSSL_VALIDATE_ECC_KEYGEN
26509     point = (sp_point_256*)XMALLOC(sizeof(sp_point_256) * 2, heap, DYNAMIC_TYPE_ECC);
26510     #else
26511     point = (sp_point_256*)XMALLOC(sizeof(sp_point_256), heap, DYNAMIC_TYPE_ECC);
26512     #endif
26513     if (point == NULL)
26514         err = MEMORY_E;
26515     if (err == MP_OKAY) {
26516         k = (sp_digit*)XMALLOC(sizeof(sp_digit) * 5, heap,
26517                                DYNAMIC_TYPE_ECC);
26518         if (k == NULL)
26519             err = MEMORY_E;
26520     }
26521 #endif
26522 
26523     if (err == MP_OKAY) {
26524     #ifdef WOLFSSL_VALIDATE_ECC_KEYGEN
26525         infinity = point + 1;
26526     #endif
26527 
26528         err = sp_256_ecc_gen_k_5(rng, k);
26529     }
26530     if (err == MP_OKAY) {
26531             err = sp_256_ecc_mulmod_base_5(point, k, 1, 1, NULL);
26532     }
26533 
26534 #ifdef WOLFSSL_VALIDATE_ECC_KEYGEN
26535     if (err == MP_OKAY) {
26536             err = sp_256_ecc_mulmod_5(infinity, point, p256_order, 1, 1, NULL);
26537     }
26538     if (err == MP_OKAY) {
26539         if (sp_256_iszero_5(point->x) || sp_256_iszero_5(point->y)) {
26540             err = ECC_INF_E;
26541         }
26542     }
26543 #endif
26544 
26545     if (err == MP_OKAY) {
26546         err = sp_256_to_mp(k, priv);
26547     }
26548     if (err == MP_OKAY) {
26549         err = sp_256_point_to_ecc_point_5(point, pub);
26550     }
26551 
26552 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
26553     if (k != NULL)
26554         XFREE(k, heap, DYNAMIC_TYPE_ECC);
26555     if (point != NULL) {
26556         /* point is not sensitive, so no need to zeroize */
26557         XFREE(point, heap, DYNAMIC_TYPE_ECC);
26558     }
26559 #endif
26560 
26561     return err;
26562 }
26563 
26564 #ifdef HAVE_ECC_DHE
26565 /* Write r as big endian to byte array.
26566  * Fixed length number of bytes written: 32
26567  *
26568  * r  A single precision integer.
26569  * a  Byte array.
26570  */
sp_256_to_bin_5(sp_digit * r,byte * a)26571 static void sp_256_to_bin_5(sp_digit* r, byte* a)
26572 {
26573     int i;
26574     int j;
26575     int s = 0;
26576     int b;
26577 
26578     for (i=0; i<4; i++) {
26579         r[i+1] += r[i] >> 52;
26580         r[i] &= 0xfffffffffffffL;
26581     }
26582     j = 256 / 8 - 1;
26583     a[j] = 0;
26584     for (i=0; i<5 && j>=0; i++) {
26585         b = 0;
26586         /* lint allow cast of mismatch sp_digit and int */
26587         a[j--] |= (byte)(r[i] << s); /*lint !e9033*/
26588         b += 8 - s;
26589         if (j < 0) {
26590             break;
26591         }
26592         while (b < 52) {
26593             a[j--] = (byte)(r[i] >> b);
26594             b += 8;
26595             if (j < 0) {
26596                 break;
26597             }
26598         }
26599         s = 8 - (b - 52);
26600         if (j >= 0) {
26601             a[j] = 0;
26602         }
26603         if (s != 0) {
26604             j++;
26605         }
26606     }
26607 }
26608 
26609 /* Multiply the point by the scalar and serialize the X ordinate.
26610  * The number is 0 padded to maximum size on output.
26611  *
26612  * priv    Scalar to multiply the point by.
26613  * pub     Point to multiply.
26614  * out     Buffer to hold X ordinate.
26615  * outLen  On entry, size of the buffer in bytes.
26616  *         On exit, length of data in buffer in bytes.
26617  * heap    Heap to use for allocation.
26618  * returns BUFFER_E if the buffer is to small for output size,
26619  * MEMORY_E when memory allocation fails and MP_OKAY on success.
26620  */
sp_ecc_secret_gen_256(const mp_int * priv,const ecc_point * pub,byte * out,word32 * outLen,void * heap)26621 int sp_ecc_secret_gen_256(const mp_int* priv, const ecc_point* pub, byte* out,
26622                           word32* outLen, void* heap)
26623 {
26624 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
26625     sp_point_256* point = NULL;
26626     sp_digit* k = NULL;
26627 #else
26628     sp_point_256 point[1];
26629     sp_digit k[5];
26630 #endif
26631     int err = MP_OKAY;
26632 
26633     if (*outLen < 32U) {
26634         err = BUFFER_E;
26635     }
26636 
26637 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
26638     if (err == MP_OKAY) {
26639         point = (sp_point_256*)XMALLOC(sizeof(sp_point_256), heap,
26640                                          DYNAMIC_TYPE_ECC);
26641         if (point == NULL)
26642             err = MEMORY_E;
26643     }
26644     if (err == MP_OKAY) {
26645         k = (sp_digit*)XMALLOC(sizeof(sp_digit) * 5, heap,
26646                                DYNAMIC_TYPE_ECC);
26647         if (k == NULL)
26648             err = MEMORY_E;
26649     }
26650 #endif
26651 
26652     if (err == MP_OKAY) {
26653         sp_256_from_mp(k, 5, priv);
26654         sp_256_point_from_ecc_point_5(point, pub);
26655             err = sp_256_ecc_mulmod_5(point, point, k, 1, 1, heap);
26656     }
26657     if (err == MP_OKAY) {
26658         sp_256_to_bin_5(point->x, out);
26659         *outLen = 32;
26660     }
26661 
26662 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
26663     if (k != NULL)
26664         XFREE(k, heap, DYNAMIC_TYPE_ECC);
26665     if (point != NULL)
26666         XFREE(point, heap, DYNAMIC_TYPE_ECC);
26667 #endif
26668 
26669     return err;
26670 }
26671 #endif /* HAVE_ECC_DHE */
26672 
26673 #if defined(HAVE_ECC_SIGN) || defined(HAVE_ECC_VERIFY)
26674 #endif
26675 #if defined(HAVE_ECC_SIGN) || defined(HAVE_ECC_VERIFY)
sp_256_rshift_5(sp_digit * r,const sp_digit * a,byte n)26676 SP_NOINLINE static void sp_256_rshift_5(sp_digit* r, const sp_digit* a,
26677         byte n)
26678 {
26679     int i;
26680 
26681 #ifdef WOLFSSL_SP_SMALL
26682     for (i=0; i<4; i++) {
26683         r[i] = ((a[i] >> n) | (a[i + 1] << (52 - n))) & 0xfffffffffffffL;
26684     }
26685 #else
26686     for (i=0; i<0; i += 8) {
26687         r[i+0] = (a[i+0] >> n) | ((a[i+1] << (52 - n)) & 0xfffffffffffffL);
26688         r[i+1] = (a[i+1] >> n) | ((a[i+2] << (52 - n)) & 0xfffffffffffffL);
26689         r[i+2] = (a[i+2] >> n) | ((a[i+3] << (52 - n)) & 0xfffffffffffffL);
26690         r[i+3] = (a[i+3] >> n) | ((a[i+4] << (52 - n)) & 0xfffffffffffffL);
26691         r[i+4] = (a[i+4] >> n) | ((a[i+5] << (52 - n)) & 0xfffffffffffffL);
26692         r[i+5] = (a[i+5] >> n) | ((a[i+6] << (52 - n)) & 0xfffffffffffffL);
26693         r[i+6] = (a[i+6] >> n) | ((a[i+7] << (52 - n)) & 0xfffffffffffffL);
26694         r[i+7] = (a[i+7] >> n) | ((a[i+8] << (52 - n)) & 0xfffffffffffffL);
26695     }
26696     r[0] = (a[0] >> n) | ((a[1] << (52 - n)) & 0xfffffffffffffL);
26697     r[1] = (a[1] >> n) | ((a[2] << (52 - n)) & 0xfffffffffffffL);
26698     r[2] = (a[2] >> n) | ((a[3] << (52 - n)) & 0xfffffffffffffL);
26699     r[3] = (a[3] >> n) | ((a[4] << (52 - n)) & 0xfffffffffffffL);
26700 #endif /* WOLFSSL_SP_SMALL */
26701     r[4] = a[4] >> n;
26702 }
26703 
26704 /* Multiply a by scalar b into r. (r = a * b)
26705  *
26706  * r  A single precision integer.
26707  * a  A single precision integer.
26708  * b  A scalar.
26709  */
sp_256_mul_d_5(sp_digit * r,const sp_digit * a,sp_digit b)26710 SP_NOINLINE static void sp_256_mul_d_5(sp_digit* r, const sp_digit* a,
26711     sp_digit b)
26712 {
26713 #ifdef WOLFSSL_SP_SMALL
26714     sp_int128 tb = b;
26715     sp_int128 t = 0;
26716     int i;
26717 
26718     for (i = 0; i < 5; i++) {
26719         t += tb * a[i];
26720         r[i] = (sp_digit)(t & 0xfffffffffffffL);
26721         t >>= 52;
26722     }
26723     r[5] = (sp_digit)t;
26724 #else
26725     sp_int128 tb = b;
26726     sp_int128 t[5];
26727 
26728     t[ 0] = tb * a[ 0];
26729     t[ 1] = tb * a[ 1];
26730     t[ 2] = tb * a[ 2];
26731     t[ 3] = tb * a[ 3];
26732     t[ 4] = tb * a[ 4];
26733     r[ 0] = (sp_digit)                 (t[ 0] & 0xfffffffffffffL);
26734     r[ 1] = (sp_digit)((t[ 0] >> 52) + (t[ 1] & 0xfffffffffffffL));
26735     r[ 2] = (sp_digit)((t[ 1] >> 52) + (t[ 2] & 0xfffffffffffffL));
26736     r[ 3] = (sp_digit)((t[ 2] >> 52) + (t[ 3] & 0xfffffffffffffL));
26737     r[ 4] = (sp_digit)((t[ 3] >> 52) + (t[ 4] & 0xfffffffffffffL));
26738     r[ 5] = (sp_digit) (t[ 4] >> 52);
26739 #endif /* WOLFSSL_SP_SMALL */
26740 }
26741 
sp_256_lshift_10(sp_digit * r,const sp_digit * a,byte n)26742 SP_NOINLINE static void sp_256_lshift_10(sp_digit* r, const sp_digit* a,
26743         byte n)
26744 {
26745 #ifdef WOLFSSL_SP_SMALL
26746     int i;
26747 
26748     r[10] = a[9] >> (52 - n);
26749     for (i=9; i>0; i--) {
26750         r[i] = ((a[i] << n) | (a[i-1] >> (52 - n))) & 0xfffffffffffffL;
26751     }
26752 #else
26753     sp_int_digit s;
26754     sp_int_digit t;
26755 
26756     s = (sp_int_digit)a[9];
26757     r[10] = s >> (52U - n);
26758     s = (sp_int_digit)(a[9]); t = (sp_int_digit)(a[8]);
26759     r[9] = ((s << n) | (t >> (52U - n))) & 0xfffffffffffffUL;
26760     s = (sp_int_digit)(a[8]); t = (sp_int_digit)(a[7]);
26761     r[8] = ((s << n) | (t >> (52U - n))) & 0xfffffffffffffUL;
26762     s = (sp_int_digit)(a[7]); t = (sp_int_digit)(a[6]);
26763     r[7] = ((s << n) | (t >> (52U - n))) & 0xfffffffffffffUL;
26764     s = (sp_int_digit)(a[6]); t = (sp_int_digit)(a[5]);
26765     r[6] = ((s << n) | (t >> (52U - n))) & 0xfffffffffffffUL;
26766     s = (sp_int_digit)(a[5]); t = (sp_int_digit)(a[4]);
26767     r[5] = ((s << n) | (t >> (52U - n))) & 0xfffffffffffffUL;
26768     s = (sp_int_digit)(a[4]); t = (sp_int_digit)(a[3]);
26769     r[4] = ((s << n) | (t >> (52U - n))) & 0xfffffffffffffUL;
26770     s = (sp_int_digit)(a[3]); t = (sp_int_digit)(a[2]);
26771     r[3] = ((s << n) | (t >> (52U - n))) & 0xfffffffffffffUL;
26772     s = (sp_int_digit)(a[2]); t = (sp_int_digit)(a[1]);
26773     r[2] = ((s << n) | (t >> (52U - n))) & 0xfffffffffffffUL;
26774     s = (sp_int_digit)(a[1]); t = (sp_int_digit)(a[0]);
26775     r[1] = ((s << n) | (t >> (52U - n))) & 0xfffffffffffffUL;
26776 #endif /* WOLFSSL_SP_SMALL */
26777     r[0] = (a[0] << n) & 0xfffffffffffffL;
26778 }
26779 
26780 /* Divide d in a and put remainder into r (m*d + r = a)
26781  * m is not calculated as it is not needed at this time.
26782  *
26783  * Simplified based on top word of divisor being very large.
26784  *
26785  * a  Number to be divided.
26786  * d  Number to divide with.
26787  * m  Multiplier result.
26788  * r  Remainder from the division.
26789  * returns MEMORY_E when unable to allocate memory and MP_OKAY otherwise.
26790  */
sp_256_div_5(const sp_digit * a,const sp_digit * d,const sp_digit * m,sp_digit * r)26791 static int sp_256_div_5(const sp_digit* a, const sp_digit* d,
26792         const sp_digit* m, sp_digit* r)
26793 {
26794     int i;
26795     sp_digit r1;
26796     sp_digit mask;
26797 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
26798     sp_digit* t1 = NULL;
26799 #else
26800     sp_digit t1[4 * 5 + 3];
26801 #endif
26802     sp_digit* t2 = NULL;
26803     sp_digit* sd = NULL;
26804     int err = MP_OKAY;
26805 
26806     (void)m;
26807 
26808 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
26809     t1 = (sp_digit*)XMALLOC(sizeof(sp_digit) * (4 * 5 + 3), NULL,
26810                                                        DYNAMIC_TYPE_TMP_BUFFER);
26811     if (t1 == NULL)
26812         err = MEMORY_E;
26813 #endif
26814 
26815     (void)m;
26816 
26817     if (err == MP_OKAY) {
26818         t2 = t1 + 10 + 1;
26819         sd = t2 + 5 + 1;
26820 
26821         sp_256_mul_d_5(sd, d, (sp_digit)1 << 4);
26822         sp_256_lshift_10(t1, a, 4);
26823         t1[5 + 5] += t1[5 + 5 - 1] >> 52;
26824         t1[5 + 5 - 1] &= 0xfffffffffffffL;
26825         for (i=4; i>=0; i--) {
26826             r1 = t1[5 + i];
26827             sp_256_mul_d_5(t2, sd, r1);
26828             (void)sp_256_sub_5(&t1[i], &t1[i], t2);
26829             t1[5 + i] -= t2[5];
26830             sp_256_norm_5(&t1[i + 1]);
26831 
26832             r1 = t1[5 + i];
26833             sp_256_mul_d_5(t2, sd, r1);
26834             (void)sp_256_sub_5(&t1[i], &t1[i], t2);
26835             t1[5 + i] -= t2[5];
26836             sp_256_norm_5(&t1[i + 1]);
26837 
26838             mask = (sp_digit)0 - ((t1[5 + i] > 0) ?
26839                     (sp_digit)1 : (sp_digit)0);
26840             sp_256_cond_sub_5(t1 + i, t1 + i, sd, mask);
26841             sp_256_norm_5(&t1[i + 1]);
26842         }
26843         sp_256_norm_5(t1);
26844         sp_256_rshift_5(r, t1, 4);
26845     }
26846 
26847 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
26848     if (t1 != NULL)
26849         XFREE(t1, NULL, DYNAMIC_TYPE_TMP_BUFFER);
26850 #endif
26851 
26852     return err;
26853 }
26854 
26855 /* Reduce a modulo m into r. (r = a mod m)
26856  *
26857  * r  A single precision number that is the reduced result.
26858  * a  A single precision number that is to be reduced.
26859  * m  A single precision number that is the modulus to reduce with.
26860  * returns MEMORY_E when unable to allocate memory and MP_OKAY otherwise.
26861  */
sp_256_mod_5(sp_digit * r,const sp_digit * a,const sp_digit * m)26862 static int sp_256_mod_5(sp_digit* r, const sp_digit* a, const sp_digit* m)
26863 {
26864     return sp_256_div_5(a, m, NULL, r);
26865 }
26866 
26867 #endif
26868 #if defined(HAVE_ECC_SIGN) || defined(HAVE_ECC_VERIFY)
26869 /* Multiply two number mod the order of P256 curve. (r = a * b mod order)
26870  *
26871  * r  Result of the multiplication.
26872  * a  First operand of the multiplication.
26873  * b  Second operand of the multiplication.
26874  */
sp_256_mont_mul_order_5(sp_digit * r,const sp_digit * a,const sp_digit * b)26875 static void sp_256_mont_mul_order_5(sp_digit* r, const sp_digit* a, const sp_digit* b)
26876 {
26877     sp_256_mul_5(r, a, b);
26878     sp_256_mont_reduce_order_5(r, p256_order, p256_mp_order);
26879 }
26880 
26881 #if defined(HAVE_ECC_SIGN) || (defined(HAVE_ECC_VERIFY) && defined(WOLFSSL_SP_SMALL))
26882 #ifdef WOLFSSL_SP_SMALL
26883 /* Order-2 for the P256 curve. */
26884 static const uint64_t p256_order_minus_2[4] = {
26885     0xf3b9cac2fc63254fU,0xbce6faada7179e84U,0xffffffffffffffffU,
26886     0xffffffff00000000U
26887 };
26888 #else
26889 /* The low half of the order-2 of the P256 curve. */
26890 static const sp_int_digit p256_order_low[2] = {
26891     0xf3b9cac2fc63254fU,0xbce6faada7179e84U
26892 };
26893 #endif /* WOLFSSL_SP_SMALL */
26894 
26895 /* Square number mod the order of P256 curve. (r = a * a mod order)
26896  *
26897  * r  Result of the squaring.
26898  * a  Number to square.
26899  */
sp_256_mont_sqr_order_5(sp_digit * r,const sp_digit * a)26900 static void sp_256_mont_sqr_order_5(sp_digit* r, const sp_digit* a)
26901 {
26902     sp_256_sqr_5(r, a);
26903     sp_256_mont_reduce_order_5(r, p256_order, p256_mp_order);
26904 }
26905 
26906 #ifndef WOLFSSL_SP_SMALL
26907 /* Square number mod the order of P256 curve a number of times.
26908  * (r = a ^ n mod order)
26909  *
26910  * r  Result of the squaring.
26911  * a  Number to square.
26912  */
sp_256_mont_sqr_n_order_5(sp_digit * r,const sp_digit * a,int n)26913 static void sp_256_mont_sqr_n_order_5(sp_digit* r, const sp_digit* a, int n)
26914 {
26915     int i;
26916 
26917     sp_256_mont_sqr_order_5(r, a);
26918     for (i=1; i<n; i++) {
26919         sp_256_mont_sqr_order_5(r, r);
26920     }
26921 }
26922 #endif /* !WOLFSSL_SP_SMALL */
26923 
26924 /* Invert the number, in Montgomery form, modulo the order of the P256 curve.
26925  * (r = 1 / a mod order)
26926  *
26927  * r   Inverse result.
26928  * a   Number to invert.
26929  * td  Temporary data.
26930  */
26931 
26932 #ifdef WOLFSSL_SP_NONBLOCK
26933 typedef struct sp_256_mont_inv_order_5_ctx {
26934     int state;
26935     int i;
26936 } sp_256_mont_inv_order_5_ctx;
sp_256_mont_inv_order_5_nb(sp_ecc_ctx_t * sp_ctx,sp_digit * r,const sp_digit * a,sp_digit * t)26937 static int sp_256_mont_inv_order_5_nb(sp_ecc_ctx_t* sp_ctx, sp_digit* r, const sp_digit* a,
26938         sp_digit* t)
26939 {
26940     int err = FP_WOULDBLOCK;
26941     sp_256_mont_inv_order_5_ctx* ctx = (sp_256_mont_inv_order_5_ctx*)sp_ctx;
26942 
26943     typedef char ctx_size_test[sizeof(sp_256_mont_inv_order_5_ctx) >= sizeof(*sp_ctx) ? -1 : 1];
26944     (void)sizeof(ctx_size_test);
26945 
26946     switch (ctx->state) {
26947     case 0:
26948         XMEMCPY(t, a, sizeof(sp_digit) * 5);
26949         ctx->i = 254;
26950         ctx->state = 1;
26951         break;
26952     case 1:
26953         sp_256_mont_sqr_order_5(t, t);
26954         ctx->state = 2;
26955         break;
26956     case 2:
26957         if ((p256_order_minus_2[ctx->i / 64] & ((sp_int_digit)1 << (ctx->i % 64))) != 0) {
26958             sp_256_mont_mul_order_5(t, t, a);
26959         }
26960         ctx->i--;
26961         ctx->state = (ctx->i == 0) ? 3 : 1;
26962         break;
26963     case 3:
26964         XMEMCPY(r, t, sizeof(sp_digit) * 5U);
26965         err = MP_OKAY;
26966         break;
26967     }
26968     return err;
26969 }
26970 #endif /* WOLFSSL_SP_NONBLOCK */
26971 
sp_256_mont_inv_order_5(sp_digit * r,const sp_digit * a,sp_digit * td)26972 static void sp_256_mont_inv_order_5(sp_digit* r, const sp_digit* a,
26973         sp_digit* td)
26974 {
26975 #ifdef WOLFSSL_SP_SMALL
26976     sp_digit* t = td;
26977     int i;
26978 
26979     XMEMCPY(t, a, sizeof(sp_digit) * 5);
26980     for (i=254; i>=0; i--) {
26981         sp_256_mont_sqr_order_5(t, t);
26982         if ((p256_order_minus_2[i / 64] & ((sp_int_digit)1 << (i % 64))) != 0) {
26983             sp_256_mont_mul_order_5(t, t, a);
26984         }
26985     }
26986     XMEMCPY(r, t, sizeof(sp_digit) * 5U);
26987 #else
26988     sp_digit* t = td;
26989     sp_digit* t2 = td + 2 * 5;
26990     sp_digit* t3 = td + 4 * 5;
26991     int i;
26992 
26993     /* t = a^2 */
26994     sp_256_mont_sqr_order_5(t, a);
26995     /* t = a^3 = t * a */
26996     sp_256_mont_mul_order_5(t, t, a);
26997     /* t2= a^c = t ^ 2 ^ 2 */
26998     sp_256_mont_sqr_n_order_5(t2, t, 2);
26999     /* t3= a^f = t2 * t */
27000     sp_256_mont_mul_order_5(t3, t2, t);
27001     /* t2= a^f0 = t3 ^ 2 ^ 4 */
27002     sp_256_mont_sqr_n_order_5(t2, t3, 4);
27003     /* t = a^ff = t2 * t3 */
27004     sp_256_mont_mul_order_5(t, t2, t3);
27005     /* t3= a^ff00 = t ^ 2 ^ 8 */
27006     sp_256_mont_sqr_n_order_5(t2, t, 8);
27007     /* t = a^ffff = t2 * t */
27008     sp_256_mont_mul_order_5(t, t2, t);
27009     /* t2= a^ffff0000 = t ^ 2 ^ 16 */
27010     sp_256_mont_sqr_n_order_5(t2, t, 16);
27011     /* t = a^ffffffff = t2 * t */
27012     sp_256_mont_mul_order_5(t, t2, t);
27013     /* t2= a^ffffffff0000000000000000 = t ^ 2 ^ 64  */
27014     sp_256_mont_sqr_n_order_5(t2, t, 64);
27015     /* t2= a^ffffffff00000000ffffffff = t2 * t */
27016     sp_256_mont_mul_order_5(t2, t2, t);
27017     /* t2= a^ffffffff00000000ffffffff00000000 = t2 ^ 2 ^ 32  */
27018     sp_256_mont_sqr_n_order_5(t2, t2, 32);
27019     /* t2= a^ffffffff00000000ffffffffffffffff = t2 * t */
27020     sp_256_mont_mul_order_5(t2, t2, t);
27021     /* t2= a^ffffffff00000000ffffffffffffffffbce6 */
27022     for (i=127; i>=112; i--) {
27023         sp_256_mont_sqr_order_5(t2, t2);
27024         if ((p256_order_low[i / 64] & ((sp_int_digit)1 << (i % 64))) != 0) {
27025             sp_256_mont_mul_order_5(t2, t2, a);
27026         }
27027     }
27028     /* t2= a^ffffffff00000000ffffffffffffffffbce6f */
27029     sp_256_mont_sqr_n_order_5(t2, t2, 4);
27030     sp_256_mont_mul_order_5(t2, t2, t3);
27031     /* t2= a^ffffffff00000000ffffffffffffffffbce6faada7179e84 */
27032     for (i=107; i>=64; i--) {
27033         sp_256_mont_sqr_order_5(t2, t2);
27034         if ((p256_order_low[i / 64] & ((sp_int_digit)1 << (i % 64))) != 0) {
27035             sp_256_mont_mul_order_5(t2, t2, a);
27036         }
27037     }
27038     /* t2= a^ffffffff00000000ffffffffffffffffbce6faada7179e84f */
27039     sp_256_mont_sqr_n_order_5(t2, t2, 4);
27040     sp_256_mont_mul_order_5(t2, t2, t3);
27041     /* t2= a^ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2 */
27042     for (i=59; i>=32; i--) {
27043         sp_256_mont_sqr_order_5(t2, t2);
27044         if ((p256_order_low[i / 64] & ((sp_int_digit)1 << (i % 64))) != 0) {
27045             sp_256_mont_mul_order_5(t2, t2, a);
27046         }
27047     }
27048     /* t2= a^ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2f */
27049     sp_256_mont_sqr_n_order_5(t2, t2, 4);
27050     sp_256_mont_mul_order_5(t2, t2, t3);
27051     /* t2= a^ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc63254 */
27052     for (i=27; i>=0; i--) {
27053         sp_256_mont_sqr_order_5(t2, t2);
27054         if ((p256_order_low[i / 64] & ((sp_int_digit)1 << (i % 64))) != 0) {
27055             sp_256_mont_mul_order_5(t2, t2, a);
27056         }
27057     }
27058     /* t2= a^ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632540 */
27059     sp_256_mont_sqr_n_order_5(t2, t2, 4);
27060     /* r = a^ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc63254f */
27061     sp_256_mont_mul_order_5(r, t2, t3);
27062 #endif /* WOLFSSL_SP_SMALL */
27063 }
27064 
27065 #endif /* HAVE_ECC_SIGN || (HAVE_ECC_VERIFY && WOLFSSL_SP_SMALL) */
27066 #endif /* HAVE_ECC_SIGN | HAVE_ECC_VERIFY */
27067 #ifdef HAVE_ECC_SIGN
27068 #ifndef SP_ECC_MAX_SIG_GEN
27069 #define SP_ECC_MAX_SIG_GEN  64
27070 #endif
27071 
27072 /* Calculate second signature value S from R, k and private value.
27073  *
27074  * s = (r * x + e) / k
27075  *
27076  * s    Signature value.
27077  * r    First signature value.
27078  * k    Ephemeral private key.
27079  * x    Private key as a number.
27080  * e    Hash of message as a number.
27081  * tmp  Temporary storage for intermediate numbers.
27082  * returns MEMORY_E when memory allocation fails and MP_OKAY on success.
27083  */
sp_256_calc_s_5(sp_digit * s,const sp_digit * r,sp_digit * k,sp_digit * x,const sp_digit * e,sp_digit * tmp)27084 static int sp_256_calc_s_5(sp_digit* s, const sp_digit* r, sp_digit* k,
27085     sp_digit* x, const sp_digit* e, sp_digit* tmp)
27086 {
27087     int err;
27088     sp_digit carry;
27089     sp_int64 c;
27090     sp_digit* kInv = k;
27091 
27092     /* Conv k to Montgomery form (mod order) */
27093         sp_256_mul_5(k, k, p256_norm_order);
27094     err = sp_256_mod_5(k, k, p256_order);
27095     if (err == MP_OKAY) {
27096         sp_256_norm_5(k);
27097 
27098         /* kInv = 1/k mod order */
27099             sp_256_mont_inv_order_5(kInv, k, tmp);
27100         sp_256_norm_5(kInv);
27101 
27102         /* s = r * x + e */
27103             sp_256_mul_5(x, x, r);
27104         err = sp_256_mod_5(x, x, p256_order);
27105     }
27106     if (err == MP_OKAY) {
27107         sp_256_norm_5(x);
27108         carry = sp_256_add_5(s, e, x);
27109         sp_256_cond_sub_5(s, s, p256_order, 0 - carry);
27110         sp_256_norm_5(s);
27111         c = sp_256_cmp_5(s, p256_order);
27112         sp_256_cond_sub_5(s, s, p256_order,
27113             (sp_digit)0 - (sp_digit)(c >= 0));
27114         sp_256_norm_5(s);
27115 
27116         /* s = s * k^-1 mod order */
27117             sp_256_mont_mul_order_5(s, s, kInv);
27118         sp_256_norm_5(s);
27119     }
27120 
27121     return err;
27122 }
27123 
27124 /* Sign the hash using the private key.
27125  *   e = [hash, 256 bits] from binary
27126  *   r = (k.G)->x mod order
27127  *   s = (r * x + e) / k mod order
27128  * The hash is truncated to the first 256 bits.
27129  *
27130  * hash     Hash to sign.
27131  * hashLen  Length of the hash data.
27132  * rng      Random number generator.
27133  * priv     Private part of key - scalar.
27134  * rm       First part of result as an mp_int.
27135  * sm       Sirst part of result as an mp_int.
27136  * heap     Heap to use for allocation.
27137  * returns RNG failures, MEMORY_E when memory allocation fails and
27138  * MP_OKAY on success.
27139  */
27140 #ifdef WOLFSSL_SP_NONBLOCK
27141 typedef struct sp_ecc_sign_256_ctx {
27142     int state;
27143     union {
27144         sp_256_ecc_mulmod_5_ctx mulmod_ctx;
27145         sp_256_mont_inv_order_5_ctx mont_inv_order_ctx;
27146     };
27147     sp_digit e[2*5];
27148     sp_digit x[2*5];
27149     sp_digit k[2*5];
27150     sp_digit r[2*5];
27151     sp_digit tmp[3 * 2*5];
27152     sp_point_256 point;
27153     sp_digit* s;
27154     sp_digit* kInv;
27155     int i;
27156 } sp_ecc_sign_256_ctx;
27157 
sp_ecc_sign_256_nb(sp_ecc_ctx_t * sp_ctx,const byte * hash,word32 hashLen,WC_RNG * rng,mp_int * priv,mp_int * rm,mp_int * sm,mp_int * km,void * heap)27158 int sp_ecc_sign_256_nb(sp_ecc_ctx_t* sp_ctx, const byte* hash, word32 hashLen, WC_RNG* rng,
27159     mp_int* priv, mp_int* rm, mp_int* sm, mp_int* km, void* heap)
27160 {
27161     int err = FP_WOULDBLOCK;
27162     sp_ecc_sign_256_ctx* ctx = (sp_ecc_sign_256_ctx*)sp_ctx->data;
27163 
27164     typedef char ctx_size_test[sizeof(sp_ecc_sign_256_ctx) >= sizeof(*sp_ctx) ? -1 : 1];
27165     (void)sizeof(ctx_size_test);
27166 
27167     (void)heap;
27168 
27169     switch (ctx->state) {
27170     case 0: /* INIT */
27171         ctx->s = ctx->e;
27172         ctx->kInv = ctx->k;
27173         if (hashLen > 32U) {
27174             hashLen = 32U;
27175         }
27176 
27177         ctx->i = SP_ECC_MAX_SIG_GEN;
27178         ctx->state = 1;
27179         break;
27180     case 1: /* GEN */
27181         /* New random point. */
27182         if (km == NULL || mp_iszero(km)) {
27183             err = sp_256_ecc_gen_k_5(rng, ctx->k);
27184         }
27185         else {
27186             sp_256_from_mp(ctx->k, 5, km);
27187             mp_zero(km);
27188         }
27189         XMEMSET(&ctx->mulmod_ctx, 0, sizeof(ctx->mulmod_ctx));
27190         ctx->state = 2;
27191         break;
27192     case 2: /* MULMOD */
27193         err = sp_256_ecc_mulmod_5_nb((sp_ecc_ctx_t*)&ctx->mulmod_ctx,
27194             &ctx->point, &p256_base, ctx->k, 1, 1, heap);
27195         if (err == MP_OKAY) {
27196             ctx->state = 3;
27197         }
27198         break;
27199     case 3: /* MODORDER */
27200     {
27201         sp_int64 c;
27202         /* r = point->x mod order */
27203         XMEMCPY(ctx->r, ctx->point.x, sizeof(sp_digit) * 5U);
27204         sp_256_norm_5(ctx->r);
27205         c = sp_256_cmp_5(ctx->r, p256_order);
27206         sp_256_cond_sub_5(ctx->r, ctx->r, p256_order,
27207             (sp_digit)0 - (sp_digit)(c >= 0));
27208         sp_256_norm_5(ctx->r);
27209 
27210         sp_256_from_mp(ctx->x, 5, priv);
27211         sp_256_from_bin(ctx->e, 5, hash, (int)hashLen);
27212         ctx->state = 4;
27213         break;
27214     }
27215     case 4: /* KMODORDER */
27216         /* Conv k to Montgomery form (mod order) */
27217         sp_256_mul_5(ctx->k, ctx->k, p256_norm_order);
27218         err = sp_256_mod_5(ctx->k, ctx->k, p256_order);
27219         if (err == MP_OKAY) {
27220             sp_256_norm_5(ctx->k);
27221             XMEMSET(&ctx->mont_inv_order_ctx, 0, sizeof(ctx->mont_inv_order_ctx));
27222             ctx->state = 5;
27223         }
27224         break;
27225     case 5: /* KINV */
27226         /* kInv = 1/k mod order */
27227         err = sp_256_mont_inv_order_5_nb((sp_ecc_ctx_t*)&ctx->mont_inv_order_ctx, ctx->kInv, ctx->k, ctx->tmp);
27228         if (err == MP_OKAY) {
27229             XMEMSET(&ctx->mont_inv_order_ctx, 0, sizeof(ctx->mont_inv_order_ctx));
27230             ctx->state = 6;
27231         }
27232         break;
27233     case 6: /* KINVNORM */
27234         sp_256_norm_5(ctx->kInv);
27235         ctx->state = 7;
27236         break;
27237     case 7: /* R */
27238         /* s = r * x + e */
27239         sp_256_mul_5(ctx->x, ctx->x, ctx->r);
27240         ctx->state = 8;
27241         break;
27242     case 8: /* S1 */
27243         err = sp_256_mod_5(ctx->x, ctx->x, p256_order);
27244         if (err == MP_OKAY)
27245             ctx->state = 9;
27246         break;
27247     case 9: /* S2 */
27248     {
27249         sp_digit carry;
27250         sp_int64 c;
27251         sp_256_norm_5(ctx->x);
27252         carry = sp_256_add_5(ctx->s, ctx->e, ctx->x);
27253         sp_256_cond_sub_5(ctx->s, ctx->s,
27254             p256_order, 0 - carry);
27255         sp_256_norm_5(ctx->s);
27256         c = sp_256_cmp_5(ctx->s, p256_order);
27257         sp_256_cond_sub_5(ctx->s, ctx->s, p256_order,
27258             (sp_digit)0 - (sp_digit)(c >= 0));
27259         sp_256_norm_5(ctx->s);
27260 
27261         /* s = s * k^-1 mod order */
27262         sp_256_mont_mul_order_5(ctx->s, ctx->s, ctx->kInv);
27263         sp_256_norm_5(ctx->s);
27264 
27265         /* Check that signature is usable. */
27266         if (sp_256_iszero_5(ctx->s) == 0) {
27267             ctx->state = 10;
27268             break;
27269         }
27270     #ifdef WOLFSSL_ECDSA_SET_K_ONE_LOOP
27271         ctx->i = 1;
27272     #endif
27273 
27274         /* not usable gen, try again */
27275         ctx->i--;
27276         if (ctx->i == 0) {
27277             err = RNG_FAILURE_E;
27278         }
27279         ctx->state = 1;
27280         break;
27281     }
27282     case 10: /* RES */
27283         err = sp_256_to_mp(ctx->r, rm);
27284         if (err == MP_OKAY) {
27285             err = sp_256_to_mp(ctx->s, sm);
27286         }
27287         break;
27288     }
27289 
27290     if (err == MP_OKAY && ctx->state != 10) {
27291         err = FP_WOULDBLOCK;
27292     }
27293     if (err != FP_WOULDBLOCK) {
27294         XMEMSET(ctx->e, 0, sizeof(sp_digit) * 2U * 5U);
27295         XMEMSET(ctx->x, 0, sizeof(sp_digit) * 2U * 5U);
27296         XMEMSET(ctx->k, 0, sizeof(sp_digit) * 2U * 5U);
27297         XMEMSET(ctx->r, 0, sizeof(sp_digit) * 2U * 5U);
27298         XMEMSET(ctx->tmp, 0, sizeof(sp_digit) * 3U * 2U * 5U);
27299     }
27300 
27301     return err;
27302 }
27303 #endif /* WOLFSSL_SP_NONBLOCK */
27304 
sp_ecc_sign_256(const byte * hash,word32 hashLen,WC_RNG * rng,const mp_int * priv,mp_int * rm,mp_int * sm,mp_int * km,void * heap)27305 int sp_ecc_sign_256(const byte* hash, word32 hashLen, WC_RNG* rng,
27306     const mp_int* priv, mp_int* rm, mp_int* sm, mp_int* km, void* heap)
27307 {
27308 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
27309     sp_digit* e = NULL;
27310     sp_point_256* point = NULL;
27311 #else
27312     sp_digit e[7 * 2 * 5];
27313     sp_point_256 point[1];
27314 #endif
27315     sp_digit* x = NULL;
27316     sp_digit* k = NULL;
27317     sp_digit* r = NULL;
27318     sp_digit* tmp = NULL;
27319     sp_digit* s = NULL;
27320     sp_int64 c;
27321     int err = MP_OKAY;
27322     int i;
27323 
27324     (void)heap;
27325 
27326 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
27327     if (err == MP_OKAY) {
27328         point = (sp_point_256*)XMALLOC(sizeof(sp_point_256), heap,
27329                                              DYNAMIC_TYPE_ECC);
27330         if (point == NULL)
27331             err = MEMORY_E;
27332     }
27333     if (err == MP_OKAY) {
27334         e = (sp_digit*)XMALLOC(sizeof(sp_digit) * 7 * 2 * 5, heap,
27335                                DYNAMIC_TYPE_ECC);
27336         if (e == NULL)
27337             err = MEMORY_E;
27338     }
27339 #endif
27340 
27341     if (err == MP_OKAY) {
27342         x = e + 2 * 5;
27343         k = e + 4 * 5;
27344         r = e + 6 * 5;
27345         tmp = e + 8 * 5;
27346         s = e;
27347 
27348         if (hashLen > 32U) {
27349             hashLen = 32U;
27350         }
27351     }
27352 
27353     for (i = SP_ECC_MAX_SIG_GEN; err == MP_OKAY && i > 0; i--) {
27354         /* New random point. */
27355         if (km == NULL || mp_iszero(km)) {
27356             err = sp_256_ecc_gen_k_5(rng, k);
27357         }
27358         else {
27359             sp_256_from_mp(k, 5, km);
27360             mp_zero(km);
27361         }
27362         if (err == MP_OKAY) {
27363                 err = sp_256_ecc_mulmod_base_5(point, k, 1, 1, heap);
27364         }
27365 
27366         if (err == MP_OKAY) {
27367             /* r = point->x mod order */
27368             XMEMCPY(r, point->x, sizeof(sp_digit) * 5U);
27369             sp_256_norm_5(r);
27370             c = sp_256_cmp_5(r, p256_order);
27371             sp_256_cond_sub_5(r, r, p256_order,
27372                 (sp_digit)0 - (sp_digit)(c >= 0));
27373             sp_256_norm_5(r);
27374 
27375             sp_256_from_mp(x, 5, priv);
27376             sp_256_from_bin(e, 5, hash, (int)hashLen);
27377 
27378             err = sp_256_calc_s_5(s, r, k, x, e, tmp);
27379         }
27380 
27381         /* Check that signature is usable. */
27382         if ((err == MP_OKAY) && (sp_256_iszero_5(s) == 0)) {
27383             break;
27384         }
27385 #ifdef WOLFSSL_ECDSA_SET_K_ONE_LOOP
27386         i = 1;
27387 #endif
27388     }
27389 
27390     if (i == 0) {
27391         err = RNG_FAILURE_E;
27392     }
27393 
27394     if (err == MP_OKAY) {
27395         err = sp_256_to_mp(r, rm);
27396     }
27397     if (err == MP_OKAY) {
27398         err = sp_256_to_mp(s, sm);
27399     }
27400 
27401 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
27402     if (e != NULL)
27403 #endif
27404     {
27405         ForceZero(e, sizeof(sp_digit) * 7 * 2 * 5);
27406     #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
27407         XFREE(e, heap, DYNAMIC_TYPE_ECC);
27408     #endif
27409     }
27410 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
27411     if (point != NULL)
27412 #endif
27413     {
27414         ForceZero(point, sizeof(sp_point_256));
27415     #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
27416         XFREE(point, heap, DYNAMIC_TYPE_ECC);
27417     #endif
27418     }
27419 
27420     return err;
27421 }
27422 #endif /* HAVE_ECC_SIGN */
27423 
27424 #ifndef WOLFSSL_SP_SMALL
27425 static const char sp_256_tab64_5[64] = {
27426     64,  1, 59,  2, 60, 48, 54,  3,
27427     61, 40, 49, 28, 55, 34, 43,  4,
27428     62, 52, 38, 41, 50, 19, 29, 21,
27429     56, 31, 35, 12, 44, 15, 23,  5,
27430     63, 58, 47, 53, 39, 27, 33, 42,
27431     51, 37, 18, 20, 30, 11, 14, 22,
27432     57, 46, 26, 32, 36, 17, 10, 13,
27433     45, 25, 16,  9, 24,  8,  7,  6};
27434 
sp_256_num_bits_52_5(sp_digit v)27435 static int sp_256_num_bits_52_5(sp_digit v)
27436 {
27437     v |= v >> 1;
27438     v |= v >> 2;
27439     v |= v >> 4;
27440     v |= v >> 8;
27441     v |= v >> 16;
27442     v |= v >> 32;
27443     return sp_256_tab64_5[((uint64_t)((v - (v >> 1))*0x07EDD5E59A4E28C2)) >> 58];
27444 }
27445 
sp_256_num_bits_5(const sp_digit * a)27446 static int sp_256_num_bits_5(const sp_digit* a)
27447 {
27448     int i;
27449     int r = 0;
27450 
27451     for (i = 4; i >= 0; i--) {
27452         if (a[i] != 0) {
27453             r = sp_256_num_bits_52_5(a[i]);
27454             r += i * 52;
27455             break;
27456         }
27457     }
27458 
27459     return r;
27460 }
27461 
27462 /* Non-constant time modular inversion.
27463  *
27464  * @param  [out]  r   Resulting number.
27465  * @param  [in]   a   Number to invert.
27466  * @param  [in]   m   Modulus.
27467  * @return  MP_OKAY on success.
27468  * @return  MEMEORY_E when dynamic memory allocation fails.
27469  */
sp_256_mod_inv_5(sp_digit * r,const sp_digit * a,const sp_digit * m)27470 static int sp_256_mod_inv_5(sp_digit* r, const sp_digit* a, const sp_digit* m)
27471 {
27472     int err = MP_OKAY;
27473 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
27474     sp_digit* u = NULL;
27475 #else
27476     sp_digit u[5 * 4];
27477 #endif
27478     sp_digit* v = NULL;
27479     sp_digit* b = NULL;
27480     sp_digit* d = NULL;
27481     int ut;
27482     int vt;
27483 
27484 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
27485     u = (sp_digit*)XMALLOC(sizeof(sp_digit) * 5 * 4, NULL,
27486                                                               DYNAMIC_TYPE_ECC);
27487     if (u == NULL)
27488         err = MEMORY_E;
27489 #endif
27490 
27491     if (err == MP_OKAY) {
27492         v = u + 5;
27493         b = u + 2 * 5;
27494         d = u + 3 * 5;
27495 
27496         XMEMCPY(u, m, sizeof(sp_digit) * 5);
27497         XMEMCPY(v, a, sizeof(sp_digit) * 5);
27498 
27499         ut = sp_256_num_bits_5(u);
27500         vt = sp_256_num_bits_5(v);
27501 
27502         XMEMSET(b, 0, sizeof(sp_digit) * 5);
27503         if ((v[0] & 1) == 0) {
27504             sp_256_rshift1_5(v, v);
27505             XMEMCPY(d, m, sizeof(sp_digit) * 5);
27506             d[0]++;
27507             sp_256_rshift1_5(d, d);
27508             vt--;
27509 
27510             while ((v[0] & 1) == 0) {
27511                 sp_256_rshift1_5(v, v);
27512                 if (d[0] & 1)
27513                     sp_256_add_5(d, d, m);
27514                 sp_256_rshift1_5(d, d);
27515                 vt--;
27516             }
27517         }
27518         else {
27519             XMEMSET(d+1, 0, sizeof(sp_digit) * (5 - 1));
27520             d[0] = 1;
27521         }
27522 
27523         while (ut > 1 && vt > 1) {
27524             if (ut > vt || (ut == vt &&
27525                                        sp_256_cmp_5(u, v) >= 0)) {
27526                 sp_256_sub_5(u, u, v);
27527                 sp_256_norm_5(u);
27528 
27529                 sp_256_sub_5(b, b, d);
27530                 sp_256_norm_5(b);
27531                 if (b[4] < 0)
27532                     sp_256_add_5(b, b, m);
27533                 sp_256_norm_5(b);
27534                 ut = sp_256_num_bits_5(u);
27535 
27536                 do {
27537                     sp_256_rshift1_5(u, u);
27538                     if (b[0] & 1)
27539                         sp_256_add_5(b, b, m);
27540                     sp_256_rshift1_5(b, b);
27541                     ut--;
27542                 }
27543                 while (ut > 0 && (u[0] & 1) == 0);
27544             }
27545             else {
27546                 sp_256_sub_5(v, v, u);
27547                 sp_256_norm_5(v);
27548 
27549                 sp_256_sub_5(d, d, b);
27550                 sp_256_norm_5(d);
27551                 if (d[4] < 0)
27552                     sp_256_add_5(d, d, m);
27553                 sp_256_norm_5(d);
27554                 vt = sp_256_num_bits_5(v);
27555 
27556                 do {
27557                     sp_256_rshift1_5(v, v);
27558                     if (d[0] & 1)
27559                         sp_256_add_5(d, d, m);
27560                     sp_256_rshift1_5(d, d);
27561                     vt--;
27562                 }
27563                 while (vt > 0 && (v[0] & 1) == 0);
27564             }
27565         }
27566 
27567         if (ut == 1)
27568             XMEMCPY(r, b, sizeof(sp_digit) * 5);
27569         else
27570             XMEMCPY(r, d, sizeof(sp_digit) * 5);
27571     }
27572 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
27573     if (u != NULL)
27574         XFREE(u, NULL, DYNAMIC_TYPE_ECC);
27575 #endif
27576 
27577     return err;
27578 }
27579 
27580 #endif /* WOLFSSL_SP_SMALL */
27581 
27582 /* Add point p1 into point p2. Handles p1 == p2 and result at infinity.
27583  *
27584  * p1   First point to add and holds result.
27585  * p2   Second point to add.
27586  * tmp  Temporary storage for intermediate numbers.
27587  */
sp_256_add_points_5(sp_point_256 * p1,const sp_point_256 * p2,sp_digit * tmp)27588 static void sp_256_add_points_5(sp_point_256* p1, const sp_point_256* p2,
27589     sp_digit* tmp)
27590 {
27591 
27592         sp_256_proj_point_add_5(p1, p1, p2, tmp);
27593     if (sp_256_iszero_5(p1->z)) {
27594         if (sp_256_iszero_5(p1->x) && sp_256_iszero_5(p1->y)) {
27595                 sp_256_proj_point_dbl_5(p1, p2, tmp);
27596         }
27597         else {
27598             /* Y ordinate is not used from here - don't set. */
27599             p1->x[0] = 0;
27600             p1->x[1] = 0;
27601             p1->x[2] = 0;
27602             p1->x[3] = 0;
27603             p1->x[4] = 0;
27604             XMEMCPY(p1->z, p256_norm_mod, sizeof(p256_norm_mod));
27605         }
27606     }
27607 }
27608 
27609 /* Calculate the verification point: [e/s]G + [r/s]Q
27610  *
27611  * p1    Calculated point.
27612  * p2    Public point and temporary.
27613  * s     Second part of signature as a number.
27614  * u1    Temporary number.
27615  * u2    Temproray number.
27616  * heap  Heap to use for allocation.
27617  * returns MEMORY_E when memory allocation fails and MP_OKAY on success.
27618  */
sp_256_calc_vfy_point_5(sp_point_256 * p1,sp_point_256 * p2,sp_digit * s,sp_digit * u1,sp_digit * u2,sp_digit * tmp,void * heap)27619 static int sp_256_calc_vfy_point_5(sp_point_256* p1, sp_point_256* p2,
27620     sp_digit* s, sp_digit* u1, sp_digit* u2, sp_digit* tmp, void* heap)
27621 {
27622     int err;
27623 
27624 #ifndef WOLFSSL_SP_SMALL
27625     err = sp_256_mod_inv_5(s, s, p256_order);
27626     if (err == MP_OKAY)
27627 #endif /* !WOLFSSL_SP_SMALL */
27628     {
27629         sp_256_mul_5(s, s, p256_norm_order);
27630         err = sp_256_mod_5(s, s, p256_order);
27631     }
27632     if (err == MP_OKAY) {
27633         sp_256_norm_5(s);
27634 #ifdef WOLFSSL_SP_SMALL
27635         {
27636             sp_256_mont_inv_order_5(s, s, tmp);
27637             sp_256_mont_mul_order_5(u1, u1, s);
27638             sp_256_mont_mul_order_5(u2, u2, s);
27639         }
27640 #else
27641         {
27642             sp_256_mont_mul_order_5(u1, u1, s);
27643             sp_256_mont_mul_order_5(u2, u2, s);
27644         }
27645 #endif /* WOLFSSL_SP_SMALL */
27646         {
27647             err = sp_256_ecc_mulmod_base_5(p1, u1, 0, 0, heap);
27648         }
27649     }
27650     if ((err == MP_OKAY) && sp_256_iszero_5(p1->z)) {
27651         p1->infinity = 1;
27652     }
27653     if (err == MP_OKAY) {
27654             err = sp_256_ecc_mulmod_5(p2, p2, u2, 0, 0, heap);
27655     }
27656     if ((err == MP_OKAY) && sp_256_iszero_5(p2->z)) {
27657         p2->infinity = 1;
27658     }
27659 
27660     if (err == MP_OKAY) {
27661         sp_256_add_points_5(p1, p2, tmp);
27662     }
27663 
27664     return err;
27665 }
27666 
27667 #ifdef HAVE_ECC_VERIFY
27668 /* Verify the signature values with the hash and public key.
27669  *   e = Truncate(hash, 256)
27670  *   u1 = e/s mod order
27671  *   u2 = r/s mod order
27672  *   r == (u1.G + u2.Q)->x mod order
27673  * Optimization: Leave point in projective form.
27674  *   (x, y, 1) == (x' / z'*z', y' / z'*z'*z', z' / z')
27675  *   (r + n*order).z'.z' mod prime == (u1.G + u2.Q)->x'
27676  * The hash is truncated to the first 256 bits.
27677  *
27678  * hash     Hash to sign.
27679  * hashLen  Length of the hash data.
27680  * rng      Random number generator.
27681  * priv     Private part of key - scalar.
27682  * rm       First part of result as an mp_int.
27683  * sm       Sirst part of result as an mp_int.
27684  * heap     Heap to use for allocation.
27685  * returns MEMORY_E when memory allocation fails and MP_OKAY on success.
27686  */
27687 #ifdef WOLFSSL_SP_NONBLOCK
27688 typedef struct sp_ecc_verify_256_ctx {
27689     int state;
27690     union {
27691         sp_256_ecc_mulmod_5_ctx mulmod_ctx;
27692         sp_256_mont_inv_order_5_ctx mont_inv_order_ctx;
27693         sp_256_proj_point_dbl_5_ctx dbl_ctx;
27694         sp_256_proj_point_add_5_ctx add_ctx;
27695     };
27696     sp_digit u1[2*5];
27697     sp_digit u2[2*5];
27698     sp_digit s[2*5];
27699     sp_digit tmp[2*5 * 5];
27700     sp_point_256 p1;
27701     sp_point_256 p2;
27702 } sp_ecc_verify_256_ctx;
27703 
sp_ecc_verify_256_nb(sp_ecc_ctx_t * sp_ctx,const byte * hash,word32 hashLen,const mp_int * pX,const mp_int * pY,const mp_int * pZ,const mp_int * rm,const mp_int * sm,int * res,void * heap)27704 int sp_ecc_verify_256_nb(sp_ecc_ctx_t* sp_ctx, const byte* hash,
27705     word32 hashLen, const mp_int* pX, const mp_int* pY, const mp_int* pZ,
27706     const mp_int* rm, const mp_int* sm, int* res, void* heap)
27707 {
27708     int err = FP_WOULDBLOCK;
27709     sp_ecc_verify_256_ctx* ctx = (sp_ecc_verify_256_ctx*)sp_ctx->data;
27710 
27711     typedef char ctx_size_test[sizeof(sp_ecc_verify_256_ctx) >= sizeof(*sp_ctx) ? -1 : 1];
27712     (void)sizeof(ctx_size_test);
27713 
27714     switch (ctx->state) {
27715     case 0: /* INIT */
27716         if (hashLen > 32U) {
27717             hashLen = 32U;
27718         }
27719 
27720         sp_256_from_bin(ctx->u1, 5, hash, (int)hashLen);
27721         sp_256_from_mp(ctx->u2, 5, rm);
27722         sp_256_from_mp(ctx->s, 5, sm);
27723         sp_256_from_mp(ctx->p2.x, 5, pX);
27724         sp_256_from_mp(ctx->p2.y, 5, pY);
27725         sp_256_from_mp(ctx->p2.z, 5, pZ);
27726         ctx->state = 1;
27727         break;
27728     case 1: /* NORMS0 */
27729         sp_256_mul_5(ctx->s, ctx->s, p256_norm_order);
27730         err = sp_256_mod_5(ctx->s, ctx->s, p256_order);
27731         if (err == MP_OKAY)
27732             ctx->state = 2;
27733         break;
27734     case 2: /* NORMS1 */
27735         sp_256_norm_5(ctx->s);
27736         XMEMSET(&ctx->mont_inv_order_ctx, 0, sizeof(ctx->mont_inv_order_ctx));
27737         ctx->state = 3;
27738         break;
27739     case 3: /* NORMS2 */
27740         err = sp_256_mont_inv_order_5_nb((sp_ecc_ctx_t*)&ctx->mont_inv_order_ctx, ctx->s, ctx->s, ctx->tmp);
27741         if (err == MP_OKAY) {
27742             ctx->state = 4;
27743         }
27744         break;
27745     case 4: /* NORMS3 */
27746         sp_256_mont_mul_order_5(ctx->u1, ctx->u1, ctx->s);
27747         ctx->state = 5;
27748         break;
27749     case 5: /* NORMS4 */
27750         sp_256_mont_mul_order_5(ctx->u2, ctx->u2, ctx->s);
27751         XMEMSET(&ctx->mulmod_ctx, 0, sizeof(ctx->mulmod_ctx));
27752         ctx->state = 6;
27753         break;
27754     case 6: /* MULBASE */
27755         err = sp_256_ecc_mulmod_5_nb((sp_ecc_ctx_t*)&ctx->mulmod_ctx, &ctx->p1, &p256_base, ctx->u1, 0, 0, heap);
27756         if (err == MP_OKAY) {
27757             if (sp_256_iszero_5(ctx->p1.z)) {
27758                 ctx->p1.infinity = 1;
27759             }
27760             XMEMSET(&ctx->mulmod_ctx, 0, sizeof(ctx->mulmod_ctx));
27761             ctx->state = 7;
27762         }
27763         break;
27764     case 7: /* MULMOD */
27765         err = sp_256_ecc_mulmod_5_nb((sp_ecc_ctx_t*)&ctx->mulmod_ctx, &ctx->p2, &ctx->p2, ctx->u2, 0, 0, heap);
27766         if (err == MP_OKAY) {
27767             if (sp_256_iszero_5(ctx->p2.z)) {
27768                 ctx->p2.infinity = 1;
27769             }
27770             XMEMSET(&ctx->add_ctx, 0, sizeof(ctx->add_ctx));
27771             ctx->state = 8;
27772         }
27773         break;
27774     case 8: /* ADD */
27775         err = sp_256_proj_point_add_5_nb((sp_ecc_ctx_t*)&ctx->add_ctx, &ctx->p1, &ctx->p1, &ctx->p2, ctx->tmp);
27776         if (err == MP_OKAY)
27777             ctx->state = 9;
27778         break;
27779     case 9: /* MONT */
27780         /* (r + n*order).z'.z' mod prime == (u1.G + u2.Q)->x' */
27781         /* Reload r and convert to Montgomery form. */
27782         sp_256_from_mp(ctx->u2, 5, rm);
27783         err = sp_256_mod_mul_norm_5(ctx->u2, ctx->u2, p256_mod);
27784         if (err == MP_OKAY)
27785             ctx->state = 10;
27786         break;
27787     case 10: /* SQR */
27788         /* u1 = r.z'.z' mod prime */
27789         sp_256_mont_sqr_5(ctx->p1.z, ctx->p1.z, p256_mod, p256_mp_mod);
27790         ctx->state = 11;
27791         break;
27792     case 11: /* MUL */
27793         sp_256_mont_mul_5(ctx->u1, ctx->u2, ctx->p1.z, p256_mod, p256_mp_mod);
27794         ctx->state = 12;
27795         break;
27796     case 12: /* RES */
27797     {
27798         sp_int64 c = 0;
27799         err = MP_OKAY; /* math okay, now check result */
27800         *res = (int)(sp_256_cmp_5(ctx->p1.x, ctx->u1) == 0);
27801         if (*res == 0) {
27802             sp_digit carry;
27803 
27804             /* Reload r and add order. */
27805             sp_256_from_mp(ctx->u2, 5, rm);
27806             carry = sp_256_add_5(ctx->u2, ctx->u2, p256_order);
27807             /* Carry means result is greater than mod and is not valid. */
27808             if (carry == 0) {
27809                 sp_256_norm_5(ctx->u2);
27810 
27811                 /* Compare with mod and if greater or equal then not valid. */
27812                 c = sp_256_cmp_5(ctx->u2, p256_mod);
27813             }
27814         }
27815         if ((*res == 0) && (c < 0)) {
27816             /* Convert to Montogomery form */
27817             err = sp_256_mod_mul_norm_5(ctx->u2, ctx->u2, p256_mod);
27818             if (err == MP_OKAY) {
27819                 /* u1 = (r + 1*order).z'.z' mod prime */
27820                 sp_256_mont_mul_5(ctx->u1, ctx->u2, ctx->p1.z, p256_mod,
27821                                                             p256_mp_mod);
27822                 *res = (int)(sp_256_cmp_5(ctx->p1.x, ctx->u1) == 0);
27823             }
27824         }
27825         break;
27826     }
27827     } /* switch */
27828 
27829     if (err == MP_OKAY && ctx->state != 12) {
27830         err = FP_WOULDBLOCK;
27831     }
27832 
27833     return err;
27834 }
27835 #endif /* WOLFSSL_SP_NONBLOCK */
27836 
sp_ecc_verify_256(const byte * hash,word32 hashLen,const mp_int * pX,const mp_int * pY,const mp_int * pZ,const mp_int * rm,const mp_int * sm,int * res,void * heap)27837 int sp_ecc_verify_256(const byte* hash, word32 hashLen, const mp_int* pX,
27838     const mp_int* pY, const mp_int* pZ, const mp_int* rm, const mp_int* sm,
27839     int* res, void* heap)
27840 {
27841 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
27842     sp_digit* u1 = NULL;
27843     sp_point_256* p1 = NULL;
27844 #else
27845     sp_digit  u1[16 * 5];
27846     sp_point_256 p1[2];
27847 #endif
27848     sp_digit* u2 = NULL;
27849     sp_digit* s = NULL;
27850     sp_digit* tmp = NULL;
27851     sp_point_256* p2 = NULL;
27852     sp_digit carry;
27853     sp_int64 c = 0;
27854     int err = MP_OKAY;
27855 
27856 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
27857     if (err == MP_OKAY) {
27858         p1 = (sp_point_256*)XMALLOC(sizeof(sp_point_256) * 2, heap,
27859                                              DYNAMIC_TYPE_ECC);
27860         if (p1 == NULL)
27861             err = MEMORY_E;
27862     }
27863     if (err == MP_OKAY) {
27864         u1 = (sp_digit*)XMALLOC(sizeof(sp_digit) * 16 * 5, heap,
27865                                                               DYNAMIC_TYPE_ECC);
27866         if (u1 == NULL)
27867             err = MEMORY_E;
27868     }
27869 #endif
27870 
27871     if (err == MP_OKAY) {
27872         u2  = u1 + 2 * 5;
27873         s   = u1 + 4 * 5;
27874         tmp = u1 + 6 * 5;
27875         p2 = p1 + 1;
27876 
27877         if (hashLen > 32U) {
27878             hashLen = 32U;
27879         }
27880 
27881         sp_256_from_bin(u1, 5, hash, (int)hashLen);
27882         sp_256_from_mp(u2, 5, rm);
27883         sp_256_from_mp(s, 5, sm);
27884         sp_256_from_mp(p2->x, 5, pX);
27885         sp_256_from_mp(p2->y, 5, pY);
27886         sp_256_from_mp(p2->z, 5, pZ);
27887 
27888         err = sp_256_calc_vfy_point_5(p1, p2, s, u1, u2, tmp, heap);
27889     }
27890     if (err == MP_OKAY) {
27891         /* (r + n*order).z'.z' mod prime == (u1.G + u2.Q)->x' */
27892         /* Reload r and convert to Montgomery form. */
27893         sp_256_from_mp(u2, 5, rm);
27894         err = sp_256_mod_mul_norm_5(u2, u2, p256_mod);
27895     }
27896 
27897     if (err == MP_OKAY) {
27898         /* u1 = r.z'.z' mod prime */
27899         sp_256_mont_sqr_5(p1->z, p1->z, p256_mod, p256_mp_mod);
27900         sp_256_mont_mul_5(u1, u2, p1->z, p256_mod, p256_mp_mod);
27901         *res = (int)(sp_256_cmp_5(p1->x, u1) == 0);
27902         if (*res == 0) {
27903             /* Reload r and add order. */
27904             sp_256_from_mp(u2, 5, rm);
27905             carry = sp_256_add_5(u2, u2, p256_order);
27906             /* Carry means result is greater than mod and is not valid. */
27907             if (carry == 0) {
27908                 sp_256_norm_5(u2);
27909 
27910                 /* Compare with mod and if greater or equal then not valid. */
27911                 c = sp_256_cmp_5(u2, p256_mod);
27912             }
27913         }
27914         if ((*res == 0) && (c < 0)) {
27915             /* Convert to Montogomery form */
27916             err = sp_256_mod_mul_norm_5(u2, u2, p256_mod);
27917             if (err == MP_OKAY) {
27918                 /* u1 = (r + 1*order).z'.z' mod prime */
27919                 sp_256_mont_mul_5(u1, u2, p1->z, p256_mod,
27920                     p256_mp_mod);
27921                 *res = (sp_256_cmp_5(p1->x, u1) == 0);
27922             }
27923         }
27924     }
27925 
27926 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
27927     if (u1 != NULL)
27928         XFREE(u1, heap, DYNAMIC_TYPE_ECC);
27929     if (p1 != NULL)
27930         XFREE(p1, heap, DYNAMIC_TYPE_ECC);
27931 #endif
27932 
27933     return err;
27934 }
27935 #endif /* HAVE_ECC_VERIFY */
27936 
27937 #ifdef HAVE_ECC_CHECK_KEY
27938 /* Check that the x and y oridinates are a valid point on the curve.
27939  *
27940  * point  EC point.
27941  * heap   Heap to use if dynamically allocating.
27942  * returns MEMORY_E if dynamic memory allocation fails, MP_VAL if the point is
27943  * not on the curve and MP_OKAY otherwise.
27944  */
sp_256_ecc_is_point_5(const sp_point_256 * point,void * heap)27945 static int sp_256_ecc_is_point_5(const sp_point_256* point,
27946     void* heap)
27947 {
27948 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
27949     sp_digit* t1 = NULL;
27950 #else
27951     sp_digit t1[5 * 4];
27952 #endif
27953     sp_digit* t2 = NULL;
27954     int err = MP_OKAY;
27955 
27956 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
27957     t1 = (sp_digit*)XMALLOC(sizeof(sp_digit) * 5 * 4, heap, DYNAMIC_TYPE_ECC);
27958     if (t1 == NULL)
27959         err = MEMORY_E;
27960 #endif
27961     (void)heap;
27962 
27963     if (err == MP_OKAY) {
27964         t2 = t1 + 2 * 5;
27965 
27966         sp_256_sqr_5(t1, point->y);
27967         (void)sp_256_mod_5(t1, t1, p256_mod);
27968         sp_256_sqr_5(t2, point->x);
27969         (void)sp_256_mod_5(t2, t2, p256_mod);
27970         sp_256_mul_5(t2, t2, point->x);
27971         (void)sp_256_mod_5(t2, t2, p256_mod);
27972         (void)sp_256_sub_5(t2, p256_mod, t2);
27973         sp_256_mont_add_5(t1, t1, t2, p256_mod);
27974 
27975         sp_256_mont_add_5(t1, t1, point->x, p256_mod);
27976         sp_256_mont_add_5(t1, t1, point->x, p256_mod);
27977         sp_256_mont_add_5(t1, t1, point->x, p256_mod);
27978 
27979         if (sp_256_cmp_5(t1, p256_b) != 0) {
27980             err = MP_VAL;
27981         }
27982     }
27983 
27984 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
27985     if (t1 != NULL)
27986         XFREE(t1, heap, DYNAMIC_TYPE_ECC);
27987 #endif
27988 
27989     return err;
27990 }
27991 
27992 /* Check that the x and y oridinates are a valid point on the curve.
27993  *
27994  * pX  X ordinate of EC point.
27995  * pY  Y ordinate of EC point.
27996  * returns MEMORY_E if dynamic memory allocation fails, MP_VAL if the point is
27997  * not on the curve and MP_OKAY otherwise.
27998  */
sp_ecc_is_point_256(const mp_int * pX,const mp_int * pY)27999 int sp_ecc_is_point_256(const mp_int* pX, const mp_int* pY)
28000 {
28001 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
28002     sp_point_256* pub = NULL;
28003 #else
28004     sp_point_256 pub[1];
28005 #endif
28006     const byte one[1] = { 1 };
28007     int err = MP_OKAY;
28008 
28009 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
28010     pub = (sp_point_256*)XMALLOC(sizeof(sp_point_256), NULL,
28011                                        DYNAMIC_TYPE_ECC);
28012     if (pub == NULL)
28013         err = MEMORY_E;
28014 #endif
28015 
28016     if (err == MP_OKAY) {
28017         sp_256_from_mp(pub->x, 5, pX);
28018         sp_256_from_mp(pub->y, 5, pY);
28019         sp_256_from_bin(pub->z, 5, one, (int)sizeof(one));
28020 
28021         err = sp_256_ecc_is_point_5(pub, NULL);
28022     }
28023 
28024 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
28025     if (pub != NULL)
28026         XFREE(pub, NULL, DYNAMIC_TYPE_ECC);
28027 #endif
28028 
28029     return err;
28030 }
28031 
28032 /* Check that the private scalar generates the EC point (px, py), the point is
28033  * on the curve and the point has the correct order.
28034  *
28035  * pX     X ordinate of EC point.
28036  * pY     Y ordinate of EC point.
28037  * privm  Private scalar that generates EC point.
28038  * returns MEMORY_E if dynamic memory allocation fails, MP_VAL if the point is
28039  * not on the curve, ECC_INF_E if the point does not have the correct order,
28040  * ECC_PRIV_KEY_E when the private scalar doesn't generate the EC point and
28041  * MP_OKAY otherwise.
28042  */
sp_ecc_check_key_256(const mp_int * pX,const mp_int * pY,const mp_int * privm,void * heap)28043 int sp_ecc_check_key_256(const mp_int* pX, const mp_int* pY,
28044     const mp_int* privm, void* heap)
28045 {
28046 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
28047     sp_digit* priv = NULL;
28048     sp_point_256* pub = NULL;
28049 #else
28050     sp_digit priv[5];
28051     sp_point_256 pub[2];
28052 #endif
28053     sp_point_256* p = NULL;
28054     const byte one[1] = { 1 };
28055     int err = MP_OKAY;
28056 
28057 
28058     /* Quick check the lengs of public key ordinates and private key are in
28059      * range. Proper check later.
28060      */
28061     if (((mp_count_bits(pX) > 256) ||
28062         (mp_count_bits(pY) > 256) ||
28063         ((privm != NULL) && (mp_count_bits(privm) > 256)))) {
28064         err = ECC_OUT_OF_RANGE_E;
28065     }
28066 
28067 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
28068     if (err == MP_OKAY) {
28069         pub = (sp_point_256*)XMALLOC(sizeof(sp_point_256) * 2, heap,
28070                                            DYNAMIC_TYPE_ECC);
28071         if (pub == NULL)
28072             err = MEMORY_E;
28073     }
28074     if (err == MP_OKAY && privm) {
28075         priv = (sp_digit*)XMALLOC(sizeof(sp_digit) * 5, heap,
28076                                   DYNAMIC_TYPE_ECC);
28077         if (priv == NULL)
28078             err = MEMORY_E;
28079     }
28080 #endif
28081 
28082     if (err == MP_OKAY) {
28083         p = pub + 1;
28084 
28085         sp_256_from_mp(pub->x, 5, pX);
28086         sp_256_from_mp(pub->y, 5, pY);
28087         sp_256_from_bin(pub->z, 5, one, (int)sizeof(one));
28088         if (privm)
28089             sp_256_from_mp(priv, 5, privm);
28090 
28091         /* Check point at infinitiy. */
28092         if ((sp_256_iszero_5(pub->x) != 0) &&
28093             (sp_256_iszero_5(pub->y) != 0)) {
28094             err = ECC_INF_E;
28095         }
28096     }
28097 
28098     /* Check range of X and Y */
28099     if ((err == MP_OKAY) &&
28100             ((sp_256_cmp_5(pub->x, p256_mod) >= 0) ||
28101              (sp_256_cmp_5(pub->y, p256_mod) >= 0))) {
28102         err = ECC_OUT_OF_RANGE_E;
28103     }
28104 
28105     if (err == MP_OKAY) {
28106         /* Check point is on curve */
28107         err = sp_256_ecc_is_point_5(pub, heap);
28108     }
28109 
28110     if (err == MP_OKAY) {
28111         /* Point * order = infinity */
28112             err = sp_256_ecc_mulmod_5(p, pub, p256_order, 1, 1, heap);
28113     }
28114     /* Check result is infinity */
28115     if ((err == MP_OKAY) && ((sp_256_iszero_5(p->x) == 0) ||
28116                              (sp_256_iszero_5(p->y) == 0))) {
28117         err = ECC_INF_E;
28118     }
28119 
28120     if (privm) {
28121         if (err == MP_OKAY) {
28122             /* Base * private = point */
28123                 err = sp_256_ecc_mulmod_base_5(p, priv, 1, 1, heap);
28124         }
28125         /* Check result is public key */
28126         if ((err == MP_OKAY) &&
28127                 ((sp_256_cmp_5(p->x, pub->x) != 0) ||
28128                  (sp_256_cmp_5(p->y, pub->y) != 0))) {
28129             err = ECC_PRIV_KEY_E;
28130         }
28131     }
28132 
28133 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
28134     if (pub != NULL)
28135         XFREE(pub, heap, DYNAMIC_TYPE_ECC);
28136     if (priv != NULL)
28137         XFREE(priv, heap, DYNAMIC_TYPE_ECC);
28138 #endif
28139 
28140     return err;
28141 }
28142 #endif
28143 #ifdef WOLFSSL_PUBLIC_ECC_ADD_DBL
28144 /* Add two projective EC points together.
28145  * (pX, pY, pZ) + (qX, qY, qZ) = (rX, rY, rZ)
28146  *
28147  * pX   First EC point's X ordinate.
28148  * pY   First EC point's Y ordinate.
28149  * pZ   First EC point's Z ordinate.
28150  * qX   Second EC point's X ordinate.
28151  * qY   Second EC point's Y ordinate.
28152  * qZ   Second EC point's Z ordinate.
28153  * rX   Resultant EC point's X ordinate.
28154  * rY   Resultant EC point's Y ordinate.
28155  * rZ   Resultant EC point's Z ordinate.
28156  * returns MEMORY_E if dynamic memory allocation fails and MP_OKAY otherwise.
28157  */
sp_ecc_proj_add_point_256(mp_int * pX,mp_int * pY,mp_int * pZ,mp_int * qX,mp_int * qY,mp_int * qZ,mp_int * rX,mp_int * rY,mp_int * rZ)28158 int sp_ecc_proj_add_point_256(mp_int* pX, mp_int* pY, mp_int* pZ,
28159                               mp_int* qX, mp_int* qY, mp_int* qZ,
28160                               mp_int* rX, mp_int* rY, mp_int* rZ)
28161 {
28162 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
28163     sp_digit* tmp = NULL;
28164     sp_point_256* p = NULL;
28165 #else
28166     sp_digit tmp[2 * 5 * 5];
28167     sp_point_256 p[2];
28168 #endif
28169     sp_point_256* q = NULL;
28170     int err = MP_OKAY;
28171 
28172 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
28173     if (err == MP_OKAY) {
28174         p = (sp_point_256*)XMALLOC(sizeof(sp_point_256) * 2, NULL,
28175                                          DYNAMIC_TYPE_ECC);
28176         if (p == NULL)
28177             err = MEMORY_E;
28178     }
28179     if (err == MP_OKAY) {
28180         tmp = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 5 * 5, NULL,
28181                                  DYNAMIC_TYPE_ECC);
28182         if (tmp == NULL) {
28183             err = MEMORY_E;
28184         }
28185     }
28186 #endif
28187 
28188     if (err == MP_OKAY) {
28189         q = p + 1;
28190 
28191         sp_256_from_mp(p->x, 5, pX);
28192         sp_256_from_mp(p->y, 5, pY);
28193         sp_256_from_mp(p->z, 5, pZ);
28194         sp_256_from_mp(q->x, 5, qX);
28195         sp_256_from_mp(q->y, 5, qY);
28196         sp_256_from_mp(q->z, 5, qZ);
28197         p->infinity = sp_256_iszero_5(p->x) &
28198                       sp_256_iszero_5(p->y);
28199         q->infinity = sp_256_iszero_5(q->x) &
28200                       sp_256_iszero_5(q->y);
28201 
28202             sp_256_proj_point_add_5(p, p, q, tmp);
28203     }
28204 
28205     if (err == MP_OKAY) {
28206         err = sp_256_to_mp(p->x, rX);
28207     }
28208     if (err == MP_OKAY) {
28209         err = sp_256_to_mp(p->y, rY);
28210     }
28211     if (err == MP_OKAY) {
28212         err = sp_256_to_mp(p->z, rZ);
28213     }
28214 
28215 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
28216     if (tmp != NULL)
28217         XFREE(tmp, NULL, DYNAMIC_TYPE_ECC);
28218     if (p != NULL)
28219         XFREE(p, NULL, DYNAMIC_TYPE_ECC);
28220 #endif
28221 
28222     return err;
28223 }
28224 
28225 /* Double a projective EC point.
28226  * (pX, pY, pZ) + (pX, pY, pZ) = (rX, rY, rZ)
28227  *
28228  * pX   EC point's X ordinate.
28229  * pY   EC point's Y ordinate.
28230  * pZ   EC point's Z ordinate.
28231  * rX   Resultant EC point's X ordinate.
28232  * rY   Resultant EC point's Y ordinate.
28233  * rZ   Resultant EC point's Z ordinate.
28234  * returns MEMORY_E if dynamic memory allocation fails and MP_OKAY otherwise.
28235  */
sp_ecc_proj_dbl_point_256(mp_int * pX,mp_int * pY,mp_int * pZ,mp_int * rX,mp_int * rY,mp_int * rZ)28236 int sp_ecc_proj_dbl_point_256(mp_int* pX, mp_int* pY, mp_int* pZ,
28237                               mp_int* rX, mp_int* rY, mp_int* rZ)
28238 {
28239 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
28240     sp_digit* tmp = NULL;
28241     sp_point_256* p = NULL;
28242 #else
28243     sp_digit tmp[2 * 5 * 2];
28244     sp_point_256 p[1];
28245 #endif
28246     int err = MP_OKAY;
28247 
28248 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
28249     if (err == MP_OKAY) {
28250         p = (sp_point_256*)XMALLOC(sizeof(sp_point_256), NULL,
28251                                          DYNAMIC_TYPE_ECC);
28252         if (p == NULL)
28253             err = MEMORY_E;
28254     }
28255     if (err == MP_OKAY) {
28256         tmp = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 5 * 2, NULL,
28257                                  DYNAMIC_TYPE_ECC);
28258         if (tmp == NULL)
28259             err = MEMORY_E;
28260     }
28261 #endif
28262 
28263     if (err == MP_OKAY) {
28264         sp_256_from_mp(p->x, 5, pX);
28265         sp_256_from_mp(p->y, 5, pY);
28266         sp_256_from_mp(p->z, 5, pZ);
28267         p->infinity = sp_256_iszero_5(p->x) &
28268                       sp_256_iszero_5(p->y);
28269 
28270             sp_256_proj_point_dbl_5(p, p, tmp);
28271     }
28272 
28273     if (err == MP_OKAY) {
28274         err = sp_256_to_mp(p->x, rX);
28275     }
28276     if (err == MP_OKAY) {
28277         err = sp_256_to_mp(p->y, rY);
28278     }
28279     if (err == MP_OKAY) {
28280         err = sp_256_to_mp(p->z, rZ);
28281     }
28282 
28283 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
28284     if (tmp != NULL)
28285         XFREE(tmp, NULL, DYNAMIC_TYPE_ECC);
28286     if (p != NULL)
28287         XFREE(p, NULL, DYNAMIC_TYPE_ECC);
28288 #endif
28289 
28290     return err;
28291 }
28292 
28293 /* Map a projective EC point to affine in place.
28294  * pZ will be one.
28295  *
28296  * pX   EC point's X ordinate.
28297  * pY   EC point's Y ordinate.
28298  * pZ   EC point's Z ordinate.
28299  * returns MEMORY_E if dynamic memory allocation fails and MP_OKAY otherwise.
28300  */
sp_ecc_map_256(mp_int * pX,mp_int * pY,mp_int * pZ)28301 int sp_ecc_map_256(mp_int* pX, mp_int* pY, mp_int* pZ)
28302 {
28303 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
28304     sp_digit* tmp = NULL;
28305     sp_point_256* p = NULL;
28306 #else
28307     sp_digit tmp[2 * 5 * 4];
28308     sp_point_256 p[1];
28309 #endif
28310     int err = MP_OKAY;
28311 
28312 
28313 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
28314     if (err == MP_OKAY) {
28315         p = (sp_point_256*)XMALLOC(sizeof(sp_point_256), NULL,
28316                                          DYNAMIC_TYPE_ECC);
28317         if (p == NULL)
28318             err = MEMORY_E;
28319     }
28320     if (err == MP_OKAY) {
28321         tmp = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 5 * 4, NULL,
28322                                  DYNAMIC_TYPE_ECC);
28323         if (tmp == NULL)
28324             err = MEMORY_E;
28325     }
28326 #endif
28327     if (err == MP_OKAY) {
28328         sp_256_from_mp(p->x, 5, pX);
28329         sp_256_from_mp(p->y, 5, pY);
28330         sp_256_from_mp(p->z, 5, pZ);
28331         p->infinity = sp_256_iszero_5(p->x) &
28332                       sp_256_iszero_5(p->y);
28333 
28334             sp_256_map_5(p, p, tmp);
28335     }
28336 
28337     if (err == MP_OKAY) {
28338         err = sp_256_to_mp(p->x, pX);
28339     }
28340     if (err == MP_OKAY) {
28341         err = sp_256_to_mp(p->y, pY);
28342     }
28343     if (err == MP_OKAY) {
28344         err = sp_256_to_mp(p->z, pZ);
28345     }
28346 
28347 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
28348     if (tmp != NULL)
28349         XFREE(tmp, NULL, DYNAMIC_TYPE_ECC);
28350     if (p != NULL)
28351         XFREE(p, NULL, DYNAMIC_TYPE_ECC);
28352 #endif
28353 
28354     return err;
28355 }
28356 #endif /* WOLFSSL_PUBLIC_ECC_ADD_DBL */
28357 #ifdef HAVE_COMP_KEY
28358 /* Find the square root of a number mod the prime of the curve.
28359  *
28360  * y  The number to operate on and the result.
28361  * returns MEMORY_E if dynamic memory allocation fails and MP_OKAY otherwise.
28362  */
sp_256_mont_sqrt_5(sp_digit * y)28363 static int sp_256_mont_sqrt_5(sp_digit* y)
28364 {
28365 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
28366     sp_digit* t1 = NULL;
28367 #else
28368     sp_digit t1[4 * 5];
28369 #endif
28370     sp_digit* t2 = NULL;
28371     int err = MP_OKAY;
28372 
28373 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
28374     t1 = (sp_digit*)XMALLOC(sizeof(sp_digit) * 4 * 5, NULL, DYNAMIC_TYPE_ECC);
28375     if (t1 == NULL) {
28376         err = MEMORY_E;
28377     }
28378 #endif
28379 
28380     if (err == MP_OKAY) {
28381         t2 = t1 + 2 * 5;
28382 
28383         {
28384             /* t2 = y ^ 0x2 */
28385             sp_256_mont_sqr_5(t2, y, p256_mod, p256_mp_mod);
28386             /* t1 = y ^ 0x3 */
28387             sp_256_mont_mul_5(t1, t2, y, p256_mod, p256_mp_mod);
28388             /* t2 = y ^ 0xc */
28389             sp_256_mont_sqr_n_5(t2, t1, 2, p256_mod, p256_mp_mod);
28390             /* t1 = y ^ 0xf */
28391             sp_256_mont_mul_5(t1, t1, t2, p256_mod, p256_mp_mod);
28392             /* t2 = y ^ 0xf0 */
28393             sp_256_mont_sqr_n_5(t2, t1, 4, p256_mod, p256_mp_mod);
28394             /* t1 = y ^ 0xff */
28395             sp_256_mont_mul_5(t1, t1, t2, p256_mod, p256_mp_mod);
28396             /* t2 = y ^ 0xff00 */
28397             sp_256_mont_sqr_n_5(t2, t1, 8, p256_mod, p256_mp_mod);
28398             /* t1 = y ^ 0xffff */
28399             sp_256_mont_mul_5(t1, t1, t2, p256_mod, p256_mp_mod);
28400             /* t2 = y ^ 0xffff0000 */
28401             sp_256_mont_sqr_n_5(t2, t1, 16, p256_mod, p256_mp_mod);
28402             /* t1 = y ^ 0xffffffff */
28403             sp_256_mont_mul_5(t1, t1, t2, p256_mod, p256_mp_mod);
28404             /* t1 = y ^ 0xffffffff00000000 */
28405             sp_256_mont_sqr_n_5(t1, t1, 32, p256_mod, p256_mp_mod);
28406             /* t1 = y ^ 0xffffffff00000001 */
28407             sp_256_mont_mul_5(t1, t1, y, p256_mod, p256_mp_mod);
28408             /* t1 = y ^ 0xffffffff00000001000000000000000000000000 */
28409             sp_256_mont_sqr_n_5(t1, t1, 96, p256_mod, p256_mp_mod);
28410             /* t1 = y ^ 0xffffffff00000001000000000000000000000001 */
28411             sp_256_mont_mul_5(t1, t1, y, p256_mod, p256_mp_mod);
28412             sp_256_mont_sqr_n_5(y, t1, 94, p256_mod, p256_mp_mod);
28413         }
28414     }
28415 
28416 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
28417     if (t1 != NULL)
28418         XFREE(t1, NULL, DYNAMIC_TYPE_ECC);
28419 #endif
28420 
28421     return err;
28422 }
28423 
28424 
28425 /* Uncompress the point given the X ordinate.
28426  *
28427  * xm    X ordinate.
28428  * odd   Whether the Y ordinate is odd.
28429  * ym    Calculated Y ordinate.
28430  * returns MEMORY_E if dynamic memory allocation fails and MP_OKAY otherwise.
28431  */
sp_ecc_uncompress_256(mp_int * xm,int odd,mp_int * ym)28432 int sp_ecc_uncompress_256(mp_int* xm, int odd, mp_int* ym)
28433 {
28434 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
28435     sp_digit* x = NULL;
28436 #else
28437     sp_digit x[4 * 5];
28438 #endif
28439     sp_digit* y = NULL;
28440     int err = MP_OKAY;
28441 
28442 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
28443     x = (sp_digit*)XMALLOC(sizeof(sp_digit) * 4 * 5, NULL, DYNAMIC_TYPE_ECC);
28444     if (x == NULL)
28445         err = MEMORY_E;
28446 #endif
28447 
28448     if (err == MP_OKAY) {
28449         y = x + 2 * 5;
28450 
28451         sp_256_from_mp(x, 5, xm);
28452         err = sp_256_mod_mul_norm_5(x, x, p256_mod);
28453     }
28454     if (err == MP_OKAY) {
28455         /* y = x^3 */
28456         {
28457             sp_256_mont_sqr_5(y, x, p256_mod, p256_mp_mod);
28458             sp_256_mont_mul_5(y, y, x, p256_mod, p256_mp_mod);
28459         }
28460         /* y = x^3 - 3x */
28461         sp_256_mont_sub_5(y, y, x, p256_mod);
28462         sp_256_mont_sub_5(y, y, x, p256_mod);
28463         sp_256_mont_sub_5(y, y, x, p256_mod);
28464         /* y = x^3 - 3x + b */
28465         err = sp_256_mod_mul_norm_5(x, p256_b, p256_mod);
28466     }
28467     if (err == MP_OKAY) {
28468         sp_256_mont_add_5(y, y, x, p256_mod);
28469         /* y = sqrt(x^3 - 3x + b) */
28470         err = sp_256_mont_sqrt_5(y);
28471     }
28472     if (err == MP_OKAY) {
28473         XMEMSET(y + 5, 0, 5U * sizeof(sp_digit));
28474         sp_256_mont_reduce_5(y, p256_mod, p256_mp_mod);
28475         if ((((word32)y[0] ^ (word32)odd) & 1U) != 0U) {
28476             sp_256_mont_sub_5(y, p256_mod, y, p256_mod);
28477         }
28478 
28479         err = sp_256_to_mp(y, ym);
28480     }
28481 
28482 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
28483     if (x != NULL)
28484         XFREE(x, NULL, DYNAMIC_TYPE_ECC);
28485 #endif
28486 
28487     return err;
28488 }
28489 #endif
28490 #endif /* !WOLFSSL_SP_NO_256 */
28491 #ifdef WOLFSSL_SP_384
28492 
28493 /* Point structure to use. */
28494 typedef struct sp_point_384 {
28495     /* X ordinate of point. */
28496     sp_digit x[2 * 7];
28497     /* Y ordinate of point. */
28498     sp_digit y[2 * 7];
28499     /* Z ordinate of point. */
28500     sp_digit z[2 * 7];
28501     /* Indicates point is at infinity. */
28502     int infinity;
28503 } sp_point_384;
28504 
28505 /* The modulus (prime) of the curve P384. */
28506 static const sp_digit p384_mod[7] = {
28507     0x000000ffffffffL,0x7ffe0000000000L,0x7ffffffffbffffL,0x7fffffffffffffL,
28508     0x7fffffffffffffL,0x7fffffffffffffL,0x3fffffffffffffL
28509 };
28510 /* The Montgomery normalizer for modulus of the curve P384. */
28511 static const sp_digit p384_norm_mod[7] = {
28512     0x7fffff00000001L,0x0001ffffffffffL,0x00000000040000L,0x00000000000000L,
28513     0x00000000000000L,0x00000000000000L,0x00000000000000L
28514 };
28515 /* The Montgomery multiplier for modulus of the curve P384. */
28516 static sp_digit p384_mp_mod = 0x0000100000001;
28517 #if defined(WOLFSSL_VALIDATE_ECC_KEYGEN) || defined(HAVE_ECC_SIGN) || \
28518                                             defined(HAVE_ECC_VERIFY)
28519 /* The order of the curve P384. */
28520 static const sp_digit p384_order[7] = {
28521     0x6c196accc52973L,0x1b6491614ef5d9L,0x07d0dcb77d6068L,0x7ffffffe3b1a6cL,
28522     0x7fffffffffffffL,0x7fffffffffffffL,0x3fffffffffffffL
28523 };
28524 #endif
28525 /* The order of the curve P384 minus 2. */
28526 static const sp_digit p384_order2[7] = {
28527     0x6c196accc52971L,0x1b6491614ef5d9L,0x07d0dcb77d6068L,0x7ffffffe3b1a6cL,
28528     0x7fffffffffffffL,0x7fffffffffffffL,0x3fffffffffffffL
28529 };
28530 #if defined(HAVE_ECC_SIGN) || defined(HAVE_ECC_VERIFY)
28531 /* The Montgomery normalizer for order of the curve P384. */
28532 static const sp_digit p384_norm_order[7] = {
28533     0x13e695333ad68dL,0x649b6e9eb10a26L,0x782f2348829f97L,0x00000001c4e593L,
28534     0x00000000000000L,0x00000000000000L,0x00000000000000L
28535 };
28536 #endif
28537 #if defined(HAVE_ECC_SIGN) || defined(HAVE_ECC_VERIFY)
28538 /* The Montgomery multiplier for order of the curve P384. */
28539 static sp_digit p384_mp_order = 0x546089e88fdc45L;
28540 #endif
28541 /* The base point of curve P384. */
28542 static const sp_point_384 p384_base = {
28543     /* X ordinate */
28544     {
28545         0x545e3872760ab7L,0x64bb7eaa52d874L,0x020950a8e1540bL,0x5d3cdcc2cfba0fL,
28546         0x0ad746e1d3b628L,0x26f1d638e3de64L,0x2aa1f288afa2c1L,
28547         (sp_digit)0, (sp_digit)0, (sp_digit)0, (sp_digit)0, (sp_digit)0,
28548         (sp_digit)0, (sp_digit)0
28549     },
28550     /* Y ordinate */
28551     {
28552         0x431d7c90ea0e5fL,0x639c3afd033af4L,0x4ed7c2e3002982L,0x44d0a3e74ed188L,
28553         0x2dc29f8f41dbd2L,0x0debb3d317f252L,0x0d85f792a5898bL,
28554         (sp_digit)0, (sp_digit)0, (sp_digit)0, (sp_digit)0, (sp_digit)0,
28555         (sp_digit)0, (sp_digit)0
28556     },
28557     /* Z ordinate */
28558     {
28559         0x00000000000001L,0x00000000000000L,0x00000000000000L,0x00000000000000L,
28560         0x00000000000000L,0x00000000000000L,0x00000000000000L,
28561         (sp_digit)0, (sp_digit)0, (sp_digit)0, (sp_digit)0, (sp_digit)0,
28562         (sp_digit)0, (sp_digit)0
28563     },
28564     /* infinity */
28565     0
28566 };
28567 #if defined(HAVE_ECC_CHECK_KEY) || defined(HAVE_COMP_KEY)
28568 static const sp_digit p384_b[7] = {
28569     0x05c8edd3ec2aefL,0x731b145da33a55L,0x3d404e1d6b1958L,0x740a089018a044L,
28570     0x02d19181d9c6efL,0x7c9311c0ad7c7fL,0x2ccc4be9f88fb9L
28571 };
28572 #endif
28573 
28574 #ifdef WOLFSSL_SP_SMALL
28575 /* Multiply a and b into r. (r = a * b)
28576  *
28577  * r  A single precision integer.
28578  * a  A single precision integer.
28579  * b  A single precision integer.
28580  */
sp_384_mul_7(sp_digit * r,const sp_digit * a,const sp_digit * b)28581 SP_NOINLINE static void sp_384_mul_7(sp_digit* r, const sp_digit* a,
28582     const sp_digit* b)
28583 {
28584     int i;
28585     int imax;
28586     int k;
28587     sp_uint128 c;
28588     sp_uint128 lo;
28589 
28590     c = ((sp_uint128)a[6]) * b[6];
28591     r[13] = (sp_digit)(c >> 55);
28592     c &= 0x7fffffffffffffL;
28593     for (k = 11; k >= 0; k--) {
28594         if (k >= 7) {
28595             i = k - 6;
28596             imax = 6;
28597         }
28598         else {
28599             i = 0;
28600             imax = k;
28601         }
28602         lo = 0;
28603         for (; i <= imax; i++) {
28604             lo += ((sp_uint128)a[i]) * b[k - i];
28605         }
28606         c += lo >> 55;
28607         r[k + 2] += (sp_digit)(c >> 55);
28608         r[k + 1]  = (sp_digit)(c & 0x7fffffffffffffL);
28609         c = lo & 0x7fffffffffffffL;
28610     }
28611     r[0] = (sp_digit)c;
28612 }
28613 
28614 #else
28615 /* Multiply a and b into r. (r = a * b)
28616  *
28617  * r  A single precision integer.
28618  * a  A single precision integer.
28619  * b  A single precision integer.
28620  */
sp_384_mul_7(sp_digit * r,const sp_digit * a,const sp_digit * b)28621 SP_NOINLINE static void sp_384_mul_7(sp_digit* r, const sp_digit* a,
28622     const sp_digit* b)
28623 {
28624     sp_int128 t0   = ((sp_int128)a[ 0]) * b[ 0];
28625     sp_int128 t1   = ((sp_int128)a[ 0]) * b[ 1]
28626                  + ((sp_int128)a[ 1]) * b[ 0];
28627     sp_int128 t2   = ((sp_int128)a[ 0]) * b[ 2]
28628                  + ((sp_int128)a[ 1]) * b[ 1]
28629                  + ((sp_int128)a[ 2]) * b[ 0];
28630     sp_int128 t3   = ((sp_int128)a[ 0]) * b[ 3]
28631                  + ((sp_int128)a[ 1]) * b[ 2]
28632                  + ((sp_int128)a[ 2]) * b[ 1]
28633                  + ((sp_int128)a[ 3]) * b[ 0];
28634     sp_int128 t4   = ((sp_int128)a[ 0]) * b[ 4]
28635                  + ((sp_int128)a[ 1]) * b[ 3]
28636                  + ((sp_int128)a[ 2]) * b[ 2]
28637                  + ((sp_int128)a[ 3]) * b[ 1]
28638                  + ((sp_int128)a[ 4]) * b[ 0];
28639     sp_int128 t5   = ((sp_int128)a[ 0]) * b[ 5]
28640                  + ((sp_int128)a[ 1]) * b[ 4]
28641                  + ((sp_int128)a[ 2]) * b[ 3]
28642                  + ((sp_int128)a[ 3]) * b[ 2]
28643                  + ((sp_int128)a[ 4]) * b[ 1]
28644                  + ((sp_int128)a[ 5]) * b[ 0];
28645     sp_int128 t6   = ((sp_int128)a[ 0]) * b[ 6]
28646                  + ((sp_int128)a[ 1]) * b[ 5]
28647                  + ((sp_int128)a[ 2]) * b[ 4]
28648                  + ((sp_int128)a[ 3]) * b[ 3]
28649                  + ((sp_int128)a[ 4]) * b[ 2]
28650                  + ((sp_int128)a[ 5]) * b[ 1]
28651                  + ((sp_int128)a[ 6]) * b[ 0];
28652     sp_int128 t7   = ((sp_int128)a[ 1]) * b[ 6]
28653                  + ((sp_int128)a[ 2]) * b[ 5]
28654                  + ((sp_int128)a[ 3]) * b[ 4]
28655                  + ((sp_int128)a[ 4]) * b[ 3]
28656                  + ((sp_int128)a[ 5]) * b[ 2]
28657                  + ((sp_int128)a[ 6]) * b[ 1];
28658     sp_int128 t8   = ((sp_int128)a[ 2]) * b[ 6]
28659                  + ((sp_int128)a[ 3]) * b[ 5]
28660                  + ((sp_int128)a[ 4]) * b[ 4]
28661                  + ((sp_int128)a[ 5]) * b[ 3]
28662                  + ((sp_int128)a[ 6]) * b[ 2];
28663     sp_int128 t9   = ((sp_int128)a[ 3]) * b[ 6]
28664                  + ((sp_int128)a[ 4]) * b[ 5]
28665                  + ((sp_int128)a[ 5]) * b[ 4]
28666                  + ((sp_int128)a[ 6]) * b[ 3];
28667     sp_int128 t10  = ((sp_int128)a[ 4]) * b[ 6]
28668                  + ((sp_int128)a[ 5]) * b[ 5]
28669                  + ((sp_int128)a[ 6]) * b[ 4];
28670     sp_int128 t11  = ((sp_int128)a[ 5]) * b[ 6]
28671                  + ((sp_int128)a[ 6]) * b[ 5];
28672     sp_int128 t12  = ((sp_int128)a[ 6]) * b[ 6];
28673 
28674     t1   += t0  >> 55; r[ 0] = t0  & 0x7fffffffffffffL;
28675     t2   += t1  >> 55; r[ 1] = t1  & 0x7fffffffffffffL;
28676     t3   += t2  >> 55; r[ 2] = t2  & 0x7fffffffffffffL;
28677     t4   += t3  >> 55; r[ 3] = t3  & 0x7fffffffffffffL;
28678     t5   += t4  >> 55; r[ 4] = t4  & 0x7fffffffffffffL;
28679     t6   += t5  >> 55; r[ 5] = t5  & 0x7fffffffffffffL;
28680     t7   += t6  >> 55; r[ 6] = t6  & 0x7fffffffffffffL;
28681     t8   += t7  >> 55; r[ 7] = t7  & 0x7fffffffffffffL;
28682     t9   += t8  >> 55; r[ 8] = t8  & 0x7fffffffffffffL;
28683     t10  += t9  >> 55; r[ 9] = t9  & 0x7fffffffffffffL;
28684     t11  += t10 >> 55; r[10] = t10 & 0x7fffffffffffffL;
28685     t12  += t11 >> 55; r[11] = t11 & 0x7fffffffffffffL;
28686     r[13] = (sp_digit)(t12 >> 55);
28687                        r[12] = t12 & 0x7fffffffffffffL;
28688 }
28689 
28690 #endif /* WOLFSSL_SP_SMALL */
28691 #ifdef WOLFSSL_SP_SMALL
28692 /* Square a and put result in r. (r = a * a)
28693  *
28694  * r  A single precision integer.
28695  * a  A single precision integer.
28696  */
sp_384_sqr_7(sp_digit * r,const sp_digit * a)28697 SP_NOINLINE static void sp_384_sqr_7(sp_digit* r, const sp_digit* a)
28698 {
28699     int i;
28700     int imax;
28701     int k;
28702     sp_uint128 c;
28703     sp_uint128 t;
28704 
28705     c = ((sp_uint128)a[6]) * a[6];
28706     r[13] = (sp_digit)(c >> 55);
28707     c = (c & 0x7fffffffffffffL) << 55;
28708     for (k = 11; k >= 0; k--) {
28709         i = (k + 1) / 2;
28710         if ((k & 1) == 0) {
28711            c += ((sp_uint128)a[i]) * a[i];
28712            i++;
28713         }
28714         if (k < 6) {
28715             imax = k;
28716         }
28717         else {
28718             imax = 6;
28719         }
28720         t = 0;
28721         for (; i <= imax; i++) {
28722             t += ((sp_uint128)a[i]) * a[k - i];
28723         }
28724         c += t * 2;
28725 
28726         r[k + 2] += (sp_digit) (c >> 110);
28727         r[k + 1]  = (sp_digit)((c >> 55) & 0x7fffffffffffffL);
28728         c = (c & 0x7fffffffffffffL) << 55;
28729     }
28730     r[0] = (sp_digit)(c >> 55);
28731 }
28732 
28733 #else
28734 /* Square a and put result in r. (r = a * a)
28735  *
28736  * r  A single precision integer.
28737  * a  A single precision integer.
28738  */
sp_384_sqr_7(sp_digit * r,const sp_digit * a)28739 SP_NOINLINE static void sp_384_sqr_7(sp_digit* r, const sp_digit* a)
28740 {
28741     sp_int128 t0   =  ((sp_int128)a[ 0]) * a[ 0];
28742     sp_int128 t1   = (((sp_int128)a[ 0]) * a[ 1]) * 2;
28743     sp_int128 t2   = (((sp_int128)a[ 0]) * a[ 2]) * 2
28744                  +  ((sp_int128)a[ 1]) * a[ 1];
28745     sp_int128 t3   = (((sp_int128)a[ 0]) * a[ 3]
28746                  +  ((sp_int128)a[ 1]) * a[ 2]) * 2;
28747     sp_int128 t4   = (((sp_int128)a[ 0]) * a[ 4]
28748                  +  ((sp_int128)a[ 1]) * a[ 3]) * 2
28749                  +  ((sp_int128)a[ 2]) * a[ 2];
28750     sp_int128 t5   = (((sp_int128)a[ 0]) * a[ 5]
28751                  +  ((sp_int128)a[ 1]) * a[ 4]
28752                  +  ((sp_int128)a[ 2]) * a[ 3]) * 2;
28753     sp_int128 t6   = (((sp_int128)a[ 0]) * a[ 6]
28754                  +  ((sp_int128)a[ 1]) * a[ 5]
28755                  +  ((sp_int128)a[ 2]) * a[ 4]) * 2
28756                  +  ((sp_int128)a[ 3]) * a[ 3];
28757     sp_int128 t7   = (((sp_int128)a[ 1]) * a[ 6]
28758                  +  ((sp_int128)a[ 2]) * a[ 5]
28759                  +  ((sp_int128)a[ 3]) * a[ 4]) * 2;
28760     sp_int128 t8   = (((sp_int128)a[ 2]) * a[ 6]
28761                  +  ((sp_int128)a[ 3]) * a[ 5]) * 2
28762                  +  ((sp_int128)a[ 4]) * a[ 4];
28763     sp_int128 t9   = (((sp_int128)a[ 3]) * a[ 6]
28764                  +  ((sp_int128)a[ 4]) * a[ 5]) * 2;
28765     sp_int128 t10  = (((sp_int128)a[ 4]) * a[ 6]) * 2
28766                  +  ((sp_int128)a[ 5]) * a[ 5];
28767     sp_int128 t11  = (((sp_int128)a[ 5]) * a[ 6]) * 2;
28768     sp_int128 t12  =  ((sp_int128)a[ 6]) * a[ 6];
28769 
28770     t1   += t0  >> 55; r[ 0] = t0  & 0x7fffffffffffffL;
28771     t2   += t1  >> 55; r[ 1] = t1  & 0x7fffffffffffffL;
28772     t3   += t2  >> 55; r[ 2] = t2  & 0x7fffffffffffffL;
28773     t4   += t3  >> 55; r[ 3] = t3  & 0x7fffffffffffffL;
28774     t5   += t4  >> 55; r[ 4] = t4  & 0x7fffffffffffffL;
28775     t6   += t5  >> 55; r[ 5] = t5  & 0x7fffffffffffffL;
28776     t7   += t6  >> 55; r[ 6] = t6  & 0x7fffffffffffffL;
28777     t8   += t7  >> 55; r[ 7] = t7  & 0x7fffffffffffffL;
28778     t9   += t8  >> 55; r[ 8] = t8  & 0x7fffffffffffffL;
28779     t10  += t9  >> 55; r[ 9] = t9  & 0x7fffffffffffffL;
28780     t11  += t10 >> 55; r[10] = t10 & 0x7fffffffffffffL;
28781     t12  += t11 >> 55; r[11] = t11 & 0x7fffffffffffffL;
28782     r[13] = (sp_digit)(t12 >> 55);
28783                        r[12] = t12 & 0x7fffffffffffffL;
28784 }
28785 
28786 #endif /* WOLFSSL_SP_SMALL */
28787 #ifdef WOLFSSL_SP_SMALL
28788 /* Add b to a into r. (r = a + b)
28789  *
28790  * r  A single precision integer.
28791  * a  A single precision integer.
28792  * b  A single precision integer.
28793  */
sp_384_add_7(sp_digit * r,const sp_digit * a,const sp_digit * b)28794 SP_NOINLINE static int sp_384_add_7(sp_digit* r, const sp_digit* a,
28795         const sp_digit* b)
28796 {
28797     int i;
28798 
28799     for (i = 0; i < 7; i++) {
28800         r[i] = a[i] + b[i];
28801     }
28802 
28803     return 0;
28804 }
28805 #else
28806 /* Add b to a into r. (r = a + b)
28807  *
28808  * r  A single precision integer.
28809  * a  A single precision integer.
28810  * b  A single precision integer.
28811  */
sp_384_add_7(sp_digit * r,const sp_digit * a,const sp_digit * b)28812 SP_NOINLINE static int sp_384_add_7(sp_digit* r, const sp_digit* a,
28813         const sp_digit* b)
28814 {
28815     r[ 0] = a[ 0] + b[ 0];
28816     r[ 1] = a[ 1] + b[ 1];
28817     r[ 2] = a[ 2] + b[ 2];
28818     r[ 3] = a[ 3] + b[ 3];
28819     r[ 4] = a[ 4] + b[ 4];
28820     r[ 5] = a[ 5] + b[ 5];
28821     r[ 6] = a[ 6] + b[ 6];
28822 
28823     return 0;
28824 }
28825 
28826 #endif /* WOLFSSL_SP_SMALL */
28827 #ifdef WOLFSSL_SP_SMALL
28828 /* Sub b from a into r. (r = a - b)
28829  *
28830  * r  A single precision integer.
28831  * a  A single precision integer.
28832  * b  A single precision integer.
28833  */
sp_384_sub_7(sp_digit * r,const sp_digit * a,const sp_digit * b)28834 SP_NOINLINE static int sp_384_sub_7(sp_digit* r, const sp_digit* a,
28835         const sp_digit* b)
28836 {
28837     int i;
28838 
28839     for (i = 0; i < 7; i++) {
28840         r[i] = a[i] - b[i];
28841     }
28842 
28843     return 0;
28844 }
28845 
28846 #else
28847 /* Sub b from a into r. (r = a - b)
28848  *
28849  * r  A single precision integer.
28850  * a  A single precision integer.
28851  * b  A single precision integer.
28852  */
sp_384_sub_7(sp_digit * r,const sp_digit * a,const sp_digit * b)28853 SP_NOINLINE static int sp_384_sub_7(sp_digit* r, const sp_digit* a,
28854         const sp_digit* b)
28855 {
28856     r[ 0] = a[ 0] - b[ 0];
28857     r[ 1] = a[ 1] - b[ 1];
28858     r[ 2] = a[ 2] - b[ 2];
28859     r[ 3] = a[ 3] - b[ 3];
28860     r[ 4] = a[ 4] - b[ 4];
28861     r[ 5] = a[ 5] - b[ 5];
28862     r[ 6] = a[ 6] - b[ 6];
28863 
28864     return 0;
28865 }
28866 
28867 #endif /* WOLFSSL_SP_SMALL */
28868 /* Convert an mp_int to an array of sp_digit.
28869  *
28870  * r  A single precision integer.
28871  * size  Maximum number of bytes to convert
28872  * a  A multi-precision integer.
28873  */
sp_384_from_mp(sp_digit * r,int size,const mp_int * a)28874 static void sp_384_from_mp(sp_digit* r, int size, const mp_int* a)
28875 {
28876 #if DIGIT_BIT == 55
28877     int j;
28878 
28879     XMEMCPY(r, a->dp, sizeof(sp_digit) * a->used);
28880 
28881     for (j = a->used; j < size; j++) {
28882         r[j] = 0;
28883     }
28884 #elif DIGIT_BIT > 55
28885     int i;
28886     int j = 0;
28887     word32 s = 0;
28888 
28889     r[0] = 0;
28890     for (i = 0; i < a->used && j < size; i++) {
28891         r[j] |= ((sp_digit)a->dp[i] << s);
28892         r[j] &= 0x7fffffffffffffL;
28893         s = 55U - s;
28894         if (j + 1 >= size) {
28895             break;
28896         }
28897         /* lint allow cast of mismatch word32 and mp_digit */
28898         r[++j] = (sp_digit)(a->dp[i] >> s); /*lint !e9033*/
28899         while ((s + 55U) <= (word32)DIGIT_BIT) {
28900             s += 55U;
28901             r[j] &= 0x7fffffffffffffL;
28902             if (j + 1 >= size) {
28903                 break;
28904             }
28905             if (s < (word32)DIGIT_BIT) {
28906                 /* lint allow cast of mismatch word32 and mp_digit */
28907                 r[++j] = (sp_digit)(a->dp[i] >> s); /*lint !e9033*/
28908             }
28909             else {
28910                 r[++j] = (sp_digit)0;
28911             }
28912         }
28913         s = (word32)DIGIT_BIT - s;
28914     }
28915 
28916     for (j++; j < size; j++) {
28917         r[j] = 0;
28918     }
28919 #else
28920     int i;
28921     int j = 0;
28922     int s = 0;
28923 
28924     r[0] = 0;
28925     for (i = 0; i < a->used && j < size; i++) {
28926         r[j] |= ((sp_digit)a->dp[i]) << s;
28927         if (s + DIGIT_BIT >= 55) {
28928             r[j] &= 0x7fffffffffffffL;
28929             if (j + 1 >= size) {
28930                 break;
28931             }
28932             s = 55 - s;
28933             if (s == DIGIT_BIT) {
28934                 r[++j] = 0;
28935                 s = 0;
28936             }
28937             else {
28938                 r[++j] = a->dp[i] >> s;
28939                 s = DIGIT_BIT - s;
28940             }
28941         }
28942         else {
28943             s += DIGIT_BIT;
28944         }
28945     }
28946 
28947     for (j++; j < size; j++) {
28948         r[j] = 0;
28949     }
28950 #endif
28951 }
28952 
28953 /* Convert a point of type ecc_point to type sp_point_384.
28954  *
28955  * p   Point of type sp_point_384 (result).
28956  * pm  Point of type ecc_point.
28957  */
sp_384_point_from_ecc_point_7(sp_point_384 * p,const ecc_point * pm)28958 static void sp_384_point_from_ecc_point_7(sp_point_384* p,
28959         const ecc_point* pm)
28960 {
28961     XMEMSET(p->x, 0, sizeof(p->x));
28962     XMEMSET(p->y, 0, sizeof(p->y));
28963     XMEMSET(p->z, 0, sizeof(p->z));
28964     sp_384_from_mp(p->x, 7, pm->x);
28965     sp_384_from_mp(p->y, 7, pm->y);
28966     sp_384_from_mp(p->z, 7, pm->z);
28967     p->infinity = 0;
28968 }
28969 
28970 /* Convert an array of sp_digit to an mp_int.
28971  *
28972  * a  A single precision integer.
28973  * r  A multi-precision integer.
28974  */
sp_384_to_mp(const sp_digit * a,mp_int * r)28975 static int sp_384_to_mp(const sp_digit* a, mp_int* r)
28976 {
28977     int err;
28978 
28979     err = mp_grow(r, (384 + DIGIT_BIT - 1) / DIGIT_BIT);
28980     if (err == MP_OKAY) { /*lint !e774 case where err is always MP_OKAY*/
28981 #if DIGIT_BIT == 55
28982         XMEMCPY(r->dp, a, sizeof(sp_digit) * 7);
28983         r->used = 7;
28984         mp_clamp(r);
28985 #elif DIGIT_BIT < 55
28986         int i;
28987         int j = 0;
28988         int s = 0;
28989 
28990         r->dp[0] = 0;
28991         for (i = 0; i < 7; i++) {
28992             r->dp[j] |= (mp_digit)(a[i] << s);
28993             r->dp[j] &= ((sp_digit)1 << DIGIT_BIT) - 1;
28994             s = DIGIT_BIT - s;
28995             r->dp[++j] = (mp_digit)(a[i] >> s);
28996             while (s + DIGIT_BIT <= 55) {
28997                 s += DIGIT_BIT;
28998                 r->dp[j++] &= ((sp_digit)1 << DIGIT_BIT) - 1;
28999                 if (s == SP_WORD_SIZE) {
29000                     r->dp[j] = 0;
29001                 }
29002                 else {
29003                     r->dp[j] = (mp_digit)(a[i] >> s);
29004                 }
29005             }
29006             s = 55 - s;
29007         }
29008         r->used = (384 + DIGIT_BIT - 1) / DIGIT_BIT;
29009         mp_clamp(r);
29010 #else
29011         int i;
29012         int j = 0;
29013         int s = 0;
29014 
29015         r->dp[0] = 0;
29016         for (i = 0; i < 7; i++) {
29017             r->dp[j] |= ((mp_digit)a[i]) << s;
29018             if (s + 55 >= DIGIT_BIT) {
29019     #if DIGIT_BIT != 32 && DIGIT_BIT != 64
29020                 r->dp[j] &= ((sp_digit)1 << DIGIT_BIT) - 1;
29021     #endif
29022                 s = DIGIT_BIT - s;
29023                 r->dp[++j] = a[i] >> s;
29024                 s = 55 - s;
29025             }
29026             else {
29027                 s += 55;
29028             }
29029         }
29030         r->used = (384 + DIGIT_BIT - 1) / DIGIT_BIT;
29031         mp_clamp(r);
29032 #endif
29033     }
29034 
29035     return err;
29036 }
29037 
29038 /* Convert a point of type sp_point_384 to type ecc_point.
29039  *
29040  * p   Point of type sp_point_384.
29041  * pm  Point of type ecc_point (result).
29042  * returns MEMORY_E when allocation of memory in ecc_point fails otherwise
29043  * MP_OKAY.
29044  */
sp_384_point_to_ecc_point_7(const sp_point_384 * p,ecc_point * pm)29045 static int sp_384_point_to_ecc_point_7(const sp_point_384* p, ecc_point* pm)
29046 {
29047     int err;
29048 
29049     err = sp_384_to_mp(p->x, pm->x);
29050     if (err == MP_OKAY) {
29051         err = sp_384_to_mp(p->y, pm->y);
29052     }
29053     if (err == MP_OKAY) {
29054         err = sp_384_to_mp(p->z, pm->z);
29055     }
29056 
29057     return err;
29058 }
29059 
29060 /* Compare a with b in constant time.
29061  *
29062  * a  A single precision integer.
29063  * b  A single precision integer.
29064  * return -ve, 0 or +ve if a is less than, equal to or greater than b
29065  * respectively.
29066  */
sp_384_cmp_7(const sp_digit * a,const sp_digit * b)29067 static sp_digit sp_384_cmp_7(const sp_digit* a, const sp_digit* b)
29068 {
29069     sp_digit r = 0;
29070 #ifdef WOLFSSL_SP_SMALL
29071     int i;
29072 
29073     for (i=6; i>=0; i--) {
29074         r |= (a[i] - b[i]) & (0 - (sp_digit)((r == 0) ? 1 : 0));
29075     }
29076 #else
29077     r |= (a[ 6] - b[ 6]) & (0 - (sp_digit)1);
29078     r |= (a[ 5] - b[ 5]) & (0 - (sp_digit)((r == 0) ? 1 : 0));
29079     r |= (a[ 4] - b[ 4]) & (0 - (sp_digit)((r == 0) ? 1 : 0));
29080     r |= (a[ 3] - b[ 3]) & (0 - (sp_digit)((r == 0) ? 1 : 0));
29081     r |= (a[ 2] - b[ 2]) & (0 - (sp_digit)((r == 0) ? 1 : 0));
29082     r |= (a[ 1] - b[ 1]) & (0 - (sp_digit)((r == 0) ? 1 : 0));
29083     r |= (a[ 0] - b[ 0]) & (0 - (sp_digit)((r == 0) ? 1 : 0));
29084 #endif /* WOLFSSL_SP_SMALL */
29085 
29086     return r;
29087 }
29088 
29089 /* Conditionally subtract b from a using the mask m.
29090  * m is -1 to subtract and 0 when not.
29091  *
29092  * r  A single precision number representing condition subtract result.
29093  * a  A single precision number to subtract from.
29094  * b  A single precision number to subtract.
29095  * m  Mask value to apply.
29096  */
sp_384_cond_sub_7(sp_digit * r,const sp_digit * a,const sp_digit * b,const sp_digit m)29097 static void sp_384_cond_sub_7(sp_digit* r, const sp_digit* a,
29098         const sp_digit* b, const sp_digit m)
29099 {
29100 #ifdef WOLFSSL_SP_SMALL
29101     int i;
29102 
29103     for (i = 0; i < 7; i++) {
29104         r[i] = a[i] - (b[i] & m);
29105     }
29106 #else
29107     r[ 0] = a[ 0] - (b[ 0] & m);
29108     r[ 1] = a[ 1] - (b[ 1] & m);
29109     r[ 2] = a[ 2] - (b[ 2] & m);
29110     r[ 3] = a[ 3] - (b[ 3] & m);
29111     r[ 4] = a[ 4] - (b[ 4] & m);
29112     r[ 5] = a[ 5] - (b[ 5] & m);
29113     r[ 6] = a[ 6] - (b[ 6] & m);
29114 #endif /* WOLFSSL_SP_SMALL */
29115 }
29116 
29117 /* Mul a by scalar b and add into r. (r += a * b)
29118  *
29119  * r  A single precision integer.
29120  * a  A single precision integer.
29121  * b  A scalar.
29122  */
sp_384_mul_add_7(sp_digit * r,const sp_digit * a,const sp_digit b)29123 SP_NOINLINE static void sp_384_mul_add_7(sp_digit* r, const sp_digit* a,
29124         const sp_digit b)
29125 {
29126 #ifdef WOLFSSL_SP_SMALL
29127     sp_int128 tb = b;
29128     sp_int128 t[4];
29129     int i;
29130 
29131     t[0] = 0;
29132     for (i = 0; i < 4; i += 4) {
29133         t[0] += (tb * a[i+0]) + r[i+0];
29134         t[1]  = (tb * a[i+1]) + r[i+1];
29135         t[2]  = (tb * a[i+2]) + r[i+2];
29136         t[3]  = (tb * a[i+3]) + r[i+3];
29137         r[i+0] = t[0] & 0x7fffffffffffffL;
29138         t[1] += t[0] >> 55;
29139         r[i+1] = t[1] & 0x7fffffffffffffL;
29140         t[2] += t[1] >> 55;
29141         r[i+2] = t[2] & 0x7fffffffffffffL;
29142         t[3] += t[2] >> 55;
29143         r[i+3] = t[3] & 0x7fffffffffffffL;
29144         t[0]  = t[3] >> 55;
29145     }
29146     t[0] += (tb * a[4]) + r[4];
29147     t[1]  = (tb * a[5]) + r[5];
29148     t[2]  = (tb * a[6]) + r[6];
29149     r[4] = t[0] & 0x7fffffffffffffL;
29150     t[1] += t[0] >> 55;
29151     r[5] = t[1] & 0x7fffffffffffffL;
29152     t[2] += t[1] >> 55;
29153     r[6] = t[2] & 0x7fffffffffffffL;
29154     r[7] +=  (sp_digit)(t[2] >> 55);
29155 #else
29156     sp_int128 tb = b;
29157     sp_int128 t[7];
29158 
29159     t[ 0] = tb * a[ 0];
29160     t[ 1] = tb * a[ 1];
29161     t[ 2] = tb * a[ 2];
29162     t[ 3] = tb * a[ 3];
29163     t[ 4] = tb * a[ 4];
29164     t[ 5] = tb * a[ 5];
29165     t[ 6] = tb * a[ 6];
29166     r[ 0] += (sp_digit)                 (t[ 0] & 0x7fffffffffffffL);
29167     r[ 1] += (sp_digit)((t[ 0] >> 55) + (t[ 1] & 0x7fffffffffffffL));
29168     r[ 2] += (sp_digit)((t[ 1] >> 55) + (t[ 2] & 0x7fffffffffffffL));
29169     r[ 3] += (sp_digit)((t[ 2] >> 55) + (t[ 3] & 0x7fffffffffffffL));
29170     r[ 4] += (sp_digit)((t[ 3] >> 55) + (t[ 4] & 0x7fffffffffffffL));
29171     r[ 5] += (sp_digit)((t[ 4] >> 55) + (t[ 5] & 0x7fffffffffffffL));
29172     r[ 6] += (sp_digit)((t[ 5] >> 55) + (t[ 6] & 0x7fffffffffffffL));
29173     r[ 7] += (sp_digit) (t[ 6] >> 55);
29174 #endif /* WOLFSSL_SP_SMALL */
29175 }
29176 
29177 /* Normalize the values in each word to 55 bits.
29178  *
29179  * a  Array of sp_digit to normalize.
29180  */
sp_384_norm_7(sp_digit * a)29181 static void sp_384_norm_7(sp_digit* a)
29182 {
29183 #ifdef WOLFSSL_SP_SMALL
29184     int i;
29185     for (i = 0; i < 6; i++) {
29186         a[i+1] += a[i] >> 55;
29187         a[i] &= 0x7fffffffffffffL;
29188     }
29189 #else
29190     a[1] += a[0] >> 55; a[0] &= 0x7fffffffffffffL;
29191     a[2] += a[1] >> 55; a[1] &= 0x7fffffffffffffL;
29192     a[3] += a[2] >> 55; a[2] &= 0x7fffffffffffffL;
29193     a[4] += a[3] >> 55; a[3] &= 0x7fffffffffffffL;
29194     a[5] += a[4] >> 55; a[4] &= 0x7fffffffffffffL;
29195     a[6] += a[5] >> 55; a[5] &= 0x7fffffffffffffL;
29196 #endif /* WOLFSSL_SP_SMALL */
29197 }
29198 
29199 /* Shift the result in the high 384 bits down to the bottom.
29200  *
29201  * r  A single precision number.
29202  * a  A single precision number.
29203  */
sp_384_mont_shift_7(sp_digit * r,const sp_digit * a)29204 static void sp_384_mont_shift_7(sp_digit* r, const sp_digit* a)
29205 {
29206 #ifdef WOLFSSL_SP_SMALL
29207     int i;
29208     sp_uint64 n;
29209 
29210     n = a[6] >> 54;
29211     for (i = 0; i < 6; i++) {
29212         n += (sp_uint64)a[7 + i] << 1;
29213         r[i] = n & 0x7fffffffffffffL;
29214         n >>= 55;
29215     }
29216     n += (sp_uint64)a[13] << 1;
29217     r[6] = n;
29218 #else
29219     sp_uint64 n;
29220 
29221     n  = a[6] >> 54;
29222     n += (sp_uint64)a[ 7] << 1U; r[ 0] = n & 0x7fffffffffffffUL; n >>= 55U;
29223     n += (sp_uint64)a[ 8] << 1U; r[ 1] = n & 0x7fffffffffffffUL; n >>= 55U;
29224     n += (sp_uint64)a[ 9] << 1U; r[ 2] = n & 0x7fffffffffffffUL; n >>= 55U;
29225     n += (sp_uint64)a[10] << 1U; r[ 3] = n & 0x7fffffffffffffUL; n >>= 55U;
29226     n += (sp_uint64)a[11] << 1U; r[ 4] = n & 0x7fffffffffffffUL; n >>= 55U;
29227     n += (sp_uint64)a[12] << 1U; r[ 5] = n & 0x7fffffffffffffUL; n >>= 55U;
29228     n += (sp_uint64)a[13] << 1U; r[ 6] = n;
29229 #endif /* WOLFSSL_SP_SMALL */
29230     XMEMSET(&r[7], 0, sizeof(*r) * 7U);
29231 }
29232 
29233 /* Reduce the number back to 384 bits using Montgomery reduction.
29234  *
29235  * a   A single precision number to reduce in place.
29236  * m   The single precision number representing the modulus.
29237  * mp  The digit representing the negative inverse of m mod 2^n.
29238  */
sp_384_mont_reduce_order_7(sp_digit * a,const sp_digit * m,sp_digit mp)29239 static void sp_384_mont_reduce_order_7(sp_digit* a, const sp_digit* m, sp_digit mp)
29240 {
29241     int i;
29242     sp_digit mu;
29243 
29244     sp_384_norm_7(a + 7);
29245 
29246     for (i=0; i<6; i++) {
29247         mu = (a[i] * mp) & 0x7fffffffffffffL;
29248         sp_384_mul_add_7(a+i, m, mu);
29249         a[i+1] += a[i] >> 55;
29250     }
29251     mu = (a[i] * mp) & 0x3fffffffffffffL;
29252     sp_384_mul_add_7(a+i, m, mu);
29253     a[i+1] += a[i] >> 55;
29254     a[i] &= 0x7fffffffffffffL;
29255     sp_384_mont_shift_7(a, a);
29256     sp_384_cond_sub_7(a, a, m, 0 - (((a[6] >> 54) > 0) ?
29257             (sp_digit)1 : (sp_digit)0));
29258     sp_384_norm_7(a);
29259 }
29260 
29261 /* Reduce the number back to 384 bits using Montgomery reduction.
29262  *
29263  * a   A single precision number to reduce in place.
29264  * m   The single precision number representing the modulus.
29265  * mp  The digit representing the negative inverse of m mod 2^n.
29266  */
sp_384_mont_reduce_7(sp_digit * a,const sp_digit * m,sp_digit mp)29267 static void sp_384_mont_reduce_7(sp_digit* a, const sp_digit* m, sp_digit mp)
29268 {
29269     int i;
29270     sp_digit am;
29271 
29272     (void)m;
29273     (void)mp;
29274 
29275     for (i = 0; i < 6; i++) {
29276         am = (a[i] * 0x100000001) & 0x7fffffffffffffL;
29277         a[i + 0] += (am << 32) & 0x7fffffffffffffL;
29278         a[i + 1] += (am >> 23) - ((am << 41) & 0x7fffffffffffffL);
29279         a[i + 2] += -(am >> 14) - ((am << 18) & 0x7fffffffffffffL);
29280         a[i + 3] += -(am >> 37);
29281         a[i + 6] += (am << 54) & 0x7fffffffffffffL;
29282         a[i + 7] += am >> 1;
29283 
29284         a[i+1] += a[i] >> 55;
29285     }
29286     am = (a[6] * 0x100000001) & 0x3fffffffffffff;
29287     a[6 + 0] += (am << 32) & 0x7fffffffffffffL;
29288     a[6 + 1] += (am >> 23) - ((am << 41) & 0x7fffffffffffffL);
29289     a[6 + 2] += -(am >> 14) - ((am << 18) & 0x7fffffffffffffL);
29290     a[6 + 3] += -(am >> 37);
29291     a[6 + 6] += (am << 54) & 0x7fffffffffffffL;
29292     a[6 + 7] += am >> 1;
29293 
29294     a[0] = (a[6] >> 54) + ((a[7] << 1) & 0x7fffffffffffffL);
29295     a[1] = (a[7] >> 54) + ((a[8] << 1) & 0x7fffffffffffffL);
29296     a[2] = (a[8] >> 54) + ((a[9] << 1) & 0x7fffffffffffffL);
29297     a[3] = (a[9] >> 54) + ((a[10] << 1) & 0x7fffffffffffffL);
29298     a[4] = (a[10] >> 54) + ((a[11] << 1) & 0x7fffffffffffffL);
29299     a[5] = (a[11] >> 54) + ((a[12] << 1) & 0x7fffffffffffffL);
29300     a[6] = (a[12] >> 54) +  (a[13] << 1);
29301 
29302     /* Get the bit over, if any. */
29303     am = a[6] >> 54;
29304     /* Create mask. */
29305     am = 0 - am;
29306 
29307     a[0] -= 0x00000000ffffffffL & am;
29308     a[1] -= 0x007ffe0000000000L & am;
29309     a[2] -= 0x007ffffffffbffffL & am;
29310     a[3] -= 0x007fffffffffffffL & am;
29311     a[4] -= 0x007fffffffffffffL & am;
29312     a[5] -= 0x007fffffffffffffL & am;
29313     a[6] -= 0x003fffffffffffffL & am;
29314 
29315     sp_384_norm_7(a);
29316 }
29317 
29318 /* Multiply two Montgomery form numbers mod the modulus (prime).
29319  * (r = a * b mod m)
29320  *
29321  * r   Result of multiplication.
29322  * a   First number to multiply in Montgomery form.
29323  * b   Second number to multiply in Montgomery form.
29324  * m   Modulus (prime).
29325  * mp  Montgomery mulitplier.
29326  */
sp_384_mont_mul_7(sp_digit * r,const sp_digit * a,const sp_digit * b,const sp_digit * m,sp_digit mp)29327 static void sp_384_mont_mul_7(sp_digit* r, const sp_digit* a,
29328         const sp_digit* b, const sp_digit* m, sp_digit mp)
29329 {
29330     sp_384_mul_7(r, a, b);
29331     sp_384_mont_reduce_7(r, m, mp);
29332 }
29333 
29334 /* Square the Montgomery form number. (r = a * a mod m)
29335  *
29336  * r   Result of squaring.
29337  * a   Number to square in Montgomery form.
29338  * m   Modulus (prime).
29339  * mp  Montgomery mulitplier.
29340  */
sp_384_mont_sqr_7(sp_digit * r,const sp_digit * a,const sp_digit * m,sp_digit mp)29341 static void sp_384_mont_sqr_7(sp_digit* r, const sp_digit* a,
29342         const sp_digit* m, sp_digit mp)
29343 {
29344     sp_384_sqr_7(r, a);
29345     sp_384_mont_reduce_7(r, m, mp);
29346 }
29347 
29348 #if !defined(WOLFSSL_SP_SMALL) || defined(HAVE_COMP_KEY)
29349 /* Square the Montgomery form number a number of times. (r = a ^ n mod m)
29350  *
29351  * r   Result of squaring.
29352  * a   Number to square in Montgomery form.
29353  * n   Number of times to square.
29354  * m   Modulus (prime).
29355  * mp  Montgomery mulitplier.
29356  */
sp_384_mont_sqr_n_7(sp_digit * r,const sp_digit * a,int n,const sp_digit * m,sp_digit mp)29357 static void sp_384_mont_sqr_n_7(sp_digit* r, const sp_digit* a, int n,
29358         const sp_digit* m, sp_digit mp)
29359 {
29360     sp_384_mont_sqr_7(r, a, m, mp);
29361     for (; n > 1; n--) {
29362         sp_384_mont_sqr_7(r, r, m, mp);
29363     }
29364 }
29365 
29366 #endif /* !WOLFSSL_SP_SMALL | HAVE_COMP_KEY */
29367 #ifdef WOLFSSL_SP_SMALL
29368 /* Mod-2 for the P384 curve. */
29369 static const uint64_t p384_mod_minus_2[6] = {
29370     0x00000000fffffffdU,0xffffffff00000000U,0xfffffffffffffffeU,
29371     0xffffffffffffffffU,0xffffffffffffffffU,0xffffffffffffffffU
29372 };
29373 #endif /* !WOLFSSL_SP_SMALL */
29374 
29375 /* Invert the number, in Montgomery form, modulo the modulus (prime) of the
29376  * P384 curve. (r = 1 / a mod m)
29377  *
29378  * r   Inverse result.
29379  * a   Number to invert.
29380  * td  Temporary data.
29381  */
sp_384_mont_inv_7(sp_digit * r,const sp_digit * a,sp_digit * td)29382 static void sp_384_mont_inv_7(sp_digit* r, const sp_digit* a, sp_digit* td)
29383 {
29384 #ifdef WOLFSSL_SP_SMALL
29385     sp_digit* t = td;
29386     int i;
29387 
29388     XMEMCPY(t, a, sizeof(sp_digit) * 7);
29389     for (i=382; i>=0; i--) {
29390         sp_384_mont_sqr_7(t, t, p384_mod, p384_mp_mod);
29391         if (p384_mod_minus_2[i / 64] & ((sp_digit)1 << (i % 64)))
29392             sp_384_mont_mul_7(t, t, a, p384_mod, p384_mp_mod);
29393     }
29394     XMEMCPY(r, t, sizeof(sp_digit) * 7);
29395 #else
29396     sp_digit* t1 = td;
29397     sp_digit* t2 = td + 2 * 7;
29398     sp_digit* t3 = td + 4 * 7;
29399     sp_digit* t4 = td + 6 * 7;
29400     sp_digit* t5 = td + 8 * 7;
29401 
29402     /* 0x2 */
29403     sp_384_mont_sqr_7(t1, a, p384_mod, p384_mp_mod);
29404     /* 0x3 */
29405     sp_384_mont_mul_7(t5, t1, a, p384_mod, p384_mp_mod);
29406     /* 0xc */
29407     sp_384_mont_sqr_n_7(t1, t5, 2, p384_mod, p384_mp_mod);
29408     /* 0xf */
29409     sp_384_mont_mul_7(t2, t5, t1, p384_mod, p384_mp_mod);
29410     /* 0x1e */
29411     sp_384_mont_sqr_7(t1, t2, p384_mod, p384_mp_mod);
29412     /* 0x1f */
29413     sp_384_mont_mul_7(t4, t1, a, p384_mod, p384_mp_mod);
29414     /* 0x3e0 */
29415     sp_384_mont_sqr_n_7(t1, t4, 5, p384_mod, p384_mp_mod);
29416     /* 0x3ff */
29417     sp_384_mont_mul_7(t2, t4, t1, p384_mod, p384_mp_mod);
29418     /* 0x7fe0 */
29419     sp_384_mont_sqr_n_7(t1, t2, 5, p384_mod, p384_mp_mod);
29420     /* 0x7fff */
29421     sp_384_mont_mul_7(t4, t4, t1, p384_mod, p384_mp_mod);
29422     /* 0x3fff8000 */
29423     sp_384_mont_sqr_n_7(t1, t4, 15, p384_mod, p384_mp_mod);
29424     /* 0x3fffffff */
29425     sp_384_mont_mul_7(t2, t4, t1, p384_mod, p384_mp_mod);
29426     /* 0xfffffffc */
29427     sp_384_mont_sqr_n_7(t3, t2, 2, p384_mod, p384_mp_mod);
29428     /* 0xfffffffd */
29429     sp_384_mont_mul_7(r, t3, a, p384_mod, p384_mp_mod);
29430     /* 0xffffffff */
29431     sp_384_mont_mul_7(t3, t5, t3, p384_mod, p384_mp_mod);
29432     /* 0xfffffffc0000000 */
29433     sp_384_mont_sqr_n_7(t1, t2, 30, p384_mod, p384_mp_mod);
29434     /* 0xfffffffffffffff */
29435     sp_384_mont_mul_7(t2, t2, t1, p384_mod, p384_mp_mod);
29436     /* 0xfffffffffffffff000000000000000 */
29437     sp_384_mont_sqr_n_7(t1, t2, 60, p384_mod, p384_mp_mod);
29438     /* 0xffffffffffffffffffffffffffffff */
29439     sp_384_mont_mul_7(t2, t2, t1, p384_mod, p384_mp_mod);
29440     /* 0xffffffffffffffffffffffffffffff000000000000000000000000000000 */
29441     sp_384_mont_sqr_n_7(t1, t2, 120, p384_mod, p384_mp_mod);
29442     /* 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff */
29443     sp_384_mont_mul_7(t2, t2, t1, p384_mod, p384_mp_mod);
29444     /* 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8000 */
29445     sp_384_mont_sqr_n_7(t1, t2, 15, p384_mod, p384_mp_mod);
29446     /* 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff */
29447     sp_384_mont_mul_7(t2, t4, t1, p384_mod, p384_mp_mod);
29448     /* 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe00000000 */
29449     sp_384_mont_sqr_n_7(t1, t2, 33, p384_mod, p384_mp_mod);
29450     /* 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff */
29451     sp_384_mont_mul_7(t2, t3, t1, p384_mod, p384_mp_mod);
29452     /* 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff000000000000000000000000 */
29453     sp_384_mont_sqr_n_7(t1, t2, 96, p384_mod, p384_mp_mod);
29454     /* 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff0000000000000000fffffffd */
29455     sp_384_mont_mul_7(r, r, t1, p384_mod, p384_mp_mod);
29456 
29457 #endif /* WOLFSSL_SP_SMALL */
29458 }
29459 
29460 /* Map the Montgomery form projective coordinate point to an affine point.
29461  *
29462  * r  Resulting affine coordinate point.
29463  * p  Montgomery form projective coordinate point.
29464  * t  Temporary ordinate data.
29465  */
sp_384_map_7(sp_point_384 * r,const sp_point_384 * p,sp_digit * t)29466 static void sp_384_map_7(sp_point_384* r, const sp_point_384* p,
29467     sp_digit* t)
29468 {
29469     sp_digit* t1 = t;
29470     sp_digit* t2 = t + 2*7;
29471     sp_int64 n;
29472 
29473     sp_384_mont_inv_7(t1, p->z, t + 2*7);
29474 
29475     sp_384_mont_sqr_7(t2, t1, p384_mod, p384_mp_mod);
29476     sp_384_mont_mul_7(t1, t2, t1, p384_mod, p384_mp_mod);
29477 
29478     /* x /= z^2 */
29479     sp_384_mont_mul_7(r->x, p->x, t2, p384_mod, p384_mp_mod);
29480     XMEMSET(r->x + 7, 0, sizeof(r->x) / 2U);
29481     sp_384_mont_reduce_7(r->x, p384_mod, p384_mp_mod);
29482     /* Reduce x to less than modulus */
29483     n = sp_384_cmp_7(r->x, p384_mod);
29484     sp_384_cond_sub_7(r->x, r->x, p384_mod, 0 - ((n >= 0) ?
29485                 (sp_digit)1 : (sp_digit)0));
29486     sp_384_norm_7(r->x);
29487 
29488     /* y /= z^3 */
29489     sp_384_mont_mul_7(r->y, p->y, t1, p384_mod, p384_mp_mod);
29490     XMEMSET(r->y + 7, 0, sizeof(r->y) / 2U);
29491     sp_384_mont_reduce_7(r->y, p384_mod, p384_mp_mod);
29492     /* Reduce y to less than modulus */
29493     n = sp_384_cmp_7(r->y, p384_mod);
29494     sp_384_cond_sub_7(r->y, r->y, p384_mod, 0 - ((n >= 0) ?
29495                 (sp_digit)1 : (sp_digit)0));
29496     sp_384_norm_7(r->y);
29497 
29498     XMEMSET(r->z, 0, sizeof(r->z));
29499     r->z[0] = 1;
29500 
29501 }
29502 
29503 /* Add two Montgomery form numbers (r = a + b % m).
29504  *
29505  * r   Result of addition.
29506  * a   First number to add in Montgomery form.
29507  * b   Second number to add in Montgomery form.
29508  * m   Modulus (prime).
29509  */
sp_384_mont_add_7(sp_digit * r,const sp_digit * a,const sp_digit * b,const sp_digit * m)29510 static void sp_384_mont_add_7(sp_digit* r, const sp_digit* a, const sp_digit* b,
29511         const sp_digit* m)
29512 {
29513     (void)sp_384_add_7(r, a, b);
29514     sp_384_norm_7(r);
29515     sp_384_cond_sub_7(r, r, m, 0 - (((r[6] >> 54) > 0) ?
29516                 (sp_digit)1 : (sp_digit)0));
29517     sp_384_norm_7(r);
29518 }
29519 
29520 /* Double a Montgomery form number (r = a + a % m).
29521  *
29522  * r   Result of doubling.
29523  * a   Number to double in Montgomery form.
29524  * m   Modulus (prime).
29525  */
sp_384_mont_dbl_7(sp_digit * r,const sp_digit * a,const sp_digit * m)29526 static void sp_384_mont_dbl_7(sp_digit* r, const sp_digit* a, const sp_digit* m)
29527 {
29528     (void)sp_384_add_7(r, a, a);
29529     sp_384_norm_7(r);
29530     sp_384_cond_sub_7(r, r, m, 0 - (((r[6] >> 54) > 0) ?
29531                 (sp_digit)1 : (sp_digit)0));
29532     sp_384_norm_7(r);
29533 }
29534 
29535 /* Triple a Montgomery form number (r = a + a + a % m).
29536  *
29537  * r   Result of Tripling.
29538  * a   Number to triple in Montgomery form.
29539  * m   Modulus (prime).
29540  */
sp_384_mont_tpl_7(sp_digit * r,const sp_digit * a,const sp_digit * m)29541 static void sp_384_mont_tpl_7(sp_digit* r, const sp_digit* a, const sp_digit* m)
29542 {
29543     (void)sp_384_add_7(r, a, a);
29544     sp_384_norm_7(r);
29545     sp_384_cond_sub_7(r, r, m, 0 - (((r[6] >> 54) > 0) ?
29546                 (sp_digit)1 : (sp_digit)0));
29547     sp_384_norm_7(r);
29548     (void)sp_384_add_7(r, r, a);
29549     sp_384_norm_7(r);
29550     sp_384_cond_sub_7(r, r, m, 0 - (((r[6] >> 54) > 0) ?
29551                 (sp_digit)1 : (sp_digit)0));
29552     sp_384_norm_7(r);
29553 }
29554 
29555 /* Conditionally add a and b using the mask m.
29556  * m is -1 to add and 0 when not.
29557  *
29558  * r  A single precision number representing conditional add result.
29559  * a  A single precision number to add with.
29560  * b  A single precision number to add.
29561  * m  Mask value to apply.
29562  */
sp_384_cond_add_7(sp_digit * r,const sp_digit * a,const sp_digit * b,const sp_digit m)29563 static void sp_384_cond_add_7(sp_digit* r, const sp_digit* a,
29564         const sp_digit* b, const sp_digit m)
29565 {
29566 #ifdef WOLFSSL_SP_SMALL
29567     int i;
29568 
29569     for (i = 0; i < 7; i++) {
29570         r[i] = a[i] + (b[i] & m);
29571     }
29572 #else
29573     r[ 0] = a[ 0] + (b[ 0] & m);
29574     r[ 1] = a[ 1] + (b[ 1] & m);
29575     r[ 2] = a[ 2] + (b[ 2] & m);
29576     r[ 3] = a[ 3] + (b[ 3] & m);
29577     r[ 4] = a[ 4] + (b[ 4] & m);
29578     r[ 5] = a[ 5] + (b[ 5] & m);
29579     r[ 6] = a[ 6] + (b[ 6] & m);
29580 #endif /* WOLFSSL_SP_SMALL */
29581 }
29582 
29583 /* Subtract two Montgomery form numbers (r = a - b % m).
29584  *
29585  * r   Result of subtration.
29586  * a   Number to subtract from in Montgomery form.
29587  * b   Number to subtract with in Montgomery form.
29588  * m   Modulus (prime).
29589  */
sp_384_mont_sub_7(sp_digit * r,const sp_digit * a,const sp_digit * b,const sp_digit * m)29590 static void sp_384_mont_sub_7(sp_digit* r, const sp_digit* a, const sp_digit* b,
29591         const sp_digit* m)
29592 {
29593     (void)sp_384_sub_7(r, a, b);
29594     sp_384_norm_7(r);
29595     sp_384_cond_add_7(r, r, m, r[6] >> 54);
29596     sp_384_norm_7(r);
29597 }
29598 
29599 /* Shift number left one bit.
29600  * Bottom bit is lost.
29601  *
29602  * r  Result of shift.
29603  * a  Number to shift.
29604  */
sp_384_rshift1_7(sp_digit * r,const sp_digit * a)29605 SP_NOINLINE static void sp_384_rshift1_7(sp_digit* r, const sp_digit* a)
29606 {
29607 #ifdef WOLFSSL_SP_SMALL
29608     int i;
29609 
29610     for (i=0; i<6; i++) {
29611         r[i] = (a[i] >> 1) + ((a[i + 1] << 54) & 0x7fffffffffffffL);
29612     }
29613 #else
29614     r[0] = (a[0] >> 1) + ((a[1] << 54) & 0x7fffffffffffffL);
29615     r[1] = (a[1] >> 1) + ((a[2] << 54) & 0x7fffffffffffffL);
29616     r[2] = (a[2] >> 1) + ((a[3] << 54) & 0x7fffffffffffffL);
29617     r[3] = (a[3] >> 1) + ((a[4] << 54) & 0x7fffffffffffffL);
29618     r[4] = (a[4] >> 1) + ((a[5] << 54) & 0x7fffffffffffffL);
29619     r[5] = (a[5] >> 1) + ((a[6] << 54) & 0x7fffffffffffffL);
29620 #endif
29621     r[6] = a[6] >> 1;
29622 }
29623 
29624 /* Divide the number by 2 mod the modulus (prime). (r = a / 2 % m)
29625  *
29626  * r  Result of division by 2.
29627  * a  Number to divide.
29628  * m  Modulus (prime).
29629  */
sp_384_div2_7(sp_digit * r,const sp_digit * a,const sp_digit * m)29630 static void sp_384_div2_7(sp_digit* r, const sp_digit* a, const sp_digit* m)
29631 {
29632     sp_384_cond_add_7(r, a, m, 0 - (a[0] & 1));
29633     sp_384_norm_7(r);
29634     sp_384_rshift1_7(r, r);
29635 }
29636 
29637 /* Double the Montgomery form projective point p.
29638  *
29639  * r  Result of doubling point.
29640  * p  Point to double.
29641  * t  Temporary ordinate data.
29642  */
29643 #ifdef WOLFSSL_SP_NONBLOCK
29644 typedef struct sp_384_proj_point_dbl_7_ctx {
29645     int state;
29646     sp_digit* t1;
29647     sp_digit* t2;
29648     sp_digit* x;
29649     sp_digit* y;
29650     sp_digit* z;
29651 } sp_384_proj_point_dbl_7_ctx;
29652 
sp_384_proj_point_dbl_7_nb(sp_ecc_ctx_t * sp_ctx,sp_point_384 * r,const sp_point_384 * p,sp_digit * t)29653 static int sp_384_proj_point_dbl_7_nb(sp_ecc_ctx_t* sp_ctx, sp_point_384* r, const sp_point_384* p, sp_digit* t)
29654 {
29655     int err = FP_WOULDBLOCK;
29656     sp_384_proj_point_dbl_7_ctx* ctx = (sp_384_proj_point_dbl_7_ctx*)sp_ctx->data;
29657 
29658     typedef char ctx_size_test[sizeof(sp_384_proj_point_dbl_7_ctx) >= sizeof(*sp_ctx) ? -1 : 1];
29659     (void)sizeof(ctx_size_test);
29660 
29661     switch (ctx->state) {
29662     case 0:
29663         ctx->t1 = t;
29664         ctx->t2 = t + 2*7;
29665         ctx->x = r->x;
29666         ctx->y = r->y;
29667         ctx->z = r->z;
29668 
29669         /* Put infinity into result. */
29670         if (r != p) {
29671             r->infinity = p->infinity;
29672         }
29673         ctx->state = 1;
29674         break;
29675     case 1:
29676         /* T1 = Z * Z */
29677         sp_384_mont_sqr_7(ctx->t1, p->z, p384_mod, p384_mp_mod);
29678         ctx->state = 2;
29679         break;
29680     case 2:
29681         /* Z = Y * Z */
29682         sp_384_mont_mul_7(ctx->z, p->y, p->z, p384_mod, p384_mp_mod);
29683         ctx->state = 3;
29684         break;
29685     case 3:
29686         /* Z = 2Z */
29687         sp_384_mont_dbl_7(ctx->z, ctx->z, p384_mod);
29688         ctx->state = 4;
29689         break;
29690     case 4:
29691         /* T2 = X - T1 */
29692         sp_384_mont_sub_7(ctx->t2, p->x, ctx->t1, p384_mod);
29693         ctx->state = 5;
29694         break;
29695     case 5:
29696         /* T1 = X + T1 */
29697         sp_384_mont_add_7(ctx->t1, p->x, ctx->t1, p384_mod);
29698         ctx->state = 6;
29699         break;
29700     case 6:
29701         /* T2 = T1 * T2 */
29702         sp_384_mont_mul_7(ctx->t2, ctx->t1, ctx->t2, p384_mod, p384_mp_mod);
29703         ctx->state = 7;
29704         break;
29705     case 7:
29706         /* T1 = 3T2 */
29707         sp_384_mont_tpl_7(ctx->t1, ctx->t2, p384_mod);
29708         ctx->state = 8;
29709         break;
29710     case 8:
29711         /* Y = 2Y */
29712         sp_384_mont_dbl_7(ctx->y, p->y, p384_mod);
29713         ctx->state = 9;
29714         break;
29715     case 9:
29716         /* Y = Y * Y */
29717         sp_384_mont_sqr_7(ctx->y, ctx->y, p384_mod, p384_mp_mod);
29718         ctx->state = 10;
29719         break;
29720     case 10:
29721         /* T2 = Y * Y */
29722         sp_384_mont_sqr_7(ctx->t2, ctx->y, p384_mod, p384_mp_mod);
29723         ctx->state = 11;
29724         break;
29725     case 11:
29726         /* T2 = T2/2 */
29727         sp_384_div2_7(ctx->t2, ctx->t2, p384_mod);
29728         ctx->state = 12;
29729         break;
29730     case 12:
29731         /* Y = Y * X */
29732         sp_384_mont_mul_7(ctx->y, ctx->y, p->x, p384_mod, p384_mp_mod);
29733         ctx->state = 13;
29734         break;
29735     case 13:
29736         /* X = T1 * T1 */
29737         sp_384_mont_sqr_7(ctx->x, ctx->t1, p384_mod, p384_mp_mod);
29738         ctx->state = 14;
29739         break;
29740     case 14:
29741         /* X = X - Y */
29742         sp_384_mont_sub_7(ctx->x, ctx->x, ctx->y, p384_mod);
29743         ctx->state = 15;
29744         break;
29745     case 15:
29746         /* X = X - Y */
29747         sp_384_mont_sub_7(ctx->x, ctx->x, ctx->y, p384_mod);
29748         ctx->state = 16;
29749         break;
29750     case 16:
29751         /* Y = Y - X */
29752         sp_384_mont_sub_7(ctx->y, ctx->y, ctx->x, p384_mod);
29753         ctx->state = 17;
29754         break;
29755     case 17:
29756         /* Y = Y * T1 */
29757         sp_384_mont_mul_7(ctx->y, ctx->y, ctx->t1, p384_mod, p384_mp_mod);
29758         ctx->state = 18;
29759         break;
29760     case 18:
29761         /* Y = Y - T2 */
29762         sp_384_mont_sub_7(ctx->y, ctx->y, ctx->t2, p384_mod);
29763         ctx->state = 19;
29764         /* fall-through */
29765     case 19:
29766         err = MP_OKAY;
29767         break;
29768     }
29769 
29770     if (err == MP_OKAY && ctx->state != 19) {
29771         err = FP_WOULDBLOCK;
29772     }
29773 
29774     return err;
29775 }
29776 #endif /* WOLFSSL_SP_NONBLOCK */
29777 
sp_384_proj_point_dbl_7(sp_point_384 * r,const sp_point_384 * p,sp_digit * t)29778 static void sp_384_proj_point_dbl_7(sp_point_384* r, const sp_point_384* p, sp_digit* t)
29779 {
29780     sp_digit* t1 = t;
29781     sp_digit* t2 = t + 2*7;
29782     sp_digit* x;
29783     sp_digit* y;
29784     sp_digit* z;
29785 
29786     x = r->x;
29787     y = r->y;
29788     z = r->z;
29789     /* Put infinity into result. */
29790     if (r != p) {
29791         r->infinity = p->infinity;
29792     }
29793 
29794     /* T1 = Z * Z */
29795     sp_384_mont_sqr_7(t1, p->z, p384_mod, p384_mp_mod);
29796     /* Z = Y * Z */
29797     sp_384_mont_mul_7(z, p->y, p->z, p384_mod, p384_mp_mod);
29798     /* Z = 2Z */
29799     sp_384_mont_dbl_7(z, z, p384_mod);
29800     /* T2 = X - T1 */
29801     sp_384_mont_sub_7(t2, p->x, t1, p384_mod);
29802     /* T1 = X + T1 */
29803     sp_384_mont_add_7(t1, p->x, t1, p384_mod);
29804     /* T2 = T1 * T2 */
29805     sp_384_mont_mul_7(t2, t1, t2, p384_mod, p384_mp_mod);
29806     /* T1 = 3T2 */
29807     sp_384_mont_tpl_7(t1, t2, p384_mod);
29808     /* Y = 2Y */
29809     sp_384_mont_dbl_7(y, p->y, p384_mod);
29810     /* Y = Y * Y */
29811     sp_384_mont_sqr_7(y, y, p384_mod, p384_mp_mod);
29812     /* T2 = Y * Y */
29813     sp_384_mont_sqr_7(t2, y, p384_mod, p384_mp_mod);
29814     /* T2 = T2/2 */
29815     sp_384_div2_7(t2, t2, p384_mod);
29816     /* Y = Y * X */
29817     sp_384_mont_mul_7(y, y, p->x, p384_mod, p384_mp_mod);
29818     /* X = T1 * T1 */
29819     sp_384_mont_sqr_7(x, t1, p384_mod, p384_mp_mod);
29820     /* X = X - Y */
29821     sp_384_mont_sub_7(x, x, y, p384_mod);
29822     /* X = X - Y */
29823     sp_384_mont_sub_7(x, x, y, p384_mod);
29824     /* Y = Y - X */
29825     sp_384_mont_sub_7(y, y, x, p384_mod);
29826     /* Y = Y * T1 */
29827     sp_384_mont_mul_7(y, y, t1, p384_mod, p384_mp_mod);
29828     /* Y = Y - T2 */
29829     sp_384_mont_sub_7(y, y, t2, p384_mod);
29830 }
29831 
29832 /* Compare two numbers to determine if they are equal.
29833  * Constant time implementation.
29834  *
29835  * a  First number to compare.
29836  * b  Second number to compare.
29837  * returns 1 when equal and 0 otherwise.
29838  */
sp_384_cmp_equal_7(const sp_digit * a,const sp_digit * b)29839 static int sp_384_cmp_equal_7(const sp_digit* a, const sp_digit* b)
29840 {
29841     return ((a[0] ^ b[0]) | (a[1] ^ b[1]) | (a[2] ^ b[2]) |
29842             (a[3] ^ b[3]) | (a[4] ^ b[4]) | (a[5] ^ b[5]) |
29843             (a[6] ^ b[6])) == 0;
29844 }
29845 
29846 /* Add two Montgomery form projective points.
29847  *
29848  * r  Result of addition.
29849  * p  First point to add.
29850  * q  Second point to add.
29851  * t  Temporary ordinate data.
29852  */
29853 
29854 #ifdef WOLFSSL_SP_NONBLOCK
29855 typedef struct sp_384_proj_point_add_7_ctx {
29856     int state;
29857     sp_384_proj_point_dbl_7_ctx dbl_ctx;
29858     const sp_point_384* ap[2];
29859     sp_point_384* rp[2];
29860     sp_digit* t1;
29861     sp_digit* t2;
29862     sp_digit* t3;
29863     sp_digit* t4;
29864     sp_digit* t5;
29865     sp_digit* x;
29866     sp_digit* y;
29867     sp_digit* z;
29868 } sp_384_proj_point_add_7_ctx;
29869 
sp_384_proj_point_add_7_nb(sp_ecc_ctx_t * sp_ctx,sp_point_384 * r,const sp_point_384 * p,const sp_point_384 * q,sp_digit * t)29870 static int sp_384_proj_point_add_7_nb(sp_ecc_ctx_t* sp_ctx, sp_point_384* r,
29871     const sp_point_384* p, const sp_point_384* q, sp_digit* t)
29872 {
29873     int err = FP_WOULDBLOCK;
29874     sp_384_proj_point_add_7_ctx* ctx = (sp_384_proj_point_add_7_ctx*)sp_ctx->data;
29875 
29876     /* Ensure only the first point is the same as the result. */
29877     if (q == r) {
29878         const sp_point_384* a = p;
29879         p = q;
29880         q = a;
29881     }
29882 
29883     typedef char ctx_size_test[sizeof(sp_384_proj_point_add_7_ctx) >= sizeof(*sp_ctx) ? -1 : 1];
29884     (void)sizeof(ctx_size_test);
29885 
29886     switch (ctx->state) {
29887     case 0: /* INIT */
29888         ctx->t1 = t;
29889         ctx->t2 = t + 2*7;
29890         ctx->t3 = t + 4*7;
29891         ctx->t4 = t + 6*7;
29892         ctx->t5 = t + 8*7;
29893 
29894         ctx->state = 1;
29895         break;
29896     case 1:
29897         /* Check double */
29898         (void)sp_384_sub_7(ctx->t1, p384_mod, q->y);
29899         sp_384_norm_7(ctx->t1);
29900         if ((sp_384_cmp_equal_7(p->x, q->x) & sp_384_cmp_equal_7(p->z, q->z) &
29901             (sp_384_cmp_equal_7(p->y, q->y) | sp_384_cmp_equal_7(p->y, ctx->t1))) != 0)
29902         {
29903             XMEMSET(&ctx->dbl_ctx, 0, sizeof(ctx->dbl_ctx));
29904             ctx->state = 2;
29905         }
29906         else {
29907             ctx->state = 3;
29908         }
29909         break;
29910     case 2:
29911         err = sp_384_proj_point_dbl_7_nb((sp_ecc_ctx_t*)&ctx->dbl_ctx, r, p, t);
29912         if (err == MP_OKAY)
29913             ctx->state = 27; /* done */
29914         break;
29915     case 3:
29916     {
29917         int i;
29918         ctx->rp[0] = r;
29919 
29920         /*lint allow cast to different type of pointer*/
29921         ctx->rp[1] = (sp_point_384*)t; /*lint !e9087 !e740*/
29922         XMEMSET(ctx->rp[1], 0, sizeof(sp_point_384));
29923         ctx->x = ctx->rp[p->infinity | q->infinity]->x;
29924         ctx->y = ctx->rp[p->infinity | q->infinity]->y;
29925         ctx->z = ctx->rp[p->infinity | q->infinity]->z;
29926 
29927         ctx->ap[0] = p;
29928         ctx->ap[1] = q;
29929         for (i=0; i<7; i++) {
29930             r->x[i] = ctx->ap[p->infinity]->x[i];
29931         }
29932         for (i=0; i<7; i++) {
29933             r->y[i] = ctx->ap[p->infinity]->y[i];
29934         }
29935         for (i=0; i<7; i++) {
29936             r->z[i] = ctx->ap[p->infinity]->z[i];
29937         }
29938         r->infinity = ctx->ap[p->infinity]->infinity;
29939 
29940         ctx->state = 4;
29941         break;
29942     }
29943     case 4:
29944         /* U1 = X1*Z2^2 */
29945         sp_384_mont_sqr_7(ctx->t1, q->z, p384_mod, p384_mp_mod);
29946         ctx->state = 5;
29947         break;
29948     case 5:
29949         sp_384_mont_mul_7(ctx->t3, ctx->t1, q->z, p384_mod, p384_mp_mod);
29950         ctx->state = 6;
29951         break;
29952     case 6:
29953         sp_384_mont_mul_7(ctx->t1, ctx->t1, ctx->x, p384_mod, p384_mp_mod);
29954         ctx->state = 7;
29955         break;
29956     case 7:
29957         /* U2 = X2*Z1^2 */
29958         sp_384_mont_sqr_7(ctx->t2, ctx->z, p384_mod, p384_mp_mod);
29959         ctx->state = 8;
29960         break;
29961     case 8:
29962         sp_384_mont_mul_7(ctx->t4, ctx->t2, ctx->z, p384_mod, p384_mp_mod);
29963         ctx->state = 9;
29964         break;
29965     case 9:
29966         sp_384_mont_mul_7(ctx->t2, ctx->t2, q->x, p384_mod, p384_mp_mod);
29967         ctx->state = 10;
29968         break;
29969     case 10:
29970         /* S1 = Y1*Z2^3 */
29971         sp_384_mont_mul_7(ctx->t3, ctx->t3, ctx->y, p384_mod, p384_mp_mod);
29972         ctx->state = 11;
29973         break;
29974     case 11:
29975         /* S2 = Y2*Z1^3 */
29976         sp_384_mont_mul_7(ctx->t4, ctx->t4, q->y, p384_mod, p384_mp_mod);
29977         ctx->state = 12;
29978         break;
29979     case 12:
29980         /* H = U2 - U1 */
29981         sp_384_mont_sub_7(ctx->t2, ctx->t2, ctx->t1, p384_mod);
29982         ctx->state = 13;
29983         break;
29984     case 13:
29985         /* R = S2 - S1 */
29986         sp_384_mont_sub_7(ctx->t4, ctx->t4, ctx->t3, p384_mod);
29987         ctx->state = 14;
29988         break;
29989     case 14:
29990         /* Z3 = H*Z1*Z2 */
29991         sp_384_mont_mul_7(ctx->z, ctx->z, q->z, p384_mod, p384_mp_mod);
29992         ctx->state = 15;
29993         break;
29994     case 15:
29995         sp_384_mont_mul_7(ctx->z, ctx->z, ctx->t2, p384_mod, p384_mp_mod);
29996         ctx->state = 16;
29997         break;
29998     case 16:
29999         /* X3 = R^2 - H^3 - 2*U1*H^2 */
30000         sp_384_mont_sqr_7(ctx->x, ctx->t4, p384_mod, p384_mp_mod);
30001         ctx->state = 17;
30002         break;
30003     case 17:
30004         sp_384_mont_sqr_7(ctx->t5, ctx->t2, p384_mod, p384_mp_mod);
30005         ctx->state = 18;
30006         break;
30007     case 18:
30008         sp_384_mont_mul_7(ctx->y, ctx->t1, ctx->t5, p384_mod, p384_mp_mod);
30009         ctx->state = 19;
30010         break;
30011     case 19:
30012         sp_384_mont_mul_7(ctx->t5, ctx->t5, ctx->t2, p384_mod, p384_mp_mod);
30013         ctx->state = 20;
30014         break;
30015     case 20:
30016         sp_384_mont_sub_7(ctx->x, ctx->x, ctx->t5, p384_mod);
30017         ctx->state = 21;
30018         break;
30019     case 21:
30020         sp_384_mont_dbl_7(ctx->t1, ctx->y, p384_mod);
30021         ctx->state = 22;
30022         break;
30023     case 22:
30024         sp_384_mont_sub_7(ctx->x, ctx->x, ctx->t1, p384_mod);
30025         ctx->state = 23;
30026         break;
30027     case 23:
30028         /* Y3 = R*(U1*H^2 - X3) - S1*H^3 */
30029         sp_384_mont_sub_7(ctx->y, ctx->y, ctx->x, p384_mod);
30030         ctx->state = 24;
30031         break;
30032     case 24:
30033         sp_384_mont_mul_7(ctx->y, ctx->y, ctx->t4, p384_mod, p384_mp_mod);
30034         ctx->state = 25;
30035         break;
30036     case 25:
30037         sp_384_mont_mul_7(ctx->t5, ctx->t5, ctx->t3, p384_mod, p384_mp_mod);
30038         ctx->state = 26;
30039         break;
30040     case 26:
30041         sp_384_mont_sub_7(ctx->y, ctx->y, ctx->t5, p384_mod);
30042         ctx->state = 27;
30043         /* fall-through */
30044     case 27:
30045         err = MP_OKAY;
30046         break;
30047     }
30048 
30049     if (err == MP_OKAY && ctx->state != 27) {
30050         err = FP_WOULDBLOCK;
30051     }
30052     return err;
30053 }
30054 #endif /* WOLFSSL_SP_NONBLOCK */
30055 
sp_384_proj_point_add_7(sp_point_384 * r,const sp_point_384 * p,const sp_point_384 * q,sp_digit * t)30056 static void sp_384_proj_point_add_7(sp_point_384* r,
30057         const sp_point_384* p, const sp_point_384* q, sp_digit* t)
30058 {
30059     const sp_point_384* ap[2];
30060     sp_point_384* rp[2];
30061     sp_digit* t1 = t;
30062     sp_digit* t2 = t + 2*7;
30063     sp_digit* t3 = t + 4*7;
30064     sp_digit* t4 = t + 6*7;
30065     sp_digit* t5 = t + 8*7;
30066     sp_digit* x;
30067     sp_digit* y;
30068     sp_digit* z;
30069     int i;
30070 
30071     /* Ensure only the first point is the same as the result. */
30072     if (q == r) {
30073         const sp_point_384* a = p;
30074         p = q;
30075         q = a;
30076     }
30077 
30078     /* Check double */
30079     (void)sp_384_sub_7(t1, p384_mod, q->y);
30080     sp_384_norm_7(t1);
30081     if ((sp_384_cmp_equal_7(p->x, q->x) & sp_384_cmp_equal_7(p->z, q->z) &
30082         (sp_384_cmp_equal_7(p->y, q->y) | sp_384_cmp_equal_7(p->y, t1))) != 0) {
30083         sp_384_proj_point_dbl_7(r, p, t);
30084     }
30085     else {
30086         rp[0] = r;
30087 
30088         /*lint allow cast to different type of pointer*/
30089         rp[1] = (sp_point_384*)t; /*lint !e9087 !e740*/
30090         XMEMSET(rp[1], 0, sizeof(sp_point_384));
30091         x = rp[p->infinity | q->infinity]->x;
30092         y = rp[p->infinity | q->infinity]->y;
30093         z = rp[p->infinity | q->infinity]->z;
30094 
30095         ap[0] = p;
30096         ap[1] = q;
30097         for (i=0; i<7; i++) {
30098             r->x[i] = ap[p->infinity]->x[i];
30099         }
30100         for (i=0; i<7; i++) {
30101             r->y[i] = ap[p->infinity]->y[i];
30102         }
30103         for (i=0; i<7; i++) {
30104             r->z[i] = ap[p->infinity]->z[i];
30105         }
30106         r->infinity = ap[p->infinity]->infinity;
30107 
30108         /* U1 = X1*Z2^2 */
30109         sp_384_mont_sqr_7(t1, q->z, p384_mod, p384_mp_mod);
30110         sp_384_mont_mul_7(t3, t1, q->z, p384_mod, p384_mp_mod);
30111         sp_384_mont_mul_7(t1, t1, x, p384_mod, p384_mp_mod);
30112         /* U2 = X2*Z1^2 */
30113         sp_384_mont_sqr_7(t2, z, p384_mod, p384_mp_mod);
30114         sp_384_mont_mul_7(t4, t2, z, p384_mod, p384_mp_mod);
30115         sp_384_mont_mul_7(t2, t2, q->x, p384_mod, p384_mp_mod);
30116         /* S1 = Y1*Z2^3 */
30117         sp_384_mont_mul_7(t3, t3, y, p384_mod, p384_mp_mod);
30118         /* S2 = Y2*Z1^3 */
30119         sp_384_mont_mul_7(t4, t4, q->y, p384_mod, p384_mp_mod);
30120         /* H = U2 - U1 */
30121         sp_384_mont_sub_7(t2, t2, t1, p384_mod);
30122         /* R = S2 - S1 */
30123         sp_384_mont_sub_7(t4, t4, t3, p384_mod);
30124         /* Z3 = H*Z1*Z2 */
30125         sp_384_mont_mul_7(z, z, q->z, p384_mod, p384_mp_mod);
30126         sp_384_mont_mul_7(z, z, t2, p384_mod, p384_mp_mod);
30127         /* X3 = R^2 - H^3 - 2*U1*H^2 */
30128         sp_384_mont_sqr_7(x, t4, p384_mod, p384_mp_mod);
30129         sp_384_mont_sqr_7(t5, t2, p384_mod, p384_mp_mod);
30130         sp_384_mont_mul_7(y, t1, t5, p384_mod, p384_mp_mod);
30131         sp_384_mont_mul_7(t5, t5, t2, p384_mod, p384_mp_mod);
30132         sp_384_mont_sub_7(x, x, t5, p384_mod);
30133         sp_384_mont_dbl_7(t1, y, p384_mod);
30134         sp_384_mont_sub_7(x, x, t1, p384_mod);
30135         /* Y3 = R*(U1*H^2 - X3) - S1*H^3 */
30136         sp_384_mont_sub_7(y, y, x, p384_mod);
30137         sp_384_mont_mul_7(y, y, t4, p384_mod, p384_mp_mod);
30138         sp_384_mont_mul_7(t5, t5, t3, p384_mod, p384_mp_mod);
30139         sp_384_mont_sub_7(y, y, t5, p384_mod);
30140     }
30141 }
30142 
30143 /* Multiply a number by Montgomery normalizer mod modulus (prime).
30144  *
30145  * r  The resulting Montgomery form number.
30146  * a  The number to convert.
30147  * m  The modulus (prime).
30148  * returns MEMORY_E when memory allocation fails and MP_OKAY otherwise.
30149  */
sp_384_mod_mul_norm_7(sp_digit * r,const sp_digit * a,const sp_digit * m)30150 static int sp_384_mod_mul_norm_7(sp_digit* r, const sp_digit* a, const sp_digit* m)
30151 {
30152 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
30153     int64_t* t = NULL;
30154 #else
30155     int64_t t[2 * 12];
30156 #endif
30157     int64_t* a32 = NULL;
30158     int64_t o;
30159     int err = MP_OKAY;
30160 
30161     (void)m;
30162 
30163 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
30164     t = (int64_t*)XMALLOC(sizeof(int64_t) * 2 * 12, NULL, DYNAMIC_TYPE_ECC);
30165     if (t == NULL)
30166         err = MEMORY_E;
30167 #endif
30168 
30169     if (err == MP_OKAY) {
30170         a32 = t + 12;
30171 
30172         a32[0] = (sp_digit)(a[0]) & 0xffffffffL;
30173         a32[1] = (sp_digit)(a[0] >> 32U);
30174         a32[1] |= (sp_digit)(a[1] << 23U);
30175         a32[1] &= 0xffffffffL;
30176         a32[2] = (sp_digit)(a[1] >> 9U) & 0xffffffffL;
30177         a32[3] = (sp_digit)(a[1] >> 41U);
30178         a32[3] |= (sp_digit)(a[2] << 14U);
30179         a32[3] &= 0xffffffffL;
30180         a32[4] = (sp_digit)(a[2] >> 18U) & 0xffffffffL;
30181         a32[5] = (sp_digit)(a[2] >> 50U);
30182         a32[5] |= (sp_digit)(a[3] << 5U);
30183         a32[5] &= 0xffffffffL;
30184         a32[6] = (sp_digit)(a[3] >> 27U);
30185         a32[6] |= (sp_digit)(a[4] << 28U);
30186         a32[6] &= 0xffffffffL;
30187         a32[7] = (sp_digit)(a[4] >> 4U) & 0xffffffffL;
30188         a32[8] = (sp_digit)(a[4] >> 36U);
30189         a32[8] |= (sp_digit)(a[5] << 19U);
30190         a32[8] &= 0xffffffffL;
30191         a32[9] = (sp_digit)(a[5] >> 13U) & 0xffffffffL;
30192         a32[10] = (sp_digit)(a[5] >> 45U);
30193         a32[10] |= (sp_digit)(a[6] << 10U);
30194         a32[10] &= 0xffffffffL;
30195         a32[11] = (sp_digit)(a[6] >> 22U) & 0xffffffffL;
30196 
30197         /*  1  0  0  0  0  0  0  0  1  1  0 -1 */
30198         t[0] = 0 + a32[0] + a32[8] + a32[9] - a32[11];
30199         /* -1  1  0  0  0  0  0  0 -1  0  1  1 */
30200         t[1] = 0 - a32[0] + a32[1] - a32[8] + a32[10] + a32[11];
30201         /*  0 -1  1  0  0  0  0  0  0 -1  0  1 */
30202         t[2] = 0 - a32[1] + a32[2] - a32[9] + a32[11];
30203         /*  1  0 -1  1  0  0  0  0  1  1 -1 -1 */
30204         t[3] = 0 + a32[0] - a32[2] + a32[3] + a32[8] + a32[9] - a32[10] - a32[11];
30205         /*  1  1  0 -1  1  0  0  0  1  2  1 -2 */
30206         t[4] = 0 + a32[0] + a32[1] - a32[3] + a32[4] + a32[8] + 2 * a32[9] + a32[10] -  2 * a32[11];
30207         /*  0  1  1  0 -1  1  0  0  0  1  2  1 */
30208         t[5] = 0 + a32[1] + a32[2] - a32[4] + a32[5] + a32[9] + 2 * a32[10] + a32[11];
30209         /*  0  0  1  1  0 -1  1  0  0  0  1  2 */
30210         t[6] = 0 + a32[2] + a32[3] - a32[5] + a32[6] + a32[10] + 2 * a32[11];
30211         /*  0  0  0  1  1  0 -1  1  0  0  0  1 */
30212         t[7] = 0 + a32[3] + a32[4] - a32[6] + a32[7] + a32[11];
30213         /*  0  0  0  0  1  1  0 -1  1  0  0  0 */
30214         t[8] = 0 + a32[4] + a32[5] - a32[7] + a32[8];
30215         /*  0  0  0  0  0  1  1  0 -1  1  0  0 */
30216         t[9] = 0 + a32[5] + a32[6] - a32[8] + a32[9];
30217         /*  0  0  0  0  0  0  1  1  0 -1  1  0 */
30218         t[10] = 0 + a32[6] + a32[7] - a32[9] + a32[10];
30219         /*  0  0  0  0  0  0  0  1  1  0 -1  1 */
30220         t[11] = 0 + a32[7] + a32[8] - a32[10] + a32[11];
30221 
30222         t[1] += t[0] >> 32; t[0] &= 0xffffffff;
30223         t[2] += t[1] >> 32; t[1] &= 0xffffffff;
30224         t[3] += t[2] >> 32; t[2] &= 0xffffffff;
30225         t[4] += t[3] >> 32; t[3] &= 0xffffffff;
30226         t[5] += t[4] >> 32; t[4] &= 0xffffffff;
30227         t[6] += t[5] >> 32; t[5] &= 0xffffffff;
30228         t[7] += t[6] >> 32; t[6] &= 0xffffffff;
30229         t[8] += t[7] >> 32; t[7] &= 0xffffffff;
30230         t[9] += t[8] >> 32; t[8] &= 0xffffffff;
30231         t[10] += t[9] >> 32; t[9] &= 0xffffffff;
30232         t[11] += t[10] >> 32; t[10] &= 0xffffffff;
30233         o     = t[11] >> 32; t[11] &= 0xffffffff;
30234         t[0] += o;
30235         t[1] -= o;
30236         t[3] += o;
30237         t[4] += o;
30238         t[1] += t[0] >> 32; t[0] &= 0xffffffff;
30239         t[2] += t[1] >> 32; t[1] &= 0xffffffff;
30240         t[3] += t[2] >> 32; t[2] &= 0xffffffff;
30241         t[4] += t[3] >> 32; t[3] &= 0xffffffff;
30242         t[5] += t[4] >> 32; t[4] &= 0xffffffff;
30243         t[6] += t[5] >> 32; t[5] &= 0xffffffff;
30244         t[7] += t[6] >> 32; t[6] &= 0xffffffff;
30245         t[8] += t[7] >> 32; t[7] &= 0xffffffff;
30246         t[9] += t[8] >> 32; t[8] &= 0xffffffff;
30247         t[10] += t[9] >> 32; t[9] &= 0xffffffff;
30248         t[11] += t[10] >> 32; t[10] &= 0xffffffff;
30249 
30250         r[0] = t[0];
30251         r[0] |= t[1] << 32U;
30252         r[0] &= 0x7fffffffffffffLL;
30253         r[1] = (t[1] >> 23);
30254         r[1] |= t[2] << 9U;
30255         r[1] |= t[3] << 41U;
30256         r[1] &= 0x7fffffffffffffLL;
30257         r[2] = (t[3] >> 14);
30258         r[2] |= t[4] << 18U;
30259         r[2] |= t[5] << 50U;
30260         r[2] &= 0x7fffffffffffffLL;
30261         r[3] = (t[5] >> 5);
30262         r[3] |= t[6] << 27U;
30263         r[3] &= 0x7fffffffffffffLL;
30264         r[4] = (t[6] >> 28);
30265         r[4] |= t[7] << 4U;
30266         r[4] |= t[8] << 36U;
30267         r[4] &= 0x7fffffffffffffLL;
30268         r[5] = (t[8] >> 19);
30269         r[5] |= t[9] << 13U;
30270         r[5] |= t[10] << 45U;
30271         r[5] &= 0x7fffffffffffffLL;
30272         r[6] = (t[10] >> 10);
30273         r[6] |= t[11] << 22U;
30274     }
30275 
30276 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
30277     if (t != NULL)
30278         XFREE(t, NULL, DYNAMIC_TYPE_ECC);
30279 #endif
30280 
30281     return err;
30282 }
30283 
30284 #ifdef WOLFSSL_SP_SMALL
30285 /* Multiply the point by the scalar and return the result.
30286  * If map is true then convert result to affine coordinates.
30287  *
30288  * Small implementation using add and double that is cache attack resistant but
30289  * allocates memory rather than use large stacks.
30290  * 384 adds and doubles.
30291  *
30292  * r     Resulting point.
30293  * g     Point to multiply.
30294  * k     Scalar to multiply by.
30295  * map   Indicates whether to convert result to affine.
30296  * ct    Constant time required.
30297  * heap  Heap to use for allocation.
30298  * returns MEMORY_E when memory allocation fails and MP_OKAY on success.
30299  */
30300 
30301 #ifdef WOLFSSL_SP_NONBLOCK
30302 typedef struct sp_384_ecc_mulmod_7_ctx {
30303     int state;
30304     union {
30305         sp_384_proj_point_dbl_7_ctx dbl_ctx;
30306         sp_384_proj_point_add_7_ctx add_ctx;
30307     };
30308     sp_point_384 t[3];
30309     sp_digit tmp[2 * 7 * 6];
30310     sp_digit n;
30311     int i;
30312     int c;
30313     int y;
30314 } sp_384_ecc_mulmod_7_ctx;
30315 
sp_384_ecc_mulmod_7_nb(sp_ecc_ctx_t * sp_ctx,sp_point_384 * r,const sp_point_384 * g,const sp_digit * k,int map,int ct,void * heap)30316 static int sp_384_ecc_mulmod_7_nb(sp_ecc_ctx_t* sp_ctx, sp_point_384* r,
30317     const sp_point_384* g, const sp_digit* k, int map, int ct, void* heap)
30318 {
30319     int err = FP_WOULDBLOCK;
30320     sp_384_ecc_mulmod_7_ctx* ctx = (sp_384_ecc_mulmod_7_ctx*)sp_ctx->data;
30321 
30322     typedef char ctx_size_test[sizeof(sp_384_ecc_mulmod_7_ctx) >= sizeof(*sp_ctx) ? -1 : 1];
30323     (void)sizeof(ctx_size_test);
30324 
30325     /* Implementation is constant time. */
30326     (void)ct;
30327 
30328     switch (ctx->state) {
30329     case 0: /* INIT */
30330         XMEMSET(ctx->t, 0, sizeof(sp_point_384) * 3);
30331         ctx->i = 6;
30332         ctx->c = 54;
30333         ctx->n = k[ctx->i--] << (55 - ctx->c);
30334 
30335         /* t[0] = {0, 0, 1} * norm */
30336         ctx->t[0].infinity = 1;
30337         ctx->state = 1;
30338         break;
30339     case 1: /* T1X */
30340         /* t[1] = {g->x, g->y, g->z} * norm */
30341         err = sp_384_mod_mul_norm_7(ctx->t[1].x, g->x, p384_mod);
30342         ctx->state = 2;
30343         break;
30344     case 2: /* T1Y */
30345         err = sp_384_mod_mul_norm_7(ctx->t[1].y, g->y, p384_mod);
30346         ctx->state = 3;
30347         break;
30348     case 3: /* T1Z */
30349         err = sp_384_mod_mul_norm_7(ctx->t[1].z, g->z, p384_mod);
30350         ctx->state = 4;
30351         break;
30352     case 4: /* ADDPREP */
30353         if (ctx->c == 0) {
30354             if (ctx->i == -1) {
30355                 ctx->state = 7;
30356                 break;
30357             }
30358 
30359             ctx->n = k[ctx->i--];
30360             ctx->c = 55;
30361         }
30362         ctx->y = (ctx->n >> 54) & 1;
30363         ctx->n <<= 1;
30364         XMEMSET(&ctx->add_ctx, 0, sizeof(ctx->add_ctx));
30365         ctx->state = 5;
30366         break;
30367     case 5: /* ADD */
30368         err = sp_384_proj_point_add_7_nb((sp_ecc_ctx_t*)&ctx->add_ctx,
30369             &ctx->t[ctx->y^1], &ctx->t[0], &ctx->t[1], ctx->tmp);
30370         if (err == MP_OKAY) {
30371             XMEMCPY(&ctx->t[2], (void*)(((size_t)&ctx->t[0] & addr_mask[ctx->y^1]) +
30372                                         ((size_t)&ctx->t[1] & addr_mask[ctx->y])),
30373                     sizeof(sp_point_384));
30374             XMEMSET(&ctx->dbl_ctx, 0, sizeof(ctx->dbl_ctx));
30375             ctx->state = 6;
30376         }
30377         break;
30378     case 6: /* DBL */
30379         err = sp_384_proj_point_dbl_7_nb((sp_ecc_ctx_t*)&ctx->dbl_ctx, &ctx->t[2],
30380             &ctx->t[2], ctx->tmp);
30381         if (err == MP_OKAY) {
30382             XMEMCPY((void*)(((size_t)&ctx->t[0] & addr_mask[ctx->y^1]) +
30383                             ((size_t)&ctx->t[1] & addr_mask[ctx->y])), &ctx->t[2],
30384                     sizeof(sp_point_384));
30385             ctx->state = 4;
30386             ctx->c--;
30387         }
30388         break;
30389     case 7: /* MAP */
30390         if (map != 0) {
30391             sp_384_map_7(r, &ctx->t[0], ctx->tmp);
30392         }
30393         else {
30394             XMEMCPY(r, &ctx->t[0], sizeof(sp_point_384));
30395         }
30396         err = MP_OKAY;
30397         break;
30398     }
30399 
30400     if (err == MP_OKAY && ctx->state != 7) {
30401         err = FP_WOULDBLOCK;
30402     }
30403     if (err != FP_WOULDBLOCK) {
30404         ForceZero(ctx->tmp, sizeof(ctx->tmp));
30405         ForceZero(ctx->t, sizeof(ctx->t));
30406     }
30407 
30408     (void)heap;
30409 
30410     return err;
30411 }
30412 
30413 #endif /* WOLFSSL_SP_NONBLOCK */
30414 
sp_384_ecc_mulmod_7(sp_point_384 * r,const sp_point_384 * g,const sp_digit * k,int map,int ct,void * heap)30415 static int sp_384_ecc_mulmod_7(sp_point_384* r, const sp_point_384* g,
30416         const sp_digit* k, int map, int ct, void* heap)
30417 {
30418 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
30419     sp_point_384* t = NULL;
30420     sp_digit* tmp = NULL;
30421 #else
30422     sp_point_384 t[3];
30423     sp_digit tmp[2 * 7 * 6];
30424 #endif
30425     sp_digit n;
30426     int i;
30427     int c;
30428     int y;
30429     int err = MP_OKAY;
30430 
30431     /* Implementation is constant time. */
30432     (void)ct;
30433     (void)heap;
30434 
30435 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
30436     t = (sp_point_384*)XMALLOC(sizeof(sp_point_384) * 3, heap,
30437                                      DYNAMIC_TYPE_ECC);
30438     if (t == NULL)
30439         err = MEMORY_E;
30440     if (err == MP_OKAY) {
30441         tmp = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 7 * 6, heap,
30442                                  DYNAMIC_TYPE_ECC);
30443         if (tmp == NULL)
30444             err = MEMORY_E;
30445     }
30446 #endif
30447 
30448     if (err == MP_OKAY) {
30449         XMEMSET(t, 0, sizeof(sp_point_384) * 3);
30450 
30451         /* t[0] = {0, 0, 1} * norm */
30452         t[0].infinity = 1;
30453         /* t[1] = {g->x, g->y, g->z} * norm */
30454         err = sp_384_mod_mul_norm_7(t[1].x, g->x, p384_mod);
30455     }
30456     if (err == MP_OKAY)
30457         err = sp_384_mod_mul_norm_7(t[1].y, g->y, p384_mod);
30458     if (err == MP_OKAY)
30459         err = sp_384_mod_mul_norm_7(t[1].z, g->z, p384_mod);
30460 
30461     if (err == MP_OKAY) {
30462         i = 6;
30463         c = 54;
30464         n = k[i--] << (55 - c);
30465         for (; ; c--) {
30466             if (c == 0) {
30467                 if (i == -1)
30468                     break;
30469 
30470                 n = k[i--];
30471                 c = 55;
30472             }
30473 
30474             y = (n >> 54) & 1;
30475             n <<= 1;
30476 
30477             sp_384_proj_point_add_7(&t[y^1], &t[0], &t[1], tmp);
30478 
30479             XMEMCPY(&t[2], (void*)(((size_t)&t[0] & addr_mask[y^1]) +
30480                                    ((size_t)&t[1] & addr_mask[y])),
30481                     sizeof(sp_point_384));
30482             sp_384_proj_point_dbl_7(&t[2], &t[2], tmp);
30483             XMEMCPY((void*)(((size_t)&t[0] & addr_mask[y^1]) +
30484                             ((size_t)&t[1] & addr_mask[y])), &t[2],
30485                     sizeof(sp_point_384));
30486         }
30487 
30488         if (map != 0) {
30489             sp_384_map_7(r, &t[0], tmp);
30490         }
30491         else {
30492             XMEMCPY(r, &t[0], sizeof(sp_point_384));
30493         }
30494     }
30495 
30496 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
30497     if (tmp != NULL)
30498 #endif
30499     {
30500         ForceZero(tmp, sizeof(sp_digit) * 2 * 7 * 6);
30501     #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
30502         XFREE(tmp, heap, DYNAMIC_TYPE_ECC);
30503     #endif
30504     }
30505 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
30506     if (t != NULL)
30507 #endif
30508     {
30509         ForceZero(t, sizeof(sp_point_384) * 3);
30510     #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
30511         XFREE(t, heap, DYNAMIC_TYPE_ECC);
30512     #endif
30513     }
30514 
30515     return err;
30516 }
30517 
30518 #else
30519 /* A table entry for pre-computed points. */
30520 typedef struct sp_table_entry_384 {
30521     sp_digit x[7];
30522     sp_digit y[7];
30523 } sp_table_entry_384;
30524 
30525 /* Conditionally copy a into r using the mask m.
30526  * m is -1 to copy and 0 when not.
30527  *
30528  * r  A single precision number to copy over.
30529  * a  A single precision number to copy.
30530  * m  Mask value to apply.
30531  */
sp_384_cond_copy_7(sp_digit * r,const sp_digit * a,const sp_digit m)30532 static void sp_384_cond_copy_7(sp_digit* r, const sp_digit* a, const sp_digit m)
30533 {
30534     sp_digit t[7];
30535 #ifdef WOLFSSL_SP_SMALL
30536     int i;
30537 
30538     for (i = 0; i < 7; i++) {
30539         t[i] = r[i] ^ a[i];
30540     }
30541     for (i = 0; i < 7; i++) {
30542         r[i] ^= t[i] & m;
30543     }
30544 #else
30545     t[ 0] = r[ 0] ^ a[ 0];
30546     t[ 1] = r[ 1] ^ a[ 1];
30547     t[ 2] = r[ 2] ^ a[ 2];
30548     t[ 3] = r[ 3] ^ a[ 3];
30549     t[ 4] = r[ 4] ^ a[ 4];
30550     t[ 5] = r[ 5] ^ a[ 5];
30551     t[ 6] = r[ 6] ^ a[ 6];
30552     r[ 0] ^= t[ 0] & m;
30553     r[ 1] ^= t[ 1] & m;
30554     r[ 2] ^= t[ 2] & m;
30555     r[ 3] ^= t[ 3] & m;
30556     r[ 4] ^= t[ 4] & m;
30557     r[ 5] ^= t[ 5] & m;
30558     r[ 6] ^= t[ 6] & m;
30559 #endif /* WOLFSSL_SP_SMALL */
30560 }
30561 
30562 /* Double the Montgomery form projective point p a number of times.
30563  *
30564  * r  Result of repeated doubling of point.
30565  * p  Point to double.
30566  * n  Number of times to double
30567  * t  Temporary ordinate data.
30568  */
sp_384_proj_point_dbl_n_7(sp_point_384 * p,int n,sp_digit * t)30569 static void sp_384_proj_point_dbl_n_7(sp_point_384* p, int n,
30570     sp_digit* t)
30571 {
30572     sp_digit* w = t;
30573     sp_digit* a = t + 2*7;
30574     sp_digit* b = t + 4*7;
30575     sp_digit* t1 = t + 6*7;
30576     sp_digit* t2 = t + 8*7;
30577     sp_digit* x;
30578     sp_digit* y;
30579     sp_digit* z;
30580 
30581     x = p->x;
30582     y = p->y;
30583     z = p->z;
30584 
30585     /* Y = 2*Y */
30586     sp_384_mont_dbl_7(y, y, p384_mod);
30587     /* W = Z^4 */
30588     sp_384_mont_sqr_7(w, z, p384_mod, p384_mp_mod);
30589     sp_384_mont_sqr_7(w, w, p384_mod, p384_mp_mod);
30590 
30591 #ifndef WOLFSSL_SP_SMALL
30592     while (--n > 0)
30593 #else
30594     while (--n >= 0)
30595 #endif
30596     {
30597         /* A = 3*(X^2 - W) */
30598         sp_384_mont_sqr_7(t1, x, p384_mod, p384_mp_mod);
30599         sp_384_mont_sub_7(t1, t1, w, p384_mod);
30600         sp_384_mont_tpl_7(a, t1, p384_mod);
30601         /* B = X*Y^2 */
30602         sp_384_mont_sqr_7(t1, y, p384_mod, p384_mp_mod);
30603         sp_384_mont_mul_7(b, t1, x, p384_mod, p384_mp_mod);
30604         /* X = A^2 - 2B */
30605         sp_384_mont_sqr_7(x, a, p384_mod, p384_mp_mod);
30606         sp_384_mont_dbl_7(t2, b, p384_mod);
30607         sp_384_mont_sub_7(x, x, t2, p384_mod);
30608         /* Z = Z*Y */
30609         sp_384_mont_mul_7(z, z, y, p384_mod, p384_mp_mod);
30610         /* t2 = Y^4 */
30611         sp_384_mont_sqr_7(t1, t1, p384_mod, p384_mp_mod);
30612 #ifdef WOLFSSL_SP_SMALL
30613         if (n != 0)
30614 #endif
30615         {
30616             /* W = W*Y^4 */
30617             sp_384_mont_mul_7(w, w, t1, p384_mod, p384_mp_mod);
30618         }
30619         /* y = 2*A*(B - X) - Y^4 */
30620         sp_384_mont_sub_7(y, b, x, p384_mod);
30621         sp_384_mont_mul_7(y, y, a, p384_mod, p384_mp_mod);
30622         sp_384_mont_dbl_7(y, y, p384_mod);
30623         sp_384_mont_sub_7(y, y, t1, p384_mod);
30624     }
30625 #ifndef WOLFSSL_SP_SMALL
30626     /* A = 3*(X^2 - W) */
30627     sp_384_mont_sqr_7(t1, x, p384_mod, p384_mp_mod);
30628     sp_384_mont_sub_7(t1, t1, w, p384_mod);
30629     sp_384_mont_tpl_7(a, t1, p384_mod);
30630     /* B = X*Y^2 */
30631     sp_384_mont_sqr_7(t1, y, p384_mod, p384_mp_mod);
30632     sp_384_mont_mul_7(b, t1, x, p384_mod, p384_mp_mod);
30633     /* X = A^2 - 2B */
30634     sp_384_mont_sqr_7(x, a, p384_mod, p384_mp_mod);
30635     sp_384_mont_dbl_7(t2, b, p384_mod);
30636     sp_384_mont_sub_7(x, x, t2, p384_mod);
30637     /* Z = Z*Y */
30638     sp_384_mont_mul_7(z, z, y, p384_mod, p384_mp_mod);
30639     /* t2 = Y^4 */
30640     sp_384_mont_sqr_7(t1, t1, p384_mod, p384_mp_mod);
30641     /* y = 2*A*(B - X) - Y^4 */
30642     sp_384_mont_sub_7(y, b, x, p384_mod);
30643     sp_384_mont_mul_7(y, y, a, p384_mod, p384_mp_mod);
30644     sp_384_mont_dbl_7(y, y, p384_mod);
30645     sp_384_mont_sub_7(y, y, t1, p384_mod);
30646 #endif
30647     /* Y = Y/2 */
30648     sp_384_div2_7(y, y, p384_mod);
30649 }
30650 
30651 /* Double the Montgomery form projective point p a number of times.
30652  *
30653  * r  Result of repeated doubling of point.
30654  * p  Point to double.
30655  * n  Number of times to double
30656  * t  Temporary ordinate data.
30657  */
sp_384_proj_point_dbl_n_store_7(sp_point_384 * r,const sp_point_384 * p,int n,int m,sp_digit * t)30658 static void sp_384_proj_point_dbl_n_store_7(sp_point_384* r,
30659         const sp_point_384* p, int n, int m, sp_digit* t)
30660 {
30661     sp_digit* w = t;
30662     sp_digit* a = t + 2*7;
30663     sp_digit* b = t + 4*7;
30664     sp_digit* t1 = t + 6*7;
30665     sp_digit* t2 = t + 8*7;
30666     sp_digit* x = r[2*m].x;
30667     sp_digit* y = r[(1<<n)*m].y;
30668     sp_digit* z = r[2*m].z;
30669     int i;
30670     int j;
30671 
30672     for (i=0; i<7; i++) {
30673         x[i] = p->x[i];
30674     }
30675     for (i=0; i<7; i++) {
30676         y[i] = p->y[i];
30677     }
30678     for (i=0; i<7; i++) {
30679         z[i] = p->z[i];
30680     }
30681 
30682     /* Y = 2*Y */
30683     sp_384_mont_dbl_7(y, y, p384_mod);
30684     /* W = Z^4 */
30685     sp_384_mont_sqr_7(w, z, p384_mod, p384_mp_mod);
30686     sp_384_mont_sqr_7(w, w, p384_mod, p384_mp_mod);
30687     j = m;
30688     for (i=1; i<=n; i++) {
30689         j *= 2;
30690 
30691         /* A = 3*(X^2 - W) */
30692         sp_384_mont_sqr_7(t1, x, p384_mod, p384_mp_mod);
30693         sp_384_mont_sub_7(t1, t1, w, p384_mod);
30694         sp_384_mont_tpl_7(a, t1, p384_mod);
30695         /* B = X*Y^2 */
30696         sp_384_mont_sqr_7(t2, y, p384_mod, p384_mp_mod);
30697         sp_384_mont_mul_7(b, t2, x, p384_mod, p384_mp_mod);
30698         x = r[j].x;
30699         /* X = A^2 - 2B */
30700         sp_384_mont_sqr_7(x, a, p384_mod, p384_mp_mod);
30701         sp_384_mont_dbl_7(t1, b, p384_mod);
30702         sp_384_mont_sub_7(x, x, t1, p384_mod);
30703         /* Z = Z*Y */
30704         sp_384_mont_mul_7(r[j].z, z, y, p384_mod, p384_mp_mod);
30705         z = r[j].z;
30706         /* t2 = Y^4 */
30707         sp_384_mont_sqr_7(t2, t2, p384_mod, p384_mp_mod);
30708         if (i != n) {
30709             /* W = W*Y^4 */
30710             sp_384_mont_mul_7(w, w, t2, p384_mod, p384_mp_mod);
30711         }
30712         /* y = 2*A*(B - X) - Y^4 */
30713         sp_384_mont_sub_7(y, b, x, p384_mod);
30714         sp_384_mont_mul_7(y, y, a, p384_mod, p384_mp_mod);
30715         sp_384_mont_dbl_7(y, y, p384_mod);
30716         sp_384_mont_sub_7(y, y, t2, p384_mod);
30717 
30718         /* Y = Y/2 */
30719         sp_384_div2_7(r[j].y, y, p384_mod);
30720         r[j].infinity = 0;
30721     }
30722 }
30723 
30724 /* Add two Montgomery form projective points.
30725  *
30726  * ra  Result of addition.
30727  * rs  Result of subtraction.
30728  * p   First point to add.
30729  * q   Second point to add.
30730  * t   Temporary ordinate data.
30731  */
sp_384_proj_point_add_sub_7(sp_point_384 * ra,sp_point_384 * rs,const sp_point_384 * p,const sp_point_384 * q,sp_digit * t)30732 static void sp_384_proj_point_add_sub_7(sp_point_384* ra,
30733         sp_point_384* rs, const sp_point_384* p, const sp_point_384* q,
30734         sp_digit* t)
30735 {
30736     sp_digit* t1 = t;
30737     sp_digit* t2 = t + 2*7;
30738     sp_digit* t3 = t + 4*7;
30739     sp_digit* t4 = t + 6*7;
30740     sp_digit* t5 = t + 8*7;
30741     sp_digit* t6 = t + 10*7;
30742     sp_digit* x = ra->x;
30743     sp_digit* y = ra->y;
30744     sp_digit* z = ra->z;
30745     sp_digit* xs = rs->x;
30746     sp_digit* ys = rs->y;
30747     sp_digit* zs = rs->z;
30748 
30749 
30750     XMEMCPY(x, p->x, sizeof(p->x) / 2);
30751     XMEMCPY(y, p->y, sizeof(p->y) / 2);
30752     XMEMCPY(z, p->z, sizeof(p->z) / 2);
30753     ra->infinity = 0;
30754     rs->infinity = 0;
30755 
30756     /* U1 = X1*Z2^2 */
30757     sp_384_mont_sqr_7(t1, q->z, p384_mod, p384_mp_mod);
30758     sp_384_mont_mul_7(t3, t1, q->z, p384_mod, p384_mp_mod);
30759     sp_384_mont_mul_7(t1, t1, x, p384_mod, p384_mp_mod);
30760     /* U2 = X2*Z1^2 */
30761     sp_384_mont_sqr_7(t2, z, p384_mod, p384_mp_mod);
30762     sp_384_mont_mul_7(t4, t2, z, p384_mod, p384_mp_mod);
30763     sp_384_mont_mul_7(t2, t2, q->x, p384_mod, p384_mp_mod);
30764     /* S1 = Y1*Z2^3 */
30765     sp_384_mont_mul_7(t3, t3, y, p384_mod, p384_mp_mod);
30766     /* S2 = Y2*Z1^3 */
30767     sp_384_mont_mul_7(t4, t4, q->y, p384_mod, p384_mp_mod);
30768     /* H = U2 - U1 */
30769     sp_384_mont_sub_7(t2, t2, t1, p384_mod);
30770     /* RS = S2 + S1 */
30771     sp_384_mont_add_7(t6, t4, t3, p384_mod);
30772     /* R = S2 - S1 */
30773     sp_384_mont_sub_7(t4, t4, t3, p384_mod);
30774     /* Z3 = H*Z1*Z2 */
30775     /* ZS = H*Z1*Z2 */
30776     sp_384_mont_mul_7(z, z, q->z, p384_mod, p384_mp_mod);
30777     sp_384_mont_mul_7(z, z, t2, p384_mod, p384_mp_mod);
30778     XMEMCPY(zs, z, sizeof(p->z)/2);
30779     /* X3 = R^2 - H^3 - 2*U1*H^2 */
30780     /* XS = RS^2 - H^3 - 2*U1*H^2 */
30781     sp_384_mont_sqr_7(x, t4, p384_mod, p384_mp_mod);
30782     sp_384_mont_sqr_7(xs, t6, p384_mod, p384_mp_mod);
30783     sp_384_mont_sqr_7(t5, t2, p384_mod, p384_mp_mod);
30784     sp_384_mont_mul_7(y, t1, t5, p384_mod, p384_mp_mod);
30785     sp_384_mont_mul_7(t5, t5, t2, p384_mod, p384_mp_mod);
30786     sp_384_mont_sub_7(x, x, t5, p384_mod);
30787     sp_384_mont_sub_7(xs, xs, t5, p384_mod);
30788     sp_384_mont_dbl_7(t1, y, p384_mod);
30789     sp_384_mont_sub_7(x, x, t1, p384_mod);
30790     sp_384_mont_sub_7(xs, xs, t1, p384_mod);
30791     /* Y3 = R*(U1*H^2 - X3) - S1*H^3 */
30792     /* YS = -RS*(U1*H^2 - XS) - S1*H^3 */
30793     sp_384_mont_sub_7(ys, y, xs, p384_mod);
30794     sp_384_mont_sub_7(y, y, x, p384_mod);
30795     sp_384_mont_mul_7(y, y, t4, p384_mod, p384_mp_mod);
30796     sp_384_sub_7(t6, p384_mod, t6);
30797     sp_384_mont_mul_7(ys, ys, t6, p384_mod, p384_mp_mod);
30798     sp_384_mont_mul_7(t5, t5, t3, p384_mod, p384_mp_mod);
30799     sp_384_mont_sub_7(y, y, t5, p384_mod);
30800     sp_384_mont_sub_7(ys, ys, t5, p384_mod);
30801 }
30802 
30803 /* Structure used to describe recoding of scalar multiplication. */
30804 typedef struct ecc_recode_384 {
30805     /* Index into pre-computation table. */
30806     uint8_t i;
30807     /* Use the negative of the point. */
30808     uint8_t neg;
30809 } ecc_recode_384;
30810 
30811 /* The index into pre-computation table to use. */
30812 static const uint8_t recode_index_7_6[66] = {
30813      0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15,
30814     16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
30815     32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17,
30816     16, 15, 14, 13, 12, 11, 10,  9,  8,  7,  6,  5,  4,  3,  2,  1,
30817      0,  1,
30818 };
30819 
30820 /* Whether to negate y-ordinate. */
30821 static const uint8_t recode_neg_7_6[66] = {
30822      0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
30823      0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
30824      1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
30825      1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
30826      0,  0,
30827 };
30828 
30829 /* Recode the scalar for multiplication using pre-computed values and
30830  * subtraction.
30831  *
30832  * k  Scalar to multiply by.
30833  * v  Vector of operations to perform.
30834  */
sp_384_ecc_recode_6_7(const sp_digit * k,ecc_recode_384 * v)30835 static void sp_384_ecc_recode_6_7(const sp_digit* k, ecc_recode_384* v)
30836 {
30837     int i;
30838     int j;
30839     uint8_t y;
30840     int carry = 0;
30841     int o;
30842     sp_digit n;
30843 
30844     j = 0;
30845     n = k[j];
30846     o = 0;
30847     for (i=0; i<65; i++) {
30848         y = (int8_t)n;
30849         if (o + 6 < 55) {
30850             y &= 0x3f;
30851             n >>= 6;
30852             o += 6;
30853         }
30854         else if (o + 6 == 55) {
30855             n >>= 6;
30856             if (++j < 7)
30857                 n = k[j];
30858             o = 0;
30859         }
30860         else if (++j < 7) {
30861             n = k[j];
30862             y |= (uint8_t)((n << (55 - o)) & 0x3f);
30863             o -= 49;
30864             n >>= o;
30865         }
30866 
30867         y += (uint8_t)carry;
30868         v[i].i = recode_index_7_6[y];
30869         v[i].neg = recode_neg_7_6[y];
30870         carry = (y >> 6) + v[i].neg;
30871     }
30872 }
30873 
30874 #ifndef WC_NO_CACHE_RESISTANT
30875 /* Touch each possible point that could be being copied.
30876  *
30877  * r      Point to copy into.
30878  * table  Table - start of the entires to access
30879  * idx    Index of entry to retrieve.
30880  */
sp_384_get_point_33_7(sp_point_384 * r,const sp_point_384 * table,int idx)30881 static void sp_384_get_point_33_7(sp_point_384* r, const sp_point_384* table,
30882     int idx)
30883 {
30884     int i;
30885     sp_digit mask;
30886 
30887     r->x[0] = 0;
30888     r->x[1] = 0;
30889     r->x[2] = 0;
30890     r->x[3] = 0;
30891     r->x[4] = 0;
30892     r->x[5] = 0;
30893     r->x[6] = 0;
30894     r->y[0] = 0;
30895     r->y[1] = 0;
30896     r->y[2] = 0;
30897     r->y[3] = 0;
30898     r->y[4] = 0;
30899     r->y[5] = 0;
30900     r->y[6] = 0;
30901     r->z[0] = 0;
30902     r->z[1] = 0;
30903     r->z[2] = 0;
30904     r->z[3] = 0;
30905     r->z[4] = 0;
30906     r->z[5] = 0;
30907     r->z[6] = 0;
30908     for (i = 1; i < 33; i++) {
30909         mask = 0 - (i == idx);
30910         r->x[0] |= mask & table[i].x[0];
30911         r->x[1] |= mask & table[i].x[1];
30912         r->x[2] |= mask & table[i].x[2];
30913         r->x[3] |= mask & table[i].x[3];
30914         r->x[4] |= mask & table[i].x[4];
30915         r->x[5] |= mask & table[i].x[5];
30916         r->x[6] |= mask & table[i].x[6];
30917         r->y[0] |= mask & table[i].y[0];
30918         r->y[1] |= mask & table[i].y[1];
30919         r->y[2] |= mask & table[i].y[2];
30920         r->y[3] |= mask & table[i].y[3];
30921         r->y[4] |= mask & table[i].y[4];
30922         r->y[5] |= mask & table[i].y[5];
30923         r->y[6] |= mask & table[i].y[6];
30924         r->z[0] |= mask & table[i].z[0];
30925         r->z[1] |= mask & table[i].z[1];
30926         r->z[2] |= mask & table[i].z[2];
30927         r->z[3] |= mask & table[i].z[3];
30928         r->z[4] |= mask & table[i].z[4];
30929         r->z[5] |= mask & table[i].z[5];
30930         r->z[6] |= mask & table[i].z[6];
30931     }
30932 }
30933 #endif /* !WC_NO_CACHE_RESISTANT */
30934 /* Multiply the point by the scalar and return the result.
30935  * If map is true then convert result to affine coordinates.
30936  *
30937  * Window technique of 6 bits. (Add-Sub variation.)
30938  * Calculate 0..32 times the point. Use function that adds and
30939  * subtracts the same two points.
30940  * Recode to add or subtract one of the computed points.
30941  * Double to push up.
30942  * NOT a sliding window.
30943  *
30944  * r     Resulting point.
30945  * g     Point to multiply.
30946  * k     Scalar to multiply by.
30947  * map   Indicates whether to convert result to affine.
30948  * ct    Constant time required.
30949  * heap  Heap to use for allocation.
30950  * returns MEMORY_E when memory allocation fails and MP_OKAY on success.
30951  */
sp_384_ecc_mulmod_win_add_sub_7(sp_point_384 * r,const sp_point_384 * g,const sp_digit * k,int map,int ct,void * heap)30952 static int sp_384_ecc_mulmod_win_add_sub_7(sp_point_384* r, const sp_point_384* g,
30953         const sp_digit* k, int map, int ct, void* heap)
30954 {
30955 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
30956     sp_point_384* t = NULL;
30957     sp_digit* tmp = NULL;
30958 #else
30959     sp_point_384 t[33+2];
30960     sp_digit tmp[2 * 7 * 6];
30961 #endif
30962     sp_point_384* rt = NULL;
30963     sp_point_384* p = NULL;
30964     sp_digit* negy;
30965     int i;
30966     ecc_recode_384 v[65];
30967     int err = MP_OKAY;
30968 
30969     /* Constant time used for cache attack resistance implementation. */
30970     (void)ct;
30971     (void)heap;
30972 
30973 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
30974     t = (sp_point_384*)XMALLOC(sizeof(sp_point_384) *
30975         (33+2), heap, DYNAMIC_TYPE_ECC);
30976     if (t == NULL)
30977         err = MEMORY_E;
30978     if (err == MP_OKAY) {
30979         tmp = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 7 * 6,
30980                                  heap, DYNAMIC_TYPE_ECC);
30981         if (tmp == NULL)
30982             err = MEMORY_E;
30983     }
30984 #endif
30985 
30986     if (err == MP_OKAY) {
30987         rt = t + 33;
30988         p  = t + 33+1;
30989 
30990         /* t[0] = {0, 0, 1} * norm */
30991         XMEMSET(&t[0], 0, sizeof(t[0]));
30992         t[0].infinity = 1;
30993         /* t[1] = {g->x, g->y, g->z} * norm */
30994         err = sp_384_mod_mul_norm_7(t[1].x, g->x, p384_mod);
30995     }
30996     if (err == MP_OKAY) {
30997         err = sp_384_mod_mul_norm_7(t[1].y, g->y, p384_mod);
30998     }
30999     if (err == MP_OKAY) {
31000         err = sp_384_mod_mul_norm_7(t[1].z, g->z, p384_mod);
31001     }
31002 
31003     if (err == MP_OKAY) {
31004         t[1].infinity = 0;
31005         /* t[2] ... t[32]  */
31006         sp_384_proj_point_dbl_n_store_7(t, &t[ 1], 5, 1, tmp);
31007         sp_384_proj_point_add_7(&t[ 3], &t[ 2], &t[ 1], tmp);
31008         sp_384_proj_point_dbl_7(&t[ 6], &t[ 3], tmp);
31009         sp_384_proj_point_add_sub_7(&t[ 7], &t[ 5], &t[ 6], &t[ 1], tmp);
31010         sp_384_proj_point_dbl_7(&t[10], &t[ 5], tmp);
31011         sp_384_proj_point_add_sub_7(&t[11], &t[ 9], &t[10], &t[ 1], tmp);
31012         sp_384_proj_point_dbl_7(&t[12], &t[ 6], tmp);
31013         sp_384_proj_point_dbl_7(&t[14], &t[ 7], tmp);
31014         sp_384_proj_point_add_sub_7(&t[15], &t[13], &t[14], &t[ 1], tmp);
31015         sp_384_proj_point_dbl_7(&t[18], &t[ 9], tmp);
31016         sp_384_proj_point_add_sub_7(&t[19], &t[17], &t[18], &t[ 1], tmp);
31017         sp_384_proj_point_dbl_7(&t[20], &t[10], tmp);
31018         sp_384_proj_point_dbl_7(&t[22], &t[11], tmp);
31019         sp_384_proj_point_add_sub_7(&t[23], &t[21], &t[22], &t[ 1], tmp);
31020         sp_384_proj_point_dbl_7(&t[24], &t[12], tmp);
31021         sp_384_proj_point_dbl_7(&t[26], &t[13], tmp);
31022         sp_384_proj_point_add_sub_7(&t[27], &t[25], &t[26], &t[ 1], tmp);
31023         sp_384_proj_point_dbl_7(&t[28], &t[14], tmp);
31024         sp_384_proj_point_dbl_7(&t[30], &t[15], tmp);
31025         sp_384_proj_point_add_sub_7(&t[31], &t[29], &t[30], &t[ 1], tmp);
31026 
31027         negy = t[0].y;
31028 
31029         sp_384_ecc_recode_6_7(k, v);
31030 
31031         i = 64;
31032     #ifndef WC_NO_CACHE_RESISTANT
31033         if (ct) {
31034             sp_384_get_point_33_7(rt, t, v[i].i);
31035             rt->infinity = !v[i].i;
31036         }
31037         else
31038     #endif
31039         {
31040             XMEMCPY(rt, &t[v[i].i], sizeof(sp_point_384));
31041         }
31042         for (--i; i>=0; i--) {
31043             sp_384_proj_point_dbl_n_7(rt, 6, tmp);
31044 
31045         #ifndef WC_NO_CACHE_RESISTANT
31046             if (ct) {
31047                 sp_384_get_point_33_7(p, t, v[i].i);
31048                 p->infinity = !v[i].i;
31049             }
31050             else
31051         #endif
31052             {
31053                 XMEMCPY(p, &t[v[i].i], sizeof(sp_point_384));
31054             }
31055             sp_384_sub_7(negy, p384_mod, p->y);
31056             sp_384_norm_7(negy);
31057             sp_384_cond_copy_7(p->y, negy, (sp_digit)0 - v[i].neg);
31058             sp_384_proj_point_add_7(rt, rt, p, tmp);
31059         }
31060 
31061         if (map != 0) {
31062             sp_384_map_7(r, rt, tmp);
31063         }
31064         else {
31065             XMEMCPY(r, rt, sizeof(sp_point_384));
31066         }
31067     }
31068 
31069 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
31070     if (t != NULL)
31071         XFREE(t, heap, DYNAMIC_TYPE_ECC);
31072     if (tmp != NULL)
31073         XFREE(tmp, heap, DYNAMIC_TYPE_ECC);
31074 #endif
31075 
31076     return err;
31077 }
31078 
31079 #ifdef FP_ECC
31080 #endif /* FP_ECC */
31081 /* Add two Montgomery form projective points. The second point has a q value of
31082  * one.
31083  * Only the first point can be the same pointer as the result point.
31084  *
31085  * r  Result of addition.
31086  * p  First point to add.
31087  * q  Second point to add.
31088  * t  Temporary ordinate data.
31089  */
sp_384_proj_point_add_qz1_7(sp_point_384 * r,const sp_point_384 * p,const sp_point_384 * q,sp_digit * t)31090 static void sp_384_proj_point_add_qz1_7(sp_point_384* r, const sp_point_384* p,
31091         const sp_point_384* q, sp_digit* t)
31092 {
31093     const sp_point_384* ap[2];
31094     sp_point_384* rp[2];
31095     sp_digit* t1 = t;
31096     sp_digit* t2 = t + 2*7;
31097     sp_digit* t3 = t + 4*7;
31098     sp_digit* t4 = t + 6*7;
31099     sp_digit* t5 = t + 8*7;
31100     sp_digit* x;
31101     sp_digit* y;
31102     sp_digit* z;
31103     int i;
31104 
31105     /* Check double */
31106     (void)sp_384_sub_7(t1, p384_mod, q->y);
31107     sp_384_norm_7(t1);
31108     if ((sp_384_cmp_equal_7(p->x, q->x) & sp_384_cmp_equal_7(p->z, q->z) &
31109         (sp_384_cmp_equal_7(p->y, q->y) | sp_384_cmp_equal_7(p->y, t1))) != 0) {
31110         sp_384_proj_point_dbl_7(r, p, t);
31111     }
31112     else {
31113         rp[0] = r;
31114 
31115         /*lint allow cast to different type of pointer*/
31116         rp[1] = (sp_point_384*)t; /*lint !e9087 !e740*/
31117         XMEMSET(rp[1], 0, sizeof(sp_point_384));
31118         x = rp[p->infinity | q->infinity]->x;
31119         y = rp[p->infinity | q->infinity]->y;
31120         z = rp[p->infinity | q->infinity]->z;
31121 
31122         ap[0] = p;
31123         ap[1] = q;
31124         for (i=0; i<7; i++) {
31125             r->x[i] = ap[p->infinity]->x[i];
31126         }
31127         for (i=0; i<7; i++) {
31128             r->y[i] = ap[p->infinity]->y[i];
31129         }
31130         for (i=0; i<7; i++) {
31131             r->z[i] = ap[p->infinity]->z[i];
31132         }
31133         r->infinity = ap[p->infinity]->infinity;
31134 
31135         /* U2 = X2*Z1^2 */
31136         sp_384_mont_sqr_7(t2, z, p384_mod, p384_mp_mod);
31137         sp_384_mont_mul_7(t4, t2, z, p384_mod, p384_mp_mod);
31138         sp_384_mont_mul_7(t2, t2, q->x, p384_mod, p384_mp_mod);
31139         /* S2 = Y2*Z1^3 */
31140         sp_384_mont_mul_7(t4, t4, q->y, p384_mod, p384_mp_mod);
31141         /* H = U2 - X1 */
31142         sp_384_mont_sub_7(t2, t2, x, p384_mod);
31143         /* R = S2 - Y1 */
31144         sp_384_mont_sub_7(t4, t4, y, p384_mod);
31145         /* Z3 = H*Z1 */
31146         sp_384_mont_mul_7(z, z, t2, p384_mod, p384_mp_mod);
31147         /* X3 = R^2 - H^3 - 2*X1*H^2 */
31148         sp_384_mont_sqr_7(t1, t4, p384_mod, p384_mp_mod);
31149         sp_384_mont_sqr_7(t5, t2, p384_mod, p384_mp_mod);
31150         sp_384_mont_mul_7(t3, x, t5, p384_mod, p384_mp_mod);
31151         sp_384_mont_mul_7(t5, t5, t2, p384_mod, p384_mp_mod);
31152         sp_384_mont_sub_7(x, t1, t5, p384_mod);
31153         sp_384_mont_dbl_7(t1, t3, p384_mod);
31154         sp_384_mont_sub_7(x, x, t1, p384_mod);
31155         /* Y3 = R*(X1*H^2 - X3) - Y1*H^3 */
31156         sp_384_mont_sub_7(t3, t3, x, p384_mod);
31157         sp_384_mont_mul_7(t3, t3, t4, p384_mod, p384_mp_mod);
31158         sp_384_mont_mul_7(t5, t5, y, p384_mod, p384_mp_mod);
31159         sp_384_mont_sub_7(y, t3, t5, p384_mod);
31160     }
31161 }
31162 
31163 #ifdef FP_ECC
31164 /* Convert the projective point to affine.
31165  * Ordinates are in Montgomery form.
31166  *
31167  * a  Point to convert.
31168  * t  Temporary data.
31169  */
sp_384_proj_to_affine_7(sp_point_384 * a,sp_digit * t)31170 static void sp_384_proj_to_affine_7(sp_point_384* a, sp_digit* t)
31171 {
31172     sp_digit* t1 = t;
31173     sp_digit* t2 = t + 2 * 7;
31174     sp_digit* tmp = t + 4 * 7;
31175 
31176     sp_384_mont_inv_7(t1, a->z, tmp);
31177 
31178     sp_384_mont_sqr_7(t2, t1, p384_mod, p384_mp_mod);
31179     sp_384_mont_mul_7(t1, t2, t1, p384_mod, p384_mp_mod);
31180 
31181     sp_384_mont_mul_7(a->x, a->x, t2, p384_mod, p384_mp_mod);
31182     sp_384_mont_mul_7(a->y, a->y, t1, p384_mod, p384_mp_mod);
31183     XMEMCPY(a->z, p384_norm_mod, sizeof(p384_norm_mod));
31184 }
31185 
31186 /* Generate the pre-computed table of points for the base point.
31187  *
31188  * width = 8
31189  * 256 entries
31190  * 48 bits between
31191  *
31192  * a      The base point.
31193  * table  Place to store generated point data.
31194  * tmp    Temporary data.
31195  * heap  Heap to use for allocation.
31196  */
sp_384_gen_stripe_table_7(const sp_point_384 * a,sp_table_entry_384 * table,sp_digit * tmp,void * heap)31197 static int sp_384_gen_stripe_table_7(const sp_point_384* a,
31198         sp_table_entry_384* table, sp_digit* tmp, void* heap)
31199 {
31200 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
31201     sp_point_384* t = NULL;
31202 #else
31203     sp_point_384 t[3];
31204 #endif
31205     sp_point_384* s1 = NULL;
31206     sp_point_384* s2 = NULL;
31207     int i;
31208     int j;
31209     int err = MP_OKAY;
31210 
31211     (void)heap;
31212 
31213 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
31214     t = (sp_point_384*)XMALLOC(sizeof(sp_point_384) * 3, heap,
31215                                      DYNAMIC_TYPE_ECC);
31216     if (t == NULL)
31217         err = MEMORY_E;
31218 #endif
31219 
31220     if (err == MP_OKAY) {
31221         s1 = t + 1;
31222         s2 = t + 2;
31223 
31224         err = sp_384_mod_mul_norm_7(t->x, a->x, p384_mod);
31225     }
31226     if (err == MP_OKAY) {
31227         err = sp_384_mod_mul_norm_7(t->y, a->y, p384_mod);
31228     }
31229     if (err == MP_OKAY) {
31230         err = sp_384_mod_mul_norm_7(t->z, a->z, p384_mod);
31231     }
31232     if (err == MP_OKAY) {
31233         t->infinity = 0;
31234         sp_384_proj_to_affine_7(t, tmp);
31235 
31236         XMEMCPY(s1->z, p384_norm_mod, sizeof(p384_norm_mod));
31237         s1->infinity = 0;
31238         XMEMCPY(s2->z, p384_norm_mod, sizeof(p384_norm_mod));
31239         s2->infinity = 0;
31240 
31241         /* table[0] = {0, 0, infinity} */
31242         XMEMSET(&table[0], 0, sizeof(sp_table_entry_384));
31243         /* table[1] = Affine version of 'a' in Montgomery form */
31244         XMEMCPY(table[1].x, t->x, sizeof(table->x));
31245         XMEMCPY(table[1].y, t->y, sizeof(table->y));
31246 
31247         for (i=1; i<8; i++) {
31248             sp_384_proj_point_dbl_n_7(t, 48, tmp);
31249             sp_384_proj_to_affine_7(t, tmp);
31250             XMEMCPY(table[1<<i].x, t->x, sizeof(table->x));
31251             XMEMCPY(table[1<<i].y, t->y, sizeof(table->y));
31252         }
31253 
31254         for (i=1; i<8; i++) {
31255             XMEMCPY(s1->x, table[1<<i].x, sizeof(table->x));
31256             XMEMCPY(s1->y, table[1<<i].y, sizeof(table->y));
31257             for (j=(1<<i)+1; j<(1<<(i+1)); j++) {
31258                 XMEMCPY(s2->x, table[j-(1<<i)].x, sizeof(table->x));
31259                 XMEMCPY(s2->y, table[j-(1<<i)].y, sizeof(table->y));
31260                 sp_384_proj_point_add_qz1_7(t, s1, s2, tmp);
31261                 sp_384_proj_to_affine_7(t, tmp);
31262                 XMEMCPY(table[j].x, t->x, sizeof(table->x));
31263                 XMEMCPY(table[j].y, t->y, sizeof(table->y));
31264             }
31265         }
31266     }
31267 
31268 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
31269     if (t != NULL)
31270         XFREE(t, heap, DYNAMIC_TYPE_ECC);
31271 #endif
31272 
31273     return err;
31274 }
31275 
31276 #endif /* FP_ECC */
31277 #ifndef WC_NO_CACHE_RESISTANT
31278 /* Touch each possible entry that could be being copied.
31279  *
31280  * r      Point to copy into.
31281  * table  Table - start of the entires to access
31282  * idx    Index of entry to retrieve.
31283  */
sp_384_get_entry_256_7(sp_point_384 * r,const sp_table_entry_384 * table,int idx)31284 static void sp_384_get_entry_256_7(sp_point_384* r,
31285     const sp_table_entry_384* table, int idx)
31286 {
31287     int i;
31288     sp_digit mask;
31289 
31290     r->x[0] = 0;
31291     r->x[1] = 0;
31292     r->x[2] = 0;
31293     r->x[3] = 0;
31294     r->x[4] = 0;
31295     r->x[5] = 0;
31296     r->x[6] = 0;
31297     r->y[0] = 0;
31298     r->y[1] = 0;
31299     r->y[2] = 0;
31300     r->y[3] = 0;
31301     r->y[4] = 0;
31302     r->y[5] = 0;
31303     r->y[6] = 0;
31304     for (i = 1; i < 256; i++) {
31305         mask = 0 - (i == idx);
31306         r->x[0] |= mask & table[i].x[0];
31307         r->x[1] |= mask & table[i].x[1];
31308         r->x[2] |= mask & table[i].x[2];
31309         r->x[3] |= mask & table[i].x[3];
31310         r->x[4] |= mask & table[i].x[4];
31311         r->x[5] |= mask & table[i].x[5];
31312         r->x[6] |= mask & table[i].x[6];
31313         r->y[0] |= mask & table[i].y[0];
31314         r->y[1] |= mask & table[i].y[1];
31315         r->y[2] |= mask & table[i].y[2];
31316         r->y[3] |= mask & table[i].y[3];
31317         r->y[4] |= mask & table[i].y[4];
31318         r->y[5] |= mask & table[i].y[5];
31319         r->y[6] |= mask & table[i].y[6];
31320     }
31321 }
31322 #endif /* !WC_NO_CACHE_RESISTANT */
31323 /* Multiply the point by the scalar and return the result.
31324  * If map is true then convert result to affine coordinates.
31325  *
31326  * Stripe implementation.
31327  * Pre-generated: 2^0, 2^48, ...
31328  * Pre-generated: products of all combinations of above.
31329  * 8 doubles and adds (with qz=1)
31330  *
31331  * r      Resulting point.
31332  * k      Scalar to multiply by.
31333  * table  Pre-computed table.
31334  * map    Indicates whether to convert result to affine.
31335  * ct     Constant time required.
31336  * heap   Heap to use for allocation.
31337  * returns MEMORY_E when memory allocation fails and MP_OKAY on success.
31338  */
sp_384_ecc_mulmod_stripe_7(sp_point_384 * r,const sp_point_384 * g,const sp_table_entry_384 * table,const sp_digit * k,int map,int ct,void * heap)31339 static int sp_384_ecc_mulmod_stripe_7(sp_point_384* r, const sp_point_384* g,
31340         const sp_table_entry_384* table, const sp_digit* k, int map,
31341         int ct, void* heap)
31342 {
31343 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
31344     sp_point_384* rt = NULL;
31345     sp_digit* t = NULL;
31346 #else
31347     sp_point_384 rt[2];
31348     sp_digit t[2 * 7 * 6];
31349 #endif
31350     sp_point_384* p = NULL;
31351     int i;
31352     int j;
31353     int y;
31354     int x;
31355     int err = MP_OKAY;
31356 
31357     (void)g;
31358     /* Constant time used for cache attack resistance implementation. */
31359     (void)ct;
31360     (void)heap;
31361 
31362 
31363 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
31364     rt = (sp_point_384*)XMALLOC(sizeof(sp_point_384) * 2, heap,
31365                                       DYNAMIC_TYPE_ECC);
31366     if (rt == NULL)
31367         err = MEMORY_E;
31368     if (err == MP_OKAY) {
31369         t = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 7 * 6, heap,
31370                                DYNAMIC_TYPE_ECC);
31371         if (t == NULL)
31372             err = MEMORY_E;
31373     }
31374 #endif
31375 
31376     if (err == MP_OKAY) {
31377         p = rt + 1;
31378 
31379         XMEMCPY(p->z, p384_norm_mod, sizeof(p384_norm_mod));
31380         XMEMCPY(rt->z, p384_norm_mod, sizeof(p384_norm_mod));
31381 
31382         y = 0;
31383         x = 47;
31384         for (j=0; j<8; j++) {
31385             y |= (int)(((k[x / 55] >> (x % 55)) & 1) << j);
31386             x += 48;
31387         }
31388     #ifndef WC_NO_CACHE_RESISTANT
31389         if (ct) {
31390             sp_384_get_entry_256_7(rt, table, y);
31391         } else
31392     #endif
31393         {
31394             XMEMCPY(rt->x, table[y].x, sizeof(table[y].x));
31395             XMEMCPY(rt->y, table[y].y, sizeof(table[y].y));
31396         }
31397         rt->infinity = !y;
31398         for (i=46; i>=0; i--) {
31399             y = 0;
31400             x = i;
31401             for (j=0; j<8; j++) {
31402                 y |= (int)(((k[x / 55] >> (x % 55)) & 1) << j);
31403                 x += 48;
31404             }
31405 
31406             sp_384_proj_point_dbl_7(rt, rt, t);
31407         #ifndef WC_NO_CACHE_RESISTANT
31408             if (ct) {
31409                 sp_384_get_entry_256_7(p, table, y);
31410             }
31411             else
31412         #endif
31413             {
31414                 XMEMCPY(p->x, table[y].x, sizeof(table[y].x));
31415                 XMEMCPY(p->y, table[y].y, sizeof(table[y].y));
31416             }
31417             p->infinity = !y;
31418             sp_384_proj_point_add_qz1_7(rt, rt, p, t);
31419         }
31420 
31421         if (map != 0) {
31422             sp_384_map_7(r, rt, t);
31423         }
31424         else {
31425             XMEMCPY(r, rt, sizeof(sp_point_384));
31426         }
31427     }
31428 
31429 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
31430     if (t != NULL)
31431         XFREE(t, heap, DYNAMIC_TYPE_ECC);
31432     if (rt != NULL)
31433         XFREE(rt, heap, DYNAMIC_TYPE_ECC);
31434 #endif
31435 
31436     return err;
31437 }
31438 
31439 #ifdef FP_ECC
31440 #ifndef FP_ENTRIES
31441     #define FP_ENTRIES 16
31442 #endif
31443 
31444 /* Cache entry - holds precomputation tables for a point. */
31445 typedef struct sp_cache_384_t {
31446     /* X ordinate of point that table was generated from. */
31447     sp_digit x[7];
31448     /* Y ordinate of point that table was generated from. */
31449     sp_digit y[7];
31450     /* Precomputation table for point. */
31451     sp_table_entry_384 table[256];
31452     /* Count of entries in table. */
31453     uint32_t cnt;
31454     /* Point and table set in entry. */
31455     int set;
31456 } sp_cache_384_t;
31457 
31458 /* Cache of tables. */
31459 static THREAD_LS_T sp_cache_384_t sp_cache_384[FP_ENTRIES];
31460 /* Index of last entry in cache. */
31461 static THREAD_LS_T int sp_cache_384_last = -1;
31462 /* Cache has been initialized. */
31463 static THREAD_LS_T int sp_cache_384_inited = 0;
31464 
31465 #ifndef HAVE_THREAD_LS
31466     static volatile int initCacheMutex_384 = 0;
31467     static wolfSSL_Mutex sp_cache_384_lock;
31468 #endif
31469 
31470 /* Get the cache entry for the point.
31471  *
31472  * g      [in]   Point scalar multipling.
31473  * cache  [out]  Cache table to use.
31474  */
sp_ecc_get_cache_384(const sp_point_384 * g,sp_cache_384_t ** cache)31475 static void sp_ecc_get_cache_384(const sp_point_384* g, sp_cache_384_t** cache)
31476 {
31477     int i;
31478     int j;
31479     uint32_t least;
31480 
31481     if (sp_cache_384_inited == 0) {
31482         for (i=0; i<FP_ENTRIES; i++) {
31483             sp_cache_384[i].set = 0;
31484         }
31485         sp_cache_384_inited = 1;
31486     }
31487 
31488     /* Compare point with those in cache. */
31489     for (i=0; i<FP_ENTRIES; i++) {
31490         if (!sp_cache_384[i].set)
31491             continue;
31492 
31493         if (sp_384_cmp_equal_7(g->x, sp_cache_384[i].x) &
31494                            sp_384_cmp_equal_7(g->y, sp_cache_384[i].y)) {
31495             sp_cache_384[i].cnt++;
31496             break;
31497         }
31498     }
31499 
31500     /* No match. */
31501     if (i == FP_ENTRIES) {
31502         /* Find empty entry. */
31503         i = (sp_cache_384_last + 1) % FP_ENTRIES;
31504         for (; i != sp_cache_384_last; i=(i+1)%FP_ENTRIES) {
31505             if (!sp_cache_384[i].set) {
31506                 break;
31507             }
31508         }
31509 
31510         /* Evict least used. */
31511         if (i == sp_cache_384_last) {
31512             least = sp_cache_384[0].cnt;
31513             for (j=1; j<FP_ENTRIES; j++) {
31514                 if (sp_cache_384[j].cnt < least) {
31515                     i = j;
31516                     least = sp_cache_384[i].cnt;
31517                 }
31518             }
31519         }
31520 
31521         XMEMCPY(sp_cache_384[i].x, g->x, sizeof(sp_cache_384[i].x));
31522         XMEMCPY(sp_cache_384[i].y, g->y, sizeof(sp_cache_384[i].y));
31523         sp_cache_384[i].set = 1;
31524         sp_cache_384[i].cnt = 1;
31525     }
31526 
31527     *cache = &sp_cache_384[i];
31528     sp_cache_384_last = i;
31529 }
31530 #endif /* FP_ECC */
31531 
31532 /* Multiply the base point of P384 by the scalar and return the result.
31533  * If map is true then convert result to affine coordinates.
31534  *
31535  * r     Resulting point.
31536  * g     Point to multiply.
31537  * k     Scalar to multiply by.
31538  * map   Indicates whether to convert result to affine.
31539  * ct    Constant time required.
31540  * heap  Heap to use for allocation.
31541  * returns MEMORY_E when memory allocation fails and MP_OKAY on success.
31542  */
sp_384_ecc_mulmod_7(sp_point_384 * r,const sp_point_384 * g,const sp_digit * k,int map,int ct,void * heap)31543 static int sp_384_ecc_mulmod_7(sp_point_384* r, const sp_point_384* g, const sp_digit* k,
31544         int map, int ct, void* heap)
31545 {
31546 #ifndef FP_ECC
31547     return sp_384_ecc_mulmod_win_add_sub_7(r, g, k, map, ct, heap);
31548 #else
31549     sp_digit tmp[2 * 7 * 7];
31550     sp_cache_384_t* cache;
31551     int err = MP_OKAY;
31552 
31553 #ifndef HAVE_THREAD_LS
31554     if (initCacheMutex_384 == 0) {
31555          wc_InitMutex(&sp_cache_384_lock);
31556          initCacheMutex_384 = 1;
31557     }
31558     if (wc_LockMutex(&sp_cache_384_lock) != 0)
31559        err = BAD_MUTEX_E;
31560 #endif /* HAVE_THREAD_LS */
31561 
31562     if (err == MP_OKAY) {
31563         sp_ecc_get_cache_384(g, &cache);
31564         if (cache->cnt == 2)
31565             sp_384_gen_stripe_table_7(g, cache->table, tmp, heap);
31566 
31567 #ifndef HAVE_THREAD_LS
31568         wc_UnLockMutex(&sp_cache_384_lock);
31569 #endif /* HAVE_THREAD_LS */
31570 
31571         if (cache->cnt < 2) {
31572             err = sp_384_ecc_mulmod_win_add_sub_7(r, g, k, map, ct, heap);
31573         }
31574         else {
31575             err = sp_384_ecc_mulmod_stripe_7(r, g, cache->table, k,
31576                     map, ct, heap);
31577         }
31578     }
31579 
31580     return err;
31581 #endif
31582 }
31583 
31584 #endif
31585 /* Multiply the point by the scalar and return the result.
31586  * If map is true then convert result to affine coordinates.
31587  *
31588  * km    Scalar to multiply by.
31589  * p     Point to multiply.
31590  * r     Resulting point.
31591  * map   Indicates whether to convert result to affine.
31592  * heap  Heap to use for allocation.
31593  * returns MEMORY_E when memory allocation fails and MP_OKAY on success.
31594  */
sp_ecc_mulmod_384(const mp_int * km,const ecc_point * gm,ecc_point * r,int map,void * heap)31595 int sp_ecc_mulmod_384(const mp_int* km, const ecc_point* gm, ecc_point* r,
31596         int map, void* heap)
31597 {
31598 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
31599     sp_point_384* point = NULL;
31600     sp_digit* k = NULL;
31601 #else
31602     sp_point_384 point[1];
31603     sp_digit k[7];
31604 #endif
31605     int err = MP_OKAY;
31606 
31607 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
31608     point = (sp_point_384*)XMALLOC(sizeof(sp_point_384), heap,
31609                                          DYNAMIC_TYPE_ECC);
31610     if (point == NULL)
31611         err = MEMORY_E;
31612     if (err == MP_OKAY) {
31613         k = (sp_digit*)XMALLOC(sizeof(sp_digit) * 7, heap,
31614                                DYNAMIC_TYPE_ECC);
31615         if (k == NULL)
31616             err = MEMORY_E;
31617     }
31618 #endif
31619 
31620     if (err == MP_OKAY) {
31621         sp_384_from_mp(k, 7, km);
31622         sp_384_point_from_ecc_point_7(point, gm);
31623 
31624             err = sp_384_ecc_mulmod_7(point, point, k, map, 1, heap);
31625     }
31626     if (err == MP_OKAY) {
31627         err = sp_384_point_to_ecc_point_7(point, r);
31628     }
31629 
31630 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
31631     if (k != NULL)
31632         XFREE(k, heap, DYNAMIC_TYPE_ECC);
31633     if (point != NULL)
31634         XFREE(point, heap, DYNAMIC_TYPE_ECC);
31635 #endif
31636 
31637     return err;
31638 }
31639 
31640 /* Multiply the point by the scalar, add point a and return the result.
31641  * If map is true then convert result to affine coordinates.
31642  *
31643  * km      Scalar to multiply by.
31644  * p       Point to multiply.
31645  * am      Point to add to scalar mulitply result.
31646  * inMont  Point to add is in montgomery form.
31647  * r       Resulting point.
31648  * map     Indicates whether to convert result to affine.
31649  * heap    Heap to use for allocation.
31650  * returns MEMORY_E when memory allocation fails and MP_OKAY on success.
31651  */
sp_ecc_mulmod_add_384(const mp_int * km,const ecc_point * gm,const ecc_point * am,int inMont,ecc_point * r,int map,void * heap)31652 int sp_ecc_mulmod_add_384(const mp_int* km, const ecc_point* gm,
31653     const ecc_point* am, int inMont, ecc_point* r, int map, void* heap)
31654 {
31655 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
31656     sp_point_384* point = NULL;
31657     sp_digit* k = NULL;
31658 #else
31659     sp_point_384 point[2];
31660     sp_digit k[7 + 7 * 2 * 6];
31661 #endif
31662     sp_point_384* addP = NULL;
31663     sp_digit* tmp = NULL;
31664     int err = MP_OKAY;
31665 
31666 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
31667     point = (sp_point_384*)XMALLOC(sizeof(sp_point_384) * 2, heap,
31668                                          DYNAMIC_TYPE_ECC);
31669     if (point == NULL)
31670         err = MEMORY_E;
31671     if (err == MP_OKAY) {
31672         k = (sp_digit*)XMALLOC(
31673             sizeof(sp_digit) * (7 + 7 * 2 * 6), heap,
31674             DYNAMIC_TYPE_ECC);
31675         if (k == NULL)
31676             err = MEMORY_E;
31677     }
31678 #endif
31679 
31680     if (err == MP_OKAY) {
31681         addP = point + 1;
31682         tmp = k + 7;
31683 
31684         sp_384_from_mp(k, 7, km);
31685         sp_384_point_from_ecc_point_7(point, gm);
31686         sp_384_point_from_ecc_point_7(addP, am);
31687     }
31688     if ((err == MP_OKAY) && (!inMont)) {
31689         err = sp_384_mod_mul_norm_7(addP->x, addP->x, p384_mod);
31690     }
31691     if ((err == MP_OKAY) && (!inMont)) {
31692         err = sp_384_mod_mul_norm_7(addP->y, addP->y, p384_mod);
31693     }
31694     if ((err == MP_OKAY) && (!inMont)) {
31695         err = sp_384_mod_mul_norm_7(addP->z, addP->z, p384_mod);
31696     }
31697     if (err == MP_OKAY) {
31698             err = sp_384_ecc_mulmod_7(point, point, k, 0, 0, heap);
31699     }
31700     if (err == MP_OKAY) {
31701             sp_384_proj_point_add_7(point, point, addP, tmp);
31702 
31703         if (map) {
31704                 sp_384_map_7(point, point, tmp);
31705         }
31706 
31707         err = sp_384_point_to_ecc_point_7(point, r);
31708     }
31709 
31710 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
31711     if (k != NULL)
31712         XFREE(k, heap, DYNAMIC_TYPE_ECC);
31713     if (point != NULL)
31714         XFREE(point, heap, DYNAMIC_TYPE_ECC);
31715 #endif
31716 
31717     return err;
31718 }
31719 
31720 #ifdef WOLFSSL_SP_SMALL
31721 /* Multiply the base point of P384 by the scalar and return the result.
31722  * If map is true then convert result to affine coordinates.
31723  *
31724  * r     Resulting point.
31725  * k     Scalar to multiply by.
31726  * map   Indicates whether to convert result to affine.
31727  * heap  Heap to use for allocation.
31728  * returns MEMORY_E when memory allocation fails and MP_OKAY on success.
31729  */
sp_384_ecc_mulmod_base_7(sp_point_384 * r,const sp_digit * k,int map,int ct,void * heap)31730 static int sp_384_ecc_mulmod_base_7(sp_point_384* r, const sp_digit* k,
31731         int map, int ct, void* heap)
31732 {
31733     /* No pre-computed values. */
31734     return sp_384_ecc_mulmod_7(r, &p384_base, k, map, ct, heap);
31735 }
31736 
31737 #else
31738 /* Striping precomputation table.
31739  * 8 points combined into a table of 256 points.
31740  * Distance of 48 between points.
31741  */
31742 static const sp_table_entry_384 p384_table[256] = {
31743     /* 0 */
31744     { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
31745       { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } },
31746     /* 1 */
31747     { { 0x50756649c0b528L,0x71c541ad9c707bL,0x71506d35b8838dL,
31748         0x4d1877fc3ce1d7L,0x6de2b645486845L,0x227025fee46c29L,
31749         0x134eab708a6785L },
31750       { 0x043dad4b03a4feL,0x517ef769535846L,0x58ba0ec14286feL,
31751         0x47a7fecc5d6f3aL,0x1a840c6c352196L,0x3d3bb00044c72dL,
31752         0x0ade2af0968571L } },
31753     /* 2 */
31754     { { 0x0647532b0c535bL,0x52a6e0a0c52c53L,0x5085aae6b24375L,
31755         0x7096bb501c66b5L,0x47bdb3df9b7b7bL,0x11227e9b2f0be6L,
31756         0x088b172704fa51L },
31757       { 0x0e796f2680dc64L,0x796eb06a482ebfL,0x2b441d02e04839L,
31758         0x19bef7312a5aecL,0x02247c38b8efb5L,0x099ed1185c329eL,
31759         0x1ed71d7cdb096fL } },
31760     /* 3 */
31761     { { 0x6a3cc39edffea5L,0x7a386fafd3f9c4L,0x366f78fbd8d6efL,
31762         0x529c7ad7873b80L,0x79eb30380eb471L,0x07c5d3b51760b7L,
31763         0x36ee4f1cc69183L },
31764       { 0x5ba260f526b605L,0x2f1dfaf0aa6e6fL,0x6bb5ca812a5752L,
31765         0x3002d8d1276bc9L,0x01f82269483777L,0x1df33eaaf733cdL,
31766         0x2b97e555f59255L } },
31767     /* 4 */
31768     { { 0x480c57f26feef9L,0x4d28741c248048L,0x0c9cf8af1f0c68L,
31769         0x778f6a639a8016L,0x148e88c42e9c53L,0x464051757ecfe9L,
31770         0x1a940bd0e2a5e1L },
31771       { 0x713a46b74536feL,0x1757b153e1d7ebL,0x30dc8c9da07486L,
31772         0x3b7460c1879b5eL,0x4b766c5317b315L,0x1b9de3aaf4d377L,
31773         0x245f124c2cf8f5L } },
31774     /* 5 */
31775     { { 0x426e2ee349ddd0L,0x7df3365f84a022L,0x03b005d29a7c45L,
31776         0x422c2337f9b5a4L,0x060494f4bde761L,0x5245e5db6da0b0L,
31777         0x22b71d744677f2L },
31778       { 0x19d097b7d5a7ceL,0x6bcb468823d34cL,0x1c3692d3be1d09L,
31779         0x3c80ec7aa01f02L,0x7170f2ebaafd97L,0x06cbcc7d79d4e8L,
31780         0x04a8da511fe760L } },
31781     /* 6 */
31782     { { 0x79c07a4fc52870L,0x6e9034a752c251L,0x603860a367382cL,
31783         0x56d912d6aa87d0L,0x0a348a24abaf76L,0x6c5a23da14adcbL,
31784         0x3cf60479a522b2L },
31785       { 0x18dd774c61ed22L,0x0ff30168f93b0cL,0x3f79ae15642eddL,
31786         0x40510f4915fbcbL,0x2c9ddfdfd1c6d6L,0x67b81b62aee55eL,
31787         0x2824de79b07a43L } },
31788     /* 7 */
31789     { { 0x6c66efe085c629L,0x48c212b7913470L,0x4480fd2d057f0aL,
31790         0x725ec7a89a9eb1L,0x78ce97ca1972b7L,0x54760ee70154fbL,
31791         0x362a40e27b9f93L },
31792       { 0x474dc7e7b14461L,0x602819389ef037L,0x1a13bc284370b2L,
31793         0x0193ff1295a59dL,0x79615bde6ea5d2L,0x2e76e3d886acc1L,
31794         0x3bb796812e2b60L } },
31795     /* 8 */
31796     { { 0x04cbb3893b9a2dL,0x4c16010a18baabL,0x19f7cb50f60831L,
31797         0x084f400a0936c1L,0x72f1cdd5bbbf00L,0x1b30b725dc6702L,
31798         0x182753e4fcc50cL },
31799       { 0x059a07eadaf9d6L,0x26d81e24bf603cL,0x45583c839dc399L,
31800         0x5579d4d6b1103aL,0x2e14ea59489ae7L,0x492f6e1c5ecc97L,
31801         0x03740dc05db420L } },
31802     /* 9 */
31803     { { 0x413be88510521fL,0x3753ee49982e99L,0x6cd4f7098e1cc5L,
31804         0x613c92bda4ec1dL,0x495378b677efe0L,0x132a2143839927L,
31805         0x0cf8c336291c0bL },
31806       { 0x7fc89d2208353fL,0x751b9da85657e1L,0x349b8a97d405c3L,
31807         0x65a964b048428fL,0x1adf481276455eL,0x5560c8d89c2ffcL,
31808         0x144fc11fac21a3L } },
31809     /* 10 */
31810     { { 0x7611f4df5bdf53L,0x634eb16234db80L,0x3c713b8e51174cL,
31811         0x52c3c68ac4b2edL,0x53025ba8bebe75L,0x7175d98143105bL,
31812         0x33ca8e266a48faL },
31813       { 0x0c9281d24fd048L,0x76b3177604bbf3L,0x3b26ae754e106fL,
31814         0x7f782275c6efc6L,0x36662538a4cb67L,0x0ca1255843e464L,
31815         0x2a4674e142d9bcL } },
31816     /* 11 */
31817     { { 0x303b4085d480d8L,0x68f23650f4fa7bL,0x552a3ceeba3367L,
31818         0x6da0c4947926e3L,0x6e0f5482eb8003L,0x0de717f3d6738aL,
31819         0x22e5dcc826a477L },
31820       { 0x1b05b27209cfc2L,0x7f0a0b65b6e146L,0x63586549ed3126L,
31821         0x7d628dd2b23124L,0x383423fe510391L,0x57ff609eabd569L,
31822         0x301f04370131baL } },
31823     /* 12 */
31824     { { 0x22fe4cdb32f048L,0x7f228ebdadbf5aL,0x02a99adb2d7c8eL,
31825         0x01a02e05286706L,0x62d6adf627a89fL,0x49c6ce906fbf2bL,
31826         0x0207256dae90b9L },
31827       { 0x23e036e71d6cebL,0x199ed8d604e3d7L,0x0c1a11c076d16fL,
31828         0x389291fb3da3f3L,0x47adc60f8f942eL,0x177048468e4b9aL,
31829         0x20c09f5e61d927L } },
31830     /* 13 */
31831     { { 0x129ea63615b0b8L,0x03fb4a9b588367L,0x5ad6da8da2d051L,
31832         0x33f782f44caeaaL,0x5a27fa80d45291L,0x6d1ed796942da4L,
31833         0x08435a931ef556L },
31834       { 0x004abb25351130L,0x6d33207c6fd7e7L,0x702130972074b7L,
31835         0x0e34748af900f7L,0x762a531a28c87aL,0x3a903b5a4a6ac7L,
31836         0x1775b79c35b105L } },
31837     /* 14 */
31838     { { 0x7470fd846612ceL,0x7dd9b431b32e53L,0x04bcd2be1a61bcL,
31839         0x36ed7c5b5c260bL,0x6795f5ef0a4084L,0x46e2880b401c93L,
31840         0x17d246c5aa8bdeL },
31841       { 0x707ae4db41b38dL,0x233c31f7f9558fL,0x585110ec67bdf4L,
31842         0x4d0cc931d0c703L,0x26fbe4356841a7L,0x64323e95239c44L,
31843         0x371dc9230f3221L } },
31844     /* 15 */
31845     { { 0x70ff1ae4b1ec9dL,0x7c1dcfddee0daaL,0x53286782188748L,
31846         0x6a5d9381e6f207L,0x3aa6c7d6523c4cL,0x6c02d83e0d97e2L,
31847         0x16a9c916b45312L },
31848       { 0x78146744b74de8L,0x742ec415269c6fL,0x237a2c6a860e79L,
31849         0x186baf17ba68a7L,0x4261e8789fa51fL,0x3dc136480a5903L,
31850         0x1953899e0cf159L } },
31851     /* 16 */
31852     { { 0x0205de2f9fbe67L,0x1706fee51c886fL,0x31a0b803c712bfL,
31853         0x0a6aa11ede7603L,0x2463ef2a145c31L,0x615403b30e8f4aL,
31854         0x3f024d6c5f5c5eL },
31855       { 0x53bc4fd4d01f95L,0x7d512ac15a692cL,0x72be38fcfe6aa0L,
31856         0x437f0b77bbca1eL,0x7fdcf70774a10eL,0x392d6c5cde37f3L,
31857         0x229cbce79621d1L } },
31858     /* 17 */
31859     { { 0x2de4da2341c342L,0x5ca9d4e08844e7L,0x60dd073bcf74c9L,
31860         0x4f30aa499b63ecL,0x23efd1eafa00d5L,0x7c99a7db1257b3L,
31861         0x00febc9b3171b1L },
31862       { 0x7e2fcf3045f8acL,0x2a642e9e3ce610L,0x23f82be69c5299L,
31863         0x66e49ad967c279L,0x1c895ddfd7a842L,0x798981e22f6d25L,
31864         0x0d595cb59322f3L } },
31865     /* 18 */
31866     { { 0x4bac017d8c1bbaL,0x73872161e7aafdL,0x0fd865f43d8163L,
31867         0x019d89457708b7L,0x1b983c4dd70684L,0x095e109b74d841L,
31868         0x25f1f0b3e0c76fL },
31869       { 0x4e61ddf96010e8L,0x1c40a53f542e5eL,0x01a74dfc8365f9L,
31870         0x69b36b92773333L,0x08e0fccc139ed3L,0x266d216ddc4269L,
31871         0x1f2b47717ce9b5L } },
31872     /* 19 */
31873     { { 0x0a9a81da57a41fL,0x0825d800736cccL,0x2d7876b4579d28L,
31874         0x3340ea6211a1e3L,0x49e89284f3ff54L,0x6276a210fe2c6eL,
31875         0x01c3c8f31be7cbL },
31876       { 0x2211da5d186e14L,0x1e6ffbb61bfea8L,0x536c7d060211d2L,
31877         0x320168720d1d55L,0x5835525ed667baL,0x5125e52495205eL,
31878         0x16113b9f3e9129L } },
31879     /* 20 */
31880     { { 0x3086073f3b236fL,0x283b03c443b5f5L,0x78e49ed0a067a7L,
31881         0x2a878fb79fb2b8L,0x662f04348a9337L,0x57ee2cf732d50bL,
31882         0x18b50dd65fd514L },
31883       { 0x5feb9ef2955926L,0x2c3edbef06a7b0L,0x32728dad651029L,
31884         0x116d00b1c4b347L,0x13254052bf1a1aL,0x3e77bf7fee5ec1L,
31885         0x253943ca388882L } },
31886     /* 21 */
31887     { { 0x32e5b33062e8afL,0x46ebd147a6d321L,0x2c8076dec6a15cL,
31888         0x7328d511ff0d80L,0x10ad7e926def0eL,0x4e8ca85937d736L,
31889         0x02638c26e8bf2fL },
31890       { 0x1deeb3fff1d63fL,0x5014417fa6e8efL,0x6e1da3de5c8f43L,
31891         0x7ca942b42295d9L,0x23faacf75bb4d1L,0x4a71fcd680053dL,
31892         0x04af4f90204dceL } },
31893     /* 22 */
31894     { { 0x23780d104cbba5L,0x4e8ff46bba9980L,0x2072a6da8d881fL,
31895         0x3cc3d881ae11c9L,0x2eee84ff19be89L,0x69b708ed77f004L,
31896         0x2a82928534eef9L },
31897       { 0x794331187d4543L,0x70e0f3edc0cc41L,0x3ab1fa0b84c854L,
31898         0x1478355c1d87baL,0x6f35fa7748ba28L,0x37b8be0531584dL,
31899         0x03c3141c23a69fL } },
31900     /* 23 */
31901     { { 0x5c244cdef029ddL,0x0d0f0a0cc37018L,0x17f8476604f6afL,
31902         0x13a6dd6ccc95c3L,0x5a242e9801b8f6L,0x211ca9cc632131L,
31903         0x264a6a46a4694fL },
31904       { 0x3ffd7235285887L,0x284be28302046fL,0x57f4b9b882f1d6L,
31905         0x5e21772c940661L,0x7619a735c600cfL,0x2f76f5a50c9106L,
31906         0x28d89c8c69de31L } },
31907     /* 24 */
31908     { { 0x799b5c91361ed8L,0x36ead8c66cd95cL,0x046c9969a91f5cL,
31909         0x46bbdba2a66ea9L,0x29db0e0215a599L,0x26c8849b36f756L,
31910         0x22c3feb31ff679L },
31911       { 0x585d1237b5d9efL,0x5ac57f522e8e8dL,0x617e66e8b56c41L,
31912         0x68826f276823cfL,0x0983f0e6f39231L,0x4e1075099084bdL,
31913         0x2a541f82be0416L } },
31914     /* 25 */
31915     { { 0x468a6e14cf381cL,0x4f7b845c6399edL,0x36aa29732ebe74L,
31916         0x19c726911ab46aL,0x2ad1fe431eec0eL,0x301e35051fd1eaL,
31917         0x36da815e7a1ab3L },
31918       { 0x05672e4507832aL,0x4ebf10fca51251L,0x6015843421cff0L,
31919         0x3affad832fc013L,0x712b58d9b45540L,0x1e4751d1f6213eL,
31920         0x0e7c2b218bafa7L } },
31921     /* 26 */
31922     { { 0x7abf784c52edf5L,0x6fcb4b135ca7b1L,0x435e46ac5f735cL,
31923         0x67f8364ca48c5fL,0x46d45b5fbd956bL,0x10deda6065db94L,
31924         0x0b37fdf85068f9L },
31925       { 0x74b3ba61f47ec8L,0x42c7ddf08c10ccL,0x1531a1fe422a20L,
31926         0x366f913d12be38L,0x6a846e30cb2edfL,0x2785898c994fedL,
31927         0x061be85f331af3L } },
31928     /* 27 */
31929     { { 0x23f5361dfcb91eL,0x3c26c8da6b1491L,0x6e444a1e620d65L,
31930         0x0c3babd5e8ac13L,0x573723ce612b82L,0x2d10e62a142c37L,
31931         0x3d1a114c2d98bdL },
31932       { 0x33950b401896f6L,0x7134efe7c12110L,0x31239fd2978472L,
31933         0x30333bf5978965L,0x79f93313dd769fL,0x457fb9e11662caL,
31934         0x190a73b251ae3cL } },
31935     /* 28 */
31936     { { 0x04dd54bb75f9a4L,0x0d7253a76ae093L,0x08f5b930792bbcL,
31937         0x041f79adafc265L,0x4a9ff24c61c11bL,0x0019c94e724725L,
31938         0x21975945d9cc2aL },
31939       { 0x3dfe76722b4a2bL,0x17f2f6107c1d94L,0x546e1ae2944b01L,
31940         0x53f1f06401e72dL,0x2dbe43fc7632d6L,0x5639132e185903L,
31941         0x0f2f34eb448385L } },
31942     /* 29 */
31943     { { 0x7b4cc7ec30ce93L,0x58fb6e4e4145f7L,0x5d1ed5540043b5L,
31944         0x19ffbe1f633adfL,0x5bfc0907259033L,0x6378f872e7ca0eL,
31945         0x2c127b2c01eb3cL },
31946       { 0x076eaf4f58839cL,0x2db54560bc9f68L,0x42ad0319b84062L,
31947         0x46c325d1fb019dL,0x76d2a19ee9eebcL,0x6fbd6d9e2aa8f7L,
31948         0x2396a598fe0991L } },
31949     /* 30 */
31950     { { 0x662fddf7fbd5e1L,0x7ca8ed22563ad3L,0x5b4768efece3b3L,
31951         0x643786a422d1eaL,0x36ce80494950e1L,0x1a30795b7f2778L,
31952         0x107f395c93f332L },
31953       { 0x7939c28332c144L,0x491610e3c8dc0bL,0x099ba2bfdac5fcL,
31954         0x5c2e3149ec29a7L,0x31b731d06f1dc3L,0x1cbb60d465d462L,
31955         0x3ca5461362cfd9L } },
31956     /* 31 */
31957     { { 0x653ff736ddc103L,0x7c6f2bdec0dfb2L,0x73f81b73a097d0L,
31958         0x05b775f84f180fL,0x56b2085af23413L,0x0d6f36256a61feL,
31959         0x26d3ed267fa68fL },
31960       { 0x54f89251d27ac2L,0x4fc6ad94a71202L,0x7ebf01969b4cc5L,
31961         0x7ba364dbc14760L,0x4f8370959a2587L,0x7b7631e37c6188L,
31962         0x29e51845f104cbL } },
31963     /* 32 */
31964     { { 0x426b775e3c647bL,0x327319e0a69180L,0x0c5cb034f6ff2fL,
31965         0x73aa39b98e9897L,0x7ee615f49fde6eL,0x3f712aa61e0db4L,
31966         0x33ca06c2ba2ce9L },
31967       { 0x14973541b8a543L,0x4b4e6101ba61faL,0x1d94e4233d0698L,
31968         0x501513c715d570L,0x1b8f8c3d01436bL,0x52f41a0445cf64L,
31969         0x3f709c3a75fb04L } },
31970     /* 33 */
31971     { { 0x073c0cbc7f41d6L,0x227c36f5ac8201L,0x508e110fef65d8L,
31972         0x0f317229529b7fL,0x45fc6030d00e24L,0x118a65d30cebeaL,
31973         0x3340cc4223a448L },
31974       { 0x204c999797612cL,0x7c05dd4ce9c5a3L,0x7b865d0a8750e4L,
31975         0x2f82c876ab7d34L,0x2243ddd2ab4808L,0x6834b9df8a4914L,
31976         0x123319ed950e0fL } },
31977     /* 34 */
31978     { { 0x50430efc14ab48L,0x7e9e4ce0d4e89cL,0x2332207fd8656dL,
31979         0x4a2809e97f4511L,0x2162bb1b968e2dL,0x29526d54af2972L,
31980         0x13edd9adcd939dL },
31981       { 0x793bca31e1ff7fL,0x6b959c9e4d2227L,0x628ac27809a5baL,
31982         0x2c71ffc7fbaa5fL,0x0c0b058f13c9ceL,0x5676eae68de2cfL,
31983         0x35508036ea19a4L } },
31984     /* 35 */
31985     { { 0x030bbd6dda1265L,0x67f9d12e31bb34L,0x7e4d8196e3ded3L,
31986         0x7b9120e5352498L,0x75857bce72d875L,0x4ead976a396caeL,
31987         0x31c5860553a64dL },
31988       { 0x1a0f792ee32189L,0x564c4efb8165d0L,0x7adc7d1a7fbcbeL,
31989         0x7ed7c2ccf327b7L,0x35df1b448ce33dL,0x6f67eb838997cdL,
31990         0x3ee37ec0077917L } },
31991     /* 36 */
31992     { { 0x345fa74d5bb921L,0x097c9a56ccfd8eL,0x00a0b5e8f971f8L,
31993         0x723d95223f69d4L,0x08e2e5c2777f87L,0x68b13676200109L,
31994         0x26ab5df0acbad6L },
31995       { 0x01bca7daac34aeL,0x49ca4d5f664dadL,0x110687b850914bL,
31996         0x1203d6f06443c9L,0x7a2ac743b04d4cL,0x40d96bd3337f82L,
31997         0x13728be0929c06L } },
31998     /* 37 */
31999     { { 0x631ca61127bc1aL,0x2b362fd5a77cd1L,0x17897d68568fb7L,
32000         0x21070af33db5b2L,0x6872e76221794aL,0x436f29fb076963L,
32001         0x1f2acfc0ecb7b3L },
32002       { 0x19bf15ca9b3586L,0x32489a4a17aee2L,0x2b31af3c929551L,
32003         0x0db7c420b9b19fL,0x538c39bd308c2bL,0x438775c0dea88fL,
32004         0x1537304d7cd07fL } },
32005     /* 38 */
32006     { { 0x53598d943caf0dL,0x1d5244bfe266adL,0x7158feb7ab3811L,
32007         0x1f46e13cf6fb53L,0x0dcab632eb9447L,0x46302968cfc632L,
32008         0x0b53d3cc5b6ec7L },
32009       { 0x69811ca143b7caL,0x5865bcf9f2a11aL,0x74ded7fa093b06L,
32010         0x1c878ec911d5afL,0x04610e82616e49L,0x1e157fe9640eb0L,
32011         0x046e6f8561d6c2L } },
32012     /* 39 */
32013     { { 0x631a3d3bbe682cL,0x3a4ce9dde5ba95L,0x28f11f7502f1f1L,
32014         0x0a55cf0c957e88L,0x495e4ec7e0a3bcL,0x30ad4d87ba365cL,
32015         0x0217b97a4c26f3L },
32016       { 0x01a9088c2e67fdL,0x7501c4c3d5e5e7L,0x265b7bb854c820L,
32017         0x729263c87e6b52L,0x308b9e3b8fb035L,0x33f1b86c1b23abL,
32018         0x0e81b8b21fc99cL } },
32019     /* 40 */
32020     { { 0x59f5a87237cac0L,0x6b3a86b0cf28b9L,0x13a53db13a4fc2L,
32021         0x313c169a1c253bL,0x060158304ed2bbL,0x21e171b71679bcL,
32022         0x10cdb754d76f86L },
32023       { 0x44355392ab473aL,0x64eb7cbda08caeL,0x3086426a900c71L,
32024         0x49016ed9f3c33cL,0x7e6354ab7e04f9L,0x17c4c91a40cd2eL,
32025         0x3509f461024c66L } },
32026     /* 41 */
32027     { { 0x2848f50f9b5a31L,0x68d1755b6c5504L,0x48cd5d5672ec00L,
32028         0x4d77421919d023L,0x1e1e349ef68807L,0x4ab5130cf415d7L,
32029         0x305464c6c7dbe6L },
32030       { 0x64eb0bad74251eL,0x64c6957e52bda4L,0x6c12583440dee6L,
32031         0x6d3bee05b00490L,0x186970de53dbc4L,0x3be03b37567a56L,
32032         0x2b553b1ebdc55bL } },
32033     /* 42 */
32034     { { 0x74dc3579efdc58L,0x26d29fed1bb71cL,0x334c825a9515afL,
32035         0x433c1e839273a6L,0x0d8a4e41cff423L,0x3454098fe42f8eL,
32036         0x1046674bf98686L },
32037       { 0x09a3e029c05dd2L,0x54d7cfc7fb53a7L,0x35f0ad37e14d7cL,
32038         0x73a294a13767b9L,0x3f519678275f4fL,0x788c63393993a4L,
32039         0x0781680b620123L } },
32040     /* 43 */
32041     { { 0x4c8e2ed4d5ffe8L,0x112db7d42fe4ebL,0x433b8f2d2be2edL,
32042         0x23e30b29a82cbcL,0x35d2f4c06ee85aL,0x78ff31ffe4b252L,
32043         0x0d31295c8cbff5L },
32044       { 0x314806ea0376a2L,0x4ea09e22bc0589L,0x0879575f00ba97L,
32045         0x188226d2996bb7L,0x7799368dc9411fL,0x7ab24e5c8cae36L,
32046         0x2b6a8e2ee4ea33L } },
32047     /* 44 */
32048     { { 0x70c7127d4ed72aL,0x24c9743ef34697L,0x2fd30e7a93683aL,
32049         0x538a89c246012cL,0x6c660a5394ed82L,0x79a95ea239d7e0L,
32050         0x3f3af3bbfb170dL },
32051       { 0x3b75aa779ae8c1L,0x33995a3cc0dde4L,0x7489d5720b7bfdL,
32052         0x599677ef9fa937L,0x3defd64c5ab44bL,0x27d52dc234522bL,
32053         0x2ac65d1a8450e0L } },
32054     /* 45 */
32055     { { 0x478585ec837d7dL,0x5f7971dc174887L,0x67576ed7bb296dL,
32056         0x5a78e529a74926L,0x640f73f4fa104bL,0x7d42a8b16e4730L,
32057         0x108c7eaa75fd01L },
32058       { 0x60661ef96e6896L,0x18d3a0761f3aa7L,0x6e71e163455539L,
32059         0x165827d6a7e583L,0x4e7f77e9527935L,0x790bebe2ae912eL,
32060         0x0b8fe9561adb55L } },
32061     /* 46 */
32062     { { 0x4d48036a9951a8L,0x371084f255a085L,0x66aeca69cea2c5L,
32063         0x04c99f40c745e7L,0x08dc4bfd9a0924L,0x0b0ec146b29df7L,
32064         0x05106218d01c91L },
32065       { 0x2a56ee99caedc7L,0x5d9b23a203922cL,0x1ce4c80b6a3ec4L,
32066         0x2666bcb75338cbL,0x185a81aac8c4aaL,0x2b4fb60a06c39eL,
32067         0x0327e1b3633f42L } },
32068     /* 47 */
32069     { { 0x72814710b2a556L,0x52c864f6e16534L,0x4978de66ddd9f2L,
32070         0x151f5950276cf0L,0x450ac6781d2dc2L,0x114b7a22dd61b2L,
32071         0x3b32b07f29faf8L },
32072       { 0x68444fdc2d6e94L,0x68526bd9e437bcL,0x0ca780e8b0d887L,
32073         0x69f3f850a716aaL,0x500b953e42cd57L,0x4e57744d812e7dL,
32074         0x000a5f0e715f48L } },
32075     /* 48 */
32076     { { 0x2aab10b8243a7dL,0x727d1f4b18b675L,0x0e6b9fdd91bbbbL,
32077         0x0d58269fc337e5L,0x45d6664105a266L,0x11946af1b14072L,
32078         0x2c2334f91e46e1L },
32079       { 0x6dc5f8756d2411L,0x21b34eaa25188bL,0x0d2797da83529eL,
32080         0x324df55616784bL,0x7039ec66d267dfL,0x2de79cdb2d108cL,
32081         0x14011b1ad0bde0L } },
32082     /* 49 */
32083     { { 0x2e160266425043L,0x55fbe11b712125L,0x7e3c58b3947fd9L,
32084         0x67aacc79c37ad3L,0x4a18e18d2dea0fL,0x5eef06e5674351L,
32085         0x37c3483ae33439L },
32086       { 0x5d5e1d75bb4045L,0x0f9d72db296efdL,0x60b1899dd894a9L,
32087         0x06e8818ded949aL,0x747fd853c39434L,0x0953b937d9efabL,
32088         0x09f08c0beeb901L } },
32089     /* 50 */
32090     { { 0x1d208a8f2d49ceL,0x54042c5be1445aL,0x1c2681fd943646L,
32091         0x219c8094e2e674L,0x442cddf07238b8L,0x574a051c590832L,
32092         0x0b72f4d61c818aL },
32093       { 0x7bc3cbe4680967L,0x0c8b3f25ae596bL,0x0445b0da74a9efL,
32094         0x0bbf46c40363b7L,0x1df575c50677a3L,0x016ea6e73d68adL,
32095         0x0b5207bd8db0fdL } },
32096     /* 51 */
32097     { { 0x2d39fdfea1103eL,0x2b252bf0362e34L,0x63d66c992baab9L,
32098         0x5ac97706de8550L,0x0cca390c39c1acL,0x0d9bec5f01b2eaL,
32099         0x369360a0f7e5f3L },
32100       { 0x6dd3461e201067L,0x70b2d3f63ed614L,0x487580487c54c7L,
32101         0x6020e48a44af2aL,0x1ccf80b21aab04L,0x3cf3b12d88d798L,
32102         0x349368eccc506fL } },
32103     /* 52 */
32104     { { 0x5a053753b0a354L,0x65e818dbb9b0aeL,0x7d5855ee50e4bfL,
32105         0x58dc06885c7467L,0x5ee15073e57bd3L,0x63254ebc1e07fdL,
32106         0x1d48e0392aa39bL },
32107       { 0x4e227c6558ffe9L,0x0c3033d8a82a3eL,0x7bde65c214e8d2L,
32108         0x6e23561559c16aL,0x5094c5e6deaffdL,0x78dca2880f1f91L,
32109         0x3d9d3f947d838dL } },
32110     /* 53 */
32111     { { 0x387ae5af63408fL,0x6d539aeb4e6edfL,0x7f3d3186368e70L,
32112         0x01a6446bc19989L,0x35288fbcd4482fL,0x39288d34ec2736L,
32113         0x1de9c47159ad76L },
32114       { 0x695dc7944f8d65L,0x3eca2c35575094L,0x0c918059a79b69L,
32115         0x4573a48c32a74eL,0x580d8bc8b93f52L,0x190be3a3d071eaL,
32116         0x2333e686b3a8cbL } },
32117     /* 54 */
32118     { { 0x2b110c7196fee2L,0x3ac70e99128a51L,0x20a6bb6b75d5e6L,
32119         0x5f447fa513149aL,0x560d69714cc7b2L,0x1d3ee25279fab1L,
32120         0x369adb2ccca959L },
32121       { 0x3fddb13dd821c2L,0x70bf21ba647be8L,0x64121227e3cbc9L,
32122         0x12633a4c892320L,0x3c15c61660f26dL,0x1932c3b3d19900L,
32123         0x18c718563eab71L } },
32124     /* 55 */
32125     { { 0x72ebe0fd752366L,0x681c2737d11759L,0x143c805e7ae4f0L,
32126         0x78ed3c2cc7b324L,0x5c16e14820254fL,0x226a4f1c4ec9f0L,
32127         0x2891bb915eaac6L },
32128       { 0x061eb453763b33L,0x07f88b81781a87L,0x72b5ac7a87127cL,
32129         0x7ea4e4cd7ff8b5L,0x5e8c3ce33908b6L,0x0bcb8a3d37feffL,
32130         0x01da9e8e7fc50bL } },
32131     /* 56 */
32132     { { 0x639dfe9e338d10L,0x32dfe856823608L,0x46a1d73bca3b9aL,
32133         0x2da685d4b0230eL,0x6e0bc1057b6d69L,0x7144ec724a5520L,
32134         0x0b067c26b87083L },
32135       { 0x0fc3f0eef4c43dL,0x63500f509552b7L,0x220d74af6f8b86L,
32136         0x038996eafa2aa9L,0x7f6750f4aee4d2L,0x3e1d3f06718720L,
32137         0x1ea1d37243814cL } },
32138     /* 57 */
32139     { { 0x322d4597c27050L,0x1beeb3ce17f109L,0x15e5ce2e6ef42eL,
32140         0x6c8be27da6b3a0L,0x66e3347f4d5f5cL,0x7172133899c279L,
32141         0x250aff4e548743L },
32142       { 0x28f0f6a43b566dL,0x0cd2437fefbca0L,0x5b1108cb36bdbaL,
32143         0x48a834d41fb7c2L,0x6cb8565680579fL,0x42da2412b45d9fL,
32144         0x33dfc1abb6c06eL } },
32145     /* 58 */
32146     { { 0x56e3c48ef96c80L,0x65667bb6c1381eL,0x09f70514375487L,
32147         0x1548ff115f4a08L,0x237de2d21a0710L,0x1425cdee9f43dfL,
32148         0x26a6a42e055b0aL },
32149       { 0x4ea9ea9dc7dfcbL,0x4df858583ac58aL,0x1d274f819f1d39L,
32150         0x26e9c56cf91fcbL,0x6cee31c7c3a465L,0x0bb8e00b108b28L,
32151         0x226158da117301L } },
32152     /* 59 */
32153     { { 0x5a7cd4fce73946L,0x7b6a462d0ac653L,0x732ea4bb1a3da5L,
32154         0x7c8e9f54711af4L,0x0a6cd55d4655f9L,0x341e6d13e4754aL,
32155         0x373c87098879a8L },
32156       { 0x7bc82e61b818bfL,0x5f2db48f44879fL,0x2a2f06833f1d28L,
32157         0x494e5b691a74c0L,0x17d6cf35fd6b57L,0x5f7028d1c25dfcL,
32158         0x377a9ab9562cb6L } },
32159     /* 60 */
32160     { { 0x4de8877e787b2eL,0x183e7352621a52L,0x2ab0509974962bL,
32161         0x045a450496cb8aL,0x3bf7118b5591c7L,0x7724f98d761c35L,
32162         0x301607e8d5a0c1L },
32163       { 0x0f58a3f24d4d58L,0x3771c19c464f3cL,0x06746f9c0bfafaL,
32164         0x56564c9c8feb52L,0x0d66d9a7d8a45fL,0x403578141193caL,
32165         0x00b0d0bdc19260L } },
32166     /* 61 */
32167     { { 0x571407157bdbc2L,0x138d5a1c2c0b99L,0x2ee4a8057dcbeaL,
32168         0x051ff2b58e9ed1L,0x067378ad9e7cdaL,0x7cc2c1db97a49eL,
32169         0x1e7536ccd849d6L },
32170       { 0x531fd95f3497c4L,0x55dc08325f61a7L,0x144e942bce32bfL,
32171         0x642d572f09e53aL,0x556ff188261678L,0x3e79c0d9d513d6L,
32172         0x0bbbc6656f6d52L } },
32173     /* 62 */
32174     { { 0x57d3eb50596edcL,0x26c520a487451dL,0x0a92db40aea8d6L,
32175         0x27df6345109616L,0x7733d611fd727cL,0x61d14171fef709L,
32176         0x36169ae417c36bL },
32177       { 0x6899f5d4091cf7L,0x56ce5dfe4ed0c1L,0x2c430ce5913fbcL,
32178         0x1b13547e0f8caeL,0x4840a8275d3699L,0x59b8ef209e81adL,
32179         0x22362dff5ea1a2L } },
32180     /* 63 */
32181     { { 0x7237237bd98425L,0x73258e162a9d0bL,0x0a59a1e8bb5118L,
32182         0x4190a7ee5d8077L,0x13684905fdbf7cL,0x31c4033a52626bL,
32183         0x010a30e4fbd448L },
32184       { 0x47623f981e909aL,0x670af7c325b481L,0x3d004241fa4944L,
32185         0x0905a2ca47f240L,0x58f3cdd7a187c3L,0x78b93aee05b43fL,
32186         0x19b91d4ef8d63bL } },
32187     /* 64 */
32188     { { 0x0d34e116973cf4L,0x4116fc9e69ee0eL,0x657ae2b4a482bbL,
32189         0x3522eed134d7cdL,0x741e0dde0a036aL,0x6554316a51cc7bL,
32190         0x00f31c6ca89837L },
32191       { 0x26770aa06b1dd7L,0x38233a4ceba649L,0x065a1110c96feaL,
32192         0x18d367839e0f15L,0x794543660558d1L,0x39b605139065dcL,
32193         0x29abbec071b637L } },
32194     /* 65 */
32195     { { 0x1464b401ab5245L,0x16db891b27ff74L,0x724eb49cb26e34L,
32196         0x74fee3bc9cc33eL,0x6a8bdbebe085eaL,0x5c2e75ca207129L,
32197         0x1d03f2268e6b08L },
32198       { 0x28b0a328e23b23L,0x645dc26209a0bcL,0x62c28990348d49L,
32199         0x4dd9be1fa333d0L,0x6183aac74a72e4L,0x1d6f3ee69e1d03L,
32200         0x2fff96db0ff670L } },
32201     /* 66 */
32202     { { 0x2358f5c6a2123fL,0x5b2bfc51bedb63L,0x4fc6674be649ecL,
32203         0x51fc16e44b813aL,0x2ffe10a73754c1L,0x69a0c7a053aeefL,
32204         0x150e605fb6b9b4L },
32205       { 0x179eef6b8b83c4L,0x64293b28ad05efL,0x331795fab98572L,
32206         0x09823eec78727dL,0x36508042b89b81L,0x65f1106adb927eL,
32207         0x2fc0234617f47cL } },
32208     /* 67 */
32209     { { 0x12aa244e8068dbL,0x0c834ae5348f00L,0x310fc1a4771cb3L,
32210         0x6c90a2f9e19ef9L,0x77946fa0573471L,0x37f5df81e5f72fL,
32211         0x204f5d72cbe048L },
32212       { 0x613c724383bba6L,0x1ce14844967e0aL,0x797c85e69aa493L,
32213         0x4fb15b0f2ce765L,0x5807978e2e8aa7L,0x52c75859876a75L,
32214         0x1554635c763d3eL } },
32215     /* 68 */
32216     { { 0x4f292200623f3bL,0x6222be53d7fe07L,0x1e02a9a08c2571L,
32217         0x22c6058216b912L,0x1ec20044c7ba17L,0x53f94c5efde12bL,
32218         0x102b8aadfe32a4L },
32219       { 0x45377aa927b102L,0x0d41b8062ee371L,0x77085a9018e62aL,
32220         0x0c69980024847cL,0x14739b423a73a9L,0x52ec6961fe3c17L,
32221         0x38a779c94b5a7dL } },
32222     /* 69 */
32223     { { 0x4d14008435af04L,0x363bfd8325b4e8L,0x48cdb715097c95L,
32224         0x1b534540f8bee0L,0x4ca1e5c90c2a76L,0x4b52c193d6eee0L,
32225         0x277a33c79becf5L },
32226       { 0x0fee0d511d3d06L,0x4627f3d6a58f8cL,0x7c81ac245119b8L,
32227         0x0c8d526ba1e07aL,0x3dbc242f55bac2L,0x2399df8f91fffdL,
32228         0x353e982079ba3bL } },
32229     /* 70 */
32230     { { 0x6405d3b0ab9645L,0x7f31abe3ee236bL,0x456170a9babbb1L,
32231         0x09634a2456a118L,0x5b1c6045acb9e5L,0x2c75c20d89d521L,
32232         0x2e27ccf5626399L },
32233       { 0x307cd97fed2ce4L,0x1c2fbb02b64087L,0x542a068d27e64dL,
32234         0x148c030b3bc6a6L,0x671129e616ade5L,0x123f40db60dafcL,
32235         0x07688f3c621220L } },
32236     /* 71 */
32237     { { 0x1c46b342f2c4b5L,0x27decc0b3c8f04L,0x0d9bd433464c54L,
32238         0x1f3d893b818572L,0x2536043b536c94L,0x57e00c4b19ebf9L,
32239         0x3938fb9e5ad55eL },
32240       { 0x6b390024c8b22fL,0x4583f97e20a976L,0x2559d24abcbad7L,
32241         0x67a9cabc9bd8c6L,0x73a56f09432e4aL,0x79eb0beb53a3b7L,
32242         0x3e19d47f6f8221L } },
32243     /* 72 */
32244     { { 0x7399cb9d10e0b2L,0x32acc1b8a36e2aL,0x287d60c2407035L,
32245         0x42c82420ea4b5cL,0x13f286658bc268L,0x3c91181156e064L,
32246         0x234b83dcdeb963L },
32247       { 0x79bc95486cfee6L,0x4d8fd3cb78af36L,0x07362ba5e80da8L,
32248         0x79d024a0d681b0L,0x6b58406907f87fL,0x4b40f1e977e58fL,
32249         0x38dcc6fd5fa342L } },
32250     /* 73 */
32251     { { 0x72282be1cd0abeL,0x02bd0fdfdf44e5L,0x19b0e0d2f753e4L,
32252         0x4514e76ce8c4c0L,0x02ebc9c8cdcc1bL,0x6ac0c0373e9fddL,
32253         0x0dc414af1c81a9L },
32254       { 0x7a109246f32562L,0x26982e6a3768edL,0x5ecd8daed76ab5L,
32255         0x2eaa70061eb261L,0x09e7c038a8c514L,0x2a2603cc300658L,
32256         0x25d93ab9e55cd4L } },
32257     /* 74 */
32258     { { 0x11b19fcbd5256aL,0x41e4d94274770fL,0x0133c1a411001fL,
32259         0x360bac481dbca3L,0x45908b18a9c22bL,0x1e34396fafb03aL,
32260         0x1b84fea7486edaL },
32261       { 0x183c62a71e6e16L,0x5f1dc30e93da8eL,0x6cb97b502573c3L,
32262         0x3708bf0964e3fcL,0x35a7f042eeacceL,0x56370da902c27fL,
32263         0x3a873c3b72797fL } },
32264     /* 75 */
32265     { { 0x6573c9cea4cc9bL,0x2c3b5f9d91e6dcL,0x2a90e2dbd9505eL,
32266         0x66a75444025f81L,0x1571fb894b03cdL,0x5d1a1f00fd26f3L,
32267         0x0d19a9fd618855L },
32268       { 0x659acd56515664L,0x7279478bd616a3L,0x09a909e76d56c3L,
32269         0x2fd70474250358L,0x3a1a25c850579cL,0x11b9e0f71b74ccL,
32270         0x1268daef3d1bffL } },
32271     /* 76 */
32272     { { 0x7f5acc46d93106L,0x5bc15512f939c8L,0x504b5f92f996deL,
32273         0x25965549be7a64L,0x357a3a2ae9b80dL,0x3f2bcf9c139cc0L,
32274         0x0a7ddd99f23b35L },
32275       { 0x6868f5a8a0b1c5L,0x319ec52f15b1beL,0x0770000a849021L,
32276         0x7f4d50287bd608L,0x62c971d28a9d7fL,0x164e89309acb72L,
32277         0x2a29f002cf4a32L } },
32278     /* 77 */
32279     { { 0x58a852ae11a338L,0x27e3a35f2dcef8L,0x494d5731ce9e18L,
32280         0x49516f33f4bb3eL,0x386b26ba370097L,0x4e8fac1ec30248L,
32281         0x2ac26d4c44455dL },
32282       { 0x20484198eb9dd0L,0x75982a0e06512bL,0x152271b9279b05L,
32283         0x5908a9857e36d2L,0x6a933ab45a60abL,0x58d8b1acb24fafL,
32284         0x28fbcf19425590L } },
32285     /* 78 */
32286     { { 0x5420e9df010879L,0x4aba72aec2f313L,0x438e544eda7494L,
32287         0x2e8e189ce6f7eaL,0x2f771e4efe45bdL,0x0d780293bce7efL,
32288         0x1569ad3d0d02acL },
32289       { 0x325251ebeaf771L,0x02510f1a8511e2L,0x3863816bf8aad1L,
32290         0x60fdb15fe6ac19L,0x4792aef52a348cL,0x38e57a104e9838L,
32291         0x0d171611a1df1bL } },
32292     /* 79 */
32293     { { 0x15ceb0bea65e90L,0x6e56482db339bcL,0x37f618f7b0261fL,
32294         0x6351abc226dabcL,0x0e999f617b74baL,0x37d3cc57af5b69L,
32295         0x21df2b987aac68L },
32296       { 0x2dddaa3a358610L,0x2da264bc560e47L,0x545615d538bf13L,
32297         0x1c95ac244b8cc7L,0x77de1f741852cbL,0x75d324f00996abL,
32298         0x3a79b13b46aa3bL } },
32299     /* 80 */
32300     { { 0x7db63998683186L,0x6849bb989d530cL,0x7b53c39ef7ed73L,
32301         0x53bcfbf664d3ffL,0x25ef27c57f71c7L,0x50120ee80f3ad6L,
32302         0x243aba40ed0205L },
32303       { 0x2aae5e0ee1fcebL,0x3449d0d8343fbeL,0x5b2864fb7cffc7L,
32304         0x64dceb5407ac3eL,0x20303a5695523dL,0x3def70812010b2L,
32305         0x07be937f2e9b6fL } },
32306     /* 81 */
32307     { { 0x5838f9e0540015L,0x728d8720efb9f7L,0x1ab5864490b0c8L,
32308         0x6531754458fdcfL,0x600ff9612440c0L,0x48735b36a585b7L,
32309         0x3d4aaea86b865dL },
32310       { 0x6898942cac32adL,0x3c84c5531f23a1L,0x3c9dbd572f7edeL,
32311         0x5691f0932a2976L,0x186f0db1ac0d27L,0x4fbed18bed5bc9L,
32312         0x0e26b0dee0b38cL } },
32313     /* 82 */
32314     { { 0x1188b4f8e60f5bL,0x602a915455b4a2L,0x60e06af289ff99L,
32315         0x579fe4bed999e5L,0x2bc03b15e6d9ddL,0x1689649edd66d5L,
32316         0x3165e277dca9d2L },
32317       { 0x7cb8a529cf5279L,0x57f8035b34d84dL,0x352e2eb26de8f1L,
32318         0x6406820c3367c4L,0x5d148f4c899899L,0x483e1408482e15L,
32319         0x1680bd1e517606L } },
32320     /* 83 */
32321     { { 0x5c877cc1c90202L,0x2881f158eae1f4L,0x6f45e207df4267L,
32322         0x59280eba1452d8L,0x4465b61e267db5L,0x171f1137e09e5cL,
32323         0x1368eb821daa93L },
32324       { 0x70fe26e3e66861L,0x52a6663170da7dL,0x71d1ce5b7d79dcL,
32325         0x1cffe9be1e1afdL,0x703745115a29c4L,0x73b7f897b2f65aL,
32326         0x02218c3a95891aL } },
32327     /* 84 */
32328     { { 0x16866db8a9e8c9L,0x4770b770123d9bL,0x4c116cf34a8465L,
32329         0x079b28263fc86aL,0x3751c755a72b58L,0x7bc8df1673243aL,
32330         0x12fff72454f064L },
32331       { 0x15c049b89554e7L,0x4ea9ef44d7cd9aL,0x42f50765c0d4f1L,
32332         0x158bb603cb011bL,0x0809dde16470b1L,0x63cad7422ea819L,
32333         0x38b6cd70f90d7eL } },
32334     /* 85 */
32335     { { 0x1e4aab6328e33fL,0x70575f026da3aeL,0x7e1b55c8c55219L,
32336         0x328d4b403d24caL,0x03b6df1f0a5bd1L,0x26b4bb8b648ed0L,
32337         0x17161f2f10b76aL },
32338       { 0x6cdb32bae8b4c0L,0x33176266227056L,0x4975fa58519b45L,
32339         0x254602ea511d96L,0x4e82e93e402a67L,0x0ca8b5929cdb4fL,
32340         0x3ae7e0a07918f5L } },
32341     /* 86 */
32342     { { 0x60f9d1fecf5b9bL,0x6257e40d2cd469L,0x6c7aa814d28456L,
32343         0x58aac7caac8e79L,0x703a55f0293cbfL,0x702390a0f48378L,
32344         0x24b9ae07218b07L },
32345       { 0x1ebc66cdaf24e3L,0x7d9ae5f9f8e199L,0x42055ee921a245L,
32346         0x035595936e4d49L,0x129c45d425c08bL,0x6486c5f19ce6ddL,
32347         0x027dbd5f18ba24L } },
32348     /* 87 */
32349     { { 0x7d6b78d29375fbL,0x0a3dc6ba22ae38L,0x35090fa91feaf6L,
32350         0x7f18587fb7b16eL,0x6e7091dd924608L,0x54e102cdbf5ff8L,
32351         0x31b131a4c22079L },
32352       { 0x368f87d6a53fb0L,0x1d3f3d69a3f240L,0x36bf5f9e40e1c6L,
32353         0x17f150e01f8456L,0x76e5d0835eb447L,0x662fc0a1207100L,
32354         0x14e3dd97a98e39L } },
32355     /* 88 */
32356     { { 0x0249d9c2663b4bL,0x56b68f9a71ba1cL,0x74b119567f9c02L,
32357         0x5e6f336d8c92acL,0x2ced58f9f74a84L,0x4b75a2c2a467c5L,
32358         0x30557011cf740eL },
32359       { 0x6a87993be454ebL,0x29b7076fb99a68L,0x62ae74aaf99bbaL,
32360         0x399f9aa8fb6c1bL,0x553c24a396dd27L,0x2868337a815ea6L,
32361         0x343ab6635cc776L } },
32362     /* 89 */
32363     { { 0x0e0b0eec142408L,0x79728229662121L,0x605d0ac75e6250L,
32364         0x49a097a01edfbeL,0x1e20cd270df6b6L,0x7438a0ca9291edL,
32365         0x29daa430da5f90L },
32366       { 0x7a33844624825aL,0x181715986985c1L,0x53a6853cae0b92L,
32367         0x6d98401bd925e8L,0x5a0a34f5dd5e24L,0x7b818ef53cf265L,
32368         0x0836e43c9d3194L } },
32369     /* 90 */
32370     { { 0x1179b70e6c5fd9L,0x0246d9305dd44cL,0x635255edfbe2fbL,
32371         0x5397b3523b4199L,0x59350cc47e6640L,0x2b57aa97ed4375L,
32372         0x37efd31abd153aL },
32373       { 0x7a7afa6907f4faL,0x75c10cb94e6a7eL,0x60a925ab69cc47L,
32374         0x2ff5bcd9239bd5L,0x13c2113e425f11L,0x56bd3d2f8a1437L,
32375         0x2c9adbab13774fL } },
32376     /* 91 */
32377     { { 0x4ab9f52a2e5f2bL,0x5e537e70b58903L,0x0f242658ebe4f2L,
32378         0x2648a1e7a5f9aeL,0x1b4c5081e73007L,0x6827d4aff51850L,
32379         0x3925e41726cd01L },
32380       { 0x56dd8a55ab3cfbL,0x72d6a31b6d5beaL,0x697bd2e5575112L,
32381         0x66935519a7aa12L,0x55e97dda7a3aceL,0x0e16afb4237b4cL,
32382         0x00b68fbff08093L } },
32383     /* 92 */
32384     { { 0x4b00366481d0d9L,0x37cb031fbfc5c4L,0x14643f6800dd03L,
32385         0x6793fef60fe0faL,0x4f43e329c92803L,0x1fce86b96a6d26L,
32386         0x0ad416975e213aL },
32387       { 0x7cc6a6711adcc9L,0x64b8a63c43c2d9L,0x1e6caa2a67c0d0L,
32388         0x610deffd17a54bL,0x57d669d5f38423L,0x77364b8f022636L,
32389         0x36d4d13602e024L } },
32390     /* 93 */
32391     { { 0x72e667ae50a2f5L,0x1b15c950c3a21aL,0x3ccc37c72e6dfeL,
32392         0x027f7e1d094fb8L,0x43ae1e90aa5d7eL,0x3f5feac3d97ce5L,
32393         0x0363ed0a336e55L },
32394       { 0x235f73d7663784L,0x5d8cfc588ad5a4L,0x10ab6ff333016eL,
32395         0x7d8886af2e1497L,0x549f34fd17988eL,0x3fc4fcaee69a33L,
32396         0x0622b133a13d9eL } },
32397     /* 94 */
32398     { { 0x6344cfa796c53eL,0x0e9a10d00136fdL,0x5d1d284a56efd8L,
32399         0x608b1968f8aca7L,0x2fa5a66776edcaL,0x13430c44f1609cL,
32400         0x1499973cb2152aL },
32401       { 0x3764648104ab58L,0x3226e409fadafcL,0x1513a8466459ddL,
32402         0x649206ec365035L,0x46149aa3f765b1L,0x3aebf0a035248eL,
32403         0x1ee60b8c373494L } },
32404     /* 95 */
32405     { { 0x4e9efcc15f3060L,0x5e5d50fd77cdc8L,0x071e5403516b58L,
32406         0x1b7d4e89b24ceaL,0x53b1fa66d6dc03L,0x457f15f892ab5fL,
32407         0x076332c9397260L },
32408       { 0x31422b79d7584bL,0x0b01d47e41ba80L,0x3e5611a3171528L,
32409         0x5f53b9a9fc1be4L,0x7e2fc3d82f110fL,0x006cf350ef0fbfL,
32410         0x123ae98ec81c12L } },
32411     /* 96 */
32412     { { 0x310d41df46e2f6L,0x2ff032a286cf13L,0x64751a721c4eadL,
32413         0x7b62bcc0339b95L,0x49acf0c195afa4L,0x359d48742544e5L,
32414         0x276b7632d9e2afL },
32415       { 0x656c6be182579aL,0x75b65a4d85b199L,0x04a911d1721bfaL,
32416         0x46e023d0e33477L,0x1ec2d580acd869L,0x540b456f398a37L,
32417         0x001f698210153dL } },
32418     /* 97 */
32419     { { 0x3ca35217b00dd0L,0x73961d034f4d3cL,0x4f520b61c4119dL,
32420         0x4919fde5cccff7L,0x4d0e0e6f38134dL,0x55c22586003e91L,
32421         0x24d39d5d8f1b19L },
32422       { 0x4d4fc3d73234dcL,0x40c50c9d5f8368L,0x149afbc86bf2b8L,
32423         0x1dbafefc21d7f1L,0x42e6b61355107fL,0x6e506cf4b54f29L,
32424         0x0f498a6c615228L } },
32425     /* 98 */
32426     { { 0x30618f437cfaf8L,0x059640658532c4L,0x1c8a4d90e96e1dL,
32427         0x4a327bcca4fb92L,0x54143b8040f1a0L,0x4ec0928c5a49e4L,
32428         0x2af5ad488d9b1fL },
32429       { 0x1b392bd5338f55L,0x539c0292b41823L,0x1fe35d4df86a02L,
32430         0x5fa5bb17988c65L,0x02b6cb715adc26L,0x09a48a0c2cb509L,
32431         0x365635f1a5a9f2L } },
32432     /* 99 */
32433     { { 0x58aa87bdc21f31L,0x156900c7cb1935L,0x0ec1f75ee2b6cfL,
32434         0x5f3e35a77ec314L,0x582dec7b9b7621L,0x3e65deb0e8202aL,
32435         0x325c314b8a66b7L },
32436       { 0x702e2a22f24d66L,0x3a20e9982014f1L,0x6424c5b86bbfb0L,
32437         0x424eea4d795351L,0x7fc4cce7c22055L,0x581383fceb92d7L,
32438         0x32b663f49ee81bL } },
32439     /* 100 */
32440     { { 0x76e2d0b648b73eL,0x59ca39fa50bddaL,0x18bb44f786a7e4L,
32441         0x28c8d49d464360L,0x1b8bf1d3a574eaL,0x7c670b9bf1635aL,
32442         0x2efb30a291f4b3L },
32443       { 0x5326c069cec548L,0x03bbe481416531L,0x08a415c8d93d6fL,
32444         0x3414a52120d383L,0x1f17a0fc6e9c5cL,0x0de9a090717463L,
32445         0x22d84b3c67ff07L } },
32446     /* 101 */
32447     { { 0x30b5014c3830ebL,0x70791dc1a18b37L,0x09e6ea4e24f423L,
32448         0x65e148a5253132L,0x446f05d5d40449L,0x7ad5d3d707c0e9L,
32449         0x18eedd63dd3ab5L },
32450       { 0x40d2eac6bb29e0L,0x5b0e9605e83c38L,0x554f2c666a56a8L,
32451         0x0ac27b6c94c48bL,0x1aaecdd91bafe5L,0x73c6e2bdf72634L,
32452         0x306dab96d19e03L } },
32453     /* 102 */
32454     { { 0x6d3e4b42772f41L,0x1aba7796f3a39bL,0x3a03fbb980e9c0L,
32455         0x2f2ea5da2186a8L,0x358ff444ef1fcfL,0x0798cc0329fcdcL,
32456         0x39a28bcc9aa46dL },
32457       { 0x42775c977fe4d2L,0x5eb8fc5483d6b0L,0x0bfe37c039e3f7L,
32458         0x429292eaf9df60L,0x188bdf4b840cd5L,0x06e10e090749cdL,
32459         0x0e52678e73192eL } },
32460     /* 103 */
32461     { { 0x05de80b08df5feL,0x2af8c77406c5f8L,0x53573c50a0304aL,
32462         0x277b10b751bca0L,0x65cf8c559132a5L,0x4c667abe25f73cL,
32463         0x0271809e05a575L },
32464       { 0x41ced461f7a2fbL,0x0889a9ebdd7075L,0x320c63f2b7760eL,
32465         0x4f8d4324151c63L,0x5af47315be2e5eL,0x73c62f6aee2885L,
32466         0x206d6412a56a97L } },
32467     /* 104 */
32468     { { 0x6b1c508b21d232L,0x3781185974ead6L,0x1aba7c3ebe1fcfL,
32469         0x5bdc03cd3f3a5aL,0x74a25036a0985bL,0x5929e30b7211b2L,
32470         0x16a9f3bc366bd7L },
32471       { 0x566a7057dcfffcL,0x23b5708a644bc0L,0x348cda2aa5ba8cL,
32472         0x466aa96b9750d4L,0x6a435ed9b20834L,0x2e7730f2cf9901L,
32473         0x2b5cd71d5b0410L } },
32474     /* 105 */
32475     { { 0x285ab3cee76ef4L,0x68895e3a57275dL,0x6fab2e48fd1265L,
32476         0x0f1de060428c94L,0x668a2b080b5905L,0x1b589dc3b0cb37L,
32477         0x3c037886592c9bL },
32478       { 0x7fb5c0f2e90d4dL,0x334eefb3d8c91aL,0x75747124700388L,
32479         0x547a2c2e2737f5L,0x2af9c080e37541L,0x0a295370d9091aL,
32480         0x0bb5c36dad99e6L } },
32481     /* 106 */
32482     { { 0x644116586f25cbL,0x0c3f41f9ee1f5dL,0x00628d43a3dedaL,
32483         0x16e1437aae9669L,0x6aba7861bf3e59L,0x60735631ff4c44L,
32484         0x345609efaa615eL },
32485       { 0x41f54792e6acefL,0x4791583f75864dL,0x37f2ff5c7508b1L,
32486         0x1288912516c3b0L,0x51a2135f6a539bL,0x3b775511f42091L,
32487         0x127c6afa7afe66L } },
32488     /* 107 */
32489     { { 0x79f4f4f7492b73L,0x583d967256342dL,0x51a729bff33ca3L,
32490         0x3977d2c22d8986L,0x066f528ba8d40bL,0x5d759d30f8eb94L,
32491         0x0f8e649192b408L },
32492       { 0x22d84e752555bbL,0x76953855c728c7L,0x3b2254e72aaaa4L,
32493         0x508cd4ce6c0212L,0x726296d6b5a6daL,0x7a77aa066986f3L,
32494         0x2267a497bbcf31L } },
32495     /* 108 */
32496     { { 0x7f3651bf825dc4L,0x3988817388c56fL,0x257313ed6c3dd0L,
32497         0x3feab7f3b8ffadL,0x6c0d3cb9e9c9b4L,0x1317be0a7b6ac4L,
32498         0x2a5f399d7df850L },
32499       { 0x2fe5a36c934f5eL,0x429199df88ded1L,0x435ea21619b357L,
32500         0x6aac6a063bac2bL,0x600c149978f5edL,0x76543aa1114c95L,
32501         0x163ca9c83c7596L } },
32502     /* 109 */
32503     { { 0x7dda4a3e4daedbL,0x1824cba360a4cdL,0x09312efd70e0c6L,
32504         0x454e68a146c885L,0x40aee762fe5c47L,0x29811cbd755a59L,
32505         0x34b37c95f28319L },
32506       { 0x77c58b08b717d2L,0x309470d9a0f491L,0x1ab9f40448e01cL,
32507         0x21c8bd819207b1L,0x6a01803e9361bcL,0x6e5e4c350ec415L,
32508         0x14fd55a91f8798L } },
32509     /* 110 */
32510     { { 0x4cee562f512a90L,0x0008361d53e390L,0x3789b307a892cfL,
32511         0x064f7be8770ae9L,0x41435d848762cfL,0x662204dd38baa6L,
32512         0x23d6dcf73f6c5aL },
32513       { 0x69bef2d2c75d95L,0x2b037c0c9bb43eL,0x495fb4d79a34cfL,
32514         0x184e140c601260L,0x60193f8d435f9cL,0x283fa52a0c3ad2L,
32515         0x1998635e3a7925L } },
32516     /* 111 */
32517     { { 0x1cfd458ce382deL,0x0dddbd201bbcaeL,0x14d2ae8ed45d60L,
32518         0x73d764ab0c24cbL,0x2a97fe899778adL,0x0dbd1e01eddfe9L,
32519         0x2ba5c72d4042c3L },
32520       { 0x27eebc3af788f1L,0x53ffc827fc5a30L,0x6d1d0726d35188L,
32521         0x4721275c50aa2aL,0x077125f02e690fL,0x6da8142405db5dL,
32522         0x126cef68992513L } },
32523     /* 112 */
32524     { { 0x3c6067035b2d69L,0x2a1ad7db2361acL,0x3debece6cad41cL,
32525         0x30095b30f9afc1L,0x25f50b9bd9c011L,0x79201b2f2c1da1L,
32526         0x3b5c151449c5bdL },
32527       { 0x76eff4127abdb4L,0x2d31e03ce0382aL,0x24ff21f8bda143L,
32528         0x0671f244fd3ebaL,0x0c1c00b6bcc6fbL,0x18de9f7c3ebefbL,
32529         0x33dd48c3809c67L } },
32530     /* 113 */
32531     { { 0x61d6c2722d94edL,0x7e426e31041cceL,0x4097439f1b47b0L,
32532         0x579e798b2d205bL,0x6a430d67f830ebL,0x0d2c676700f727L,
32533         0x05fea83a82f25bL },
32534       { 0x3f3482df866b98L,0x3dd353b6a5a9cdL,0x77fe6ae1a48170L,
32535         0x2f75cc2a8f7cddL,0x7442a3863dad17L,0x643de42d877a79L,
32536         0x0fec8a38fe7238L } },
32537     /* 114 */
32538     { { 0x79b70c0760ac07L,0x195d3af37e9b29L,0x1317ff20f7cf27L,
32539         0x624e1c739e7504L,0x67330ef50f943dL,0x775e8cf455d793L,
32540         0x17b94d2d913a9fL },
32541       { 0x4b627203609e7fL,0x06aac5fb93e041L,0x603c515fdc2611L,
32542         0x2592ca0d7ae472L,0x02395d1f50a6cbL,0x466ef9648f85d9L,
32543         0x297cf879768f72L } },
32544     /* 115 */
32545     { { 0x3489d67d85fa94L,0x0a6e5b739c8e04L,0x7ebb5eab442e90L,
32546         0x52665a007efbd0L,0x0967ca57b0d739L,0x24891f9d932b63L,
32547         0x3cc2d6dbadc9d3L },
32548       { 0x4b4773c81c5338L,0x73cd47dad7a0f9L,0x7c755bab6ae158L,
32549         0x50b03d6becefcaL,0x574d6e256d57f0L,0x188db4fffb92aeL,
32550         0x197e10118071eaL } },
32551     /* 116 */
32552     { { 0x45d0cbcba1e7f1L,0x1180056abec91aL,0x6c5f86624bbc28L,
32553         0x442c83f3b8e518L,0x4e16ae1843ecb4L,0x670cef2fd786c9L,
32554         0x205b4acb637d2cL },
32555       { 0x70b0e539aa8671L,0x67c982056bebd0L,0x645c831a5e7c36L,
32556         0x09e06951a14b32L,0x5dd610ad4c89e6L,0x41c35f20164831L,
32557         0x3821f29cb4cdb8L } },
32558     /* 117 */
32559     { { 0x2831ffaba10079L,0x70f6dac9ffe444L,0x1cfa32ccc03717L,
32560         0x01519fda22a3c8L,0x23215e815aaa27L,0x390671ad65cbf7L,
32561         0x03dd4d72de7d52L },
32562       { 0x1ecd972ee95923L,0x166f8da3813e8eL,0x33199bbd387a1aL,
32563         0x04525fe15e3dc7L,0x44d2ef54165898L,0x4b7e47d3dc47f7L,
32564         0x10d5c8db0b5d44L } },
32565     /* 118 */
32566     { { 0x176d95ba9cdb1bL,0x14025f04f23dfcL,0x49379332891687L,
32567         0x6625e5ccbb2a57L,0x7ac0abdbf9d0e5L,0x7aded4fbea15b2L,
32568         0x314844ac184d67L },
32569       { 0x6d9ce34f05eae3L,0x3805d2875856d2L,0x1c2122f85e40ebL,
32570         0x51cb9f2d483a9aL,0x367e91e20f1702L,0x573c3559838dfdL,
32571         0x0b282b0cb85af1L } },
32572     /* 119 */
32573     { { 0x6a12e4ef871eb5L,0x64bb517e14f5ffL,0x29e04d3aaa530bL,
32574         0x1b07d88268f261L,0x411be11ed16fb0L,0x1f480536db70bfL,
32575         0x17a7deadfd34e4L },
32576       { 0x76d72f30646612L,0x5a3bbb43a1b0a0L,0x5e1687440e82bfL,
32577         0x713b5e69481112L,0x46c3dcb499e174L,0x0862da3b4e2a24L,
32578         0x31cb55b4d62681L } },
32579     /* 120 */
32580     { { 0x5ffc74dae5bb45L,0x18944c37adb9beL,0x6aaa63b1ee641aL,
32581         0x090f4b6ee057d3L,0x4045cedd2ee00fL,0x21c2c798f7c282L,
32582         0x2c2c6ef38cd6bdL },
32583       { 0x40d78501a06293L,0x56f8caa5cc89a8L,0x7231d5f91b37aeL,
32584         0x655f1e5a465c6dL,0x3f59a81f9cf783L,0x09bbba04c23624L,
32585         0x0f71ee23bbacdeL } },
32586     /* 121 */
32587     { { 0x38d398c4741456L,0x5204c0654243c3L,0x34498c916ea77eL,
32588         0x12238c60e5fe43L,0x0fc54f411c7625L,0x30b2ca43aa80b6L,
32589         0x06bead1bb6ea92L },
32590       { 0x5902ba8674b4adL,0x075ab5b0fa254eL,0x58db83426521adL,
32591         0x5b66b6b3958e39L,0x2ce4e39890e07bL,0x46702513338b37L,
32592         0x363690c2ded4d7L } },
32593     /* 122 */
32594     { { 0x765642c6b75791L,0x0f4c4300d7f673L,0x404d8bbe101425L,
32595         0x61e91c88651f1bL,0x61ddc9bc60aed8L,0x0ef36910ce2e65L,
32596         0x04b44367aa63b8L },
32597       { 0x72822d3651b7dcL,0x4b750157a2716dL,0x091cb4f2118d16L,
32598         0x662ba93b101993L,0x447cbd54a1d40aL,0x12cdd48d674848L,
32599         0x16f10415cbec69L } },
32600     /* 123 */
32601     { { 0x0c57a3a751cd0eL,0x0833d7478fadceL,0x1e751f55686436L,
32602         0x489636c58e1df7L,0x26ad6da941266fL,0x22225d3559880fL,
32603         0x35b397c45ba0e2L },
32604       { 0x3ca97b70e1f2ceL,0x78e50427a8680cL,0x06137e042a8f91L,
32605         0x7ec40d2500b712L,0x3f0ad688ad7b0dL,0x24746fb33f9513L,
32606         0x3638fcce688f0bL } },
32607     /* 124 */
32608     { { 0x753163750bed6fL,0x786507cd16157bL,0x1d6ec228ce022aL,
32609         0x587255f42d1b31L,0x0c6adf72a3a0f6L,0x4bfeee2da33f5eL,
32610         0x08b7300814de6cL },
32611       { 0x00bf8df9a56e11L,0x75aead48fe42e8L,0x3de9bad911b2e2L,
32612         0x0fadb233e4b8bbL,0x5b054e8fd84f7dL,0x5eb3064152889bL,
32613         0x01c1c6e8c777a1L } },
32614     /* 125 */
32615     { { 0x5fa0e598f8fcb9L,0x11c129a1ae18dfL,0x5c41b482a2273bL,
32616         0x545664e5044c9cL,0x7e01c915bfb9abL,0x7f626e19296aa0L,
32617         0x20c91a9822a087L },
32618       { 0x273a9fbe3c378fL,0x0f126b44b7d350L,0x493764a75df951L,
32619         0x32dec3c367d24bL,0x1a7ae987fed9d3L,0x58a93055928b85L,
32620         0x11626975d7775fL } },
32621     /* 126 */
32622     { { 0x2bb174a95540a9L,0x10de02c58b613fL,0x2fa8f7b861f3eeL,
32623         0x44731260bdf3b3L,0x19c38ff7da41feL,0x3535a16e3d7172L,
32624         0x21a948b83cc7feL },
32625       { 0x0e6f72868bc259L,0x0c70799df3c979L,0x526919955584c3L,
32626         0x4d95fda04f8fa2L,0x7bb228e6c0f091L,0x4f728b88d92194L,
32627         0x2b361c5a136bedL } },
32628     /* 127 */
32629     { { 0x0c72ca10c53841L,0x4036ab49f9da12L,0x578408d2b7082bL,
32630         0x2c4903201fbf5eL,0x14722b3f42a6a8L,0x1997b786181694L,
32631         0x25c6f10de32849L },
32632       { 0x79f46d517ff2ffL,0x2dc5d97528f6deL,0x518a494489aa72L,
32633         0x52748f8af3cf97L,0x472da30a96bb16L,0x1be228f92465a9L,
32634         0x196f0c47d60479L } },
32635     /* 128 */
32636     { { 0x47dd7d139b3239L,0x049c9b06775d0fL,0x627ffc00562d5eL,
32637         0x04f578d5e5e243L,0x43a788ffcef8b9L,0x7db320be9dde28L,
32638         0x00837528b8572fL },
32639       { 0x2969eca306d695L,0x195b72795ec194L,0x5e1fa9b8e77e50L,
32640         0x4c627f2b3fbfd5L,0x4b91e0d0ee10ffL,0x5698c8d0f35833L,
32641         0x12d3a9431f475eL } },
32642     /* 129 */
32643     { { 0x6409457a0db57eL,0x795b35192e0433L,0x146f973fe79805L,
32644         0x3d49c516dfb9cfL,0x50dfc3646b3cdaL,0x16a08a2210ad06L,
32645         0x2b4ef5bcd5b826L },
32646       { 0x5ebabfee2e3e3eL,0x2e048e724d9726L,0x0a7a7ed6abef40L,
32647         0x71ff7f83e39ad8L,0x3405ac52a1b852L,0x2e3233357a608dL,
32648         0x38c1bf3b0e40e6L } },
32649     /* 130 */
32650     { { 0x59aec823e4712cL,0x6ed9878331ddadL,0x1cc6faf629f2a0L,
32651         0x445ff79f36c18cL,0x4edc7ed57aff3dL,0x22ee54c8bdd9e8L,
32652         0x35398f42d72ec5L },
32653       { 0x4e7a1cceee0ecfL,0x4c66a707dd1d31L,0x629ad157a23c04L,
32654         0x3b2c6031dc3c83L,0x3336acbcd3d96cL,0x26ce43adfce0f0L,
32655         0x3c869c98d699dcL } },
32656     /* 131 */
32657     { { 0x58b3cd9586ba11L,0x5d6514b8090033L,0x7c88c3bd736782L,
32658         0x1735f84f2130edL,0x47784095a9dee0L,0x76312c6e47901bL,
32659         0x1725f6ebc51455L },
32660       { 0x6744344bc4503eL,0x16630b4d66e12fL,0x7b3481752c3ec7L,
32661         0x47bb2ed1f46f95L,0x08a1a497dd1bcfL,0x1f525df2b8ed93L,
32662         0x0fe492ea993713L } },
32663     /* 132 */
32664     { { 0x71b8dd7268b448L,0x1743dfaf3728d7L,0x23938d547f530aL,
32665         0x648c3d497d0fc6L,0x26c0d769e3ad45L,0x4d25108769a806L,
32666         0x3fbf2025143575L },
32667       { 0x485bfd90339366L,0x2de2b99ed87461L,0x24a33347713badL,
32668         0x1674bc7073958aL,0x5bb2373ee85b5fL,0x57f9bd657e662cL,
32669         0x2041b248d39042L } },
32670     /* 133 */
32671     { { 0x5f01617d02f4eeL,0x2a8e31c4244b91L,0x2dab3e790229e0L,
32672         0x72d319ea7544afL,0x01ffb8b000cb56L,0x065e63b0daafd3L,
32673         0x3d7200a7111d6fL },
32674       { 0x4561ce1b568973L,0x37034c532dd8ecL,0x1368215020be02L,
32675         0x30e7184cf289ebL,0x199e0c27d815deL,0x7ee1b4dff324e5L,
32676         0x2f4a11de7fab5cL } },
32677     /* 134 */
32678     { { 0x33c2f99b1cdf2bL,0x1e0d78bf42a2c0L,0x64485dececaa67L,
32679         0x2242a41be93e92L,0x62297b1f15273cL,0x16ebfaafb02205L,
32680         0x0f50f805f1fdabL },
32681       { 0x28bb0b3a70eb28L,0x5b1c7d0160d683L,0x05c30a37959f78L,
32682         0x3d9301184922d2L,0x46c1ead7dbcb1aL,0x03ee161146a597L,
32683         0x2d413ed9a6ccc1L } },
32684     /* 135 */
32685     { { 0x685ab5f97a27c2L,0x59178214023751L,0x4ffef3c585ab17L,
32686         0x2bc85302aba2a9L,0x675b001780e856L,0x103c8a37f0b33dL,
32687         0x2241e98ece70a6L },
32688       { 0x546738260189edL,0x086c8f7a6b96edL,0x00832ad878a129L,
32689         0x0b679056ba7462L,0x020ce6264bf8c4L,0x3f9f4b4d92abfbL,
32690         0x3e9c55343c92edL } },
32691     /* 136 */
32692     { { 0x482cec9b3f5034L,0x08b59b3cd1fa30L,0x5a55d1bc8e58b5L,
32693         0x464a5259337d8eL,0x0a5b6c66ade5a5L,0x55db77b504ddadL,
32694         0x015992935eac35L },
32695       { 0x54fe51025e32fcL,0x5d7f52dbe4a579L,0x08c564a8c58696L,
32696         0x4482a8bec4503fL,0x440e75d9d94de9L,0x6992d768020bfaL,
32697         0x06c311e8ba01f6L } },
32698     /* 137 */
32699     { { 0x2a6ac808223878L,0x04d3ccb4aab0b8L,0x6e6ef09ff6e823L,
32700         0x15cb03ee9158dcL,0x0dc58919171bf7L,0x3273568abf3cb1L,
32701         0x1b55245b88d98bL },
32702       { 0x28e9383b1de0c1L,0x30d5009e4f1f1bL,0x334d185a56a134L,
32703         0x0875865dfa4c46L,0x266edf5eae3beeL,0x2e03ff16d1f7e5L,
32704         0x29a36bd9f0c16dL } },
32705     /* 138 */
32706     { { 0x004cff44b2e045L,0x426c96380ba982L,0x422292281e46d7L,
32707         0x508dd8d29d7204L,0x3a4ea73fb2995eL,0x4be64090ae07b2L,
32708         0x3339177a0eff22L },
32709       { 0x74a97ec2b3106eL,0x0c616d09169f5fL,0x1bb5d8907241a7L,
32710         0x661fb67f6d41bdL,0x018a88a0daf136L,0x746333a093a7b4L,
32711         0x3e19f1ac76424eL } },
32712     /* 139 */
32713     { { 0x542a5656527296L,0x0e7b9ce22f1bc9L,0x31b0945992b89bL,
32714         0x6e0570eb85056dL,0x32daf813483ae5L,0x69eeae9d59bb55L,
32715         0x315ad4b730b557L },
32716       { 0x2bc16795f32923L,0x6b02b7ba55130eL,0x1e9da67c012f85L,
32717         0x5616f014dabf8fL,0x777395fcd9c723L,0x2ff075e7743246L,
32718         0x2993538aff142eL } },
32719     /* 140 */
32720     { { 0x72dae20e552b40L,0x2e4ba69aa5d042L,0x001e563e618bd2L,
32721         0x28feeba3c98772L,0x648c356da2a907L,0x687e2325069ea7L,
32722         0x0d34ab09a394f0L },
32723       { 0x73c21813111286L,0x5829b53b304e20L,0x6fba574de08076L,
32724         0x79f7058f61614eL,0x4e71c9316f1191L,0x24ef12193e0a89L,
32725         0x35dc4e2bc9d848L } },
32726     /* 141 */
32727     { { 0x045e6d3b4ad1cdL,0x729c95493782f0L,0x77f59de85b361aL,
32728         0x5309b4babf28f8L,0x4d893d9290935fL,0x736f47f2b2669eL,
32729         0x23270922d757f3L },
32730       { 0x23a4826f70d4e9L,0x68a8c63215d33eL,0x4d6c2069205c9cL,
32731         0x46b2938a5eebe0L,0x41d1f1e2de3892L,0x5ca1775544bcb0L,
32732         0x3130629e5d19dcL } },
32733     /* 142 */
32734     { { 0x6e2681593375acL,0x117cfbabc22621L,0x6c903cd4e13ccaL,
32735         0x6f358f14d4bd97L,0x1bc58fa11089f1L,0x36aa2db4ac426aL,
32736         0x15ced8464b7ea1L },
32737       { 0x6966836cba7df5L,0x7c2b1851568113L,0x22b50ff2ffca66L,
32738         0x50e77d9f48e49aL,0x32775e9bbc7cc9L,0x403915bb0ece71L,
32739         0x1b8ec7cb9dd7aaL } },
32740     /* 143 */
32741     { { 0x65a888b677788bL,0x51887fac2e7806L,0x06792636f98d2bL,
32742         0x47bbcd59824c3bL,0x1aca908c43e6dcL,0x2e00d15c708981L,
32743         0x08e031c2c80634L },
32744       { 0x77fbc3a297c5ecL,0x10a7948af2919eL,0x10cdafb1fb6b2fL,
32745         0x27762309b486f0L,0x13abf26bbac641L,0x53da38478fc3eeL,
32746         0x3c22eff379bf55L } },
32747     /* 144 */
32748     { { 0x0163f484770ee3L,0x7f28e8942e0cbfL,0x5f86cb51b43831L,
32749         0x00feccd4e4782fL,0x40e5b417eafe7dL,0x79e5742bbea228L,
32750         0x3717154aa469beL },
32751       { 0x271d74a270f721L,0x40eb400890b70cL,0x0e37be81d4cb02L,
32752         0x786907f4e8d43fL,0x5a1f5b590a7acbL,0x048861883851fdL,
32753         0x11534a1e563dbbL } },
32754     /* 145 */
32755     { { 0x37a6357c525435L,0x6afe6f897b78a5L,0x7b7ff311d4f67bL,
32756         0x38879df15dc9f4L,0x727def7b8ba987L,0x20285dd0db4436L,
32757         0x156b0fc64b9243L },
32758       { 0x7e3a6ec0c1c390L,0x668a88d9bcf690L,0x5925aba5440dbeL,
32759         0x0f6891a044f593L,0x70b46edfed4d97L,0x1a6cc361bab201L,
32760         0x046f5bc6e160bcL } },
32761     /* 146 */
32762     { { 0x79350f076bc9d1L,0x077d9e79a586b9L,0x0896bc0c705764L,
32763         0x58e632b90e7e46L,0x14e87e0ad32488L,0x4b1bb3f72c6e00L,
32764         0x3c3ce9684a5fc5L },
32765       { 0x108fbaf1f703aaL,0x08405ecec17577L,0x199a8e2d44be73L,
32766         0x2eb22ed0067763L,0x633944deda3300L,0x20d739eb8e5efbL,
32767         0x2bbbd94086b532L } },
32768     /* 147 */
32769     { { 0x03c8b17a19045dL,0x6205a0a504980bL,0x67fdb3e962b9f0L,
32770         0x16399e01511a4bL,0x44b09fe9dffc96L,0x00a74ff44a1381L,
32771         0x14590deed3f886L },
32772       { 0x54e3d5c2a23ddbL,0x310e5138209d28L,0x613f45490c1c9bL,
32773         0x6bbc85d44bbec8L,0x2f85fc559e73f6L,0x0d71fa7d0fa8cbL,
32774         0x2898571d17fbb9L } },
32775     /* 148 */
32776     { { 0x5607a84335167dL,0x3009c1eb910f91L,0x7ce63447e62d0bL,
32777         0x03a0633afcf89eL,0x1234b5aaa50872L,0x5a307b534d547bL,
32778         0x2f4e97138a952eL },
32779       { 0x13914c2db0f658L,0x6cdcb47e6e75baL,0x5549169caca772L,
32780         0x0f20423dfeb16fL,0x6b1ae19d180239L,0x0b7b3bee9b7626L,
32781         0x1ca81adacfe4efL } },
32782     /* 149 */
32783     { { 0x219ec3ad19d96fL,0x3549f6548132dbL,0x699889c7aacd0bL,
32784         0x74602a58730b19L,0x62dc63bcece81cL,0x316f991c0c317aL,
32785         0x2b8627867b95e3L },
32786       { 0x67a25ddced1eedL,0x7e14f0eba756e7L,0x0873fbc09b0495L,
32787         0x0fefb0e16596adL,0x03e6cd98ef39bbL,0x1179b1cded249dL,
32788         0x35c79c1db1edc2L } },
32789     /* 150 */
32790     { { 0x1368309d4245bfL,0x442e55852a7667L,0x095b0f0f348b65L,
32791         0x6834cf459dfad4L,0x6645950c9be910L,0x06bd81288c71e6L,
32792         0x1b015b6e944edfL },
32793       { 0x7a6a83045ab0e3L,0x6afe88b9252ad0L,0x2285bd65523502L,
32794         0x6c78543879a282L,0x1c5e264b5c6393L,0x3a820c6a7453eeL,
32795         0x37562d1d61d3c3L } },
32796     /* 151 */
32797     { { 0x6c084f62230c72L,0x599490270bc6cfL,0x1d3369ddd3c53dL,
32798         0x516ddb5fac5da0L,0x35ab1e15011b1aL,0x5fba9106d3a180L,
32799         0x3be0f092a0917cL },
32800       { 0x57328f9fdc2538L,0x0526323fc8d5f6L,0x10cbb79521e602L,
32801         0x50d01167147ae2L,0x2ec7f1b3cda99eL,0x43073cc736e7beL,
32802         0x1ded89cadd83a6L } },
32803     /* 152 */
32804     { { 0x1d51bda65d56d5L,0x63f2fd4d2dc056L,0x326413d310ea6dL,
32805         0x3abba5bca92876L,0x6b9aa8bc4d6ebeL,0x1961c687f15d5dL,
32806         0x311cf07464c381L },
32807       { 0x2321b1064cd8aeL,0x6e3caac4443850L,0x3346fc4887d2d0L,
32808         0x1640417e0e640fL,0x4a958a52a07a9eL,0x1346a1b1cb374cL,
32809         0x0a793cf79beccbL } },
32810     /* 153 */
32811     { { 0x29d56cba89aaa5L,0x1581898c0b3c15L,0x1af5b77293c082L,
32812         0x1617ba53a006ceL,0x62dd3b384e475fL,0x71a9820c3f962aL,
32813         0x0e4938920b854eL },
32814       { 0x0b8d98849808abL,0x64c14923546de7L,0x6a20883b78a6fcL,
32815         0x72de211428acd6L,0x009678b47915bbL,0x21b5269ae5dae6L,
32816         0x313cc0e60b9457L } },
32817     /* 154 */
32818     { { 0x69ee421b1de38bL,0x44b484c6cec1c7L,0x0240596c6a8493L,
32819         0x2321a62c85fb9eL,0x7a10921802a341L,0x3d2a95507e45c3L,
32820         0x0752f40f3b6714L },
32821       { 0x596a38798751e6L,0x46bf186a0feb85L,0x0b23093e23b49cL,
32822         0x1bfa7bc5afdc07L,0x4ba96f873eefadL,0x292e453fae9e44L,
32823         0x2773646667b75cL } },
32824     /* 155 */
32825     { { 0x1f81a64e94f22aL,0x3125ee3d8683ddL,0x76a660a13b9582L,
32826         0x5aa584c3640c6eL,0x27cc99fd472953L,0x7048f4d58061d1L,
32827         0x379a1397ac81e8L },
32828       { 0x5d1ecd2b6b956bL,0x0829e0366b0697L,0x49548cec502421L,
32829         0x7af5e2f717c059L,0x329a25a0fec54eL,0x028e99e4bcd7f1L,
32830         0x071d5fe81fca78L } },
32831     /* 156 */
32832     { { 0x4b5c4aeb0fdfe4L,0x1367e11326ce37L,0x7c16f020ef5f19L,
32833         0x3c55303d77b471L,0x23a4457a06e46aL,0x2174426dd98424L,
32834         0x226f592114bd69L },
32835       { 0x4411b94455f15aL,0x52e0115381fae4L,0x45b6d8efbc8f7eL,
32836         0x58b1221bd86d26L,0x284fb6f8a7ec1fL,0x045835939ddd30L,
32837         0x0216960accd598L } },
32838     /* 157 */
32839     { { 0x4b61f9ec1f138aL,0x4460cd1e18502bL,0x277e4fce3c4726L,
32840         0x0244246d6414b9L,0x28fbfcef256984L,0x3347ed0db40577L,
32841         0x3b57fa9e044718L },
32842       { 0x4f73bcd6d1c833L,0x2c0d0dcf7f0136L,0x2010ac75454254L,
32843         0x7dc4f6151539a8L,0x0b8929ef6ea495L,0x517e20119d2bdfL,
32844         0x1e29f9a126ba15L } },
32845     /* 158 */
32846     { { 0x683a7c10470cd8L,0x0d05f0dbe0007fL,0x2f6a5026d649cdL,
32847         0x249ce2fdaed603L,0x116dc1e7a96609L,0x199bd8d82a0b98L,
32848         0x0694ad0219aeb2L },
32849       { 0x03a3656e864045L,0x4e552273df82a6L,0x19bcc7553d17abL,
32850         0x74ac536c1df632L,0x440302fb4a86f6L,0x1becec0e31c9feL,
32851         0x002045f8fa46b8L } },
32852     /* 159 */
32853     { { 0x5833ba384310a2L,0x1db83fad93f8baL,0x0a12713ee2f7edL,
32854         0x40e0f0fdcd2788L,0x1746de5fb239a5L,0x573748965cfa15L,
32855         0x1e3dedda0ef650L },
32856       { 0x6c8ca1c87607aeL,0x785dab9554fc0eL,0x649d8f91860ac8L,
32857         0x4436f88b52c0f9L,0x67f22ca8a5e4a3L,0x1f990fd219e4c9L,
32858         0x013dd21c08573fL } },
32859     /* 160 */
32860     { { 0x05d116141d161cL,0x5c1d2789da2ea5L,0x11f0d861f99f34L,
32861         0x692c2650963153L,0x3bd69f5329539eL,0x215898eef8885fL,
32862         0x041f79dd86f7f1L },
32863       { 0x76dcc5e96beebdL,0x7f2b50cb42a332L,0x067621cabef8abL,
32864         0x31e0be607054edL,0x4c67c5e357a3daL,0x5b1a63fbfb1c2bL,
32865         0x3112efbf5e5c31L } },
32866     /* 161 */
32867     { { 0x3f83e24c0c62f1L,0x51dc9c32aae4e0L,0x2ff89b33b66c78L,
32868         0x21b1c7d354142cL,0x243d8d381c84bcL,0x68729ee50cf4b7L,
32869         0x0ed29e0f442e09L },
32870       { 0x1ad7b57576451eL,0x6b2e296d6b91dcL,0x53f2b306e30f42L,
32871         0x3964ebd9ee184aL,0x0a32855df110e4L,0x31f2f90ddae05fL,
32872         0x3410cd04e23702L } },
32873     /* 162 */
32874     { { 0x60d1522ca8f2feL,0x12909237a83e34L,0x15637f80d58590L,
32875         0x3c72431b6d714dL,0x7c8e59a615bea2L,0x5f977b688ef35aL,
32876         0x071c198c0b3ab0L },
32877       { 0x2b54c699699b4bL,0x14da473c2fd0bcL,0x7ba818ea0ad427L,
32878         0x35117013940b2fL,0x6e1df6b5e609dbL,0x3f42502720b64dL,
32879         0x01ee7dc890e524L } },
32880     /* 163 */
32881     { { 0x12ec1448ff4e49L,0x3e2edac882522bL,0x20455ab300f93aL,
32882         0x5849585bd67c14L,0x0393d5aa34ba8bL,0x30f9a1f2044fa7L,
32883         0x1059c9377a93e0L },
32884       { 0x4e641cc0139e73L,0x0d9f23c9b0fa78L,0x4b2ad87e2b83f9L,
32885         0x1c343a9f6d9e3cL,0x1098a4cb46de4dL,0x4ddc893843a41eL,
32886         0x1797f4167d6e3aL } },
32887     /* 164 */
32888     { { 0x4add4675856031L,0x499bd5e5f7a0ffL,0x39ea1f1202271eL,
32889         0x0ecd7480d7a91eL,0x395f5e5fc10956L,0x0fa7f6b0c9f79bL,
32890         0x2fad4623aed6cbL },
32891       { 0x1563c33ae65825L,0x29881cafac827aL,0x50650baf4c45a1L,
32892         0x034aad988fb9e9L,0x20a6224dc5904cL,0x6fb141a990732bL,
32893         0x3ec9ae1b5755deL } },
32894     /* 165 */
32895     { { 0x3108e7c686ae17L,0x2e73a383b4ad8aL,0x4e6bb142ba4243L,
32896         0x24d355922c1d80L,0x2f850dd9a088baL,0x21c50325dd5e70L,
32897         0x33237dd5bd7fa4L },
32898       { 0x7823a39cab7630L,0x1535f71cff830eL,0x70d92ff0599261L,
32899         0x227154d2a2477cL,0x495e9bbb4f871cL,0x40d2034835686bL,
32900         0x31b08f97eaa942L } },
32901     /* 166 */
32902     { { 0x0016c19034d8ddL,0x68961627cf376fL,0x6acc90681615aeL,
32903         0x6bc7690c2e3204L,0x6ddf28d2fe19a2L,0x609b98f84dae4dL,
32904         0x0f32bfd7c94413L },
32905       { 0x7d7edc6b21f843L,0x49bbd2ebbc9872L,0x593d6ada7b6a23L,
32906         0x55736602939e9cL,0x79461537680e39L,0x7a7ee9399ca7cdL,
32907         0x008776f6655effL } },
32908     /* 167 */
32909     { { 0x64585f777233cfL,0x63ec12854de0f6L,0x6b7f9bbbc3f99dL,
32910         0x301c014b1b55d3L,0x7cf3663bbeb568L,0x24959dcb085bd1L,
32911         0x12366aa6752881L },
32912       { 0x77a74c0da5e57aL,0x3279ca93ad939fL,0x33c3c8a1ef08c9L,
32913         0x641b05ab42825eL,0x02f416d7d098dbL,0x7e3d58be292b68L,
32914         0x1864dbc46e1f46L } },
32915     /* 168 */
32916     { { 0x1da167b8153a9dL,0x47593d07d9e155L,0x386d984e12927fL,
32917         0x421a6f08a60c7cL,0x5ae9661c24dab3L,0x7927b2e7874507L,
32918         0x3266ea80609d53L },
32919       { 0x7d198f4c26b1e3L,0x430d4ea2c4048eL,0x58d8ab77e84ba3L,
32920         0x1cb14299c37297L,0x6db6031e8f695cL,0x159bd855e26d55L,
32921         0x3f3f6d318a73ddL } },
32922     /* 169 */
32923     { { 0x3ee958cca40298L,0x02a7e5eba32ad6L,0x43b4bab96f0e1eL,
32924         0x534be79062b2b1L,0x029ead089b37e3L,0x4d585da558f5aaL,
32925         0x1f9737eb43c376L },
32926       { 0x0426dfd9b86202L,0x4162866bc0a9f3L,0x18fc518e7bb465L,
32927         0x6db63380fed812L,0x421e117f709c30L,0x1597f8d0f5cee6L,
32928         0x04ffbf1289b06aL } },
32929     /* 170 */
32930     { { 0x61a1987ffa0a5fL,0x42058c7fc213c6L,0x15b1d38447d2c9L,
32931         0x3d5f5d7932565eL,0x5db754af445fa7L,0x5d489189fba499L,
32932         0x02c4c55f51141bL },
32933       { 0x26b15972e9993dL,0x2fc90bcbd97c45L,0x2ff60f8684b0f1L,
32934         0x1dc641dd339ab0L,0x3e38e6be23f82cL,0x3368162752c817L,
32935         0x19bba80ceb45ceL } },
32936     /* 171 */
32937     { { 0x7c6e95b4c6c693L,0x6bbc6d5efa7093L,0x74d7f90bf3bf1cL,
32938         0x54d5be1f0299a1L,0x7cb24f0aa427c6L,0x0a18f3e086c941L,
32939         0x058a1c90e4faefL },
32940       { 0x3d6bd016927e1eL,0x1da4ce773098b8L,0x2133522e690056L,
32941         0x0751416d3fc37eL,0x1beed1643eda66L,0x5288b6727d5c54L,
32942         0x199320e78655c6L } },
32943     /* 172 */
32944     { { 0x74575027eeaf94L,0x124bd533c3ceaeL,0x69421ab7a8a1d7L,
32945         0x37f2127e093f3dL,0x40281765252a08L,0x25a228798d856dL,
32946         0x326eca62759c4cL },
32947       { 0x0c337c51acb0a5L,0x122ba78c1ef110L,0x02498adbb68dc4L,
32948         0x67240c124b089eL,0x135865d25d9f89L,0x338a76d5ae5670L,
32949         0x03a8efaf130385L } },
32950     /* 173 */
32951     { { 0x3a450ac5e49beaL,0x282af80bb4b395L,0x6779eb0db1a139L,
32952         0x737cabdd174e55L,0x017b14ca79b5f2L,0x61fdef6048e137L,
32953         0x3acc12641f6277L },
32954       { 0x0f730746fe5096L,0x21d05c09d55ea1L,0x64d44bddb1a560L,
32955         0x75e5035c4778deL,0x158b7776613513L,0x7b5efa90c7599eL,
32956         0x2caa0791253b95L } },
32957     /* 174 */
32958     { { 0x288e5b6d53e6baL,0x435228909d45feL,0x33b4cf23b2a437L,
32959         0x45b352017d6db0L,0x4372d579d6ef32L,0x0fa9e5badbbd84L,
32960         0x3a78cff24759bbL },
32961       { 0x0899d2039eab6eL,0x4cf47d2f76bc22L,0x373f739a3a8c69L,
32962         0x09beaa5b1000b3L,0x0acdfbe83ebae5L,0x10c10befb0e900L,
32963         0x33d2ac4cc31be3L } },
32964     /* 175 */
32965     { { 0x765845931e08fbL,0x2a3c2a0dc58007L,0x7270da587d90e1L,
32966         0x1ee648b2bc8f86L,0x5d2ca68107b29eL,0x2b7064846e9e92L,
32967         0x3633ed98dbb962L },
32968       { 0x5e0f16a0349b1bL,0x58d8941f570ca4L,0x20abe376a4cf34L,
32969         0x0f4bd69a360977L,0x21eb07cc424ba7L,0x720d2ecdbbe6ecL,
32970         0x255597d5a97c34L } },
32971     /* 176 */
32972     { { 0x67bbf21a0f5e94L,0x422a3b05a64fc1L,0x773ac447ebddc7L,
32973         0x1a1331c08019f1L,0x01ef6d269744ddL,0x55f7be5b3b401aL,
32974         0x072e031c681273L },
32975       { 0x7183289e21c677L,0x5e0a3391f3162fL,0x5e02d9e65d914aL,
32976         0x07c79ea1adce2fL,0x667ca5c2e1cbe4L,0x4f287f22caccdaL,
32977         0x27eaa81673e75bL } },
32978     /* 177 */
32979     { { 0x5246180a078fe6L,0x67cc8c9fa3bb15L,0x370f8dd123db31L,
32980         0x1938dafa69671aL,0x5af72624950c5eL,0x78cc5221ebddf8L,
32981         0x22d616fe2a84caL },
32982       { 0x723985a839327fL,0x24fa95584a5e22L,0x3d8a5b3138d38bL,
32983         0x3829ef4a017acfL,0x4f09b00ae055c4L,0x01df84552e4516L,
32984         0x2a7a18993e8306L } },
32985     /* 178 */
32986     { { 0x7b6224bc310eccL,0x69e2cff429da16L,0x01c850e5722869L,
32987         0x2e4889443ee84bL,0x264a8df1b3d09fL,0x18a73fe478d0d6L,
32988         0x370b52740f9635L },
32989       { 0x52b7d3a9d6f501L,0x5c49808129ee42L,0x5b64e2643fd30cL,
32990         0x27d903fe31b32cL,0x594cb084d078f9L,0x567fb33e3ae650L,
32991         0x0db7be9932cb65L } },
32992     /* 179 */
32993     { { 0x19b78113ed7cbeL,0x002b2f097a1c8cL,0x70b1dc17fa5794L,
32994         0x786e8419519128L,0x1a45ba376af995L,0x4f6aa84b8d806cL,
32995         0x204b4b3bc7ca47L },
32996       { 0x7581a05fd94972L,0x1c73cadb870799L,0x758f6fefc09b88L,
32997         0x35c62ba8049b42L,0x6f5e71fc164cc3L,0x0cd738b5702721L,
32998         0x10021afac9a423L } },
32999     /* 180 */
33000     { { 0x654f7937e3c115L,0x5d198288b515cbL,0x4add965c25a6e3L,
33001         0x5a37df33cd76ffL,0x57bb7e288e1631L,0x049b69089e1a31L,
33002         0x383a88f4122a99L },
33003       { 0x4c0e4ef3d80a73L,0x553c77ac9f30e2L,0x20bb18c2021e82L,
33004         0x2aec0d1c4225c5L,0x397fce0ac9c302L,0x2ab0c2a246e8aaL,
33005         0x02e5e5190be080L } },
33006     /* 181 */
33007     { { 0x7a255a4ae03080L,0x0d68b01513f624L,0x29905bd4e48c8cL,
33008         0x1d81507027466bL,0x1684aaeb70dee1L,0x7dd460719f0981L,
33009         0x29c43b0f0a390cL },
33010       { 0x272567681b1f7dL,0x1d2a5f8502e0efL,0x0fd5cd6b221befL,
33011         0x5eb4749e9a0434L,0x7d1553a324e2a6L,0x2eefd8e86a7804L,
33012         0x2ad80d5335109cL } },
33013     /* 182 */
33014     { { 0x25342aef4c209dL,0x24e811ac4e0865L,0x3f209757f8ae9dL,
33015         0x1473ff8a5da57bL,0x340f61c3919cedL,0x7523bf85fb9bc0L,
33016         0x319602ebca7cceL },
33017       { 0x121e7541d442cbL,0x4ffa748e49c95cL,0x11493cd1d131dcL,
33018         0x42b215172ab6b5L,0x045fd87e13cc77L,0x0ae305df76342fL,
33019         0x373b033c538512L } },
33020     /* 183 */
33021     { { 0x389541e9539819L,0x769f3b29b7e239L,0x0d05f695e3232cL,
33022         0x029d04f0e9a9fbL,0x58b78b7a697fb8L,0x7531b082e6386bL,
33023         0x215d235bed95a9L },
33024       { 0x503947c1859c5dL,0x4b82a6ba45443fL,0x78328eab71b3a5L,
33025         0x7d8a77f8cb3509L,0x53fcd9802e41d4L,0x77552091976edbL,
33026         0x226c60ad7a5156L } },
33027     /* 184 */
33028     { { 0x77ad6a43360710L,0x0fdeabd326d7aeL,0x4012886c92104aL,
33029         0x2d6c378dd7ae33L,0x7e72ef2c0725f3L,0x4a4671f4ca18e0L,
33030         0x0afe3b4bb6220fL },
33031       { 0x212cf4b56e0d6aL,0x7c24d086521960L,0x0662cf71bd414dL,
33032         0x1085b916c58c25L,0x781eed2be9a350L,0x26880e80db6ab2L,
33033         0x169e356442f061L } },
33034     /* 185 */
33035     { { 0x57aa2ad748b02cL,0x68a34256772a9aL,0x1591c44962f96cL,
33036         0x110a9edd6e53d2L,0x31eab597e091a3L,0x603e64e200c65dL,
33037         0x2f66b72e8a1cfcL },
33038       { 0x5c79d138543f7fL,0x412524363fdfa3L,0x547977e3b40008L,
33039         0x735ca25436d9f7L,0x232b4888cae049L,0x27ce37a53d8f23L,
33040         0x34d45881a9b470L } },
33041     /* 186 */
33042     { { 0x76b95255924f43L,0x035c9f3bd1aa5dL,0x5eb71a010b4bd0L,
33043         0x6ce8dda7e39f46L,0x35679627ea70c0L,0x5c987767c7d77eL,
33044         0x1fa28952b620b7L },
33045       { 0x106f50b5924407L,0x1cc3435a889411L,0x0597cdce3bc528L,
33046         0x738f8b0d5077d1L,0x5894dd60c7dd6aL,0x0013d0721f5e2eL,
33047         0x344573480527d3L } },
33048     /* 187 */
33049     { { 0x2e2c1da52abf77L,0x394aa8464ad05eL,0x095259b7330a83L,
33050         0x686e81cf6a11f5L,0x405c7e48c93c7cL,0x65c3ca9444a2ecL,
33051         0x07bed6c59c3563L },
33052       { 0x51f9d994fb1471L,0x3c3ecfa5283b4eL,0x494dccda63f6ccL,
33053         0x4d07b255363a75L,0x0d2b6d3155d118L,0x3c688299fc9497L,
33054         0x235692fa3dea3aL } },
33055     /* 188 */
33056     { { 0x16b4d452669e98L,0x72451fa85406b9L,0x674a145d39151fL,
33057         0x325ffd067ae098L,0x527e7805cd1ae0L,0x422a1d1789e48dL,
33058         0x3e27be63f55e07L },
33059       { 0x7f95f6dee0b63fL,0x008e444cc74969L,0x01348f3a72b614L,
33060         0x000cfac81348c3L,0x508ae3e5309ce5L,0x2584fcdee44d34L,
33061         0x3a4dd994899ee9L } },
33062     /* 189 */
33063     { { 0x4d289cc0368708L,0x0e5ebc60dc3b40L,0x78cc44bfab1162L,
33064         0x77ef2173b7d11eL,0x06091718e39746L,0x30fe19319b83a4L,
33065         0x17e8f2988529c6L },
33066       { 0x68188bdcaa9f2aL,0x0e64b1350c1bddL,0x5b18ebac7cc4b3L,
33067         0x75315a9fcc046eL,0x36e9770fd43db4L,0x54c5857fc69121L,
33068         0x0417e18f3e909aL } },
33069     /* 190 */
33070     { { 0x29795db38059adL,0x6efd20c8fd4016L,0x3b6d1ce8f95a1aL,
33071         0x4db68f177f8238L,0x14ec7278d2340fL,0x47bd77ff2b77abL,
33072         0x3d2dc8cd34e9fcL },
33073       { 0x285980a5a83f0bL,0x08352e2d516654L,0x74894460481e1bL,
33074         0x17f6f3709c480dL,0x6b590d1b55221eL,0x45c100dc4c9be9L,
33075         0x1b13225f9d8b91L } },
33076     /* 191 */
33077     { { 0x0b905fb4b41d9dL,0x48cc8a474cb7a2L,0x4eda67e8de09b2L,
33078         0x1de47c829adde8L,0x118ad5b9933d77L,0x7a12665ac3f9a4L,
33079         0x05631a4fb52997L },
33080       { 0x5fb2a8e6806e63L,0x27d96bbcca369bL,0x46066f1a6b8c7bL,
33081         0x63b58fc7ca3072L,0x170a36229c0d62L,0x57176f1e463203L,
33082         0x0c7ce083e73b9cL } },
33083     /* 192 */
33084     { { 0x31caf2c09e1c72L,0x6530253219e9d2L,0x7650c98b601c57L,
33085         0x182469f99d56c0L,0x415f65d292b7a7L,0x30f62a55549b8eL,
33086         0x30f443f643f465L },
33087       { 0x6b35c575ddadd0L,0x14a23cf6d299eeL,0x2f0198c0967d7dL,
33088         0x1013058178d5bfL,0x39da601c9cc879L,0x09d8963ec340baL,
33089         0x1b735db13ad2a7L } },
33090     /* 193 */
33091     { { 0x20916ffdc83f01L,0x16892aa7c9f217L,0x6bff179888d532L,
33092         0x4adf3c3d366288L,0x41a62b954726aeL,0x3139609022aeb6L,
33093         0x3e8ab9b37aff7aL },
33094       { 0x76bbc70f24659aL,0x33fa98513886c6L,0x13b26af62c4ea6L,
33095         0x3c4d5826389a0cL,0x526ec28c02bf6aL,0x751ff083d79a7cL,
33096         0x110ac647990224L } },
33097     /* 194 */
33098     { { 0x2c6c62fa2b6e20L,0x3d37edad30c299L,0x6ef25b44b65fcaL,
33099         0x7470846914558eL,0x712456eb913275L,0x075a967a9a280eL,
33100         0x186c8188f2a2a0L },
33101       { 0x2f3b41a6a560b1L,0x3a8070b3f9e858L,0x140936ff0e1e78L,
33102         0x5fd298abe6da8aL,0x3823a55d08f153L,0x3445eafaee7552L,
33103         0x2a5fc96731a8b2L } },
33104     /* 195 */
33105     { { 0x06317be58edbbbL,0x4a38f3bfbe2786L,0x445b60f75896b7L,
33106         0x6ec7c92b5adf57L,0x07b6be8038a441L,0x1bcfe002879655L,
33107         0x2a2174037d6d0eL },
33108       { 0x776790cf9e48bdL,0x73e14a2c4ed1d3L,0x7eb5ed5f2fc2f7L,
33109         0x3e0aedb821b384L,0x0ee3b7e151c12fL,0x51a6a29e044bb2L,
33110         0x0ba13a00cb0d86L } },
33111     /* 196 */
33112     { { 0x77607d563ec8d8L,0x023fc726996e44L,0x6bd63f577a9986L,
33113         0x114a6351e53973L,0x3efe97989da046L,0x1051166e117ed7L,
33114         0x0354933dd4fb5fL },
33115       { 0x7699ca2f30c073L,0x4c973b83b9e6d3L,0x2017c2abdbc3e8L,
33116         0x0cdcdd7a26522bL,0x511070f5b23c7dL,0x70672327e83d57L,
33117         0x278f842b4a9f26L } },
33118     /* 197 */
33119     { { 0x0824f0d4ae972fL,0x60578dd08dcf52L,0x48a74858290fbbL,
33120         0x7302748bf23030L,0x184b229a178acfL,0x3e8460ade089d6L,
33121         0x13f2b557fad533L },
33122       { 0x7f96f3ae728d15L,0x018d8d40066341L,0x01fb94955a289aL,
33123         0x2d32ed6afc2657L,0x23f4f5e462c3acL,0x60eba5703bfc5aL,
33124         0x1b91cc06f16c7aL } },
33125     /* 198 */
33126     { { 0x411d68af8219b9L,0x79cca36320f4eeL,0x5c404e0ed72e20L,
33127         0x417cb8692e43f2L,0x305d29c7d98599L,0x3b754d5794a230L,
33128         0x1c97fb4be404e9L },
33129       { 0x7cdbafababd109L,0x1ead0eb0ca5090L,0x1a2b56095303e3L,
33130         0x75dea935012c8fL,0x67e31c071b1d1dL,0x7c324fbfd172c3L,
33131         0x157e257e6498f7L } },
33132     /* 199 */
33133     { { 0x19b00db175645bL,0x4c4f6cb69725f1L,0x36d9ce67bd47ceL,
33134         0x2005e105179d64L,0x7b952e717867feL,0x3c28599204032cL,
33135         0x0f5659d44fb347L },
33136       { 0x1ebcdedb979775L,0x4378d45cfd11a8L,0x14c85413ca66e9L,
33137         0x3dd17d681c8a4dL,0x58368e7dc23142L,0x14f3eaac6116afL,
33138         0x0adb45b255f6a0L } },
33139     /* 200 */
33140     { { 0x2f5e76279ad982L,0x125b3917034d09L,0x3839a6399e6ed3L,
33141         0x32fe0b3ebcd6a2L,0x24ccce8be90482L,0x467e26befcc187L,
33142         0x2828434e2e218eL },
33143       { 0x17247cd386efd9L,0x27f36a468d85c3L,0x65e181ef203bbfL,
33144         0x0433a6761120afL,0x1d607a2a8f8625L,0x49f4e55a13d919L,
33145         0x3367c3b7943e9dL } },
33146     /* 201 */
33147     { { 0x3391c7d1a46d4dL,0x38233d602d260cL,0x02127a0f78b7d4L,
33148         0x56841c162c24c0L,0x4273648fd09aa8L,0x019480bb0e754eL,
33149         0x3b927987b87e58L },
33150       { 0x6676be48c76f73L,0x01ec024e9655aeL,0x720fe1c6376704L,
33151         0x17e06b98885db3L,0x656adec85a4200L,0x73780893c3ce88L,
33152         0x0a339cdd8df664L } },
33153     /* 202 */
33154     { { 0x69af7244544ac7L,0x31ab7402084d2fL,0x67eceb7ef7cb19L,
33155         0x16f8583b996f61L,0x1e208d12faf91aL,0x4a91584ce4a42eL,
33156         0x3e08337216c93eL },
33157       { 0x7a6eea94f4cf77L,0x07a52894678c60L,0x302dd06b14631eL,
33158         0x7fddb7225c9ceaL,0x55e441d7acd153L,0x2a00d4490b0f44L,
33159         0x053ef125338cdbL } },
33160     /* 203 */
33161     { { 0x120c0c51584e3cL,0x78b3efca804f37L,0x662108aefb1dccL,
33162         0x11deb55f126709L,0x66def11ada8125L,0x05bbc0d1001711L,
33163         0x1ee1c99c7fa316L },
33164       { 0x746f287de53510L,0x1733ef2e32d09cL,0x1df64a2b0924beL,
33165         0x19758da8f6405eL,0x28f6eb3913e484L,0x7175a1090cc640L,
33166         0x048aee0d63f0bcL } },
33167     /* 204 */
33168     { { 0x1f3b1e3b0b29c3L,0x48649f4882a215L,0x485eca3a9e0dedL,
33169         0x4228ba85cc82e4L,0x36da1f39bc9379L,0x1659a7078499d1L,
33170         0x0a67d5f6c04188L },
33171       { 0x6ac39658afdce3L,0x0d667a0bde8ef6L,0x0ae6ec0bfe8548L,
33172         0x6d9cb2650571bfL,0x54bea107760ab9L,0x705c53bd340cf2L,
33173         0x111a86b610c70fL } },
33174     /* 205 */
33175     { { 0x7ecea05c6b8195L,0x4f8be93ce3738dL,0x305de9eb9f5d12L,
33176         0x2c3b9d3d474b56L,0x673691a05746c3L,0x2e3482c428c6eaL,
33177         0x2a8085fde1f472L },
33178       { 0x69d15877fd3226L,0x4609c9ec017cc3L,0x71e9b7fc1c3dbcL,
33179         0x4f8951254e2675L,0x63ee9d15afa010L,0x0f05775b645190L,
33180         0x28a0a439397ae3L } },
33181     /* 206 */
33182     { { 0x387fa03e9de330L,0x40cc32b828b6abL,0x02a482fbc04ac9L,
33183         0x68cad6e70429b7L,0x741877bff6f2c4L,0x48efe633d3b28bL,
33184         0x3e612218fe24b3L },
33185       { 0x6fc1d34fe37657L,0x3d04b9e1c8b5a1L,0x6a2c332ef8f163L,
33186         0x7ca97e2b135690L,0x37357d2a31208aL,0x29f02f2332bd68L,
33187         0x17c674c3e63a57L } },
33188     /* 207 */
33189     { { 0x683d9a0e6865bbL,0x5e77ec68ad4ce5L,0x4d18f236788bd6L,
33190         0x7f34b87204f4e3L,0x391ca40e9e578dL,0x3470ed6ddf4e23L,
33191         0x225544b3e50989L },
33192       { 0x48eda8cb4e462bL,0x2a948825cf9109L,0x473adedc7e1300L,
33193         0x37b843b82192edL,0x2b9ac1537dde36L,0x4efe7412732332L,
33194         0x29cc5981b5262bL } },
33195     /* 208 */
33196     { { 0x190d2fcad260f5L,0x7c53dd81d18027L,0x003def5f55db0eL,
33197         0x7f5ed25bee2df7L,0x2b87e9be167d2eL,0x2b999c7bbcd224L,
33198         0x1d68a2c260ad50L },
33199       { 0x010bcde84607a6L,0x0250de9b7e1bedL,0x746d36bfaf1b56L,
33200         0x3359475ff56abbL,0x7e84b9bc440b20L,0x2eaa7e3b52f162L,
33201         0x01165412f36a69L } },
33202     /* 209 */
33203     { { 0x639a02329e5836L,0x7aa3ee2e4d3a27L,0x5bc9b258ecb279L,
33204         0x4cb3dfae2d62c6L,0x08d9d3b0c6c437L,0x5a2c177d47eab2L,
33205         0x36120479fc1f26L },
33206       { 0x7609a75bd20e4aL,0x3ba414e17551fcL,0x42cd800e1b90c9L,
33207         0x04921811b88f9bL,0x4443697f9562fdL,0x3a8081b8186959L,
33208         0x3f5b5c97379e73L } },
33209     /* 210 */
33210     { { 0x6fd0e3cf13eafbL,0x3976b5415cbf67L,0x4de40889e48402L,
33211         0x17e4d36f24062aL,0x16ae7755cf334bL,0x2730ac94b7e0e1L,
33212         0x377592742f48e0L },
33213       { 0x5e10b18a045041L,0x682792afaae5a1L,0x19383ec971b816L,
33214         0x208b17dae2ffc0L,0x439f9d933179b6L,0x55485a9090bcaeL,
33215         0x1c316f42a2a35cL } },
33216     /* 211 */
33217     { { 0x67173897bdf646L,0x0b6956653ef94eL,0x5be3c97f7ea852L,
33218         0x3110c12671f08eL,0x2474076a3fc7ecL,0x53408be503fe72L,
33219         0x09155f53a5b44eL },
33220       { 0x5c804bdd4c27cdL,0x61e81eb8ffd50eL,0x2f7157fdf84717L,
33221         0x081f880d646440L,0x7aa892acddec51L,0x6ae70683443f33L,
33222         0x31ed9e8b33a75aL } },
33223     /* 212 */
33224     { { 0x0d724f8e357586L,0x1febbec91b4134L,0x6ff7b98a9475fdL,
33225         0x1c4d9b94e1f364L,0x2b8790499cef00L,0x42fd2080a1b31dL,
33226         0x3a3bbc6d9b0145L },
33227       { 0x75bfebc37e3ca9L,0x28db49c1723bd7L,0x50b12fa8a1f17aL,
33228         0x733d95bbc84b98L,0x45ede81f6c109eL,0x18f5e46fb37b5fL,
33229         0x34b980804aaec1L } },
33230     /* 213 */
33231     { { 0x56060c8a4f57bfL,0x0d2dfe223054c2L,0x718a5bbc03e5d6L,
33232         0x7b3344cc19b3b9L,0x4d11c9c054bcefL,0x1f5ad422c22e33L,
33233         0x2609299076f86bL },
33234       { 0x7b7a5fba89fd01L,0x7013113ef3b016L,0x23d5e0a173e34eL,
33235         0x736c14462f0f50L,0x1ef5f7ac74536aL,0x4baba6f4400ea4L,
33236         0x17b310612c9828L } },
33237     /* 214 */
33238     { { 0x4ebb19a708c8d3L,0x209f8c7f03d9bbL,0x00461cfe5798fbL,
33239         0x4f93b6ae822fadL,0x2e5b33b5ad5447L,0x40b024e547a84bL,
33240         0x22ffad40443385L },
33241       { 0x33809c888228bfL,0x559f655fefbe84L,0x0032f529fd2f60L,
33242         0x5a2191ece3478cL,0x5b957fcd771246L,0x6fec181f9ed123L,
33243         0x33eed3624136a3L } },
33244     /* 215 */
33245     { { 0x6a5df93b26139aL,0x55076598fd7134L,0x356a592f34f81dL,
33246         0x493c6b5a3d4741L,0x435498a4e2a39bL,0x2cd26a0d931c88L,
33247         0x01925ea3fc7835L },
33248       { 0x6e8d992b1efa05L,0x79508a727c667bL,0x5f3c15e6b4b698L,
33249         0x11b6c755257b93L,0x617f5af4b46393L,0x248d995b2b6656L,
33250         0x339db62e2e22ecL } },
33251     /* 216 */
33252     { { 0x52537a083843dcL,0x6a283c82a768c7L,0x13aa6bf25227acL,
33253         0x768d76ba8baf5eL,0x682977a6525808L,0x67ace52ac23b0bL,
33254         0x2374b5a2ed612dL },
33255       { 0x7139e60133c3a4L,0x715697a4f1d446L,0x4b018bf36677a0L,
33256         0x1dd43837414d83L,0x505ec70730d4f6L,0x09ac100907fa79L,
33257         0x21caad6e03217eL } },
33258     /* 217 */
33259     { { 0x0776d3999d4d49L,0x33bdd87e8bcff8L,0x1036b87f068fadL,
33260         0x0a9b8ffde4c872L,0x7ab2533596b1eaL,0x305a88fb965378L,
33261         0x3356d8fa4d65e5L },
33262       { 0x3366fa77d1ff11L,0x1e0bdbdcd2075cL,0x46910cefc967caL,
33263         0x7ce700737a1ff6L,0x1c5dc15409c9bdL,0x368436b9bdb595L,
33264         0x3e7ccd6560b5efL } },
33265     /* 218 */
33266     { { 0x1443789422c792L,0x524792b1717f2bL,0x1f7c1d95048e7aL,
33267         0x5cfe2a225b0d12L,0x245594d29ce85bL,0x20134d254ce168L,
33268         0x1b83296803921aL },
33269       { 0x79a78285b3beceL,0x3c738c3f3124d6L,0x6ab9d1fe0907cdL,
33270         0x0652ceb7fc104cL,0x06b5f58c8ae3fdL,0x486959261c5328L,
33271         0x0b3813ae677c90L } },
33272     /* 219 */
33273     { { 0x66b9941ac37b82L,0x651a4b609b0686L,0x046711edf3fc31L,
33274         0x77f89f38faa89bL,0x2683ddbf2d5edbL,0x389ef1dfaa3c25L,
33275         0x20b3616e66273eL },
33276       { 0x3c6db6e0cb5d37L,0x5d7ae5dc342bc4L,0x74a1dc6c52062bL,
33277         0x6f7c0bec109557L,0x5c51f7bc221d91L,0x0d7b5880745288L,
33278         0x1c46c145c4b0ddL } },
33279     /* 220 */
33280     { { 0x59ed485ea99eccL,0x201b71956bc21dL,0x72d5c32f73de65L,
33281         0x1aefd76547643eL,0x580a452cfb2c2dL,0x7cb1a63f5c4dc9L,
33282         0x39a8df727737aaL },
33283       { 0x365a341deca452L,0x714a1ad1689cbaL,0x16981d12c42697L,
33284         0x5a124f4ac91c75L,0x1b2e3f2fedc0dbL,0x4a1c72b8e9d521L,
33285         0x3855b4694e4e20L } },
33286     /* 221 */
33287     { { 0x16b3d047181ae9L,0x17508832f011afL,0x50d33cfeb2ebd1L,
33288         0x1deae237349984L,0x147c641aa6adecL,0x24a9fb4ebb1ddbL,
33289         0x2b367504a7a969L },
33290       { 0x4c55a3d430301bL,0x379ef6a5d492cbL,0x3c56541fc0f269L,
33291         0x73a546e91698ceL,0x2c2b62ee0b9b5dL,0x6284184d43d0efL,
33292         0x0e1f5cf6a4b9f0L } },
33293     /* 222 */
33294     { { 0x44833e8cd3fdacL,0x28e6665cb71c27L,0x2f8bf87f4ddbf3L,
33295         0x6cc6c767fb38daL,0x3bc114d734e8b5L,0x12963d5a78ca29L,
33296         0x34532a161ece41L },
33297       { 0x2443af5d2d37e9L,0x54e6008c8c452bL,0x2c55d54111cf1bL,
33298         0x55ac7f7522575aL,0x00a6fba3f8575fL,0x3f92ef3b793b8dL,
33299         0x387b97d69ecdf7L } },
33300     /* 223 */
33301     { { 0x0b464812d29f46L,0x36161daa626f9aL,0x5202fbdb264ca5L,
33302         0x21245805ff1304L,0x7f9c4a65657885L,0x542d3887f9501cL,
33303         0x086420deef8507L },
33304       { 0x5e159aa1b26cfbL,0x3f0ef5ffd0a50eL,0x364b29663a432aL,
33305         0x49c56888af32a8L,0x6f937e3e0945d1L,0x3cbdeec6d766cdL,
33306         0x2d80d342ece61aL } },
33307     /* 224 */
33308     { { 0x255e3026d8356eL,0x4ddba628c4de9aL,0x074323b593e0d9L,
33309         0x333bdb0a10eefbL,0x318b396e473c52L,0x6ebb5a95efd3d3L,
33310         0x3f3bff52aa4e4fL },
33311       { 0x3138a111c731d5L,0x674365e283b308L,0x5585edd9c416f2L,
33312         0x466763d9070fd4L,0x1b568befce8128L,0x16eb040e7b921eL,
33313         0x3d5c898687c157L } },
33314     /* 225 */
33315     { { 0x14827736973088L,0x4e110d53f301e6L,0x1f811b09870023L,
33316         0x53b5e500dbcacaL,0x4ddf0df1e6a7dcL,0x1e9575fb10ce35L,
33317         0x3fdc153644d936L },
33318       { 0x763547e2260594L,0x26e5ae764efc59L,0x13be6f4d791a29L,
33319         0x2021e61e3a0cf1L,0x339cd2b4a1c202L,0x5c7451e08f5121L,
33320         0x3728b3a851be68L } },
33321     /* 226 */
33322     { { 0x78873653277538L,0x444b9ed2ee7156L,0x79ac8b8b069cd3L,
33323         0x5f0e90933770e8L,0x307662c615389eL,0x40fe6d95a80057L,
33324         0x04822170cf993cL },
33325       { 0x677d5690fbfec2L,0x0355af4ae95cb3L,0x417411794fe79eL,
33326         0x48daf87400a085L,0x33521d3b5f0aaaL,0x53567a3be00ff7L,
33327         0x04712ccfb1cafbL } },
33328     /* 227 */
33329     { { 0x2b983283c3a7f3L,0x579f11b146a9a6L,0x1143d3b16a020eL,
33330         0x20f1483ef58b20L,0x3f03e18d747f06L,0x3129d12f15de37L,
33331         0x24c911f7222833L },
33332       { 0x1e0febcf3d5897L,0x505e26c01cdaacL,0x4f45a9adcff0e9L,
33333         0x14dfac063c5cebL,0x69e5ce713fededL,0x3481444a44611aL,
33334         0x0ea49295c7fdffL } },
33335     /* 228 */
33336     { { 0x64554cb4093beeL,0x344b4b18dd81f6L,0x350f43b4de9b59L,
33337         0x28a96a220934caL,0x4aa8da5689a515L,0x27171cbd518509L,
33338         0x0cfc1753f47c95L },
33339       { 0x7dfe091b615d6eL,0x7d1ee0aa0fb5c1L,0x145eef3200b7b5L,
33340         0x33fe88feeab18fL,0x1d62d4f87453e2L,0x43b8db4e47fff1L,
33341         0x1572f2b8b8f368L } },
33342     /* 229 */
33343     { { 0x6bc94e6b4e84f3L,0x60629dee586a66L,0x3bbad5fe65ca18L,
33344         0x217670db6c2fefL,0x0320a7f4e3272aL,0x3ccff0d976a6deL,
33345         0x3c26da8ae48cccL },
33346       { 0x53ecf156778435L,0x7533064765a443L,0x6c5c12f03ca5deL,
33347         0x44f8245350dabfL,0x342cdd777cf8b3L,0x2b539c42e9f58dL,
33348         0x10138affc279b1L } },
33349     /* 230 */
33350     { { 0x1b135e204c5ddbL,0x40887dfeaa1d37L,0x7fb0ef83da76ffL,
33351         0x521f2b79af55a5L,0x3f9b38b4c3f0d0L,0x20a9838cce61ceL,
33352         0x24bb4e2f4b1e32L },
33353       { 0x003f6aa386e27cL,0x68df59db0a0f8eL,0x21677d5192e713L,
33354         0x14ab9757501276L,0x411944af961524L,0x3184f39abc5c3fL,
33355         0x2a8dda80ca078dL } },
33356     /* 231 */
33357     { { 0x0592233cdbc95cL,0x54d5de5c66f40fL,0x351caa1512ab86L,
33358         0x681bdbee020084L,0x6ee2480c853e68L,0x6a5a44262b918fL,
33359         0x06574e15a3b91dL },
33360       { 0x31ba03dacd7fbeL,0x0c3da7c18a57a9L,0x49aaaded492d6bL,
33361         0x3071ff53469e02L,0x5efb4f0d7248c6L,0x6db5fb67f12628L,
33362         0x29cff668e3d024L } },
33363     /* 232 */
33364     { { 0x1b9ef3bb1b17ceL,0x6ccf8c24fe6312L,0x34c15487f45008L,
33365         0x1a84044095972cL,0x515073a47e449eL,0x2ddc93f9097feeL,
33366         0x1008fdc894c434L },
33367       { 0x08e5edb73399faL,0x65b1aa65547d4cL,0x3a117a1057c498L,
33368         0x7e16c3089d13acL,0x502f2ae4b6f851L,0x57a70f3eb62673L,
33369         0x111b48a9a03667L } },
33370     /* 233 */
33371     { { 0x5023024be164f1L,0x25ad117032401eL,0x46612b3bfe3427L,
33372         0x2f4f406a8a02b7L,0x16a93a5c4ddf07L,0x7ee71968fcdbe9L,
33373         0x2267875ace37daL },
33374       { 0x687e88b59eb2a6L,0x3ac7368fe716d3L,0x28d953a554a036L,
33375         0x34d52c0acca08fL,0x742a7cf8dd4fd9L,0x10bfeb8575ea60L,
33376         0x290e454d868dccL } },
33377     /* 234 */
33378     { { 0x4e72a3a8a4bdd2L,0x1ba36d1dee04d5L,0x7a43136b63195bL,
33379         0x6ca8e286a519f3L,0x568e64aece08a9L,0x571d5000b5c10bL,
33380         0x3f75e9f5dbdd40L },
33381       { 0x6fb0a698d6fa45L,0x0ce42209d7199cL,0x1f68275f708a3eL,
33382         0x5749832e91ec3cL,0x6c3665521428b2L,0x14b2bf5747bd4aL,
33383         0x3b6f940e42a22bL } },
33384     /* 235 */
33385     { { 0x4da0adbfb26c82L,0x16792a585f39acL,0x17df9dfda3975cL,
33386         0x4796b4afaf479bL,0x67be67234e0020L,0x69df5f201dda25L,
33387         0x09f71a4d12b3dcL },
33388       { 0x64ff5ec260a46aL,0x579c5b86385101L,0x4f29a7d549f697L,
33389         0x4e64261242e2ebL,0x54ecacdfb6b296L,0x46e0638b5fddadL,
33390         0x31eefd3208891dL } },
33391     /* 236 */
33392     { { 0x5b72c749fe01b2L,0x230cf27523713aL,0x533d1810e0d1e1L,
33393         0x5590db7d1dd1e2L,0x7b8ab73e8e43d3L,0x4c8a19bd1c17caL,
33394         0x19222ce9f74810L },
33395       { 0x6398b3dddc4582L,0x0352b7d88dfd53L,0x3c55b4e10c5a63L,
33396         0x38194d13f8a237L,0x106683fd25dd87L,0x59e0b62443458eL,
33397         0x196cb70aa9cbb9L } },
33398     /* 237 */
33399     { { 0x2885f7cd021d63L,0x162bfd4c3e1043L,0x77173dcf98fcd1L,
33400         0x13d4591d6add36L,0x59311154d0d8f2L,0x74336e86e79b8aL,
33401         0x13faadc5661883L },
33402       { 0x18938e7d9ec924L,0x14bcda8fcaa0a1L,0x706d85d41a1355L,
33403         0x0ac34520d168deL,0x5a92499fe17826L,0x36c2e3b4f00600L,
33404         0x29c2fd7b5f63deL } },
33405     /* 238 */
33406     { { 0x41250dfe2216c5L,0x44a0ec0366a217L,0x575bc1adf8b0dfL,
33407         0x5ff5cdbdb1800bL,0x7843d4dde8ca18L,0x5fa9e420865705L,
33408         0x235c38be6c6b02L },
33409       { 0x473b78aae91abbL,0x39470c6051e44bL,0x3f973cc2dc08c3L,
33410         0x2837932c5c91f6L,0x25e39ed754ec25L,0x1371c837118e53L,
33411         0x3b99f3b0aeafe2L } },
33412     /* 239 */
33413     { { 0x03acf51be46c65L,0x271fceacbaf5c3L,0x476589ed3a5e25L,
33414         0x78ec8c3c3c399cL,0x1f5c8bf4ac4c19L,0x730bb733ec68d2L,
33415         0x29a37e00dd287eL },
33416       { 0x448ed1bf92b5faL,0x10827c17b86478L,0x55e6fc05b28263L,
33417         0x0af1226c73a66aL,0x0b66e5df0d09c1L,0x26128315a02682L,
33418         0x22d84932c5e808L } },
33419     /* 240 */
33420     { { 0x5ec3afc26e3392L,0x08e142e45c0084L,0x4388d5ad0f01feL,
33421         0x0f7acd36e6140cL,0x028c14ed97dffbL,0x311845675a38c6L,
33422         0x01c1c8f09a3062L },
33423       { 0x5a302f4cf49e7dL,0x79267e254a44e1L,0x746165052317a1L,
33424         0x53a09263a566e8L,0x7d478ad5f73abcL,0x187ce5c947dad3L,
33425         0x18564e1a1ec45fL } },
33426     /* 241 */
33427     { { 0x7b9577a9aa0486L,0x766b40c7aaaef6L,0x1f6a411f5db907L,
33428         0x4543dd4d80beaeL,0x0ad938c7482806L,0x451568bf4b9be1L,
33429         0x3367ec85d30a22L },
33430       { 0x5446425747843dL,0x18d94ac223c6b2L,0x052ff3a354d359L,
33431         0x0b4933f89723f5L,0x03fb517740e056L,0x226b892871dddaL,
33432         0x2768c2b753f0fdL } },
33433     /* 242 */
33434     { { 0x685282ccfa5200L,0x411ed433627b89L,0x77d5c9b8bc9c1dL,
33435         0x4a13ef2ee5cd29L,0x5582a612407c9eL,0x2307cb42fc3aa9L,
33436         0x2e661df79956b8L },
33437       { 0x0e972b015254deL,0x5b63e14def8adeL,0x06995be2ca4a95L,
33438         0x6cc0cc1e94bf27L,0x7ed8499fe0052aL,0x671a6ca5a5e0f9L,
33439         0x31e10d4ba10f05L } },
33440     /* 243 */
33441     { { 0x690af07e9b2d8aL,0x6030af9e32c8ddL,0x45c7ca3bf2b235L,
33442         0x40959077b76c81L,0x61eee7f70d5a96L,0x6b04f6aafe9e38L,
33443         0x3c726f55f1898dL },
33444       { 0x77d0142a1a6194L,0x1c1631215708b9L,0x403a4f0a9b7585L,
33445         0x066c8e29f7cef0L,0x6fc32f98cf575eL,0x518a09d818c297L,
33446         0x34144e99989e75L } },
33447     /* 244 */
33448     { { 0x6adbada859fb6aL,0x0dcfb6506ccd51L,0x68f88b8d573e0dL,
33449         0x4b1ce35bd9af30L,0x241c8293ece2c9L,0x3b5f402c5c4adeL,
33450         0x34b9b1ee6fde87L },
33451       { 0x5e625340075e63L,0x54c3f3d9050da1L,0x2a3f9152509016L,
33452         0x3274e46111bc18L,0x3a7504fd01ac73L,0x4169b387a43209L,
33453         0x35626f852bc6d4L } },
33454     /* 245 */
33455     { { 0x576a4f4662e53bL,0x5ea3f20eecec26L,0x4e5f02be5cd7b0L,
33456         0x72cc5ac3314be8L,0x0f604ed3201fe9L,0x2a29378ea54bceL,
33457         0x2d52bd4d6ec4b6L },
33458       { 0x6a4c2b212c1c76L,0x778fd64a1bfa6dL,0x326828691863d6L,
33459         0x5616c8bd06a336L,0x5fab552564da4dL,0x46640cab3e91d2L,
33460         0x1d21f06427299eL } },
33461     /* 246 */
33462     { { 0x2bfe37dde98e9cL,0x164c54822332ebL,0x5b736c7df266e4L,
33463         0x59dab3a8da084cL,0x0ae1eab346f118L,0x182090a4327e3fL,
33464         0x07b13489dae2e6L },
33465       { 0x3bc92645452baaL,0x30b159894ae574L,0x5b947c5c78e1f4L,
33466         0x18f0e004a3c77fL,0x48ca8f357077d9L,0x349ffdcef9bca9L,
33467         0x3ed224bfd54772L } },
33468     /* 247 */
33469     { { 0x1bdad02db8dff8L,0x69fab4450b44b6L,0x3b6802d187518bL,
33470         0x098368d8eb556cL,0x3fe1943fbefcf4L,0x008851d0de6d42L,
33471         0x322cbc4605fe25L },
33472       { 0x2528aaf0d51afbL,0x7d48a9363a0cecL,0x4ba8f77d9a8f8bL,
33473         0x7dee903437d6c7L,0x1ff5a0d9ccc4b4L,0x34d9bd2fa99831L,
33474         0x30d9e4f58667c6L } },
33475     /* 248 */
33476     { { 0x38909b51b85197L,0x7ba16992512bd4L,0x2c776cfcfffec5L,
33477         0x2be7879075843cL,0x557e2b05d28ffcL,0x641b17bc5ce357L,
33478         0x1fcaf8a3710306L },
33479       { 0x54dca2299a2d48L,0x745d06ef305acaL,0x7c41c65c6944c2L,
33480         0x679412ec431902L,0x48f2b15ee62827L,0x341a96d8afe06eL,
33481         0x2a78fd3690c0e1L } },
33482     /* 249 */
33483     { { 0x6b7cec83fbc9c6L,0x238e8a82eefc67L,0x5d3c1d9ff0928cL,
33484         0x55b816d6409bbfL,0x7969612adae364L,0x55b6ff96db654eL,
33485         0x129beca10073a9L },
33486       { 0x0b1d2acdfc73deL,0x5d1a3605fa64bdL,0x436076146743beL,
33487         0x64044b89fcce0cL,0x7ae7b3c18f7fafL,0x7f083ee27cea36L,
33488         0x0292cd0d7c1ff0L } },
33489     /* 250 */
33490     { { 0x5a3c4c019b7d2eL,0x1a35a9b89712fbL,0x38736cc4f18c72L,
33491         0x603dd832a44e6bL,0x000d1d44aed104L,0x69b1f2fc274ebeL,
33492         0x03a7b993f76977L },
33493       { 0x299f3b3e346910L,0x5243f45295afd5L,0x34342cbfa588bdL,
33494         0x72c40dd1155510L,0x718024fed2f991L,0x2f935e765ad82aL,
33495         0x246799ea371fb8L } },
33496     /* 251 */
33497     { { 0x24fe4c76250533L,0x01cafb02fdf18eL,0x505cb25d462882L,
33498         0x3e038175157d87L,0x7e3e99b10cdeb1L,0x38b7e72ebc7936L,
33499         0x081845f7c73433L },
33500       { 0x049e61be05ebd5L,0x6ab82d8f0581f6L,0x62adffb427ac2eL,
33501         0x19431f809d198dL,0x36195f6c58b1d6L,0x22cc4c9dedc9a7L,
33502         0x24b146d8e694fcL } },
33503     /* 252 */
33504     { { 0x7c7bc8288b364dL,0x5c10f683cb894aL,0x19a62a68452958L,
33505         0x1fc24dcb4ce90eL,0x726baa4ed9581fL,0x1f34447dde73d6L,
33506         0x04c56708f30a21L },
33507       { 0x131e583a3f4963L,0x071215b4d502e7L,0x196aca542e5940L,
33508         0x3afd5a91f7450eL,0x671b6eedf49497L,0x6aac7aca5c29e4L,
33509         0x3fb512470f138bL } },
33510     /* 253 */
33511     { { 0x5eadc3f4eb453eL,0x16c795ba34b666L,0x5d7612a4697fddL,
33512         0x24dd19bb499e86L,0x415b89ca3eeb9bL,0x7c83edf599d809L,
33513         0x13bc64c9b70269L },
33514       { 0x52d3243dca3233L,0x0b21444b3a96a7L,0x6d551bc0083b90L,
33515         0x4f535b88c61176L,0x11e61924298010L,0x0a155b415bb61dL,
33516         0x17f94fbd26658fL } },
33517     /* 254 */
33518     { { 0x2dd06b90c28c65L,0x48582339c8fa6eL,0x01ac8bf2085d94L,
33519         0x053e660e020fdcL,0x1bece667edf07bL,0x4558f2b33ce24cL,
33520         0x2f1a766e8673fcL },
33521       { 0x1d77cd13c06819L,0x4d5dc5056f3a01L,0x18896c6fa18d69L,
33522         0x120047ca76d625L,0x6af8457d4f4e45L,0x70ddc53358b60aL,
33523         0x330e11130e82f0L } },
33524     /* 255 */
33525     { { 0x0643b1cd4c2356L,0x10a2ea0a8f7c92L,0x2752513011d029L,
33526         0x4cd4c50321f579L,0x5fdf9ba5724792L,0x2f691653e2ddc0L,
33527         0x0cfed3d84226cbL },
33528       { 0x704902a950f955L,0x069bfdb87bbf0cL,0x5817eeda8a5f84L,
33529         0x1914cdd9089905L,0x0e4a323d7b93f4L,0x1cc3fc340af0b2L,
33530         0x23874161bd6303L } },
33531 };
33532 
33533 /* Multiply the base point of P384 by the scalar and return the result.
33534  * If map is true then convert result to affine coordinates.
33535  *
33536  * Stripe implementation.
33537  * Pre-generated: 2^0, 2^48, ...
33538  * Pre-generated: products of all combinations of above.
33539  * 8 doubles and adds (with qz=1)
33540  *
33541  * r     Resulting point.
33542  * k     Scalar to multiply by.
33543  * map   Indicates whether to convert result to affine.
33544  * ct    Constant time required.
33545  * heap  Heap to use for allocation.
33546  * returns MEMORY_E when memory allocation fails and MP_OKAY on success.
33547  */
sp_384_ecc_mulmod_base_7(sp_point_384 * r,const sp_digit * k,int map,int ct,void * heap)33548 static int sp_384_ecc_mulmod_base_7(sp_point_384* r, const sp_digit* k,
33549         int map, int ct, void* heap)
33550 {
33551     return sp_384_ecc_mulmod_stripe_7(r, &p384_base, p384_table,
33552                                       k, map, ct, heap);
33553 }
33554 
33555 #endif
33556 
33557 /* Multiply the base point of P384 by the scalar and return the result.
33558  * If map is true then convert result to affine coordinates.
33559  *
33560  * km    Scalar to multiply by.
33561  * r     Resulting point.
33562  * map   Indicates whether to convert result to affine.
33563  * heap  Heap to use for allocation.
33564  * returns MEMORY_E when memory allocation fails and MP_OKAY on success.
33565  */
sp_ecc_mulmod_base_384(const mp_int * km,ecc_point * r,int map,void * heap)33566 int sp_ecc_mulmod_base_384(const mp_int* km, ecc_point* r, int map, void* heap)
33567 {
33568 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
33569     sp_point_384* point = NULL;
33570     sp_digit* k = NULL;
33571 #else
33572     sp_point_384  point[1];
33573     sp_digit k[7];
33574 #endif
33575     int err = MP_OKAY;
33576 
33577 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
33578     point = (sp_point_384*)XMALLOC(sizeof(sp_point_384), heap,
33579                                          DYNAMIC_TYPE_ECC);
33580     if (point == NULL)
33581         err = MEMORY_E;
33582     if (err == MP_OKAY) {
33583         k = (sp_digit*)XMALLOC(sizeof(sp_digit) * 7, heap,
33584                                DYNAMIC_TYPE_ECC);
33585         if (k == NULL)
33586             err = MEMORY_E;
33587     }
33588 #endif
33589 
33590     if (err == MP_OKAY) {
33591         sp_384_from_mp(k, 7, km);
33592 
33593             err = sp_384_ecc_mulmod_base_7(point, k, map, 1, heap);
33594     }
33595     if (err == MP_OKAY) {
33596         err = sp_384_point_to_ecc_point_7(point, r);
33597     }
33598 
33599 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
33600     if (k != NULL)
33601         XFREE(k, heap, DYNAMIC_TYPE_ECC);
33602     if (point != NULL)
33603         XFREE(point, heap, DYNAMIC_TYPE_ECC);
33604 #endif
33605 
33606     return err;
33607 }
33608 
33609 /* Multiply the base point of P384 by the scalar, add point a and return
33610  * the result. If map is true then convert result to affine coordinates.
33611  *
33612  * km      Scalar to multiply by.
33613  * am      Point to add to scalar mulitply result.
33614  * inMont  Point to add is in montgomery form.
33615  * r       Resulting point.
33616  * map     Indicates whether to convert result to affine.
33617  * heap    Heap to use for allocation.
33618  * returns MEMORY_E when memory allocation fails and MP_OKAY on success.
33619  */
sp_ecc_mulmod_base_add_384(const mp_int * km,const ecc_point * am,int inMont,ecc_point * r,int map,void * heap)33620 int sp_ecc_mulmod_base_add_384(const mp_int* km, const ecc_point* am,
33621         int inMont, ecc_point* r, int map, void* heap)
33622 {
33623 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
33624     sp_point_384* point = NULL;
33625     sp_digit* k = NULL;
33626 #else
33627     sp_point_384 point[2];
33628     sp_digit k[7 + 7 * 2 * 6];
33629 #endif
33630     sp_point_384* addP = NULL;
33631     sp_digit* tmp = NULL;
33632     int err = MP_OKAY;
33633 
33634 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
33635     point = (sp_point_384*)XMALLOC(sizeof(sp_point_384) * 2, heap,
33636                                          DYNAMIC_TYPE_ECC);
33637     if (point == NULL)
33638         err = MEMORY_E;
33639     if (err == MP_OKAY) {
33640         k = (sp_digit*)XMALLOC(
33641             sizeof(sp_digit) * (7 + 7 * 2 * 6),
33642             heap, DYNAMIC_TYPE_ECC);
33643         if (k == NULL)
33644             err = MEMORY_E;
33645     }
33646 #endif
33647 
33648     if (err == MP_OKAY) {
33649         addP = point + 1;
33650         tmp = k + 7;
33651 
33652         sp_384_from_mp(k, 7, km);
33653         sp_384_point_from_ecc_point_7(addP, am);
33654     }
33655     if ((err == MP_OKAY) && (!inMont)) {
33656         err = sp_384_mod_mul_norm_7(addP->x, addP->x, p384_mod);
33657     }
33658     if ((err == MP_OKAY) && (!inMont)) {
33659         err = sp_384_mod_mul_norm_7(addP->y, addP->y, p384_mod);
33660     }
33661     if ((err == MP_OKAY) && (!inMont)) {
33662         err = sp_384_mod_mul_norm_7(addP->z, addP->z, p384_mod);
33663     }
33664     if (err == MP_OKAY) {
33665             err = sp_384_ecc_mulmod_base_7(point, k, 0, 0, heap);
33666     }
33667     if (err == MP_OKAY) {
33668             sp_384_proj_point_add_7(point, point, addP, tmp);
33669 
33670         if (map) {
33671                 sp_384_map_7(point, point, tmp);
33672         }
33673 
33674         err = sp_384_point_to_ecc_point_7(point, r);
33675     }
33676 
33677 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
33678     if (k != NULL)
33679         XFREE(k, heap, DYNAMIC_TYPE_ECC);
33680     if (point)
33681         XFREE(point, heap, DYNAMIC_TYPE_ECC);
33682 #endif
33683 
33684     return err;
33685 }
33686 
33687 #if defined(WOLFSSL_VALIDATE_ECC_KEYGEN) || defined(HAVE_ECC_SIGN) || \
33688                                                         defined(HAVE_ECC_VERIFY)
33689 /* Returns 1 if the number of zero.
33690  * Implementation is constant time.
33691  *
33692  * a  Number to check.
33693  * returns 1 if the number is zero and 0 otherwise.
33694  */
sp_384_iszero_7(const sp_digit * a)33695 static int sp_384_iszero_7(const sp_digit* a)
33696 {
33697     return (a[0] | a[1] | a[2] | a[3] | a[4] | a[5] | a[6]) == 0;
33698 }
33699 
33700 #endif /* WOLFSSL_VALIDATE_ECC_KEYGEN | HAVE_ECC_SIGN | HAVE_ECC_VERIFY */
33701 /* Add 1 to a. (a = a + 1)
33702  *
33703  * r  A single precision integer.
33704  * a  A single precision integer.
33705  */
sp_384_add_one_7(sp_digit * a)33706 SP_NOINLINE static void sp_384_add_one_7(sp_digit* a)
33707 {
33708     a[0]++;
33709     sp_384_norm_7(a);
33710 }
33711 
33712 /* Read big endian unsigned byte array into r.
33713  *
33714  * r  A single precision integer.
33715  * size  Maximum number of bytes to convert
33716  * a  Byte array.
33717  * n  Number of bytes in array to read.
33718  */
sp_384_from_bin(sp_digit * r,int size,const byte * a,int n)33719 static void sp_384_from_bin(sp_digit* r, int size, const byte* a, int n)
33720 {
33721     int i;
33722     int j = 0;
33723     word32 s = 0;
33724 
33725     r[0] = 0;
33726     for (i = n-1; i >= 0; i--) {
33727         r[j] |= (((sp_digit)a[i]) << s);
33728         if (s >= 47U) {
33729             r[j] &= 0x7fffffffffffffL;
33730             s = 55U - s;
33731             if (j + 1 >= size) {
33732                 break;
33733             }
33734             r[++j] = (sp_digit)a[i] >> s;
33735             s = 8U - s;
33736         }
33737         else {
33738             s += 8U;
33739         }
33740     }
33741 
33742     for (j++; j < size; j++) {
33743         r[j] = 0;
33744     }
33745 }
33746 
33747 /* Generates a scalar that is in the range 1..order-1.
33748  *
33749  * rng  Random number generator.
33750  * k    Scalar value.
33751  * returns RNG failures, MEMORY_E when memory allocation fails and
33752  * MP_OKAY on success.
33753  */
sp_384_ecc_gen_k_7(WC_RNG * rng,sp_digit * k)33754 static int sp_384_ecc_gen_k_7(WC_RNG* rng, sp_digit* k)
33755 {
33756     int err;
33757     byte buf[48];
33758 
33759     do {
33760         err = wc_RNG_GenerateBlock(rng, buf, sizeof(buf));
33761         if (err == 0) {
33762             sp_384_from_bin(k, 7, buf, (int)sizeof(buf));
33763             if (sp_384_cmp_7(k, p384_order2) <= 0) {
33764                 sp_384_add_one_7(k);
33765                 break;
33766             }
33767         }
33768     }
33769     while (err == 0);
33770 
33771     return err;
33772 }
33773 
33774 /* Makes a random EC key pair.
33775  *
33776  * rng   Random number generator.
33777  * priv  Generated private value.
33778  * pub   Generated public point.
33779  * heap  Heap to use for allocation.
33780  * returns ECC_INF_E when the point does not have the correct order, RNG
33781  * failures, MEMORY_E when memory allocation fails and MP_OKAY on success.
33782  */
sp_ecc_make_key_384(WC_RNG * rng,mp_int * priv,ecc_point * pub,void * heap)33783 int sp_ecc_make_key_384(WC_RNG* rng, mp_int* priv, ecc_point* pub, void* heap)
33784 {
33785 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
33786     sp_point_384* point = NULL;
33787     sp_digit* k = NULL;
33788 #else
33789     #ifdef WOLFSSL_VALIDATE_ECC_KEYGEN
33790     sp_point_384 point[2];
33791     #else
33792     sp_point_384 point[1];
33793     #endif
33794     sp_digit k[7];
33795 #endif
33796 #ifdef WOLFSSL_VALIDATE_ECC_KEYGEN
33797     sp_point_384* infinity = NULL;
33798 #endif
33799     int err = MP_OKAY;
33800 
33801 
33802     (void)heap;
33803 
33804 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
33805     #ifdef WOLFSSL_VALIDATE_ECC_KEYGEN
33806     point = (sp_point_384*)XMALLOC(sizeof(sp_point_384) * 2, heap, DYNAMIC_TYPE_ECC);
33807     #else
33808     point = (sp_point_384*)XMALLOC(sizeof(sp_point_384), heap, DYNAMIC_TYPE_ECC);
33809     #endif
33810     if (point == NULL)
33811         err = MEMORY_E;
33812     if (err == MP_OKAY) {
33813         k = (sp_digit*)XMALLOC(sizeof(sp_digit) * 7, heap,
33814                                DYNAMIC_TYPE_ECC);
33815         if (k == NULL)
33816             err = MEMORY_E;
33817     }
33818 #endif
33819 
33820     if (err == MP_OKAY) {
33821     #ifdef WOLFSSL_VALIDATE_ECC_KEYGEN
33822         infinity = point + 1;
33823     #endif
33824 
33825         err = sp_384_ecc_gen_k_7(rng, k);
33826     }
33827     if (err == MP_OKAY) {
33828             err = sp_384_ecc_mulmod_base_7(point, k, 1, 1, NULL);
33829     }
33830 
33831 #ifdef WOLFSSL_VALIDATE_ECC_KEYGEN
33832     if (err == MP_OKAY) {
33833             err = sp_384_ecc_mulmod_7(infinity, point, p384_order, 1, 1, NULL);
33834     }
33835     if (err == MP_OKAY) {
33836         if (sp_384_iszero_7(point->x) || sp_384_iszero_7(point->y)) {
33837             err = ECC_INF_E;
33838         }
33839     }
33840 #endif
33841 
33842     if (err == MP_OKAY) {
33843         err = sp_384_to_mp(k, priv);
33844     }
33845     if (err == MP_OKAY) {
33846         err = sp_384_point_to_ecc_point_7(point, pub);
33847     }
33848 
33849 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
33850     if (k != NULL)
33851         XFREE(k, heap, DYNAMIC_TYPE_ECC);
33852     if (point != NULL) {
33853         /* point is not sensitive, so no need to zeroize */
33854         XFREE(point, heap, DYNAMIC_TYPE_ECC);
33855     }
33856 #endif
33857 
33858     return err;
33859 }
33860 
33861 #ifdef HAVE_ECC_DHE
33862 /* Write r as big endian to byte array.
33863  * Fixed length number of bytes written: 48
33864  *
33865  * r  A single precision integer.
33866  * a  Byte array.
33867  */
sp_384_to_bin_7(sp_digit * r,byte * a)33868 static void sp_384_to_bin_7(sp_digit* r, byte* a)
33869 {
33870     int i;
33871     int j;
33872     int s = 0;
33873     int b;
33874 
33875     for (i=0; i<6; i++) {
33876         r[i+1] += r[i] >> 55;
33877         r[i] &= 0x7fffffffffffffL;
33878     }
33879     j = 384 / 8 - 1;
33880     a[j] = 0;
33881     for (i=0; i<7 && j>=0; i++) {
33882         b = 0;
33883         /* lint allow cast of mismatch sp_digit and int */
33884         a[j--] |= (byte)(r[i] << s); /*lint !e9033*/
33885         b += 8 - s;
33886         if (j < 0) {
33887             break;
33888         }
33889         while (b < 55) {
33890             a[j--] = (byte)(r[i] >> b);
33891             b += 8;
33892             if (j < 0) {
33893                 break;
33894             }
33895         }
33896         s = 8 - (b - 55);
33897         if (j >= 0) {
33898             a[j] = 0;
33899         }
33900         if (s != 0) {
33901             j++;
33902         }
33903     }
33904 }
33905 
33906 /* Multiply the point by the scalar and serialize the X ordinate.
33907  * The number is 0 padded to maximum size on output.
33908  *
33909  * priv    Scalar to multiply the point by.
33910  * pub     Point to multiply.
33911  * out     Buffer to hold X ordinate.
33912  * outLen  On entry, size of the buffer in bytes.
33913  *         On exit, length of data in buffer in bytes.
33914  * heap    Heap to use for allocation.
33915  * returns BUFFER_E if the buffer is to small for output size,
33916  * MEMORY_E when memory allocation fails and MP_OKAY on success.
33917  */
sp_ecc_secret_gen_384(const mp_int * priv,const ecc_point * pub,byte * out,word32 * outLen,void * heap)33918 int sp_ecc_secret_gen_384(const mp_int* priv, const ecc_point* pub, byte* out,
33919                           word32* outLen, void* heap)
33920 {
33921 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
33922     sp_point_384* point = NULL;
33923     sp_digit* k = NULL;
33924 #else
33925     sp_point_384 point[1];
33926     sp_digit k[7];
33927 #endif
33928     int err = MP_OKAY;
33929 
33930     if (*outLen < 48U) {
33931         err = BUFFER_E;
33932     }
33933 
33934 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
33935     if (err == MP_OKAY) {
33936         point = (sp_point_384*)XMALLOC(sizeof(sp_point_384), heap,
33937                                          DYNAMIC_TYPE_ECC);
33938         if (point == NULL)
33939             err = MEMORY_E;
33940     }
33941     if (err == MP_OKAY) {
33942         k = (sp_digit*)XMALLOC(sizeof(sp_digit) * 7, heap,
33943                                DYNAMIC_TYPE_ECC);
33944         if (k == NULL)
33945             err = MEMORY_E;
33946     }
33947 #endif
33948 
33949     if (err == MP_OKAY) {
33950         sp_384_from_mp(k, 7, priv);
33951         sp_384_point_from_ecc_point_7(point, pub);
33952             err = sp_384_ecc_mulmod_7(point, point, k, 1, 1, heap);
33953     }
33954     if (err == MP_OKAY) {
33955         sp_384_to_bin_7(point->x, out);
33956         *outLen = 48;
33957     }
33958 
33959 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
33960     if (k != NULL)
33961         XFREE(k, heap, DYNAMIC_TYPE_ECC);
33962     if (point != NULL)
33963         XFREE(point, heap, DYNAMIC_TYPE_ECC);
33964 #endif
33965 
33966     return err;
33967 }
33968 #endif /* HAVE_ECC_DHE */
33969 
33970 #if defined(HAVE_ECC_SIGN) || defined(HAVE_ECC_VERIFY)
33971 #endif
33972 #if defined(HAVE_ECC_SIGN) || defined(HAVE_ECC_VERIFY)
sp_384_rshift_7(sp_digit * r,const sp_digit * a,byte n)33973 SP_NOINLINE static void sp_384_rshift_7(sp_digit* r, const sp_digit* a,
33974         byte n)
33975 {
33976     int i;
33977 
33978 #ifdef WOLFSSL_SP_SMALL
33979     for (i=0; i<6; i++) {
33980         r[i] = ((a[i] >> n) | (a[i + 1] << (55 - n))) & 0x7fffffffffffffL;
33981     }
33982 #else
33983     for (i=0; i<0; i += 8) {
33984         r[i+0] = (a[i+0] >> n) | ((a[i+1] << (55 - n)) & 0x7fffffffffffffL);
33985         r[i+1] = (a[i+1] >> n) | ((a[i+2] << (55 - n)) & 0x7fffffffffffffL);
33986         r[i+2] = (a[i+2] >> n) | ((a[i+3] << (55 - n)) & 0x7fffffffffffffL);
33987         r[i+3] = (a[i+3] >> n) | ((a[i+4] << (55 - n)) & 0x7fffffffffffffL);
33988         r[i+4] = (a[i+4] >> n) | ((a[i+5] << (55 - n)) & 0x7fffffffffffffL);
33989         r[i+5] = (a[i+5] >> n) | ((a[i+6] << (55 - n)) & 0x7fffffffffffffL);
33990         r[i+6] = (a[i+6] >> n) | ((a[i+7] << (55 - n)) & 0x7fffffffffffffL);
33991         r[i+7] = (a[i+7] >> n) | ((a[i+8] << (55 - n)) & 0x7fffffffffffffL);
33992     }
33993     r[0] = (a[0] >> n) | ((a[1] << (55 - n)) & 0x7fffffffffffffL);
33994     r[1] = (a[1] >> n) | ((a[2] << (55 - n)) & 0x7fffffffffffffL);
33995     r[2] = (a[2] >> n) | ((a[3] << (55 - n)) & 0x7fffffffffffffL);
33996     r[3] = (a[3] >> n) | ((a[4] << (55 - n)) & 0x7fffffffffffffL);
33997     r[4] = (a[4] >> n) | ((a[5] << (55 - n)) & 0x7fffffffffffffL);
33998     r[5] = (a[5] >> n) | ((a[6] << (55 - n)) & 0x7fffffffffffffL);
33999 #endif /* WOLFSSL_SP_SMALL */
34000     r[6] = a[6] >> n;
34001 }
34002 
34003 /* Multiply a by scalar b into r. (r = a * b)
34004  *
34005  * r  A single precision integer.
34006  * a  A single precision integer.
34007  * b  A scalar.
34008  */
sp_384_mul_d_7(sp_digit * r,const sp_digit * a,sp_digit b)34009 SP_NOINLINE static void sp_384_mul_d_7(sp_digit* r, const sp_digit* a,
34010     sp_digit b)
34011 {
34012 #ifdef WOLFSSL_SP_SMALL
34013     sp_int128 tb = b;
34014     sp_int128 t = 0;
34015     int i;
34016 
34017     for (i = 0; i < 7; i++) {
34018         t += tb * a[i];
34019         r[i] = (sp_digit)(t & 0x7fffffffffffffL);
34020         t >>= 55;
34021     }
34022     r[7] = (sp_digit)t;
34023 #else
34024     sp_int128 tb = b;
34025     sp_int128 t[7];
34026 
34027     t[ 0] = tb * a[ 0];
34028     t[ 1] = tb * a[ 1];
34029     t[ 2] = tb * a[ 2];
34030     t[ 3] = tb * a[ 3];
34031     t[ 4] = tb * a[ 4];
34032     t[ 5] = tb * a[ 5];
34033     t[ 6] = tb * a[ 6];
34034     r[ 0] = (sp_digit)                 (t[ 0] & 0x7fffffffffffffL);
34035     r[ 1] = (sp_digit)((t[ 0] >> 55) + (t[ 1] & 0x7fffffffffffffL));
34036     r[ 2] = (sp_digit)((t[ 1] >> 55) + (t[ 2] & 0x7fffffffffffffL));
34037     r[ 3] = (sp_digit)((t[ 2] >> 55) + (t[ 3] & 0x7fffffffffffffL));
34038     r[ 4] = (sp_digit)((t[ 3] >> 55) + (t[ 4] & 0x7fffffffffffffL));
34039     r[ 5] = (sp_digit)((t[ 4] >> 55) + (t[ 5] & 0x7fffffffffffffL));
34040     r[ 6] = (sp_digit)((t[ 5] >> 55) + (t[ 6] & 0x7fffffffffffffL));
34041     r[ 7] = (sp_digit) (t[ 6] >> 55);
34042 #endif /* WOLFSSL_SP_SMALL */
34043 }
34044 
sp_384_lshift_14(sp_digit * r,const sp_digit * a,byte n)34045 SP_NOINLINE static void sp_384_lshift_14(sp_digit* r, const sp_digit* a,
34046         byte n)
34047 {
34048 #ifdef WOLFSSL_SP_SMALL
34049     int i;
34050 
34051     r[14] = a[13] >> (55 - n);
34052     for (i=13; i>0; i--) {
34053         r[i] = ((a[i] << n) | (a[i-1] >> (55 - n))) & 0x7fffffffffffffL;
34054     }
34055 #else
34056     sp_int_digit s;
34057     sp_int_digit t;
34058 
34059     s = (sp_int_digit)a[13];
34060     r[14] = s >> (55U - n);
34061     s = (sp_int_digit)(a[13]); t = (sp_int_digit)(a[12]);
34062     r[13] = ((s << n) | (t >> (55U - n))) & 0x7fffffffffffffUL;
34063     s = (sp_int_digit)(a[12]); t = (sp_int_digit)(a[11]);
34064     r[12] = ((s << n) | (t >> (55U - n))) & 0x7fffffffffffffUL;
34065     s = (sp_int_digit)(a[11]); t = (sp_int_digit)(a[10]);
34066     r[11] = ((s << n) | (t >> (55U - n))) & 0x7fffffffffffffUL;
34067     s = (sp_int_digit)(a[10]); t = (sp_int_digit)(a[9]);
34068     r[10] = ((s << n) | (t >> (55U - n))) & 0x7fffffffffffffUL;
34069     s = (sp_int_digit)(a[9]); t = (sp_int_digit)(a[8]);
34070     r[9] = ((s << n) | (t >> (55U - n))) & 0x7fffffffffffffUL;
34071     s = (sp_int_digit)(a[8]); t = (sp_int_digit)(a[7]);
34072     r[8] = ((s << n) | (t >> (55U - n))) & 0x7fffffffffffffUL;
34073     s = (sp_int_digit)(a[7]); t = (sp_int_digit)(a[6]);
34074     r[7] = ((s << n) | (t >> (55U - n))) & 0x7fffffffffffffUL;
34075     s = (sp_int_digit)(a[6]); t = (sp_int_digit)(a[5]);
34076     r[6] = ((s << n) | (t >> (55U - n))) & 0x7fffffffffffffUL;
34077     s = (sp_int_digit)(a[5]); t = (sp_int_digit)(a[4]);
34078     r[5] = ((s << n) | (t >> (55U - n))) & 0x7fffffffffffffUL;
34079     s = (sp_int_digit)(a[4]); t = (sp_int_digit)(a[3]);
34080     r[4] = ((s << n) | (t >> (55U - n))) & 0x7fffffffffffffUL;
34081     s = (sp_int_digit)(a[3]); t = (sp_int_digit)(a[2]);
34082     r[3] = ((s << n) | (t >> (55U - n))) & 0x7fffffffffffffUL;
34083     s = (sp_int_digit)(a[2]); t = (sp_int_digit)(a[1]);
34084     r[2] = ((s << n) | (t >> (55U - n))) & 0x7fffffffffffffUL;
34085     s = (sp_int_digit)(a[1]); t = (sp_int_digit)(a[0]);
34086     r[1] = ((s << n) | (t >> (55U - n))) & 0x7fffffffffffffUL;
34087 #endif /* WOLFSSL_SP_SMALL */
34088     r[0] = (a[0] << n) & 0x7fffffffffffffL;
34089 }
34090 
34091 /* Divide d in a and put remainder into r (m*d + r = a)
34092  * m is not calculated as it is not needed at this time.
34093  *
34094  * Simplified based on top word of divisor being (1 << 55) - 1
34095  *
34096  * a  Number to be divided.
34097  * d  Number to divide with.
34098  * m  Multiplier result.
34099  * r  Remainder from the division.
34100  * returns MEMORY_E when unable to allocate memory and MP_OKAY otherwise.
34101  */
sp_384_div_7(const sp_digit * a,const sp_digit * d,const sp_digit * m,sp_digit * r)34102 static int sp_384_div_7(const sp_digit* a, const sp_digit* d,
34103         const sp_digit* m, sp_digit* r)
34104 {
34105     int i;
34106     sp_digit r1;
34107     sp_digit mask;
34108 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
34109     sp_digit* t1 = NULL;
34110 #else
34111     sp_digit t1[4 * 7 + 3];
34112 #endif
34113     sp_digit* t2 = NULL;
34114     sp_digit* sd = NULL;
34115     int err = MP_OKAY;
34116 
34117     (void)m;
34118 
34119 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
34120     t1 = (sp_digit*)XMALLOC(sizeof(sp_digit) * (4 * 7 + 3), NULL,
34121                                                        DYNAMIC_TYPE_TMP_BUFFER);
34122     if (t1 == NULL)
34123         err = MEMORY_E;
34124 #endif
34125 
34126     (void)m;
34127 
34128     if (err == MP_OKAY) {
34129         t2 = t1 + 14 + 1;
34130         sd = t2 + 7 + 1;
34131 
34132         sp_384_mul_d_7(sd, d, (sp_digit)1 << 1);
34133         sp_384_lshift_14(t1, a, 1);
34134         t1[7 + 7] += t1[7 + 7 - 1] >> 55;
34135         t1[7 + 7 - 1] &= 0x7fffffffffffffL;
34136         for (i=6; i>=0; i--) {
34137             r1 = t1[7 + i];
34138             sp_384_mul_d_7(t2, sd, r1);
34139             (void)sp_384_sub_7(&t1[i], &t1[i], t2);
34140             t1[7 + i] -= t2[7];
34141             sp_384_norm_7(&t1[i + 1]);
34142 
34143             mask = (sp_digit)0 - ((t1[7 + i] > 0) ?
34144                     (sp_digit)1 : (sp_digit)0);
34145             sp_384_cond_sub_7(t1 + i, t1 + i, sd, mask);
34146             sp_384_norm_7(&t1[i + 1]);
34147         }
34148         sp_384_norm_7(t1);
34149         sp_384_rshift_7(r, t1, 1);
34150     }
34151 
34152 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
34153     if (t1 != NULL)
34154         XFREE(t1, NULL, DYNAMIC_TYPE_TMP_BUFFER);
34155 #endif
34156 
34157     return err;
34158 }
34159 
34160 /* Reduce a modulo m into r. (r = a mod m)
34161  *
34162  * r  A single precision number that is the reduced result.
34163  * a  A single precision number that is to be reduced.
34164  * m  A single precision number that is the modulus to reduce with.
34165  * returns MEMORY_E when unable to allocate memory and MP_OKAY otherwise.
34166  */
sp_384_mod_7(sp_digit * r,const sp_digit * a,const sp_digit * m)34167 static int sp_384_mod_7(sp_digit* r, const sp_digit* a, const sp_digit* m)
34168 {
34169     return sp_384_div_7(a, m, NULL, r);
34170 }
34171 
34172 #endif
34173 #if defined(HAVE_ECC_SIGN) || defined(HAVE_ECC_VERIFY)
34174 /* Multiply two number mod the order of P384 curve. (r = a * b mod order)
34175  *
34176  * r  Result of the multiplication.
34177  * a  First operand of the multiplication.
34178  * b  Second operand of the multiplication.
34179  */
sp_384_mont_mul_order_7(sp_digit * r,const sp_digit * a,const sp_digit * b)34180 static void sp_384_mont_mul_order_7(sp_digit* r, const sp_digit* a, const sp_digit* b)
34181 {
34182     sp_384_mul_7(r, a, b);
34183     sp_384_mont_reduce_order_7(r, p384_order, p384_mp_order);
34184 }
34185 
34186 #if defined(HAVE_ECC_SIGN) || (defined(HAVE_ECC_VERIFY) && defined(WOLFSSL_SP_SMALL))
34187 #ifdef WOLFSSL_SP_SMALL
34188 /* Order-2 for the P384 curve. */
34189 static const uint64_t p384_order_minus_2[6] = {
34190     0xecec196accc52971U,0x581a0db248b0a77aU,0xc7634d81f4372ddfU,
34191     0xffffffffffffffffU,0xffffffffffffffffU,0xffffffffffffffffU
34192 };
34193 #else
34194 /* The low half of the order-2 of the P384 curve. */
34195 static const uint64_t p384_order_low[3] = {
34196     0xecec196accc52971U,0x581a0db248b0a77aU,0xc7634d81f4372ddfU
34197 };
34198 #endif /* WOLFSSL_SP_SMALL */
34199 
34200 /* Square number mod the order of P384 curve. (r = a * a mod order)
34201  *
34202  * r  Result of the squaring.
34203  * a  Number to square.
34204  */
sp_384_mont_sqr_order_7(sp_digit * r,const sp_digit * a)34205 static void sp_384_mont_sqr_order_7(sp_digit* r, const sp_digit* a)
34206 {
34207     sp_384_sqr_7(r, a);
34208     sp_384_mont_reduce_order_7(r, p384_order, p384_mp_order);
34209 }
34210 
34211 #ifndef WOLFSSL_SP_SMALL
34212 /* Square number mod the order of P384 curve a number of times.
34213  * (r = a ^ n mod order)
34214  *
34215  * r  Result of the squaring.
34216  * a  Number to square.
34217  */
sp_384_mont_sqr_n_order_7(sp_digit * r,const sp_digit * a,int n)34218 static void sp_384_mont_sqr_n_order_7(sp_digit* r, const sp_digit* a, int n)
34219 {
34220     int i;
34221 
34222     sp_384_mont_sqr_order_7(r, a);
34223     for (i=1; i<n; i++) {
34224         sp_384_mont_sqr_order_7(r, r);
34225     }
34226 }
34227 #endif /* !WOLFSSL_SP_SMALL */
34228 
34229 /* Invert the number, in Montgomery form, modulo the order of the P384 curve.
34230  * (r = 1 / a mod order)
34231  *
34232  * r   Inverse result.
34233  * a   Number to invert.
34234  * td  Temporary data.
34235  */
34236 
34237 #ifdef WOLFSSL_SP_NONBLOCK
34238 typedef struct sp_384_mont_inv_order_7_ctx {
34239     int state;
34240     int i;
34241 } sp_384_mont_inv_order_7_ctx;
sp_384_mont_inv_order_7_nb(sp_ecc_ctx_t * sp_ctx,sp_digit * r,const sp_digit * a,sp_digit * t)34242 static int sp_384_mont_inv_order_7_nb(sp_ecc_ctx_t* sp_ctx, sp_digit* r, const sp_digit* a,
34243         sp_digit* t)
34244 {
34245     int err = FP_WOULDBLOCK;
34246     sp_384_mont_inv_order_7_ctx* ctx = (sp_384_mont_inv_order_7_ctx*)sp_ctx;
34247 
34248     typedef char ctx_size_test[sizeof(sp_384_mont_inv_order_7_ctx) >= sizeof(*sp_ctx) ? -1 : 1];
34249     (void)sizeof(ctx_size_test);
34250 
34251     switch (ctx->state) {
34252     case 0:
34253         XMEMCPY(t, a, sizeof(sp_digit) * 7);
34254         ctx->i = 382;
34255         ctx->state = 1;
34256         break;
34257     case 1:
34258         sp_384_mont_sqr_order_7(t, t);
34259         ctx->state = 2;
34260         break;
34261     case 2:
34262         if ((p384_order_minus_2[ctx->i / 64] & ((sp_int_digit)1 << (ctx->i % 64))) != 0) {
34263             sp_384_mont_mul_order_7(t, t, a);
34264         }
34265         ctx->i--;
34266         ctx->state = (ctx->i == 0) ? 3 : 1;
34267         break;
34268     case 3:
34269         XMEMCPY(r, t, sizeof(sp_digit) * 7U);
34270         err = MP_OKAY;
34271         break;
34272     }
34273     return err;
34274 }
34275 #endif /* WOLFSSL_SP_NONBLOCK */
34276 
sp_384_mont_inv_order_7(sp_digit * r,const sp_digit * a,sp_digit * td)34277 static void sp_384_mont_inv_order_7(sp_digit* r, const sp_digit* a,
34278         sp_digit* td)
34279 {
34280 #ifdef WOLFSSL_SP_SMALL
34281     sp_digit* t = td;
34282     int i;
34283 
34284     XMEMCPY(t, a, sizeof(sp_digit) * 7);
34285     for (i=382; i>=0; i--) {
34286         sp_384_mont_sqr_order_7(t, t);
34287         if ((p384_order_minus_2[i / 64] & ((sp_int_digit)1 << (i % 64))) != 0) {
34288             sp_384_mont_mul_order_7(t, t, a);
34289         }
34290     }
34291     XMEMCPY(r, t, sizeof(sp_digit) * 7U);
34292 #else
34293     sp_digit* t = td;
34294     sp_digit* t2 = td + 2 * 7;
34295     sp_digit* t3 = td + 4 * 7;
34296     int i;
34297 
34298     /* t = a^2 */
34299     sp_384_mont_sqr_order_7(t, a);
34300     /* t = a^3 = t * a */
34301     sp_384_mont_mul_order_7(t, t, a);
34302     /* t2= a^c = t ^ 2 ^ 2 */
34303     sp_384_mont_sqr_n_order_7(t2, t, 2);
34304     /* t = a^f = t2 * t */
34305     sp_384_mont_mul_order_7(t, t2, t);
34306     /* t2= a^f0 = t ^ 2 ^ 4 */
34307     sp_384_mont_sqr_n_order_7(t2, t, 4);
34308     /* t = a^ff = t2 * t */
34309     sp_384_mont_mul_order_7(t, t2, t);
34310     /* t2= a^ff00 = t ^ 2 ^ 8 */
34311     sp_384_mont_sqr_n_order_7(t2, t, 8);
34312     /* t3= a^ffff = t2 * t */
34313     sp_384_mont_mul_order_7(t3, t2, t);
34314     /* t2= a^ffff0000 = t3 ^ 2 ^ 16 */
34315     sp_384_mont_sqr_n_order_7(t2, t3, 16);
34316     /* t = a^ffffffff = t2 * t3 */
34317     sp_384_mont_mul_order_7(t, t2, t3);
34318     /* t2= a^ffffffff0000 = t ^ 2 ^ 16  */
34319     sp_384_mont_sqr_n_order_7(t2, t, 16);
34320     /* t = a^ffffffffffff = t2 * t3 */
34321     sp_384_mont_mul_order_7(t, t2, t3);
34322     /* t2= a^ffffffffffff000000000000 = t ^ 2 ^ 48  */
34323     sp_384_mont_sqr_n_order_7(t2, t, 48);
34324     /* t= a^fffffffffffffffffffffffff = t2 * t */
34325     sp_384_mont_mul_order_7(t, t2, t);
34326     /* t2= a^ffffffffffffffffffffffff000000000000000000000000 */
34327     sp_384_mont_sqr_n_order_7(t2, t, 96);
34328     /* t2= a^ffffffffffffffffffffffffffffffffffffffffffffffff = t2 * t */
34329     sp_384_mont_mul_order_7(t2, t2, t);
34330     for (i=191; i>=1; i--) {
34331         sp_384_mont_sqr_order_7(t2, t2);
34332         if ((p384_order_low[i / 64] & ((sp_int_digit)1 << (i % 64))) != 0) {
34333             sp_384_mont_mul_order_7(t2, t2, a);
34334         }
34335     }
34336     sp_384_mont_sqr_order_7(t2, t2);
34337     sp_384_mont_mul_order_7(r, t2, a);
34338 #endif /* WOLFSSL_SP_SMALL */
34339 }
34340 
34341 #endif /* HAVE_ECC_SIGN || (HAVE_ECC_VERIFY && WOLFSSL_SP_SMALL) */
34342 #endif /* HAVE_ECC_SIGN | HAVE_ECC_VERIFY */
34343 #ifdef HAVE_ECC_SIGN
34344 #ifndef SP_ECC_MAX_SIG_GEN
34345 #define SP_ECC_MAX_SIG_GEN  64
34346 #endif
34347 
34348 /* Calculate second signature value S from R, k and private value.
34349  *
34350  * s = (r * x + e) / k
34351  *
34352  * s    Signature value.
34353  * r    First signature value.
34354  * k    Ephemeral private key.
34355  * x    Private key as a number.
34356  * e    Hash of message as a number.
34357  * tmp  Temporary storage for intermediate numbers.
34358  * returns MEMORY_E when memory allocation fails and MP_OKAY on success.
34359  */
sp_384_calc_s_7(sp_digit * s,const sp_digit * r,sp_digit * k,sp_digit * x,const sp_digit * e,sp_digit * tmp)34360 static int sp_384_calc_s_7(sp_digit* s, const sp_digit* r, sp_digit* k,
34361     sp_digit* x, const sp_digit* e, sp_digit* tmp)
34362 {
34363     int err;
34364     sp_digit carry;
34365     sp_int64 c;
34366     sp_digit* kInv = k;
34367 
34368     /* Conv k to Montgomery form (mod order) */
34369         sp_384_mul_7(k, k, p384_norm_order);
34370     err = sp_384_mod_7(k, k, p384_order);
34371     if (err == MP_OKAY) {
34372         sp_384_norm_7(k);
34373 
34374         /* kInv = 1/k mod order */
34375             sp_384_mont_inv_order_7(kInv, k, tmp);
34376         sp_384_norm_7(kInv);
34377 
34378         /* s = r * x + e */
34379             sp_384_mul_7(x, x, r);
34380         err = sp_384_mod_7(x, x, p384_order);
34381     }
34382     if (err == MP_OKAY) {
34383         sp_384_norm_7(x);
34384         carry = sp_384_add_7(s, e, x);
34385         sp_384_cond_sub_7(s, s, p384_order, 0 - carry);
34386         sp_384_norm_7(s);
34387         c = sp_384_cmp_7(s, p384_order);
34388         sp_384_cond_sub_7(s, s, p384_order,
34389             (sp_digit)0 - (sp_digit)(c >= 0));
34390         sp_384_norm_7(s);
34391 
34392         /* s = s * k^-1 mod order */
34393             sp_384_mont_mul_order_7(s, s, kInv);
34394         sp_384_norm_7(s);
34395     }
34396 
34397     return err;
34398 }
34399 
34400 /* Sign the hash using the private key.
34401  *   e = [hash, 384 bits] from binary
34402  *   r = (k.G)->x mod order
34403  *   s = (r * x + e) / k mod order
34404  * The hash is truncated to the first 384 bits.
34405  *
34406  * hash     Hash to sign.
34407  * hashLen  Length of the hash data.
34408  * rng      Random number generator.
34409  * priv     Private part of key - scalar.
34410  * rm       First part of result as an mp_int.
34411  * sm       Sirst part of result as an mp_int.
34412  * heap     Heap to use for allocation.
34413  * returns RNG failures, MEMORY_E when memory allocation fails and
34414  * MP_OKAY on success.
34415  */
34416 #ifdef WOLFSSL_SP_NONBLOCK
34417 typedef struct sp_ecc_sign_384_ctx {
34418     int state;
34419     union {
34420         sp_384_ecc_mulmod_7_ctx mulmod_ctx;
34421         sp_384_mont_inv_order_7_ctx mont_inv_order_ctx;
34422     };
34423     sp_digit e[2*7];
34424     sp_digit x[2*7];
34425     sp_digit k[2*7];
34426     sp_digit r[2*7];
34427     sp_digit tmp[3 * 2*7];
34428     sp_point_384 point;
34429     sp_digit* s;
34430     sp_digit* kInv;
34431     int i;
34432 } sp_ecc_sign_384_ctx;
34433 
sp_ecc_sign_384_nb(sp_ecc_ctx_t * sp_ctx,const byte * hash,word32 hashLen,WC_RNG * rng,mp_int * priv,mp_int * rm,mp_int * sm,mp_int * km,void * heap)34434 int sp_ecc_sign_384_nb(sp_ecc_ctx_t* sp_ctx, const byte* hash, word32 hashLen, WC_RNG* rng,
34435     mp_int* priv, mp_int* rm, mp_int* sm, mp_int* km, void* heap)
34436 {
34437     int err = FP_WOULDBLOCK;
34438     sp_ecc_sign_384_ctx* ctx = (sp_ecc_sign_384_ctx*)sp_ctx->data;
34439 
34440     typedef char ctx_size_test[sizeof(sp_ecc_sign_384_ctx) >= sizeof(*sp_ctx) ? -1 : 1];
34441     (void)sizeof(ctx_size_test);
34442 
34443     (void)heap;
34444 
34445     switch (ctx->state) {
34446     case 0: /* INIT */
34447         ctx->s = ctx->e;
34448         ctx->kInv = ctx->k;
34449         if (hashLen > 48U) {
34450             hashLen = 48U;
34451         }
34452 
34453         ctx->i = SP_ECC_MAX_SIG_GEN;
34454         ctx->state = 1;
34455         break;
34456     case 1: /* GEN */
34457         /* New random point. */
34458         if (km == NULL || mp_iszero(km)) {
34459             err = sp_384_ecc_gen_k_7(rng, ctx->k);
34460         }
34461         else {
34462             sp_384_from_mp(ctx->k, 7, km);
34463             mp_zero(km);
34464         }
34465         XMEMSET(&ctx->mulmod_ctx, 0, sizeof(ctx->mulmod_ctx));
34466         ctx->state = 2;
34467         break;
34468     case 2: /* MULMOD */
34469         err = sp_384_ecc_mulmod_7_nb((sp_ecc_ctx_t*)&ctx->mulmod_ctx,
34470             &ctx->point, &p384_base, ctx->k, 1, 1, heap);
34471         if (err == MP_OKAY) {
34472             ctx->state = 3;
34473         }
34474         break;
34475     case 3: /* MODORDER */
34476     {
34477         sp_int64 c;
34478         /* r = point->x mod order */
34479         XMEMCPY(ctx->r, ctx->point.x, sizeof(sp_digit) * 7U);
34480         sp_384_norm_7(ctx->r);
34481         c = sp_384_cmp_7(ctx->r, p384_order);
34482         sp_384_cond_sub_7(ctx->r, ctx->r, p384_order,
34483             (sp_digit)0 - (sp_digit)(c >= 0));
34484         sp_384_norm_7(ctx->r);
34485 
34486         sp_384_from_mp(ctx->x, 7, priv);
34487         sp_384_from_bin(ctx->e, 7, hash, (int)hashLen);
34488         ctx->state = 4;
34489         break;
34490     }
34491     case 4: /* KMODORDER */
34492         /* Conv k to Montgomery form (mod order) */
34493         sp_384_mul_7(ctx->k, ctx->k, p384_norm_order);
34494         err = sp_384_mod_7(ctx->k, ctx->k, p384_order);
34495         if (err == MP_OKAY) {
34496             sp_384_norm_7(ctx->k);
34497             XMEMSET(&ctx->mont_inv_order_ctx, 0, sizeof(ctx->mont_inv_order_ctx));
34498             ctx->state = 5;
34499         }
34500         break;
34501     case 5: /* KINV */
34502         /* kInv = 1/k mod order */
34503         err = sp_384_mont_inv_order_7_nb((sp_ecc_ctx_t*)&ctx->mont_inv_order_ctx, ctx->kInv, ctx->k, ctx->tmp);
34504         if (err == MP_OKAY) {
34505             XMEMSET(&ctx->mont_inv_order_ctx, 0, sizeof(ctx->mont_inv_order_ctx));
34506             ctx->state = 6;
34507         }
34508         break;
34509     case 6: /* KINVNORM */
34510         sp_384_norm_7(ctx->kInv);
34511         ctx->state = 7;
34512         break;
34513     case 7: /* R */
34514         /* s = r * x + e */
34515         sp_384_mul_7(ctx->x, ctx->x, ctx->r);
34516         ctx->state = 8;
34517         break;
34518     case 8: /* S1 */
34519         err = sp_384_mod_7(ctx->x, ctx->x, p384_order);
34520         if (err == MP_OKAY)
34521             ctx->state = 9;
34522         break;
34523     case 9: /* S2 */
34524     {
34525         sp_digit carry;
34526         sp_int64 c;
34527         sp_384_norm_7(ctx->x);
34528         carry = sp_384_add_7(ctx->s, ctx->e, ctx->x);
34529         sp_384_cond_sub_7(ctx->s, ctx->s,
34530             p384_order, 0 - carry);
34531         sp_384_norm_7(ctx->s);
34532         c = sp_384_cmp_7(ctx->s, p384_order);
34533         sp_384_cond_sub_7(ctx->s, ctx->s, p384_order,
34534             (sp_digit)0 - (sp_digit)(c >= 0));
34535         sp_384_norm_7(ctx->s);
34536 
34537         /* s = s * k^-1 mod order */
34538         sp_384_mont_mul_order_7(ctx->s, ctx->s, ctx->kInv);
34539         sp_384_norm_7(ctx->s);
34540 
34541         /* Check that signature is usable. */
34542         if (sp_384_iszero_7(ctx->s) == 0) {
34543             ctx->state = 10;
34544             break;
34545         }
34546     #ifdef WOLFSSL_ECDSA_SET_K_ONE_LOOP
34547         ctx->i = 1;
34548     #endif
34549 
34550         /* not usable gen, try again */
34551         ctx->i--;
34552         if (ctx->i == 0) {
34553             err = RNG_FAILURE_E;
34554         }
34555         ctx->state = 1;
34556         break;
34557     }
34558     case 10: /* RES */
34559         err = sp_384_to_mp(ctx->r, rm);
34560         if (err == MP_OKAY) {
34561             err = sp_384_to_mp(ctx->s, sm);
34562         }
34563         break;
34564     }
34565 
34566     if (err == MP_OKAY && ctx->state != 10) {
34567         err = FP_WOULDBLOCK;
34568     }
34569     if (err != FP_WOULDBLOCK) {
34570         XMEMSET(ctx->e, 0, sizeof(sp_digit) * 2U * 7U);
34571         XMEMSET(ctx->x, 0, sizeof(sp_digit) * 2U * 7U);
34572         XMEMSET(ctx->k, 0, sizeof(sp_digit) * 2U * 7U);
34573         XMEMSET(ctx->r, 0, sizeof(sp_digit) * 2U * 7U);
34574         XMEMSET(ctx->tmp, 0, sizeof(sp_digit) * 3U * 2U * 7U);
34575     }
34576 
34577     return err;
34578 }
34579 #endif /* WOLFSSL_SP_NONBLOCK */
34580 
sp_ecc_sign_384(const byte * hash,word32 hashLen,WC_RNG * rng,const mp_int * priv,mp_int * rm,mp_int * sm,mp_int * km,void * heap)34581 int sp_ecc_sign_384(const byte* hash, word32 hashLen, WC_RNG* rng,
34582     const mp_int* priv, mp_int* rm, mp_int* sm, mp_int* km, void* heap)
34583 {
34584 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
34585     sp_digit* e = NULL;
34586     sp_point_384* point = NULL;
34587 #else
34588     sp_digit e[7 * 2 * 7];
34589     sp_point_384 point[1];
34590 #endif
34591     sp_digit* x = NULL;
34592     sp_digit* k = NULL;
34593     sp_digit* r = NULL;
34594     sp_digit* tmp = NULL;
34595     sp_digit* s = NULL;
34596     sp_int64 c;
34597     int err = MP_OKAY;
34598     int i;
34599 
34600     (void)heap;
34601 
34602 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
34603     if (err == MP_OKAY) {
34604         point = (sp_point_384*)XMALLOC(sizeof(sp_point_384), heap,
34605                                              DYNAMIC_TYPE_ECC);
34606         if (point == NULL)
34607             err = MEMORY_E;
34608     }
34609     if (err == MP_OKAY) {
34610         e = (sp_digit*)XMALLOC(sizeof(sp_digit) * 7 * 2 * 7, heap,
34611                                DYNAMIC_TYPE_ECC);
34612         if (e == NULL)
34613             err = MEMORY_E;
34614     }
34615 #endif
34616 
34617     if (err == MP_OKAY) {
34618         x = e + 2 * 7;
34619         k = e + 4 * 7;
34620         r = e + 6 * 7;
34621         tmp = e + 8 * 7;
34622         s = e;
34623 
34624         if (hashLen > 48U) {
34625             hashLen = 48U;
34626         }
34627     }
34628 
34629     for (i = SP_ECC_MAX_SIG_GEN; err == MP_OKAY && i > 0; i--) {
34630         /* New random point. */
34631         if (km == NULL || mp_iszero(km)) {
34632             err = sp_384_ecc_gen_k_7(rng, k);
34633         }
34634         else {
34635             sp_384_from_mp(k, 7, km);
34636             mp_zero(km);
34637         }
34638         if (err == MP_OKAY) {
34639                 err = sp_384_ecc_mulmod_base_7(point, k, 1, 1, heap);
34640         }
34641 
34642         if (err == MP_OKAY) {
34643             /* r = point->x mod order */
34644             XMEMCPY(r, point->x, sizeof(sp_digit) * 7U);
34645             sp_384_norm_7(r);
34646             c = sp_384_cmp_7(r, p384_order);
34647             sp_384_cond_sub_7(r, r, p384_order,
34648                 (sp_digit)0 - (sp_digit)(c >= 0));
34649             sp_384_norm_7(r);
34650 
34651             sp_384_from_mp(x, 7, priv);
34652             sp_384_from_bin(e, 7, hash, (int)hashLen);
34653 
34654             err = sp_384_calc_s_7(s, r, k, x, e, tmp);
34655         }
34656 
34657         /* Check that signature is usable. */
34658         if ((err == MP_OKAY) && (sp_384_iszero_7(s) == 0)) {
34659             break;
34660         }
34661 #ifdef WOLFSSL_ECDSA_SET_K_ONE_LOOP
34662         i = 1;
34663 #endif
34664     }
34665 
34666     if (i == 0) {
34667         err = RNG_FAILURE_E;
34668     }
34669 
34670     if (err == MP_OKAY) {
34671         err = sp_384_to_mp(r, rm);
34672     }
34673     if (err == MP_OKAY) {
34674         err = sp_384_to_mp(s, sm);
34675     }
34676 
34677 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
34678     if (e != NULL)
34679 #endif
34680     {
34681         ForceZero(e, sizeof(sp_digit) * 7 * 2 * 7);
34682     #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
34683         XFREE(e, heap, DYNAMIC_TYPE_ECC);
34684     #endif
34685     }
34686 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
34687     if (point != NULL)
34688 #endif
34689     {
34690         ForceZero(point, sizeof(sp_point_384));
34691     #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
34692         XFREE(point, heap, DYNAMIC_TYPE_ECC);
34693     #endif
34694     }
34695 
34696     return err;
34697 }
34698 #endif /* HAVE_ECC_SIGN */
34699 
34700 #ifndef WOLFSSL_SP_SMALL
34701 static const char sp_384_tab64_7[64] = {
34702     64,  1, 59,  2, 60, 48, 54,  3,
34703     61, 40, 49, 28, 55, 34, 43,  4,
34704     62, 52, 38, 41, 50, 19, 29, 21,
34705     56, 31, 35, 12, 44, 15, 23,  5,
34706     63, 58, 47, 53, 39, 27, 33, 42,
34707     51, 37, 18, 20, 30, 11, 14, 22,
34708     57, 46, 26, 32, 36, 17, 10, 13,
34709     45, 25, 16,  9, 24,  8,  7,  6};
34710 
sp_384_num_bits_55_7(sp_digit v)34711 static int sp_384_num_bits_55_7(sp_digit v)
34712 {
34713     v |= v >> 1;
34714     v |= v >> 2;
34715     v |= v >> 4;
34716     v |= v >> 8;
34717     v |= v >> 16;
34718     v |= v >> 32;
34719     return sp_384_tab64_7[((uint64_t)((v - (v >> 1))*0x07EDD5E59A4E28C2)) >> 58];
34720 }
34721 
sp_384_num_bits_7(const sp_digit * a)34722 static int sp_384_num_bits_7(const sp_digit* a)
34723 {
34724     int i;
34725     int r = 0;
34726 
34727     for (i = 6; i >= 0; i--) {
34728         if (a[i] != 0) {
34729             r = sp_384_num_bits_55_7(a[i]);
34730             r += i * 55;
34731             break;
34732         }
34733     }
34734 
34735     return r;
34736 }
34737 
34738 /* Non-constant time modular inversion.
34739  *
34740  * @param  [out]  r   Resulting number.
34741  * @param  [in]   a   Number to invert.
34742  * @param  [in]   m   Modulus.
34743  * @return  MP_OKAY on success.
34744  * @return  MEMEORY_E when dynamic memory allocation fails.
34745  */
sp_384_mod_inv_7(sp_digit * r,const sp_digit * a,const sp_digit * m)34746 static int sp_384_mod_inv_7(sp_digit* r, const sp_digit* a, const sp_digit* m)
34747 {
34748     int err = MP_OKAY;
34749 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
34750     sp_digit* u = NULL;
34751 #else
34752     sp_digit u[7 * 4];
34753 #endif
34754     sp_digit* v = NULL;
34755     sp_digit* b = NULL;
34756     sp_digit* d = NULL;
34757     int ut;
34758     int vt;
34759 
34760 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
34761     u = (sp_digit*)XMALLOC(sizeof(sp_digit) * 7 * 4, NULL,
34762                                                               DYNAMIC_TYPE_ECC);
34763     if (u == NULL)
34764         err = MEMORY_E;
34765 #endif
34766 
34767     if (err == MP_OKAY) {
34768         v = u + 7;
34769         b = u + 2 * 7;
34770         d = u + 3 * 7;
34771 
34772         XMEMCPY(u, m, sizeof(sp_digit) * 7);
34773         XMEMCPY(v, a, sizeof(sp_digit) * 7);
34774 
34775         ut = sp_384_num_bits_7(u);
34776         vt = sp_384_num_bits_7(v);
34777 
34778         XMEMSET(b, 0, sizeof(sp_digit) * 7);
34779         if ((v[0] & 1) == 0) {
34780             sp_384_rshift1_7(v, v);
34781             XMEMCPY(d, m, sizeof(sp_digit) * 7);
34782             d[0]++;
34783             sp_384_rshift1_7(d, d);
34784             vt--;
34785 
34786             while ((v[0] & 1) == 0) {
34787                 sp_384_rshift1_7(v, v);
34788                 if (d[0] & 1)
34789                     sp_384_add_7(d, d, m);
34790                 sp_384_rshift1_7(d, d);
34791                 vt--;
34792             }
34793         }
34794         else {
34795             XMEMSET(d+1, 0, sizeof(sp_digit) * (7 - 1));
34796             d[0] = 1;
34797         }
34798 
34799         while (ut > 1 && vt > 1) {
34800             if (ut > vt || (ut == vt &&
34801                                        sp_384_cmp_7(u, v) >= 0)) {
34802                 sp_384_sub_7(u, u, v);
34803                 sp_384_norm_7(u);
34804 
34805                 sp_384_sub_7(b, b, d);
34806                 sp_384_norm_7(b);
34807                 if (b[6] < 0)
34808                     sp_384_add_7(b, b, m);
34809                 sp_384_norm_7(b);
34810                 ut = sp_384_num_bits_7(u);
34811 
34812                 do {
34813                     sp_384_rshift1_7(u, u);
34814                     if (b[0] & 1)
34815                         sp_384_add_7(b, b, m);
34816                     sp_384_rshift1_7(b, b);
34817                     ut--;
34818                 }
34819                 while (ut > 0 && (u[0] & 1) == 0);
34820             }
34821             else {
34822                 sp_384_sub_7(v, v, u);
34823                 sp_384_norm_7(v);
34824 
34825                 sp_384_sub_7(d, d, b);
34826                 sp_384_norm_7(d);
34827                 if (d[6] < 0)
34828                     sp_384_add_7(d, d, m);
34829                 sp_384_norm_7(d);
34830                 vt = sp_384_num_bits_7(v);
34831 
34832                 do {
34833                     sp_384_rshift1_7(v, v);
34834                     if (d[0] & 1)
34835                         sp_384_add_7(d, d, m);
34836                     sp_384_rshift1_7(d, d);
34837                     vt--;
34838                 }
34839                 while (vt > 0 && (v[0] & 1) == 0);
34840             }
34841         }
34842 
34843         if (ut == 1)
34844             XMEMCPY(r, b, sizeof(sp_digit) * 7);
34845         else
34846             XMEMCPY(r, d, sizeof(sp_digit) * 7);
34847     }
34848 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
34849     if (u != NULL)
34850         XFREE(u, NULL, DYNAMIC_TYPE_ECC);
34851 #endif
34852 
34853     return err;
34854 }
34855 
34856 #endif /* WOLFSSL_SP_SMALL */
34857 
34858 /* Add point p1 into point p2. Handles p1 == p2 and result at infinity.
34859  *
34860  * p1   First point to add and holds result.
34861  * p2   Second point to add.
34862  * tmp  Temporary storage for intermediate numbers.
34863  */
sp_384_add_points_7(sp_point_384 * p1,const sp_point_384 * p2,sp_digit * tmp)34864 static void sp_384_add_points_7(sp_point_384* p1, const sp_point_384* p2,
34865     sp_digit* tmp)
34866 {
34867 
34868         sp_384_proj_point_add_7(p1, p1, p2, tmp);
34869     if (sp_384_iszero_7(p1->z)) {
34870         if (sp_384_iszero_7(p1->x) && sp_384_iszero_7(p1->y)) {
34871                 sp_384_proj_point_dbl_7(p1, p2, tmp);
34872         }
34873         else {
34874             /* Y ordinate is not used from here - don't set. */
34875             p1->x[0] = 0;
34876             p1->x[1] = 0;
34877             p1->x[2] = 0;
34878             p1->x[3] = 0;
34879             p1->x[4] = 0;
34880             p1->x[5] = 0;
34881             p1->x[6] = 0;
34882             XMEMCPY(p1->z, p384_norm_mod, sizeof(p384_norm_mod));
34883         }
34884     }
34885 }
34886 
34887 /* Calculate the verification point: [e/s]G + [r/s]Q
34888  *
34889  * p1    Calculated point.
34890  * p2    Public point and temporary.
34891  * s     Second part of signature as a number.
34892  * u1    Temporary number.
34893  * u2    Temproray number.
34894  * heap  Heap to use for allocation.
34895  * returns MEMORY_E when memory allocation fails and MP_OKAY on success.
34896  */
sp_384_calc_vfy_point_7(sp_point_384 * p1,sp_point_384 * p2,sp_digit * s,sp_digit * u1,sp_digit * u2,sp_digit * tmp,void * heap)34897 static int sp_384_calc_vfy_point_7(sp_point_384* p1, sp_point_384* p2,
34898     sp_digit* s, sp_digit* u1, sp_digit* u2, sp_digit* tmp, void* heap)
34899 {
34900     int err;
34901 
34902 #ifndef WOLFSSL_SP_SMALL
34903     err = sp_384_mod_inv_7(s, s, p384_order);
34904     if (err == MP_OKAY)
34905 #endif /* !WOLFSSL_SP_SMALL */
34906     {
34907         sp_384_mul_7(s, s, p384_norm_order);
34908         err = sp_384_mod_7(s, s, p384_order);
34909     }
34910     if (err == MP_OKAY) {
34911         sp_384_norm_7(s);
34912 #ifdef WOLFSSL_SP_SMALL
34913         {
34914             sp_384_mont_inv_order_7(s, s, tmp);
34915             sp_384_mont_mul_order_7(u1, u1, s);
34916             sp_384_mont_mul_order_7(u2, u2, s);
34917         }
34918 #else
34919         {
34920             sp_384_mont_mul_order_7(u1, u1, s);
34921             sp_384_mont_mul_order_7(u2, u2, s);
34922         }
34923 #endif /* WOLFSSL_SP_SMALL */
34924         {
34925             err = sp_384_ecc_mulmod_base_7(p1, u1, 0, 0, heap);
34926         }
34927     }
34928     if ((err == MP_OKAY) && sp_384_iszero_7(p1->z)) {
34929         p1->infinity = 1;
34930     }
34931     if (err == MP_OKAY) {
34932             err = sp_384_ecc_mulmod_7(p2, p2, u2, 0, 0, heap);
34933     }
34934     if ((err == MP_OKAY) && sp_384_iszero_7(p2->z)) {
34935         p2->infinity = 1;
34936     }
34937 
34938     if (err == MP_OKAY) {
34939         sp_384_add_points_7(p1, p2, tmp);
34940     }
34941 
34942     return err;
34943 }
34944 
34945 #ifdef HAVE_ECC_VERIFY
34946 /* Verify the signature values with the hash and public key.
34947  *   e = Truncate(hash, 384)
34948  *   u1 = e/s mod order
34949  *   u2 = r/s mod order
34950  *   r == (u1.G + u2.Q)->x mod order
34951  * Optimization: Leave point in projective form.
34952  *   (x, y, 1) == (x' / z'*z', y' / z'*z'*z', z' / z')
34953  *   (r + n*order).z'.z' mod prime == (u1.G + u2.Q)->x'
34954  * The hash is truncated to the first 384 bits.
34955  *
34956  * hash     Hash to sign.
34957  * hashLen  Length of the hash data.
34958  * rng      Random number generator.
34959  * priv     Private part of key - scalar.
34960  * rm       First part of result as an mp_int.
34961  * sm       Sirst part of result as an mp_int.
34962  * heap     Heap to use for allocation.
34963  * returns MEMORY_E when memory allocation fails and MP_OKAY on success.
34964  */
34965 #ifdef WOLFSSL_SP_NONBLOCK
34966 typedef struct sp_ecc_verify_384_ctx {
34967     int state;
34968     union {
34969         sp_384_ecc_mulmod_7_ctx mulmod_ctx;
34970         sp_384_mont_inv_order_7_ctx mont_inv_order_ctx;
34971         sp_384_proj_point_dbl_7_ctx dbl_ctx;
34972         sp_384_proj_point_add_7_ctx add_ctx;
34973     };
34974     sp_digit u1[2*7];
34975     sp_digit u2[2*7];
34976     sp_digit s[2*7];
34977     sp_digit tmp[2*7 * 5];
34978     sp_point_384 p1;
34979     sp_point_384 p2;
34980 } sp_ecc_verify_384_ctx;
34981 
sp_ecc_verify_384_nb(sp_ecc_ctx_t * sp_ctx,const byte * hash,word32 hashLen,const mp_int * pX,const mp_int * pY,const mp_int * pZ,const mp_int * rm,const mp_int * sm,int * res,void * heap)34982 int sp_ecc_verify_384_nb(sp_ecc_ctx_t* sp_ctx, const byte* hash,
34983     word32 hashLen, const mp_int* pX, const mp_int* pY, const mp_int* pZ,
34984     const mp_int* rm, const mp_int* sm, int* res, void* heap)
34985 {
34986     int err = FP_WOULDBLOCK;
34987     sp_ecc_verify_384_ctx* ctx = (sp_ecc_verify_384_ctx*)sp_ctx->data;
34988 
34989     typedef char ctx_size_test[sizeof(sp_ecc_verify_384_ctx) >= sizeof(*sp_ctx) ? -1 : 1];
34990     (void)sizeof(ctx_size_test);
34991 
34992     switch (ctx->state) {
34993     case 0: /* INIT */
34994         if (hashLen > 48U) {
34995             hashLen = 48U;
34996         }
34997 
34998         sp_384_from_bin(ctx->u1, 7, hash, (int)hashLen);
34999         sp_384_from_mp(ctx->u2, 7, rm);
35000         sp_384_from_mp(ctx->s, 7, sm);
35001         sp_384_from_mp(ctx->p2.x, 7, pX);
35002         sp_384_from_mp(ctx->p2.y, 7, pY);
35003         sp_384_from_mp(ctx->p2.z, 7, pZ);
35004         ctx->state = 1;
35005         break;
35006     case 1: /* NORMS0 */
35007         sp_384_mul_7(ctx->s, ctx->s, p384_norm_order);
35008         err = sp_384_mod_7(ctx->s, ctx->s, p384_order);
35009         if (err == MP_OKAY)
35010             ctx->state = 2;
35011         break;
35012     case 2: /* NORMS1 */
35013         sp_384_norm_7(ctx->s);
35014         XMEMSET(&ctx->mont_inv_order_ctx, 0, sizeof(ctx->mont_inv_order_ctx));
35015         ctx->state = 3;
35016         break;
35017     case 3: /* NORMS2 */
35018         err = sp_384_mont_inv_order_7_nb((sp_ecc_ctx_t*)&ctx->mont_inv_order_ctx, ctx->s, ctx->s, ctx->tmp);
35019         if (err == MP_OKAY) {
35020             ctx->state = 4;
35021         }
35022         break;
35023     case 4: /* NORMS3 */
35024         sp_384_mont_mul_order_7(ctx->u1, ctx->u1, ctx->s);
35025         ctx->state = 5;
35026         break;
35027     case 5: /* NORMS4 */
35028         sp_384_mont_mul_order_7(ctx->u2, ctx->u2, ctx->s);
35029         XMEMSET(&ctx->mulmod_ctx, 0, sizeof(ctx->mulmod_ctx));
35030         ctx->state = 6;
35031         break;
35032     case 6: /* MULBASE */
35033         err = sp_384_ecc_mulmod_7_nb((sp_ecc_ctx_t*)&ctx->mulmod_ctx, &ctx->p1, &p384_base, ctx->u1, 0, 0, heap);
35034         if (err == MP_OKAY) {
35035             if (sp_384_iszero_7(ctx->p1.z)) {
35036                 ctx->p1.infinity = 1;
35037             }
35038             XMEMSET(&ctx->mulmod_ctx, 0, sizeof(ctx->mulmod_ctx));
35039             ctx->state = 7;
35040         }
35041         break;
35042     case 7: /* MULMOD */
35043         err = sp_384_ecc_mulmod_7_nb((sp_ecc_ctx_t*)&ctx->mulmod_ctx, &ctx->p2, &ctx->p2, ctx->u2, 0, 0, heap);
35044         if (err == MP_OKAY) {
35045             if (sp_384_iszero_7(ctx->p2.z)) {
35046                 ctx->p2.infinity = 1;
35047             }
35048             XMEMSET(&ctx->add_ctx, 0, sizeof(ctx->add_ctx));
35049             ctx->state = 8;
35050         }
35051         break;
35052     case 8: /* ADD */
35053         err = sp_384_proj_point_add_7_nb((sp_ecc_ctx_t*)&ctx->add_ctx, &ctx->p1, &ctx->p1, &ctx->p2, ctx->tmp);
35054         if (err == MP_OKAY)
35055             ctx->state = 9;
35056         break;
35057     case 9: /* MONT */
35058         /* (r + n*order).z'.z' mod prime == (u1.G + u2.Q)->x' */
35059         /* Reload r and convert to Montgomery form. */
35060         sp_384_from_mp(ctx->u2, 7, rm);
35061         err = sp_384_mod_mul_norm_7(ctx->u2, ctx->u2, p384_mod);
35062         if (err == MP_OKAY)
35063             ctx->state = 10;
35064         break;
35065     case 10: /* SQR */
35066         /* u1 = r.z'.z' mod prime */
35067         sp_384_mont_sqr_7(ctx->p1.z, ctx->p1.z, p384_mod, p384_mp_mod);
35068         ctx->state = 11;
35069         break;
35070     case 11: /* MUL */
35071         sp_384_mont_mul_7(ctx->u1, ctx->u2, ctx->p1.z, p384_mod, p384_mp_mod);
35072         ctx->state = 12;
35073         break;
35074     case 12: /* RES */
35075     {
35076         sp_int64 c = 0;
35077         err = MP_OKAY; /* math okay, now check result */
35078         *res = (int)(sp_384_cmp_7(ctx->p1.x, ctx->u1) == 0);
35079         if (*res == 0) {
35080             sp_digit carry;
35081 
35082             /* Reload r and add order. */
35083             sp_384_from_mp(ctx->u2, 7, rm);
35084             carry = sp_384_add_7(ctx->u2, ctx->u2, p384_order);
35085             /* Carry means result is greater than mod and is not valid. */
35086             if (carry == 0) {
35087                 sp_384_norm_7(ctx->u2);
35088 
35089                 /* Compare with mod and if greater or equal then not valid. */
35090                 c = sp_384_cmp_7(ctx->u2, p384_mod);
35091             }
35092         }
35093         if ((*res == 0) && (c < 0)) {
35094             /* Convert to Montogomery form */
35095             err = sp_384_mod_mul_norm_7(ctx->u2, ctx->u2, p384_mod);
35096             if (err == MP_OKAY) {
35097                 /* u1 = (r + 1*order).z'.z' mod prime */
35098                 sp_384_mont_mul_7(ctx->u1, ctx->u2, ctx->p1.z, p384_mod,
35099                                                             p384_mp_mod);
35100                 *res = (int)(sp_384_cmp_7(ctx->p1.x, ctx->u1) == 0);
35101             }
35102         }
35103         break;
35104     }
35105     } /* switch */
35106 
35107     if (err == MP_OKAY && ctx->state != 12) {
35108         err = FP_WOULDBLOCK;
35109     }
35110 
35111     return err;
35112 }
35113 #endif /* WOLFSSL_SP_NONBLOCK */
35114 
sp_ecc_verify_384(const byte * hash,word32 hashLen,const mp_int * pX,const mp_int * pY,const mp_int * pZ,const mp_int * rm,const mp_int * sm,int * res,void * heap)35115 int sp_ecc_verify_384(const byte* hash, word32 hashLen, const mp_int* pX,
35116     const mp_int* pY, const mp_int* pZ, const mp_int* rm, const mp_int* sm,
35117     int* res, void* heap)
35118 {
35119 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
35120     sp_digit* u1 = NULL;
35121     sp_point_384* p1 = NULL;
35122 #else
35123     sp_digit  u1[16 * 7];
35124     sp_point_384 p1[2];
35125 #endif
35126     sp_digit* u2 = NULL;
35127     sp_digit* s = NULL;
35128     sp_digit* tmp = NULL;
35129     sp_point_384* p2 = NULL;
35130     sp_digit carry;
35131     sp_int64 c = 0;
35132     int err = MP_OKAY;
35133 
35134 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
35135     if (err == MP_OKAY) {
35136         p1 = (sp_point_384*)XMALLOC(sizeof(sp_point_384) * 2, heap,
35137                                              DYNAMIC_TYPE_ECC);
35138         if (p1 == NULL)
35139             err = MEMORY_E;
35140     }
35141     if (err == MP_OKAY) {
35142         u1 = (sp_digit*)XMALLOC(sizeof(sp_digit) * 16 * 7, heap,
35143                                                               DYNAMIC_TYPE_ECC);
35144         if (u1 == NULL)
35145             err = MEMORY_E;
35146     }
35147 #endif
35148 
35149     if (err == MP_OKAY) {
35150         u2  = u1 + 2 * 7;
35151         s   = u1 + 4 * 7;
35152         tmp = u1 + 6 * 7;
35153         p2 = p1 + 1;
35154 
35155         if (hashLen > 48U) {
35156             hashLen = 48U;
35157         }
35158 
35159         sp_384_from_bin(u1, 7, hash, (int)hashLen);
35160         sp_384_from_mp(u2, 7, rm);
35161         sp_384_from_mp(s, 7, sm);
35162         sp_384_from_mp(p2->x, 7, pX);
35163         sp_384_from_mp(p2->y, 7, pY);
35164         sp_384_from_mp(p2->z, 7, pZ);
35165 
35166         err = sp_384_calc_vfy_point_7(p1, p2, s, u1, u2, tmp, heap);
35167     }
35168     if (err == MP_OKAY) {
35169         /* (r + n*order).z'.z' mod prime == (u1.G + u2.Q)->x' */
35170         /* Reload r and convert to Montgomery form. */
35171         sp_384_from_mp(u2, 7, rm);
35172         err = sp_384_mod_mul_norm_7(u2, u2, p384_mod);
35173     }
35174 
35175     if (err == MP_OKAY) {
35176         /* u1 = r.z'.z' mod prime */
35177         sp_384_mont_sqr_7(p1->z, p1->z, p384_mod, p384_mp_mod);
35178         sp_384_mont_mul_7(u1, u2, p1->z, p384_mod, p384_mp_mod);
35179         *res = (int)(sp_384_cmp_7(p1->x, u1) == 0);
35180         if (*res == 0) {
35181             /* Reload r and add order. */
35182             sp_384_from_mp(u2, 7, rm);
35183             carry = sp_384_add_7(u2, u2, p384_order);
35184             /* Carry means result is greater than mod and is not valid. */
35185             if (carry == 0) {
35186                 sp_384_norm_7(u2);
35187 
35188                 /* Compare with mod and if greater or equal then not valid. */
35189                 c = sp_384_cmp_7(u2, p384_mod);
35190             }
35191         }
35192         if ((*res == 0) && (c < 0)) {
35193             /* Convert to Montogomery form */
35194             err = sp_384_mod_mul_norm_7(u2, u2, p384_mod);
35195             if (err == MP_OKAY) {
35196                 /* u1 = (r + 1*order).z'.z' mod prime */
35197                 sp_384_mont_mul_7(u1, u2, p1->z, p384_mod,
35198                     p384_mp_mod);
35199                 *res = (sp_384_cmp_7(p1->x, u1) == 0);
35200             }
35201         }
35202     }
35203 
35204 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
35205     if (u1 != NULL)
35206         XFREE(u1, heap, DYNAMIC_TYPE_ECC);
35207     if (p1 != NULL)
35208         XFREE(p1, heap, DYNAMIC_TYPE_ECC);
35209 #endif
35210 
35211     return err;
35212 }
35213 #endif /* HAVE_ECC_VERIFY */
35214 
35215 #ifdef HAVE_ECC_CHECK_KEY
35216 /* Check that the x and y oridinates are a valid point on the curve.
35217  *
35218  * point  EC point.
35219  * heap   Heap to use if dynamically allocating.
35220  * returns MEMORY_E if dynamic memory allocation fails, MP_VAL if the point is
35221  * not on the curve and MP_OKAY otherwise.
35222  */
sp_384_ecc_is_point_7(const sp_point_384 * point,void * heap)35223 static int sp_384_ecc_is_point_7(const sp_point_384* point,
35224     void* heap)
35225 {
35226 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
35227     sp_digit* t1 = NULL;
35228 #else
35229     sp_digit t1[7 * 4];
35230 #endif
35231     sp_digit* t2 = NULL;
35232     int err = MP_OKAY;
35233 
35234 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
35235     t1 = (sp_digit*)XMALLOC(sizeof(sp_digit) * 7 * 4, heap, DYNAMIC_TYPE_ECC);
35236     if (t1 == NULL)
35237         err = MEMORY_E;
35238 #endif
35239     (void)heap;
35240 
35241     if (err == MP_OKAY) {
35242         t2 = t1 + 2 * 7;
35243 
35244         sp_384_sqr_7(t1, point->y);
35245         (void)sp_384_mod_7(t1, t1, p384_mod);
35246         sp_384_sqr_7(t2, point->x);
35247         (void)sp_384_mod_7(t2, t2, p384_mod);
35248         sp_384_mul_7(t2, t2, point->x);
35249         (void)sp_384_mod_7(t2, t2, p384_mod);
35250         (void)sp_384_sub_7(t2, p384_mod, t2);
35251         sp_384_mont_add_7(t1, t1, t2, p384_mod);
35252 
35253         sp_384_mont_add_7(t1, t1, point->x, p384_mod);
35254         sp_384_mont_add_7(t1, t1, point->x, p384_mod);
35255         sp_384_mont_add_7(t1, t1, point->x, p384_mod);
35256 
35257         if (sp_384_cmp_7(t1, p384_b) != 0) {
35258             err = MP_VAL;
35259         }
35260     }
35261 
35262 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
35263     if (t1 != NULL)
35264         XFREE(t1, heap, DYNAMIC_TYPE_ECC);
35265 #endif
35266 
35267     return err;
35268 }
35269 
35270 /* Check that the x and y oridinates are a valid point on the curve.
35271  *
35272  * pX  X ordinate of EC point.
35273  * pY  Y ordinate of EC point.
35274  * returns MEMORY_E if dynamic memory allocation fails, MP_VAL if the point is
35275  * not on the curve and MP_OKAY otherwise.
35276  */
sp_ecc_is_point_384(const mp_int * pX,const mp_int * pY)35277 int sp_ecc_is_point_384(const mp_int* pX, const mp_int* pY)
35278 {
35279 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
35280     sp_point_384* pub = NULL;
35281 #else
35282     sp_point_384 pub[1];
35283 #endif
35284     const byte one[1] = { 1 };
35285     int err = MP_OKAY;
35286 
35287 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
35288     pub = (sp_point_384*)XMALLOC(sizeof(sp_point_384), NULL,
35289                                        DYNAMIC_TYPE_ECC);
35290     if (pub == NULL)
35291         err = MEMORY_E;
35292 #endif
35293 
35294     if (err == MP_OKAY) {
35295         sp_384_from_mp(pub->x, 7, pX);
35296         sp_384_from_mp(pub->y, 7, pY);
35297         sp_384_from_bin(pub->z, 7, one, (int)sizeof(one));
35298 
35299         err = sp_384_ecc_is_point_7(pub, NULL);
35300     }
35301 
35302 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
35303     if (pub != NULL)
35304         XFREE(pub, NULL, DYNAMIC_TYPE_ECC);
35305 #endif
35306 
35307     return err;
35308 }
35309 
35310 /* Check that the private scalar generates the EC point (px, py), the point is
35311  * on the curve and the point has the correct order.
35312  *
35313  * pX     X ordinate of EC point.
35314  * pY     Y ordinate of EC point.
35315  * privm  Private scalar that generates EC point.
35316  * returns MEMORY_E if dynamic memory allocation fails, MP_VAL if the point is
35317  * not on the curve, ECC_INF_E if the point does not have the correct order,
35318  * ECC_PRIV_KEY_E when the private scalar doesn't generate the EC point and
35319  * MP_OKAY otherwise.
35320  */
sp_ecc_check_key_384(const mp_int * pX,const mp_int * pY,const mp_int * privm,void * heap)35321 int sp_ecc_check_key_384(const mp_int* pX, const mp_int* pY,
35322     const mp_int* privm, void* heap)
35323 {
35324 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
35325     sp_digit* priv = NULL;
35326     sp_point_384* pub = NULL;
35327 #else
35328     sp_digit priv[7];
35329     sp_point_384 pub[2];
35330 #endif
35331     sp_point_384* p = NULL;
35332     const byte one[1] = { 1 };
35333     int err = MP_OKAY;
35334 
35335 
35336     /* Quick check the lengs of public key ordinates and private key are in
35337      * range. Proper check later.
35338      */
35339     if (((mp_count_bits(pX) > 384) ||
35340         (mp_count_bits(pY) > 384) ||
35341         ((privm != NULL) && (mp_count_bits(privm) > 384)))) {
35342         err = ECC_OUT_OF_RANGE_E;
35343     }
35344 
35345 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
35346     if (err == MP_OKAY) {
35347         pub = (sp_point_384*)XMALLOC(sizeof(sp_point_384) * 2, heap,
35348                                            DYNAMIC_TYPE_ECC);
35349         if (pub == NULL)
35350             err = MEMORY_E;
35351     }
35352     if (err == MP_OKAY && privm) {
35353         priv = (sp_digit*)XMALLOC(sizeof(sp_digit) * 7, heap,
35354                                   DYNAMIC_TYPE_ECC);
35355         if (priv == NULL)
35356             err = MEMORY_E;
35357     }
35358 #endif
35359 
35360     if (err == MP_OKAY) {
35361         p = pub + 1;
35362 
35363         sp_384_from_mp(pub->x, 7, pX);
35364         sp_384_from_mp(pub->y, 7, pY);
35365         sp_384_from_bin(pub->z, 7, one, (int)sizeof(one));
35366         if (privm)
35367             sp_384_from_mp(priv, 7, privm);
35368 
35369         /* Check point at infinitiy. */
35370         if ((sp_384_iszero_7(pub->x) != 0) &&
35371             (sp_384_iszero_7(pub->y) != 0)) {
35372             err = ECC_INF_E;
35373         }
35374     }
35375 
35376     /* Check range of X and Y */
35377     if ((err == MP_OKAY) &&
35378             ((sp_384_cmp_7(pub->x, p384_mod) >= 0) ||
35379              (sp_384_cmp_7(pub->y, p384_mod) >= 0))) {
35380         err = ECC_OUT_OF_RANGE_E;
35381     }
35382 
35383     if (err == MP_OKAY) {
35384         /* Check point is on curve */
35385         err = sp_384_ecc_is_point_7(pub, heap);
35386     }
35387 
35388     if (err == MP_OKAY) {
35389         /* Point * order = infinity */
35390             err = sp_384_ecc_mulmod_7(p, pub, p384_order, 1, 1, heap);
35391     }
35392     /* Check result is infinity */
35393     if ((err == MP_OKAY) && ((sp_384_iszero_7(p->x) == 0) ||
35394                              (sp_384_iszero_7(p->y) == 0))) {
35395         err = ECC_INF_E;
35396     }
35397 
35398     if (privm) {
35399         if (err == MP_OKAY) {
35400             /* Base * private = point */
35401                 err = sp_384_ecc_mulmod_base_7(p, priv, 1, 1, heap);
35402         }
35403         /* Check result is public key */
35404         if ((err == MP_OKAY) &&
35405                 ((sp_384_cmp_7(p->x, pub->x) != 0) ||
35406                  (sp_384_cmp_7(p->y, pub->y) != 0))) {
35407             err = ECC_PRIV_KEY_E;
35408         }
35409     }
35410 
35411 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
35412     if (pub != NULL)
35413         XFREE(pub, heap, DYNAMIC_TYPE_ECC);
35414     if (priv != NULL)
35415         XFREE(priv, heap, DYNAMIC_TYPE_ECC);
35416 #endif
35417 
35418     return err;
35419 }
35420 #endif
35421 #ifdef WOLFSSL_PUBLIC_ECC_ADD_DBL
35422 /* Add two projective EC points together.
35423  * (pX, pY, pZ) + (qX, qY, qZ) = (rX, rY, rZ)
35424  *
35425  * pX   First EC point's X ordinate.
35426  * pY   First EC point's Y ordinate.
35427  * pZ   First EC point's Z ordinate.
35428  * qX   Second EC point's X ordinate.
35429  * qY   Second EC point's Y ordinate.
35430  * qZ   Second EC point's Z ordinate.
35431  * rX   Resultant EC point's X ordinate.
35432  * rY   Resultant EC point's Y ordinate.
35433  * rZ   Resultant EC point's Z ordinate.
35434  * returns MEMORY_E if dynamic memory allocation fails and MP_OKAY otherwise.
35435  */
sp_ecc_proj_add_point_384(mp_int * pX,mp_int * pY,mp_int * pZ,mp_int * qX,mp_int * qY,mp_int * qZ,mp_int * rX,mp_int * rY,mp_int * rZ)35436 int sp_ecc_proj_add_point_384(mp_int* pX, mp_int* pY, mp_int* pZ,
35437                               mp_int* qX, mp_int* qY, mp_int* qZ,
35438                               mp_int* rX, mp_int* rY, mp_int* rZ)
35439 {
35440 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
35441     sp_digit* tmp = NULL;
35442     sp_point_384* p = NULL;
35443 #else
35444     sp_digit tmp[2 * 7 * 5];
35445     sp_point_384 p[2];
35446 #endif
35447     sp_point_384* q = NULL;
35448     int err = MP_OKAY;
35449 
35450 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
35451     if (err == MP_OKAY) {
35452         p = (sp_point_384*)XMALLOC(sizeof(sp_point_384) * 2, NULL,
35453                                          DYNAMIC_TYPE_ECC);
35454         if (p == NULL)
35455             err = MEMORY_E;
35456     }
35457     if (err == MP_OKAY) {
35458         tmp = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 7 * 5, NULL,
35459                                  DYNAMIC_TYPE_ECC);
35460         if (tmp == NULL) {
35461             err = MEMORY_E;
35462         }
35463     }
35464 #endif
35465 
35466     if (err == MP_OKAY) {
35467         q = p + 1;
35468 
35469         sp_384_from_mp(p->x, 7, pX);
35470         sp_384_from_mp(p->y, 7, pY);
35471         sp_384_from_mp(p->z, 7, pZ);
35472         sp_384_from_mp(q->x, 7, qX);
35473         sp_384_from_mp(q->y, 7, qY);
35474         sp_384_from_mp(q->z, 7, qZ);
35475         p->infinity = sp_384_iszero_7(p->x) &
35476                       sp_384_iszero_7(p->y);
35477         q->infinity = sp_384_iszero_7(q->x) &
35478                       sp_384_iszero_7(q->y);
35479 
35480             sp_384_proj_point_add_7(p, p, q, tmp);
35481     }
35482 
35483     if (err == MP_OKAY) {
35484         err = sp_384_to_mp(p->x, rX);
35485     }
35486     if (err == MP_OKAY) {
35487         err = sp_384_to_mp(p->y, rY);
35488     }
35489     if (err == MP_OKAY) {
35490         err = sp_384_to_mp(p->z, rZ);
35491     }
35492 
35493 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
35494     if (tmp != NULL)
35495         XFREE(tmp, NULL, DYNAMIC_TYPE_ECC);
35496     if (p != NULL)
35497         XFREE(p, NULL, DYNAMIC_TYPE_ECC);
35498 #endif
35499 
35500     return err;
35501 }
35502 
35503 /* Double a projective EC point.
35504  * (pX, pY, pZ) + (pX, pY, pZ) = (rX, rY, rZ)
35505  *
35506  * pX   EC point's X ordinate.
35507  * pY   EC point's Y ordinate.
35508  * pZ   EC point's Z ordinate.
35509  * rX   Resultant EC point's X ordinate.
35510  * rY   Resultant EC point's Y ordinate.
35511  * rZ   Resultant EC point's Z ordinate.
35512  * returns MEMORY_E if dynamic memory allocation fails and MP_OKAY otherwise.
35513  */
sp_ecc_proj_dbl_point_384(mp_int * pX,mp_int * pY,mp_int * pZ,mp_int * rX,mp_int * rY,mp_int * rZ)35514 int sp_ecc_proj_dbl_point_384(mp_int* pX, mp_int* pY, mp_int* pZ,
35515                               mp_int* rX, mp_int* rY, mp_int* rZ)
35516 {
35517 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
35518     sp_digit* tmp = NULL;
35519     sp_point_384* p = NULL;
35520 #else
35521     sp_digit tmp[2 * 7 * 2];
35522     sp_point_384 p[1];
35523 #endif
35524     int err = MP_OKAY;
35525 
35526 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
35527     if (err == MP_OKAY) {
35528         p = (sp_point_384*)XMALLOC(sizeof(sp_point_384), NULL,
35529                                          DYNAMIC_TYPE_ECC);
35530         if (p == NULL)
35531             err = MEMORY_E;
35532     }
35533     if (err == MP_OKAY) {
35534         tmp = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 7 * 2, NULL,
35535                                  DYNAMIC_TYPE_ECC);
35536         if (tmp == NULL)
35537             err = MEMORY_E;
35538     }
35539 #endif
35540 
35541     if (err == MP_OKAY) {
35542         sp_384_from_mp(p->x, 7, pX);
35543         sp_384_from_mp(p->y, 7, pY);
35544         sp_384_from_mp(p->z, 7, pZ);
35545         p->infinity = sp_384_iszero_7(p->x) &
35546                       sp_384_iszero_7(p->y);
35547 
35548             sp_384_proj_point_dbl_7(p, p, tmp);
35549     }
35550 
35551     if (err == MP_OKAY) {
35552         err = sp_384_to_mp(p->x, rX);
35553     }
35554     if (err == MP_OKAY) {
35555         err = sp_384_to_mp(p->y, rY);
35556     }
35557     if (err == MP_OKAY) {
35558         err = sp_384_to_mp(p->z, rZ);
35559     }
35560 
35561 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
35562     if (tmp != NULL)
35563         XFREE(tmp, NULL, DYNAMIC_TYPE_ECC);
35564     if (p != NULL)
35565         XFREE(p, NULL, DYNAMIC_TYPE_ECC);
35566 #endif
35567 
35568     return err;
35569 }
35570 
35571 /* Map a projective EC point to affine in place.
35572  * pZ will be one.
35573  *
35574  * pX   EC point's X ordinate.
35575  * pY   EC point's Y ordinate.
35576  * pZ   EC point's Z ordinate.
35577  * returns MEMORY_E if dynamic memory allocation fails and MP_OKAY otherwise.
35578  */
sp_ecc_map_384(mp_int * pX,mp_int * pY,mp_int * pZ)35579 int sp_ecc_map_384(mp_int* pX, mp_int* pY, mp_int* pZ)
35580 {
35581 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
35582     sp_digit* tmp = NULL;
35583     sp_point_384* p = NULL;
35584 #else
35585     sp_digit tmp[2 * 7 * 6];
35586     sp_point_384 p[1];
35587 #endif
35588     int err = MP_OKAY;
35589 
35590 
35591 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
35592     if (err == MP_OKAY) {
35593         p = (sp_point_384*)XMALLOC(sizeof(sp_point_384), NULL,
35594                                          DYNAMIC_TYPE_ECC);
35595         if (p == NULL)
35596             err = MEMORY_E;
35597     }
35598     if (err == MP_OKAY) {
35599         tmp = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 7 * 6, NULL,
35600                                  DYNAMIC_TYPE_ECC);
35601         if (tmp == NULL)
35602             err = MEMORY_E;
35603     }
35604 #endif
35605     if (err == MP_OKAY) {
35606         sp_384_from_mp(p->x, 7, pX);
35607         sp_384_from_mp(p->y, 7, pY);
35608         sp_384_from_mp(p->z, 7, pZ);
35609         p->infinity = sp_384_iszero_7(p->x) &
35610                       sp_384_iszero_7(p->y);
35611 
35612             sp_384_map_7(p, p, tmp);
35613     }
35614 
35615     if (err == MP_OKAY) {
35616         err = sp_384_to_mp(p->x, pX);
35617     }
35618     if (err == MP_OKAY) {
35619         err = sp_384_to_mp(p->y, pY);
35620     }
35621     if (err == MP_OKAY) {
35622         err = sp_384_to_mp(p->z, pZ);
35623     }
35624 
35625 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
35626     if (tmp != NULL)
35627         XFREE(tmp, NULL, DYNAMIC_TYPE_ECC);
35628     if (p != NULL)
35629         XFREE(p, NULL, DYNAMIC_TYPE_ECC);
35630 #endif
35631 
35632     return err;
35633 }
35634 #endif /* WOLFSSL_PUBLIC_ECC_ADD_DBL */
35635 #ifdef HAVE_COMP_KEY
35636 /* Find the square root of a number mod the prime of the curve.
35637  *
35638  * y  The number to operate on and the result.
35639  * returns MEMORY_E if dynamic memory allocation fails and MP_OKAY otherwise.
35640  */
sp_384_mont_sqrt_7(sp_digit * y)35641 static int sp_384_mont_sqrt_7(sp_digit* y)
35642 {
35643 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
35644     sp_digit* t1 = NULL;
35645 #else
35646     sp_digit t1[5 * 2 * 7];
35647 #endif
35648     sp_digit* t2 = NULL;
35649     sp_digit* t3 = NULL;
35650     sp_digit* t4 = NULL;
35651     sp_digit* t5 = NULL;
35652     int err = MP_OKAY;
35653 
35654 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
35655     t1 = (sp_digit*)XMALLOC(sizeof(sp_digit) * 5 * 2 * 7, NULL, DYNAMIC_TYPE_ECC);
35656     if (t1 == NULL)
35657         err = MEMORY_E;
35658 #endif
35659 
35660     if (err == MP_OKAY) {
35661         t2 = t1 + 2 * 7;
35662         t3 = t1 + 4 * 7;
35663         t4 = t1 + 6 * 7;
35664         t5 = t1 + 8 * 7;
35665 
35666         {
35667             /* t2 = y ^ 0x2 */
35668             sp_384_mont_sqr_7(t2, y, p384_mod, p384_mp_mod);
35669             /* t1 = y ^ 0x3 */
35670             sp_384_mont_mul_7(t1, t2, y, p384_mod, p384_mp_mod);
35671             /* t5 = y ^ 0xc */
35672             sp_384_mont_sqr_n_7(t5, t1, 2, p384_mod, p384_mp_mod);
35673             /* t1 = y ^ 0xf */
35674             sp_384_mont_mul_7(t1, t1, t5, p384_mod, p384_mp_mod);
35675             /* t2 = y ^ 0x1e */
35676             sp_384_mont_sqr_7(t2, t1, p384_mod, p384_mp_mod);
35677             /* t3 = y ^ 0x1f */
35678             sp_384_mont_mul_7(t3, t2, y, p384_mod, p384_mp_mod);
35679             /* t2 = y ^ 0x3e0 */
35680             sp_384_mont_sqr_n_7(t2, t3, 5, p384_mod, p384_mp_mod);
35681             /* t1 = y ^ 0x3ff */
35682             sp_384_mont_mul_7(t1, t3, t2, p384_mod, p384_mp_mod);
35683             /* t2 = y ^ 0x7fe0 */
35684             sp_384_mont_sqr_n_7(t2, t1, 5, p384_mod, p384_mp_mod);
35685             /* t3 = y ^ 0x7fff */
35686             sp_384_mont_mul_7(t3, t3, t2, p384_mod, p384_mp_mod);
35687             /* t2 = y ^ 0x3fff800 */
35688             sp_384_mont_sqr_n_7(t2, t3, 15, p384_mod, p384_mp_mod);
35689             /* t4 = y ^ 0x3ffffff */
35690             sp_384_mont_mul_7(t4, t3, t2, p384_mod, p384_mp_mod);
35691             /* t2 = y ^ 0xffffffc000000 */
35692             sp_384_mont_sqr_n_7(t2, t4, 30, p384_mod, p384_mp_mod);
35693             /* t1 = y ^ 0xfffffffffffff */
35694             sp_384_mont_mul_7(t1, t4, t2, p384_mod, p384_mp_mod);
35695             /* t2 = y ^ 0xfffffffffffffff000000000000000 */
35696             sp_384_mont_sqr_n_7(t2, t1, 60, p384_mod, p384_mp_mod);
35697             /* t1 = y ^ 0xffffffffffffffffffffffffffffff */
35698             sp_384_mont_mul_7(t1, t1, t2, p384_mod, p384_mp_mod);
35699             /* t2 = y ^ 0xffffffffffffffffffffffffffffff000000000000000000000000000000 */
35700             sp_384_mont_sqr_n_7(t2, t1, 120, p384_mod, p384_mp_mod);
35701             /* t1 = y ^ 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff */
35702             sp_384_mont_mul_7(t1, t1, t2, p384_mod, p384_mp_mod);
35703             /* t2 = y ^ 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8000 */
35704             sp_384_mont_sqr_n_7(t2, t1, 15, p384_mod, p384_mp_mod);
35705             /* t1 = y ^ 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff */
35706             sp_384_mont_mul_7(t1, t3, t2, p384_mod, p384_mp_mod);
35707             /* t2 = y ^ 0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80000000 */
35708             sp_384_mont_sqr_n_7(t2, t1, 31, p384_mod, p384_mp_mod);
35709             /* t1 = y ^ 0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbfffffff */
35710             sp_384_mont_mul_7(t1, t4, t2, p384_mod, p384_mp_mod);
35711             /* t2 = y ^ 0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbfffffff0 */
35712             sp_384_mont_sqr_n_7(t2, t1, 4, p384_mod, p384_mp_mod);
35713             /* t1 = y ^ 0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbfffffffc */
35714             sp_384_mont_mul_7(t1, t5, t2, p384_mod, p384_mp_mod);
35715             /* t2 = y ^ 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff0000000000000000 */
35716             sp_384_mont_sqr_n_7(t2, t1, 62, p384_mod, p384_mp_mod);
35717             /* t1 = y ^ 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff0000000000000001 */
35718             sp_384_mont_mul_7(t1, y, t2, p384_mod, p384_mp_mod);
35719             /* t2 = y ^ 0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbfffffffc00000000000000040000000 */
35720             sp_384_mont_sqr_n_7(y, t1, 30, p384_mod, p384_mp_mod);
35721         }
35722     }
35723 
35724 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
35725     if (t1 != NULL)
35726         XFREE(t1, NULL, DYNAMIC_TYPE_ECC);
35727 #endif
35728 
35729     return err;
35730 }
35731 
35732 
35733 /* Uncompress the point given the X ordinate.
35734  *
35735  * xm    X ordinate.
35736  * odd   Whether the Y ordinate is odd.
35737  * ym    Calculated Y ordinate.
35738  * returns MEMORY_E if dynamic memory allocation fails and MP_OKAY otherwise.
35739  */
sp_ecc_uncompress_384(mp_int * xm,int odd,mp_int * ym)35740 int sp_ecc_uncompress_384(mp_int* xm, int odd, mp_int* ym)
35741 {
35742 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
35743     sp_digit* x = NULL;
35744 #else
35745     sp_digit x[4 * 7];
35746 #endif
35747     sp_digit* y = NULL;
35748     int err = MP_OKAY;
35749 
35750 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
35751     x = (sp_digit*)XMALLOC(sizeof(sp_digit) * 4 * 7, NULL, DYNAMIC_TYPE_ECC);
35752     if (x == NULL)
35753         err = MEMORY_E;
35754 #endif
35755 
35756     if (err == MP_OKAY) {
35757         y = x + 2 * 7;
35758 
35759         sp_384_from_mp(x, 7, xm);
35760         err = sp_384_mod_mul_norm_7(x, x, p384_mod);
35761     }
35762     if (err == MP_OKAY) {
35763         /* y = x^3 */
35764         {
35765             sp_384_mont_sqr_7(y, x, p384_mod, p384_mp_mod);
35766             sp_384_mont_mul_7(y, y, x, p384_mod, p384_mp_mod);
35767         }
35768         /* y = x^3 - 3x */
35769         sp_384_mont_sub_7(y, y, x, p384_mod);
35770         sp_384_mont_sub_7(y, y, x, p384_mod);
35771         sp_384_mont_sub_7(y, y, x, p384_mod);
35772         /* y = x^3 - 3x + b */
35773         err = sp_384_mod_mul_norm_7(x, p384_b, p384_mod);
35774     }
35775     if (err == MP_OKAY) {
35776         sp_384_mont_add_7(y, y, x, p384_mod);
35777         /* y = sqrt(x^3 - 3x + b) */
35778         err = sp_384_mont_sqrt_7(y);
35779     }
35780     if (err == MP_OKAY) {
35781         XMEMSET(y + 7, 0, 7U * sizeof(sp_digit));
35782         sp_384_mont_reduce_7(y, p384_mod, p384_mp_mod);
35783         if ((((word32)y[0] ^ (word32)odd) & 1U) != 0U) {
35784             sp_384_mont_sub_7(y, p384_mod, y, p384_mod);
35785         }
35786 
35787         err = sp_384_to_mp(y, ym);
35788     }
35789 
35790 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
35791     if (x != NULL)
35792         XFREE(x, NULL, DYNAMIC_TYPE_ECC);
35793 #endif
35794 
35795     return err;
35796 }
35797 #endif
35798 #endif /* WOLFSSL_SP_384 */
35799 #ifdef WOLFSSL_SP_1024
35800 
35801 /* Point structure to use. */
35802 typedef struct sp_point_1024 {
35803     /* X ordinate of point. */
35804     sp_digit x[2 * 18];
35805     /* Y ordinate of point. */
35806     sp_digit y[2 * 18];
35807     /* Z ordinate of point. */
35808     sp_digit z[2 * 18];
35809     /* Indicates point is at infinity. */
35810     int infinity;
35811 } sp_point_1024;
35812 
35813 #ifndef WOLFSSL_SP_SMALL
35814 /* Multiply a and b into r. (r = a * b)
35815  *
35816  * r  A single precision integer.
35817  * a  A single precision integer.
35818  * b  A single precision integer.
35819  */
sp_1024_mul_9(sp_digit * r,const sp_digit * a,const sp_digit * b)35820 SP_NOINLINE static void sp_1024_mul_9(sp_digit* r, const sp_digit* a,
35821     const sp_digit* b)
35822 {
35823     sp_int128 t0   = ((sp_int128)a[ 0]) * b[ 0];
35824     sp_int128 t1   = ((sp_int128)a[ 0]) * b[ 1]
35825                  + ((sp_int128)a[ 1]) * b[ 0];
35826     sp_int128 t2   = ((sp_int128)a[ 0]) * b[ 2]
35827                  + ((sp_int128)a[ 1]) * b[ 1]
35828                  + ((sp_int128)a[ 2]) * b[ 0];
35829     sp_int128 t3   = ((sp_int128)a[ 0]) * b[ 3]
35830                  + ((sp_int128)a[ 1]) * b[ 2]
35831                  + ((sp_int128)a[ 2]) * b[ 1]
35832                  + ((sp_int128)a[ 3]) * b[ 0];
35833     sp_int128 t4   = ((sp_int128)a[ 0]) * b[ 4]
35834                  + ((sp_int128)a[ 1]) * b[ 3]
35835                  + ((sp_int128)a[ 2]) * b[ 2]
35836                  + ((sp_int128)a[ 3]) * b[ 1]
35837                  + ((sp_int128)a[ 4]) * b[ 0];
35838     sp_int128 t5   = ((sp_int128)a[ 0]) * b[ 5]
35839                  + ((sp_int128)a[ 1]) * b[ 4]
35840                  + ((sp_int128)a[ 2]) * b[ 3]
35841                  + ((sp_int128)a[ 3]) * b[ 2]
35842                  + ((sp_int128)a[ 4]) * b[ 1]
35843                  + ((sp_int128)a[ 5]) * b[ 0];
35844     sp_int128 t6   = ((sp_int128)a[ 0]) * b[ 6]
35845                  + ((sp_int128)a[ 1]) * b[ 5]
35846                  + ((sp_int128)a[ 2]) * b[ 4]
35847                  + ((sp_int128)a[ 3]) * b[ 3]
35848                  + ((sp_int128)a[ 4]) * b[ 2]
35849                  + ((sp_int128)a[ 5]) * b[ 1]
35850                  + ((sp_int128)a[ 6]) * b[ 0];
35851     sp_int128 t7   = ((sp_int128)a[ 0]) * b[ 7]
35852                  + ((sp_int128)a[ 1]) * b[ 6]
35853                  + ((sp_int128)a[ 2]) * b[ 5]
35854                  + ((sp_int128)a[ 3]) * b[ 4]
35855                  + ((sp_int128)a[ 4]) * b[ 3]
35856                  + ((sp_int128)a[ 5]) * b[ 2]
35857                  + ((sp_int128)a[ 6]) * b[ 1]
35858                  + ((sp_int128)a[ 7]) * b[ 0];
35859     sp_int128 t8   = ((sp_int128)a[ 0]) * b[ 8]
35860                  + ((sp_int128)a[ 1]) * b[ 7]
35861                  + ((sp_int128)a[ 2]) * b[ 6]
35862                  + ((sp_int128)a[ 3]) * b[ 5]
35863                  + ((sp_int128)a[ 4]) * b[ 4]
35864                  + ((sp_int128)a[ 5]) * b[ 3]
35865                  + ((sp_int128)a[ 6]) * b[ 2]
35866                  + ((sp_int128)a[ 7]) * b[ 1]
35867                  + ((sp_int128)a[ 8]) * b[ 0];
35868     sp_int128 t9   = ((sp_int128)a[ 1]) * b[ 8]
35869                  + ((sp_int128)a[ 2]) * b[ 7]
35870                  + ((sp_int128)a[ 3]) * b[ 6]
35871                  + ((sp_int128)a[ 4]) * b[ 5]
35872                  + ((sp_int128)a[ 5]) * b[ 4]
35873                  + ((sp_int128)a[ 6]) * b[ 3]
35874                  + ((sp_int128)a[ 7]) * b[ 2]
35875                  + ((sp_int128)a[ 8]) * b[ 1];
35876     sp_int128 t10  = ((sp_int128)a[ 2]) * b[ 8]
35877                  + ((sp_int128)a[ 3]) * b[ 7]
35878                  + ((sp_int128)a[ 4]) * b[ 6]
35879                  + ((sp_int128)a[ 5]) * b[ 5]
35880                  + ((sp_int128)a[ 6]) * b[ 4]
35881                  + ((sp_int128)a[ 7]) * b[ 3]
35882                  + ((sp_int128)a[ 8]) * b[ 2];
35883     sp_int128 t11  = ((sp_int128)a[ 3]) * b[ 8]
35884                  + ((sp_int128)a[ 4]) * b[ 7]
35885                  + ((sp_int128)a[ 5]) * b[ 6]
35886                  + ((sp_int128)a[ 6]) * b[ 5]
35887                  + ((sp_int128)a[ 7]) * b[ 4]
35888                  + ((sp_int128)a[ 8]) * b[ 3];
35889     sp_int128 t12  = ((sp_int128)a[ 4]) * b[ 8]
35890                  + ((sp_int128)a[ 5]) * b[ 7]
35891                  + ((sp_int128)a[ 6]) * b[ 6]
35892                  + ((sp_int128)a[ 7]) * b[ 5]
35893                  + ((sp_int128)a[ 8]) * b[ 4];
35894     sp_int128 t13  = ((sp_int128)a[ 5]) * b[ 8]
35895                  + ((sp_int128)a[ 6]) * b[ 7]
35896                  + ((sp_int128)a[ 7]) * b[ 6]
35897                  + ((sp_int128)a[ 8]) * b[ 5];
35898     sp_int128 t14  = ((sp_int128)a[ 6]) * b[ 8]
35899                  + ((sp_int128)a[ 7]) * b[ 7]
35900                  + ((sp_int128)a[ 8]) * b[ 6];
35901     sp_int128 t15  = ((sp_int128)a[ 7]) * b[ 8]
35902                  + ((sp_int128)a[ 8]) * b[ 7];
35903     sp_int128 t16  = ((sp_int128)a[ 8]) * b[ 8];
35904 
35905     t1   += t0  >> 57; r[ 0] = t0  & 0x1ffffffffffffffL;
35906     t2   += t1  >> 57; r[ 1] = t1  & 0x1ffffffffffffffL;
35907     t3   += t2  >> 57; r[ 2] = t2  & 0x1ffffffffffffffL;
35908     t4   += t3  >> 57; r[ 3] = t3  & 0x1ffffffffffffffL;
35909     t5   += t4  >> 57; r[ 4] = t4  & 0x1ffffffffffffffL;
35910     t6   += t5  >> 57; r[ 5] = t5  & 0x1ffffffffffffffL;
35911     t7   += t6  >> 57; r[ 6] = t6  & 0x1ffffffffffffffL;
35912     t8   += t7  >> 57; r[ 7] = t7  & 0x1ffffffffffffffL;
35913     t9   += t8  >> 57; r[ 8] = t8  & 0x1ffffffffffffffL;
35914     t10  += t9  >> 57; r[ 9] = t9  & 0x1ffffffffffffffL;
35915     t11  += t10 >> 57; r[10] = t10 & 0x1ffffffffffffffL;
35916     t12  += t11 >> 57; r[11] = t11 & 0x1ffffffffffffffL;
35917     t13  += t12 >> 57; r[12] = t12 & 0x1ffffffffffffffL;
35918     t14  += t13 >> 57; r[13] = t13 & 0x1ffffffffffffffL;
35919     t15  += t14 >> 57; r[14] = t14 & 0x1ffffffffffffffL;
35920     t16  += t15 >> 57; r[15] = t15 & 0x1ffffffffffffffL;
35921     r[17] = (sp_digit)(t16 >> 57);
35922                        r[16] = t16 & 0x1ffffffffffffffL;
35923 }
35924 
35925 /* Square a and put result in r. (r = a * a)
35926  *
35927  * r  A single precision integer.
35928  * a  A single precision integer.
35929  */
sp_1024_sqr_9(sp_digit * r,const sp_digit * a)35930 SP_NOINLINE static void sp_1024_sqr_9(sp_digit* r, const sp_digit* a)
35931 {
35932     sp_int128 t0   =  ((sp_int128)a[ 0]) * a[ 0];
35933     sp_int128 t1   = (((sp_int128)a[ 0]) * a[ 1]) * 2;
35934     sp_int128 t2   = (((sp_int128)a[ 0]) * a[ 2]) * 2
35935                  +  ((sp_int128)a[ 1]) * a[ 1];
35936     sp_int128 t3   = (((sp_int128)a[ 0]) * a[ 3]
35937                  +  ((sp_int128)a[ 1]) * a[ 2]) * 2;
35938     sp_int128 t4   = (((sp_int128)a[ 0]) * a[ 4]
35939                  +  ((sp_int128)a[ 1]) * a[ 3]) * 2
35940                  +  ((sp_int128)a[ 2]) * a[ 2];
35941     sp_int128 t5   = (((sp_int128)a[ 0]) * a[ 5]
35942                  +  ((sp_int128)a[ 1]) * a[ 4]
35943                  +  ((sp_int128)a[ 2]) * a[ 3]) * 2;
35944     sp_int128 t6   = (((sp_int128)a[ 0]) * a[ 6]
35945                  +  ((sp_int128)a[ 1]) * a[ 5]
35946                  +  ((sp_int128)a[ 2]) * a[ 4]) * 2
35947                  +  ((sp_int128)a[ 3]) * a[ 3];
35948     sp_int128 t7   = (((sp_int128)a[ 0]) * a[ 7]
35949                  +  ((sp_int128)a[ 1]) * a[ 6]
35950                  +  ((sp_int128)a[ 2]) * a[ 5]
35951                  +  ((sp_int128)a[ 3]) * a[ 4]) * 2;
35952     sp_int128 t8   = (((sp_int128)a[ 0]) * a[ 8]
35953                  +  ((sp_int128)a[ 1]) * a[ 7]
35954                  +  ((sp_int128)a[ 2]) * a[ 6]
35955                  +  ((sp_int128)a[ 3]) * a[ 5]) * 2
35956                  +  ((sp_int128)a[ 4]) * a[ 4];
35957     sp_int128 t9   = (((sp_int128)a[ 1]) * a[ 8]
35958                  +  ((sp_int128)a[ 2]) * a[ 7]
35959                  +  ((sp_int128)a[ 3]) * a[ 6]
35960                  +  ((sp_int128)a[ 4]) * a[ 5]) * 2;
35961     sp_int128 t10  = (((sp_int128)a[ 2]) * a[ 8]
35962                  +  ((sp_int128)a[ 3]) * a[ 7]
35963                  +  ((sp_int128)a[ 4]) * a[ 6]) * 2
35964                  +  ((sp_int128)a[ 5]) * a[ 5];
35965     sp_int128 t11  = (((sp_int128)a[ 3]) * a[ 8]
35966                  +  ((sp_int128)a[ 4]) * a[ 7]
35967                  +  ((sp_int128)a[ 5]) * a[ 6]) * 2;
35968     sp_int128 t12  = (((sp_int128)a[ 4]) * a[ 8]
35969                  +  ((sp_int128)a[ 5]) * a[ 7]) * 2
35970                  +  ((sp_int128)a[ 6]) * a[ 6];
35971     sp_int128 t13  = (((sp_int128)a[ 5]) * a[ 8]
35972                  +  ((sp_int128)a[ 6]) * a[ 7]) * 2;
35973     sp_int128 t14  = (((sp_int128)a[ 6]) * a[ 8]) * 2
35974                  +  ((sp_int128)a[ 7]) * a[ 7];
35975     sp_int128 t15  = (((sp_int128)a[ 7]) * a[ 8]) * 2;
35976     sp_int128 t16  =  ((sp_int128)a[ 8]) * a[ 8];
35977 
35978     t1   += t0  >> 57; r[ 0] = t0  & 0x1ffffffffffffffL;
35979     t2   += t1  >> 57; r[ 1] = t1  & 0x1ffffffffffffffL;
35980     t3   += t2  >> 57; r[ 2] = t2  & 0x1ffffffffffffffL;
35981     t4   += t3  >> 57; r[ 3] = t3  & 0x1ffffffffffffffL;
35982     t5   += t4  >> 57; r[ 4] = t4  & 0x1ffffffffffffffL;
35983     t6   += t5  >> 57; r[ 5] = t5  & 0x1ffffffffffffffL;
35984     t7   += t6  >> 57; r[ 6] = t6  & 0x1ffffffffffffffL;
35985     t8   += t7  >> 57; r[ 7] = t7  & 0x1ffffffffffffffL;
35986     t9   += t8  >> 57; r[ 8] = t8  & 0x1ffffffffffffffL;
35987     t10  += t9  >> 57; r[ 9] = t9  & 0x1ffffffffffffffL;
35988     t11  += t10 >> 57; r[10] = t10 & 0x1ffffffffffffffL;
35989     t12  += t11 >> 57; r[11] = t11 & 0x1ffffffffffffffL;
35990     t13  += t12 >> 57; r[12] = t12 & 0x1ffffffffffffffL;
35991     t14  += t13 >> 57; r[13] = t13 & 0x1ffffffffffffffL;
35992     t15  += t14 >> 57; r[14] = t14 & 0x1ffffffffffffffL;
35993     t16  += t15 >> 57; r[15] = t15 & 0x1ffffffffffffffL;
35994     r[17] = (sp_digit)(t16 >> 57);
35995                        r[16] = t16 & 0x1ffffffffffffffL;
35996 }
35997 
35998 /* Add b to a into r. (r = a + b)
35999  *
36000  * r  A single precision integer.
36001  * a  A single precision integer.
36002  * b  A single precision integer.
36003  */
sp_1024_add_9(sp_digit * r,const sp_digit * a,const sp_digit * b)36004 SP_NOINLINE static int sp_1024_add_9(sp_digit* r, const sp_digit* a,
36005         const sp_digit* b)
36006 {
36007     r[ 0] = a[ 0] + b[ 0];
36008     r[ 1] = a[ 1] + b[ 1];
36009     r[ 2] = a[ 2] + b[ 2];
36010     r[ 3] = a[ 3] + b[ 3];
36011     r[ 4] = a[ 4] + b[ 4];
36012     r[ 5] = a[ 5] + b[ 5];
36013     r[ 6] = a[ 6] + b[ 6];
36014     r[ 7] = a[ 7] + b[ 7];
36015     r[ 8] = a[ 8] + b[ 8];
36016 
36017     return 0;
36018 }
36019 
36020 /* Add b to a into r. (r = a + b)
36021  *
36022  * r  A single precision integer.
36023  * a  A single precision integer.
36024  * b  A single precision integer.
36025  */
sp_1024_add_18(sp_digit * r,const sp_digit * a,const sp_digit * b)36026 SP_NOINLINE static int sp_1024_add_18(sp_digit* r, const sp_digit* a,
36027         const sp_digit* b)
36028 {
36029     int i;
36030 
36031     for (i = 0; i < 16; i += 8) {
36032         r[i + 0] = a[i + 0] + b[i + 0];
36033         r[i + 1] = a[i + 1] + b[i + 1];
36034         r[i + 2] = a[i + 2] + b[i + 2];
36035         r[i + 3] = a[i + 3] + b[i + 3];
36036         r[i + 4] = a[i + 4] + b[i + 4];
36037         r[i + 5] = a[i + 5] + b[i + 5];
36038         r[i + 6] = a[i + 6] + b[i + 6];
36039         r[i + 7] = a[i + 7] + b[i + 7];
36040     }
36041     r[16] = a[16] + b[16];
36042     r[17] = a[17] + b[17];
36043 
36044     return 0;
36045 }
36046 
36047 /* Sub b from a into r. (r = a - b)
36048  *
36049  * r  A single precision integer.
36050  * a  A single precision integer.
36051  * b  A single precision integer.
36052  */
sp_1024_sub_18(sp_digit * r,const sp_digit * a,const sp_digit * b)36053 SP_NOINLINE static int sp_1024_sub_18(sp_digit* r, const sp_digit* a,
36054         const sp_digit* b)
36055 {
36056     int i;
36057 
36058     for (i = 0; i < 16; i += 8) {
36059         r[i + 0] = a[i + 0] - b[i + 0];
36060         r[i + 1] = a[i + 1] - b[i + 1];
36061         r[i + 2] = a[i + 2] - b[i + 2];
36062         r[i + 3] = a[i + 3] - b[i + 3];
36063         r[i + 4] = a[i + 4] - b[i + 4];
36064         r[i + 5] = a[i + 5] - b[i + 5];
36065         r[i + 6] = a[i + 6] - b[i + 6];
36066         r[i + 7] = a[i + 7] - b[i + 7];
36067     }
36068     r[16] = a[16] - b[16];
36069     r[17] = a[17] - b[17];
36070 
36071     return 0;
36072 }
36073 
36074 /* Multiply a and b into r. (r = a * b)
36075  *
36076  * r  A single precision integer.
36077  * a  A single precision integer.
36078  * b  A single precision integer.
36079  */
sp_1024_mul_18(sp_digit * r,const sp_digit * a,const sp_digit * b)36080 SP_NOINLINE static void sp_1024_mul_18(sp_digit* r, const sp_digit* a,
36081     const sp_digit* b)
36082 {
36083     sp_digit* z0 = r;
36084     sp_digit z1[18];
36085     sp_digit* a1 = z1;
36086     sp_digit b1[9];
36087     sp_digit* z2 = r + 18;
36088     (void)sp_1024_add_9(a1, a, &a[9]);
36089     (void)sp_1024_add_9(b1, b, &b[9]);
36090     sp_1024_mul_9(z2, &a[9], &b[9]);
36091     sp_1024_mul_9(z0, a, b);
36092     sp_1024_mul_9(z1, a1, b1);
36093     (void)sp_1024_sub_18(z1, z1, z2);
36094     (void)sp_1024_sub_18(z1, z1, z0);
36095     (void)sp_1024_add_18(r + 9, r + 9, z1);
36096 }
36097 
36098 /* Square a and put result in r. (r = a * a)
36099  *
36100  * r  A single precision integer.
36101  * a  A single precision integer.
36102  */
sp_1024_sqr_18(sp_digit * r,const sp_digit * a)36103 SP_NOINLINE static void sp_1024_sqr_18(sp_digit* r, const sp_digit* a)
36104 {
36105     sp_digit* z0 = r;
36106     sp_digit z1[18];
36107     sp_digit* a1 = z1;
36108     sp_digit* z2 = r + 18;
36109     (void)sp_1024_add_9(a1, a, &a[9]);
36110     sp_1024_sqr_9(z2, &a[9]);
36111     sp_1024_sqr_9(z0, a);
36112     sp_1024_sqr_9(z1, a1);
36113     (void)sp_1024_sub_18(z1, z1, z2);
36114     (void)sp_1024_sub_18(z1, z1, z0);
36115     (void)sp_1024_add_18(r + 9, r + 9, z1);
36116 }
36117 
36118 #else
36119 /* Multiply a and b into r. (r = a * b)
36120  *
36121  * r  A single precision integer.
36122  * a  A single precision integer.
36123  * b  A single precision integer.
36124  */
sp_1024_mul_18(sp_digit * r,const sp_digit * a,const sp_digit * b)36125 SP_NOINLINE static void sp_1024_mul_18(sp_digit* r, const sp_digit* a,
36126     const sp_digit* b)
36127 {
36128     int i;
36129     int imax;
36130     int k;
36131     sp_uint128 c;
36132     sp_uint128 lo;
36133 
36134     c = ((sp_uint128)a[17]) * b[17];
36135     r[35] = (sp_digit)(c >> 57);
36136     c &= 0x1ffffffffffffffL;
36137     for (k = 33; k >= 0; k--) {
36138         if (k >= 18) {
36139             i = k - 17;
36140             imax = 17;
36141         }
36142         else {
36143             i = 0;
36144             imax = k;
36145         }
36146         lo = 0;
36147         for (; i <= imax; i++) {
36148             lo += ((sp_uint128)a[i]) * b[k - i];
36149         }
36150         c += lo >> 57;
36151         r[k + 2] += (sp_digit)(c >> 57);
36152         r[k + 1]  = (sp_digit)(c & 0x1ffffffffffffffL);
36153         c = lo & 0x1ffffffffffffffL;
36154     }
36155     r[0] = (sp_digit)c;
36156 }
36157 
36158 /* Square a and put result in r. (r = a * a)
36159  *
36160  * r  A single precision integer.
36161  * a  A single precision integer.
36162  */
sp_1024_sqr_18(sp_digit * r,const sp_digit * a)36163 SP_NOINLINE static void sp_1024_sqr_18(sp_digit* r, const sp_digit* a)
36164 {
36165     int i;
36166     int imax;
36167     int k;
36168     sp_uint128 c;
36169     sp_uint128 t;
36170 
36171     c = ((sp_uint128)a[17]) * a[17];
36172     r[35] = (sp_digit)(c >> 57);
36173     c = (c & 0x1ffffffffffffffL) << 57;
36174     for (k = 33; k >= 0; k--) {
36175         i = (k + 1) / 2;
36176         if ((k & 1) == 0) {
36177            c += ((sp_uint128)a[i]) * a[i];
36178            i++;
36179         }
36180         if (k < 17) {
36181             imax = k;
36182         }
36183         else {
36184             imax = 17;
36185         }
36186         t = 0;
36187         for (; i <= imax; i++) {
36188             t += ((sp_uint128)a[i]) * a[k - i];
36189         }
36190         c += t * 2;
36191 
36192         r[k + 2] += (sp_digit) (c >> 114);
36193         r[k + 1]  = (sp_digit)((c >> 57) & 0x1ffffffffffffffL);
36194         c = (c & 0x1ffffffffffffffL) << 57;
36195     }
36196     r[0] = (sp_digit)(c >> 57);
36197 }
36198 
36199 #endif /* !WOLFSSL_SP_SMALL */
36200 /* The modulus (prime) of the curve P1024. */
36201 static const sp_digit p1024_mod[18] = {
36202     0x06d807afea85febL,0x0ef88563d6743b3L,0x008e2615f6c2031L,0x1ead2e3e3ff9c7dL,
36203     0x1c3c09aa9f94d6aL,0x02954153e79e290L,0x07386dabfd2a0c6L,0x1a8a2558b9acad0L,
36204     0x0e26c6487326b4cL,0x0b693fa53335368L,0x06ce7fdf222864dL,0x01aa634b3961cf2L,
36205     0x07e2fc0f1b22873L,0x19f00d177a05559L,0x0d20986fa6b8d62L,0x0caf482d819c339L,
36206     0x1da65c61198dad0L,0x04cbd5d8f852b1fL
36207 };
36208 /* The Montgomery normalizer for modulus of the curve P1024. */
36209 static const sp_digit p1024_norm_mod[18] = {
36210     0x1927f850157a015L,0x11077a9c298bc4cL,0x1f71d9ea093dfceL,0x0152d1c1c006382L,
36211     0x03c3f655606b295L,0x1d6abeac1861d6fL,0x18c7925402d5f39L,0x0575daa7465352fL,
36212     0x11d939b78cd94b3L,0x1496c05acccac97L,0x19318020ddd79b2L,0x1e559cb4c69e30dL,
36213     0x181d03f0e4dd78cL,0x060ff2e885faaa6L,0x12df6790594729dL,0x1350b7d27e63cc6L,
36214     0x0259a39ee67252fL,0x03342a2707ad4e0L
36215 };
36216 /* The Montgomery multiplier for modulus of the curve P1024. */
36217 static sp_digit p1024_mp_mod = 0x10420077c8f2f3d;
36218 #if defined(WOLFSSL_SP_SMALL) || defined(HAVE_ECC_CHECK_KEY)
36219 /* The order of the curve P1024. */
36220 static const sp_digit p1024_order[18] = {
36221     0x19b601ebfaa17fbL,0x0bbe2158f59d0ecL,0x082389857db080cL,0x17ab4b8f8ffe71fL,
36222     0x070f026aa7e535aL,0x10a55054f9e78a4L,0x01ce1b6aff4a831L,0x06a289562e6b2b4L,
36223     0x0389b1921cc9ad3L,0x0ada4fe94ccd4daL,0x11b39ff7c88a193L,0x186a98d2ce5873cL,
36224     0x09f8bf03c6c8a1cL,0x167c0345de81556L,0x0b48261be9ae358L,0x032bd20b60670ceL,
36225     0x1f69971846636b4L,0x0132f5763e14ac7L
36226 };
36227 #endif
36228 /* The base point of curve P1024. */
36229 static const sp_point_1024 p1024_base = {
36230     /* X ordinate */
36231     {
36232         0x00dc8abeae63895L,0x023624b3f04bcc4L,0x0e96d8fdcfb203bL,
36233         0x1900e51b0fdd22cL,0x1a66910dd5cfb4cL,0x106f3a53e0a8a6dL,
36234         0x1cb869c0b0ce5e9L,0x19666f90ca916e5L,0x09760af765dd5bcL,
36235         0x0c5ecf3a0367448L,0x17c8b36e77e955cL,0x172061613c2087aL,
36236         0x00f6ce2308ab10dL,0x1b7fbe5fdaf6db6L,0x1b1a71a62cbc812L,
36237         0x16a5456345fac15L,0x1ad0a7990053ed9L,0x029fe04f7199614L,
36238         (sp_digit)0, (sp_digit)0, (sp_digit)0, (sp_digit)0, (sp_digit)0,
36239         (sp_digit)0, (sp_digit)0, (sp_digit)0, (sp_digit)0, (sp_digit)0,
36240         (sp_digit)0, (sp_digit)0, (sp_digit)0, (sp_digit)0, (sp_digit)0,
36241         (sp_digit)0, (sp_digit)0, (sp_digit)0
36242     },
36243     /* Y ordinate */
36244     {
36245         0x1573fd71bef16d7L,0x0dab83533ee6f3aL,0x156b56ed18dab6eL,
36246         0x0fd3973353017b5L,0x05a4d5f213515adL,0x0554c4a496cbcfeL,
36247         0x0bf82b1bc7a0059L,0x0d995ad2d6b6ecaL,0x170dae117ad547cL,
36248         0x0b67f8654f0195cL,0x06333e68502cb90L,0x0bcbe1bcabecd6bL,
36249         0x14654ec2b9e7f7fL,0x0f0a08bc7af534fL,0x0641a58f5de3608L,
36250         0x1426ba7d0402c05L,0x1f1f9f1f0533634L,0x0054124831fb004L,
36251         (sp_digit)0, (sp_digit)0, (sp_digit)0, (sp_digit)0, (sp_digit)0,
36252         (sp_digit)0, (sp_digit)0, (sp_digit)0, (sp_digit)0, (sp_digit)0,
36253         (sp_digit)0, (sp_digit)0, (sp_digit)0, (sp_digit)0, (sp_digit)0,
36254         (sp_digit)0, (sp_digit)0, (sp_digit)0
36255     },
36256     /* Z ordinate */
36257     {
36258         0x000000000000001L,0x000000000000000L,0x000000000000000L,
36259         0x000000000000000L,0x000000000000000L,0x000000000000000L,
36260         0x000000000000000L,0x000000000000000L,0x000000000000000L,
36261         0x000000000000000L,0x000000000000000L,0x000000000000000L,
36262         0x000000000000000L,0x000000000000000L,0x000000000000000L,
36263         0x000000000000000L,0x000000000000000L,0x000000000000000L,
36264         (sp_digit)0, (sp_digit)0, (sp_digit)0, (sp_digit)0, (sp_digit)0,
36265         (sp_digit)0, (sp_digit)0, (sp_digit)0, (sp_digit)0, (sp_digit)0,
36266         (sp_digit)0, (sp_digit)0, (sp_digit)0, (sp_digit)0, (sp_digit)0,
36267         (sp_digit)0, (sp_digit)0, (sp_digit)0
36268     },
36269     /* infinity */
36270     0
36271 };
36272 
36273 /* Normalize the values in each word to 57 bits.
36274  *
36275  * a  Array of sp_digit to normalize.
36276  */
sp_1024_norm_18(sp_digit * a)36277 static void sp_1024_norm_18(sp_digit* a)
36278 {
36279 #ifdef WOLFSSL_SP_SMALL
36280     int i;
36281     for (i = 0; i < 17; i++) {
36282         a[i+1] += a[i] >> 57;
36283         a[i] &= 0x1ffffffffffffffL;
36284     }
36285 #else
36286     int i;
36287     for (i = 0; i < 16; i += 8) {
36288         a[i+1] += a[i+0] >> 57; a[i+0] &= 0x1ffffffffffffffL;
36289         a[i+2] += a[i+1] >> 57; a[i+1] &= 0x1ffffffffffffffL;
36290         a[i+3] += a[i+2] >> 57; a[i+2] &= 0x1ffffffffffffffL;
36291         a[i+4] += a[i+3] >> 57; a[i+3] &= 0x1ffffffffffffffL;
36292         a[i+5] += a[i+4] >> 57; a[i+4] &= 0x1ffffffffffffffL;
36293         a[i+6] += a[i+5] >> 57; a[i+5] &= 0x1ffffffffffffffL;
36294         a[i+7] += a[i+6] >> 57; a[i+6] &= 0x1ffffffffffffffL;
36295         a[i+8] += a[i+7] >> 57; a[i+7] &= 0x1ffffffffffffffL;
36296     }
36297     a[17] += a[16] >> 57; a[16] &= 0x1ffffffffffffffL;
36298 #endif /* WOLFSSL_SP_SMALL */
36299 }
36300 
36301 /* Multiply a by scalar b into r. (r = a * b)
36302  *
36303  * r  A single precision integer.
36304  * a  A single precision integer.
36305  * b  A scalar.
36306  */
sp_1024_mul_d_18(sp_digit * r,const sp_digit * a,sp_digit b)36307 SP_NOINLINE static void sp_1024_mul_d_18(sp_digit* r, const sp_digit* a,
36308     sp_digit b)
36309 {
36310 #ifdef WOLFSSL_SP_SMALL
36311     sp_int128 tb = b;
36312     sp_int128 t = 0;
36313     int i;
36314 
36315     for (i = 0; i < 18; i++) {
36316         t += tb * a[i];
36317         r[i] = (sp_digit)(t & 0x1ffffffffffffffL);
36318         t >>= 57;
36319     }
36320     r[18] = (sp_digit)t;
36321 #else
36322     sp_int128 tb = b;
36323     sp_int128 t = 0;
36324     sp_digit t2;
36325     sp_int128 p[4];
36326     int i;
36327 
36328     for (i = 0; i < 16; i += 4) {
36329         p[0] = tb * a[i + 0];
36330         p[1] = tb * a[i + 1];
36331         p[2] = tb * a[i + 2];
36332         p[3] = tb * a[i + 3];
36333         t += p[0];
36334         t2 = (sp_digit)(t & 0x1ffffffffffffffL);
36335         t >>= 57;
36336         r[i + 0] = (sp_digit)t2;
36337         t += p[1];
36338         t2 = (sp_digit)(t & 0x1ffffffffffffffL);
36339         t >>= 57;
36340         r[i + 1] = (sp_digit)t2;
36341         t += p[2];
36342         t2 = (sp_digit)(t & 0x1ffffffffffffffL);
36343         t >>= 57;
36344         r[i + 2] = (sp_digit)t2;
36345         t += p[3];
36346         t2 = (sp_digit)(t & 0x1ffffffffffffffL);
36347         t >>= 57;
36348         r[i + 3] = (sp_digit)t2;
36349     }
36350     t += tb * a[16];
36351     r[16] = (sp_digit)(t & 0x1ffffffffffffffL);
36352     t >>= 57;
36353     t += tb * a[17];
36354     r[17] = (sp_digit)(t & 0x1ffffffffffffffL);
36355     t >>= 57;
36356     r[18] = (sp_digit)(t & 0x1ffffffffffffffL);
36357 #endif /* WOLFSSL_SP_SMALL */
36358 }
36359 
36360 /* Multiply a by scalar b into r. (r = a * b)
36361  *
36362  * r  A single precision integer.
36363  * a  A single precision integer.
36364  * b  A scalar.
36365  */
sp_1024_mul_d_36(sp_digit * r,const sp_digit * a,sp_digit b)36366 SP_NOINLINE static void sp_1024_mul_d_36(sp_digit* r, const sp_digit* a,
36367     sp_digit b)
36368 {
36369 #ifdef WOLFSSL_SP_SMALL
36370     sp_int128 tb = b;
36371     sp_int128 t = 0;
36372     int i;
36373 
36374     for (i = 0; i < 36; i++) {
36375         t += tb * a[i];
36376         r[i] = (sp_digit)(t & 0x1ffffffffffffffL);
36377         t >>= 57;
36378     }
36379     r[36] = (sp_digit)t;
36380 #else
36381     sp_int128 tb = b;
36382     sp_int128 t = 0;
36383     sp_digit t2;
36384     sp_int128 p[4];
36385     int i;
36386 
36387     for (i = 0; i < 36; i += 4) {
36388         p[0] = tb * a[i + 0];
36389         p[1] = tb * a[i + 1];
36390         p[2] = tb * a[i + 2];
36391         p[3] = tb * a[i + 3];
36392         t += p[0];
36393         t2 = (sp_digit)(t & 0x1ffffffffffffffL);
36394         t >>= 57;
36395         r[i + 0] = (sp_digit)t2;
36396         t += p[1];
36397         t2 = (sp_digit)(t & 0x1ffffffffffffffL);
36398         t >>= 57;
36399         r[i + 1] = (sp_digit)t2;
36400         t += p[2];
36401         t2 = (sp_digit)(t & 0x1ffffffffffffffL);
36402         t >>= 57;
36403         r[i + 2] = (sp_digit)t2;
36404         t += p[3];
36405         t2 = (sp_digit)(t & 0x1ffffffffffffffL);
36406         t >>= 57;
36407         r[i + 3] = (sp_digit)t2;
36408     }
36409     r[36] = (sp_digit)(t & 0x1ffffffffffffffL);
36410 #endif /* WOLFSSL_SP_SMALL */
36411 }
36412 
36413 /* Conditionally add a and b using the mask m.
36414  * m is -1 to add and 0 when not.
36415  *
36416  * r  A single precision number representing conditional add result.
36417  * a  A single precision number to add with.
36418  * b  A single precision number to add.
36419  * m  Mask value to apply.
36420  */
sp_1024_cond_add_18(sp_digit * r,const sp_digit * a,const sp_digit * b,const sp_digit m)36421 static void sp_1024_cond_add_18(sp_digit* r, const sp_digit* a,
36422         const sp_digit* b, const sp_digit m)
36423 {
36424 #ifdef WOLFSSL_SP_SMALL
36425     int i;
36426 
36427     for (i = 0; i < 18; i++) {
36428         r[i] = a[i] + (b[i] & m);
36429     }
36430 #else
36431     int i;
36432 
36433     for (i = 0; i < 16; i += 8) {
36434         r[i + 0] = a[i + 0] + (b[i + 0] & m);
36435         r[i + 1] = a[i + 1] + (b[i + 1] & m);
36436         r[i + 2] = a[i + 2] + (b[i + 2] & m);
36437         r[i + 3] = a[i + 3] + (b[i + 3] & m);
36438         r[i + 4] = a[i + 4] + (b[i + 4] & m);
36439         r[i + 5] = a[i + 5] + (b[i + 5] & m);
36440         r[i + 6] = a[i + 6] + (b[i + 6] & m);
36441         r[i + 7] = a[i + 7] + (b[i + 7] & m);
36442     }
36443     r[16] = a[16] + (b[16] & m);
36444     r[17] = a[17] + (b[17] & m);
36445 #endif /* WOLFSSL_SP_SMALL */
36446 }
36447 
36448 #ifdef WOLFSSL_SP_SMALL
36449 /* Sub b from a into r. (r = a - b)
36450  *
36451  * r  A single precision integer.
36452  * a  A single precision integer.
36453  * b  A single precision integer.
36454  */
sp_1024_sub_18(sp_digit * r,const sp_digit * a,const sp_digit * b)36455 SP_NOINLINE static int sp_1024_sub_18(sp_digit* r, const sp_digit* a,
36456         const sp_digit* b)
36457 {
36458     int i;
36459 
36460     for (i = 0; i < 18; i++) {
36461         r[i] = a[i] - b[i];
36462     }
36463 
36464     return 0;
36465 }
36466 
36467 #endif
36468 #ifdef WOLFSSL_SP_SMALL
36469 /* Add b to a into r. (r = a + b)
36470  *
36471  * r  A single precision integer.
36472  * a  A single precision integer.
36473  * b  A single precision integer.
36474  */
sp_1024_add_18(sp_digit * r,const sp_digit * a,const sp_digit * b)36475 SP_NOINLINE static int sp_1024_add_18(sp_digit* r, const sp_digit* a,
36476         const sp_digit* b)
36477 {
36478     int i;
36479 
36480     for (i = 0; i < 18; i++) {
36481         r[i] = a[i] + b[i];
36482     }
36483 
36484     return 0;
36485 }
36486 #endif /* WOLFSSL_SP_SMALL */
36487 
sp_1024_rshift_18(sp_digit * r,const sp_digit * a,byte n)36488 SP_NOINLINE static void sp_1024_rshift_18(sp_digit* r, const sp_digit* a,
36489         byte n)
36490 {
36491     int i;
36492 
36493 #ifdef WOLFSSL_SP_SMALL
36494     for (i=0; i<17; i++) {
36495         r[i] = ((a[i] >> n) | (a[i + 1] << (57 - n))) & 0x1ffffffffffffffL;
36496     }
36497 #else
36498     for (i=0; i<16; i += 8) {
36499         r[i+0] = (a[i+0] >> n) | ((a[i+1] << (57 - n)) & 0x1ffffffffffffffL);
36500         r[i+1] = (a[i+1] >> n) | ((a[i+2] << (57 - n)) & 0x1ffffffffffffffL);
36501         r[i+2] = (a[i+2] >> n) | ((a[i+3] << (57 - n)) & 0x1ffffffffffffffL);
36502         r[i+3] = (a[i+3] >> n) | ((a[i+4] << (57 - n)) & 0x1ffffffffffffffL);
36503         r[i+4] = (a[i+4] >> n) | ((a[i+5] << (57 - n)) & 0x1ffffffffffffffL);
36504         r[i+5] = (a[i+5] >> n) | ((a[i+6] << (57 - n)) & 0x1ffffffffffffffL);
36505         r[i+6] = (a[i+6] >> n) | ((a[i+7] << (57 - n)) & 0x1ffffffffffffffL);
36506         r[i+7] = (a[i+7] >> n) | ((a[i+8] << (57 - n)) & 0x1ffffffffffffffL);
36507     }
36508     r[16] = (a[16] >> n) | ((a[17] << (57 - n)) & 0x1ffffffffffffffL);
36509 #endif /* WOLFSSL_SP_SMALL */
36510     r[17] = a[17] >> n;
36511 }
36512 
36513 #ifdef WOLFSSL_SP_DIV_64
sp_1024_div_word_18(sp_digit d1,sp_digit d0,sp_digit dv)36514 static WC_INLINE sp_digit sp_1024_div_word_18(sp_digit d1, sp_digit d0,
36515     sp_digit dv)
36516 {
36517     sp_digit d;
36518     sp_digit r;
36519     sp_digit t;
36520 
36521     /* All 57 bits from d1 and top 6 bits from d0. */
36522     d = (d1 << 6) + (d0 >> 51);
36523     r = d / dv;
36524     d -= r * dv;
36525     /* Up to 7 bits in r */
36526     /* Next 6 bits from d0. */
36527     r <<= 6;
36528     d <<= 6;
36529     d += (d0 >> 45) & ((1 << 6) - 1);
36530     t = d / dv;
36531     d -= t * dv;
36532     r += t;
36533     /* Up to 13 bits in r */
36534     /* Next 6 bits from d0. */
36535     r <<= 6;
36536     d <<= 6;
36537     d += (d0 >> 39) & ((1 << 6) - 1);
36538     t = d / dv;
36539     d -= t * dv;
36540     r += t;
36541     /* Up to 19 bits in r */
36542     /* Next 6 bits from d0. */
36543     r <<= 6;
36544     d <<= 6;
36545     d += (d0 >> 33) & ((1 << 6) - 1);
36546     t = d / dv;
36547     d -= t * dv;
36548     r += t;
36549     /* Up to 25 bits in r */
36550     /* Next 6 bits from d0. */
36551     r <<= 6;
36552     d <<= 6;
36553     d += (d0 >> 27) & ((1 << 6) - 1);
36554     t = d / dv;
36555     d -= t * dv;
36556     r += t;
36557     /* Up to 31 bits in r */
36558     /* Next 6 bits from d0. */
36559     r <<= 6;
36560     d <<= 6;
36561     d += (d0 >> 21) & ((1 << 6) - 1);
36562     t = d / dv;
36563     d -= t * dv;
36564     r += t;
36565     /* Up to 37 bits in r */
36566     /* Next 6 bits from d0. */
36567     r <<= 6;
36568     d <<= 6;
36569     d += (d0 >> 15) & ((1 << 6) - 1);
36570     t = d / dv;
36571     d -= t * dv;
36572     r += t;
36573     /* Up to 43 bits in r */
36574     /* Next 6 bits from d0. */
36575     r <<= 6;
36576     d <<= 6;
36577     d += (d0 >> 9) & ((1 << 6) - 1);
36578     t = d / dv;
36579     d -= t * dv;
36580     r += t;
36581     /* Up to 49 bits in r */
36582     /* Next 6 bits from d0. */
36583     r <<= 6;
36584     d <<= 6;
36585     d += (d0 >> 3) & ((1 << 6) - 1);
36586     t = d / dv;
36587     d -= t * dv;
36588     r += t;
36589     /* Up to 55 bits in r */
36590     /* Remaining 3 bits from d0. */
36591     r <<= 3;
36592     d <<= 3;
36593     d += d0 & ((1 << 3) - 1);
36594     t = d / dv;
36595     r += t;
36596 
36597     /* All 57 bits from d1 and top 6 bits from d0. */
36598     return r;
36599 }
36600 #endif /* WOLFSSL_SP_DIV_64 */
36601 
36602 /* Divide d in a and put remainder into r (m*d + r = a)
36603  * m is not calculated as it is not needed at this time.
36604  *
36605  * Full implementation.
36606  *
36607  * a  Number to be divided.
36608  * d  Number to divide with.
36609  * m  Multiplier result.
36610  * r  Remainder from the division.
36611  * returns MEMORY_E when unable to allocate memory and MP_OKAY otherwise.
36612  */
sp_1024_div_18(const sp_digit * a,const sp_digit * d,const sp_digit * m,sp_digit * r)36613 static int sp_1024_div_18(const sp_digit* a, const sp_digit* d,
36614         const sp_digit* m, sp_digit* r)
36615 {
36616     int i;
36617 #ifndef WOLFSSL_SP_DIV_64
36618     sp_int128 d1;
36619 #endif
36620     sp_digit dv;
36621     sp_digit r1;
36622 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
36623     sp_digit* t1 = NULL;
36624 #else
36625     sp_digit t1[4 * 18 + 3];
36626 #endif
36627     sp_digit* t2 = NULL;
36628     sp_digit* sd = NULL;
36629     int err = MP_OKAY;
36630 
36631     (void)m;
36632 
36633 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
36634     t1 = (sp_digit*)XMALLOC(sizeof(sp_digit) * (4 * 18 + 3), NULL,
36635                                                        DYNAMIC_TYPE_TMP_BUFFER);
36636     if (t1 == NULL)
36637         err = MEMORY_E;
36638 #endif
36639 
36640     (void)m;
36641 
36642     if (err == MP_OKAY) {
36643         t2 = t1 + 36 + 1;
36644         sd = t2 + 18 + 1;
36645 
36646         sp_1024_mul_d_18(sd, d, (sp_digit)1 << 2);
36647         sp_1024_mul_d_36(t1, a, (sp_digit)1 << 2);
36648         dv = sd[17];
36649         t1[18 + 18] += t1[18 + 18 - 1] >> 57;
36650         t1[18 + 18 - 1] &= 0x1ffffffffffffffL;
36651         for (i=18; i>=0; i--) {
36652 #ifndef WOLFSSL_SP_DIV_64
36653             d1 = t1[18 + i];
36654             d1 <<= 57;
36655             d1 += t1[18 + i - 1];
36656             r1 = (sp_digit)(d1 / dv);
36657 #else
36658             r1 = sp_1024_div_word_18(t1[18 + i], t1[18 + i - 1], dv);
36659 #endif
36660 
36661             sp_1024_mul_d_18(t2, sd, r1);
36662             (void)sp_1024_sub_18(&t1[i], &t1[i], t2);
36663             sp_1024_norm_18(&t1[i]);
36664             t1[18 + i] -= t2[18];
36665             t1[18 + i] += t1[18 + i - 1] >> 57;
36666             t1[18 + i - 1] &= 0x1ffffffffffffffL;
36667 #ifndef WOLFSSL_SP_DIV_64
36668             d1 = -t1[18 + i];
36669             d1 <<= 57;
36670             d1 -= t1[18 + i - 1];
36671             r1 = (sp_digit)(d1 / dv);
36672 #else
36673             r1 = sp_1024_div_word_18(-t1[18 + i], -t1[18 + i - 1], dv);
36674 #endif
36675             r1 -= t1[18 + i];
36676             sp_1024_mul_d_18(t2, sd, r1);
36677             (void)sp_1024_add_18(&t1[i], &t1[i], t2);
36678             t1[18 + i] += t1[18 + i - 1] >> 57;
36679             t1[18 + i - 1] &= 0x1ffffffffffffffL;
36680         }
36681         t1[18 - 1] += t1[18 - 2] >> 57;
36682         t1[18 - 2] &= 0x1ffffffffffffffL;
36683         r1 = t1[18 - 1] / dv;
36684 
36685         sp_1024_mul_d_18(t2, sd, r1);
36686         sp_1024_sub_18(t1, t1, t2);
36687         XMEMCPY(r, t1, sizeof(*r) * 36U);
36688         for (i=0; i<17; i++) {
36689             r[i+1] += r[i] >> 57;
36690             r[i] &= 0x1ffffffffffffffL;
36691         }
36692         sp_1024_cond_add_18(r, r, sd, 0 - ((r[17] < 0) ?
36693                     (sp_digit)1 : (sp_digit)0));
36694 
36695         sp_1024_norm_18(r);
36696         sp_1024_rshift_18(r, r, 2);
36697     }
36698 
36699 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
36700     if (t1 != NULL)
36701         XFREE(t1, NULL, DYNAMIC_TYPE_TMP_BUFFER);
36702 #endif
36703 
36704     return err;
36705 }
36706 
36707 /* Reduce a modulo m into r. (r = a mod m)
36708  *
36709  * r  A single precision number that is the reduced result.
36710  * a  A single precision number that is to be reduced.
36711  * m  A single precision number that is the modulus to reduce with.
36712  * returns MEMORY_E when unable to allocate memory and MP_OKAY otherwise.
36713  */
sp_1024_mod_18(sp_digit * r,const sp_digit * a,const sp_digit * m)36714 static int sp_1024_mod_18(sp_digit* r, const sp_digit* a, const sp_digit* m)
36715 {
36716     return sp_1024_div_18(a, m, NULL, r);
36717 }
36718 
36719 /* Multiply a number by Montgomery normalizer mod modulus (prime).
36720  *
36721  * r  The resulting Montgomery form number.
36722  * a  The number to convert.
36723  * m  The modulus (prime).
36724  * returns MEMORY_E when memory allocation fails and MP_OKAY otherwise.
36725  */
sp_1024_mod_mul_norm_18(sp_digit * r,const sp_digit * a,const sp_digit * m)36726 static int sp_1024_mod_mul_norm_18(sp_digit* r, const sp_digit* a,
36727         const sp_digit* m)
36728 {
36729     sp_1024_mul_18(r, a, p1024_norm_mod);
36730     return sp_1024_mod_18(r, r, m);
36731 }
36732 
36733 
36734 #ifdef WOLFCRYPT_HAVE_SAKKE
36735 /* Create a new point.
36736  *
36737  * heap  [in]   Buffer to allocate dynamic memory from.
36738  * sp    [in]   Data for point - only if not allocating.
36739  * p     [out]  New point.
36740  * returns MEMORY_E when dynamic memory allocation fails and 0 otherwise.
36741  */
sp_1024_point_new_ex_18(void * heap,sp_point_1024 * sp,sp_point_1024 ** p)36742 static int sp_1024_point_new_ex_18(void* heap, sp_point_1024* sp,
36743     sp_point_1024** p)
36744 {
36745     int ret = MP_OKAY;
36746     (void)heap;
36747 #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC)
36748     (void)sp;
36749     *p = (sp_point_1024*)XMALLOC(sizeof(sp_point_1024), heap, DYNAMIC_TYPE_ECC);
36750 #else
36751     *p = sp;
36752 #endif
36753     if (*p == NULL) {
36754         ret = MEMORY_E;
36755     }
36756     return ret;
36757 }
36758 
36759 #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC)
36760 /* Allocate memory for point and return error. */
36761 #define sp_1024_point_new_18(heap, sp, p) sp_1024_point_new_ex_18((heap), NULL, &(p))
36762 #else
36763 /* Set pointer to data and return no error. */
36764 #define sp_1024_point_new_18(heap, sp, p) sp_1024_point_new_ex_18((heap), &(sp), &(p))
36765 #endif
36766 #endif /* WOLFCRYPT_HAVE_SAKKE */
36767 #ifdef WOLFCRYPT_HAVE_SAKKE
36768 /* Free the point.
36769  *
36770  * p      [in,out]  Point to free.
36771  * clear  [in]      Indicates whether to zeroize point.
36772  * heap   [in]      Buffer from which dynamic memory was allocate from.
36773  */
sp_1024_point_free_18(sp_point_1024 * p,int clear,void * heap)36774 static void sp_1024_point_free_18(sp_point_1024* p, int clear, void* heap)
36775 {
36776 #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC)
36777 /* If valid pointer then clear point data if requested and free data. */
36778     if (p != NULL) {
36779         if (clear != 0) {
36780             XMEMSET(p, 0, sizeof(*p));
36781         }
36782         XFREE(p, heap, DYNAMIC_TYPE_ECC);
36783     }
36784 #else
36785 /* Clear point data if requested. */
36786     if ((p != NULL) && (clear != 0)) {
36787         XMEMSET(p, 0, sizeof(*p));
36788     }
36789 #endif
36790     (void)heap;
36791 }
36792 #endif /* WOLFCRYPT_HAVE_SAKKE */
36793 
36794 /* Convert an mp_int to an array of sp_digit.
36795  *
36796  * r  A single precision integer.
36797  * size  Maximum number of bytes to convert
36798  * a  A multi-precision integer.
36799  */
sp_1024_from_mp(sp_digit * r,int size,const mp_int * a)36800 static void sp_1024_from_mp(sp_digit* r, int size, const mp_int* a)
36801 {
36802 #if DIGIT_BIT == 57
36803     int j;
36804 
36805     XMEMCPY(r, a->dp, sizeof(sp_digit) * a->used);
36806 
36807     for (j = a->used; j < size; j++) {
36808         r[j] = 0;
36809     }
36810 #elif DIGIT_BIT > 57
36811     int i;
36812     int j = 0;
36813     word32 s = 0;
36814 
36815     r[0] = 0;
36816     for (i = 0; i < a->used && j < size; i++) {
36817         r[j] |= ((sp_digit)a->dp[i] << s);
36818         r[j] &= 0x1ffffffffffffffL;
36819         s = 57U - s;
36820         if (j + 1 >= size) {
36821             break;
36822         }
36823         /* lint allow cast of mismatch word32 and mp_digit */
36824         r[++j] = (sp_digit)(a->dp[i] >> s); /*lint !e9033*/
36825         while ((s + 57U) <= (word32)DIGIT_BIT) {
36826             s += 57U;
36827             r[j] &= 0x1ffffffffffffffL;
36828             if (j + 1 >= size) {
36829                 break;
36830             }
36831             if (s < (word32)DIGIT_BIT) {
36832                 /* lint allow cast of mismatch word32 and mp_digit */
36833                 r[++j] = (sp_digit)(a->dp[i] >> s); /*lint !e9033*/
36834             }
36835             else {
36836                 r[++j] = (sp_digit)0;
36837             }
36838         }
36839         s = (word32)DIGIT_BIT - s;
36840     }
36841 
36842     for (j++; j < size; j++) {
36843         r[j] = 0;
36844     }
36845 #else
36846     int i;
36847     int j = 0;
36848     int s = 0;
36849 
36850     r[0] = 0;
36851     for (i = 0; i < a->used && j < size; i++) {
36852         r[j] |= ((sp_digit)a->dp[i]) << s;
36853         if (s + DIGIT_BIT >= 57) {
36854             r[j] &= 0x1ffffffffffffffL;
36855             if (j + 1 >= size) {
36856                 break;
36857             }
36858             s = 57 - s;
36859             if (s == DIGIT_BIT) {
36860                 r[++j] = 0;
36861                 s = 0;
36862             }
36863             else {
36864                 r[++j] = a->dp[i] >> s;
36865                 s = DIGIT_BIT - s;
36866             }
36867         }
36868         else {
36869             s += DIGIT_BIT;
36870         }
36871     }
36872 
36873     for (j++; j < size; j++) {
36874         r[j] = 0;
36875     }
36876 #endif
36877 }
36878 
36879 /* Convert a point of type ecc_point to type sp_point_1024.
36880  *
36881  * p   Point of type sp_point_1024 (result).
36882  * pm  Point of type ecc_point.
36883  */
sp_1024_point_from_ecc_point_18(sp_point_1024 * p,const ecc_point * pm)36884 static void sp_1024_point_from_ecc_point_18(sp_point_1024* p,
36885         const ecc_point* pm)
36886 {
36887     XMEMSET(p->x, 0, sizeof(p->x));
36888     XMEMSET(p->y, 0, sizeof(p->y));
36889     XMEMSET(p->z, 0, sizeof(p->z));
36890     sp_1024_from_mp(p->x, 18, pm->x);
36891     sp_1024_from_mp(p->y, 18, pm->y);
36892     sp_1024_from_mp(p->z, 18, pm->z);
36893     p->infinity = 0;
36894 }
36895 
36896 /* Convert an array of sp_digit to an mp_int.
36897  *
36898  * a  A single precision integer.
36899  * r  A multi-precision integer.
36900  */
sp_1024_to_mp(const sp_digit * a,mp_int * r)36901 static int sp_1024_to_mp(const sp_digit* a, mp_int* r)
36902 {
36903     int err;
36904 
36905     err = mp_grow(r, (1024 + DIGIT_BIT - 1) / DIGIT_BIT);
36906     if (err == MP_OKAY) { /*lint !e774 case where err is always MP_OKAY*/
36907 #if DIGIT_BIT == 57
36908         XMEMCPY(r->dp, a, sizeof(sp_digit) * 18);
36909         r->used = 18;
36910         mp_clamp(r);
36911 #elif DIGIT_BIT < 57
36912         int i;
36913         int j = 0;
36914         int s = 0;
36915 
36916         r->dp[0] = 0;
36917         for (i = 0; i < 18; i++) {
36918             r->dp[j] |= (mp_digit)(a[i] << s);
36919             r->dp[j] &= ((sp_digit)1 << DIGIT_BIT) - 1;
36920             s = DIGIT_BIT - s;
36921             r->dp[++j] = (mp_digit)(a[i] >> s);
36922             while (s + DIGIT_BIT <= 57) {
36923                 s += DIGIT_BIT;
36924                 r->dp[j++] &= ((sp_digit)1 << DIGIT_BIT) - 1;
36925                 if (s == SP_WORD_SIZE) {
36926                     r->dp[j] = 0;
36927                 }
36928                 else {
36929                     r->dp[j] = (mp_digit)(a[i] >> s);
36930                 }
36931             }
36932             s = 57 - s;
36933         }
36934         r->used = (1024 + DIGIT_BIT - 1) / DIGIT_BIT;
36935         mp_clamp(r);
36936 #else
36937         int i;
36938         int j = 0;
36939         int s = 0;
36940 
36941         r->dp[0] = 0;
36942         for (i = 0; i < 18; i++) {
36943             r->dp[j] |= ((mp_digit)a[i]) << s;
36944             if (s + 57 >= DIGIT_BIT) {
36945     #if DIGIT_BIT != 32 && DIGIT_BIT != 64
36946                 r->dp[j] &= ((sp_digit)1 << DIGIT_BIT) - 1;
36947     #endif
36948                 s = DIGIT_BIT - s;
36949                 r->dp[++j] = a[i] >> s;
36950                 s = 57 - s;
36951             }
36952             else {
36953                 s += 57;
36954             }
36955         }
36956         r->used = (1024 + DIGIT_BIT - 1) / DIGIT_BIT;
36957         mp_clamp(r);
36958 #endif
36959     }
36960 
36961     return err;
36962 }
36963 
36964 /* Convert a point of type sp_point_1024 to type ecc_point.
36965  *
36966  * p   Point of type sp_point_1024.
36967  * pm  Point of type ecc_point (result).
36968  * returns MEMORY_E when allocation of memory in ecc_point fails otherwise
36969  * MP_OKAY.
36970  */
sp_1024_point_to_ecc_point_18(const sp_point_1024 * p,ecc_point * pm)36971 static int sp_1024_point_to_ecc_point_18(const sp_point_1024* p, ecc_point* pm)
36972 {
36973     int err;
36974 
36975     err = sp_1024_to_mp(p->x, pm->x);
36976     if (err == MP_OKAY) {
36977         err = sp_1024_to_mp(p->y, pm->y);
36978     }
36979     if (err == MP_OKAY) {
36980         err = sp_1024_to_mp(p->z, pm->z);
36981     }
36982 
36983     return err;
36984 }
36985 
36986 /* Compare a with b in constant time.
36987  *
36988  * a  A single precision integer.
36989  * b  A single precision integer.
36990  * return -ve, 0 or +ve if a is less than, equal to or greater than b
36991  * respectively.
36992  */
sp_1024_cmp_18(const sp_digit * a,const sp_digit * b)36993 static sp_digit sp_1024_cmp_18(const sp_digit* a, const sp_digit* b)
36994 {
36995     sp_digit r = 0;
36996 #ifdef WOLFSSL_SP_SMALL
36997     int i;
36998 
36999     for (i=17; i>=0; i--) {
37000         r |= (a[i] - b[i]) & (0 - (sp_digit)((r == 0) ? 1 : 0));
37001     }
37002 #else
37003     int i;
37004 
37005     r |= (a[17] - b[17]) & (0 - (sp_digit)1);
37006     r |= (a[16] - b[16]) & (0 - (sp_digit)((r == 0) ? 1 : 0));
37007     for (i = 8; i >= 0; i -= 8) {
37008         r |= (a[i + 7] - b[i + 7]) & (0 - (sp_digit)((r == 0) ? 1 : 0));
37009         r |= (a[i + 6] - b[i + 6]) & (0 - (sp_digit)((r == 0) ? 1 : 0));
37010         r |= (a[i + 5] - b[i + 5]) & (0 - (sp_digit)((r == 0) ? 1 : 0));
37011         r |= (a[i + 4] - b[i + 4]) & (0 - (sp_digit)((r == 0) ? 1 : 0));
37012         r |= (a[i + 3] - b[i + 3]) & (0 - (sp_digit)((r == 0) ? 1 : 0));
37013         r |= (a[i + 2] - b[i + 2]) & (0 - (sp_digit)((r == 0) ? 1 : 0));
37014         r |= (a[i + 1] - b[i + 1]) & (0 - (sp_digit)((r == 0) ? 1 : 0));
37015         r |= (a[i + 0] - b[i + 0]) & (0 - (sp_digit)((r == 0) ? 1 : 0));
37016     }
37017 #endif /* WOLFSSL_SP_SMALL */
37018 
37019     return r;
37020 }
37021 
37022 /* Conditionally subtract b from a using the mask m.
37023  * m is -1 to subtract and 0 when not.
37024  *
37025  * r  A single precision number representing condition subtract result.
37026  * a  A single precision number to subtract from.
37027  * b  A single precision number to subtract.
37028  * m  Mask value to apply.
37029  */
sp_1024_cond_sub_18(sp_digit * r,const sp_digit * a,const sp_digit * b,const sp_digit m)37030 static void sp_1024_cond_sub_18(sp_digit* r, const sp_digit* a,
37031         const sp_digit* b, const sp_digit m)
37032 {
37033 #ifdef WOLFSSL_SP_SMALL
37034     int i;
37035 
37036     for (i = 0; i < 18; i++) {
37037         r[i] = a[i] - (b[i] & m);
37038     }
37039 #else
37040     int i;
37041 
37042     for (i = 0; i < 16; i += 8) {
37043         r[i + 0] = a[i + 0] - (b[i + 0] & m);
37044         r[i + 1] = a[i + 1] - (b[i + 1] & m);
37045         r[i + 2] = a[i + 2] - (b[i + 2] & m);
37046         r[i + 3] = a[i + 3] - (b[i + 3] & m);
37047         r[i + 4] = a[i + 4] - (b[i + 4] & m);
37048         r[i + 5] = a[i + 5] - (b[i + 5] & m);
37049         r[i + 6] = a[i + 6] - (b[i + 6] & m);
37050         r[i + 7] = a[i + 7] - (b[i + 7] & m);
37051     }
37052     r[16] = a[16] - (b[16] & m);
37053     r[17] = a[17] - (b[17] & m);
37054 #endif /* WOLFSSL_SP_SMALL */
37055 }
37056 
37057 /* Mul a by scalar b and add into r. (r += a * b)
37058  *
37059  * r  A single precision integer.
37060  * a  A single precision integer.
37061  * b  A scalar.
37062  */
sp_1024_mul_add_18(sp_digit * r,const sp_digit * a,const sp_digit b)37063 SP_NOINLINE static void sp_1024_mul_add_18(sp_digit* r, const sp_digit* a,
37064         const sp_digit b)
37065 {
37066 #ifdef WOLFSSL_SP_SMALL
37067     sp_int128 tb = b;
37068     sp_int128 t[4];
37069     int i;
37070 
37071     t[0] = 0;
37072     for (i = 0; i < 16; i += 4) {
37073         t[0] += (tb * a[i+0]) + r[i+0];
37074         t[1]  = (tb * a[i+1]) + r[i+1];
37075         t[2]  = (tb * a[i+2]) + r[i+2];
37076         t[3]  = (tb * a[i+3]) + r[i+3];
37077         r[i+0] = t[0] & 0x1ffffffffffffffL;
37078         t[1] += t[0] >> 57;
37079         r[i+1] = t[1] & 0x1ffffffffffffffL;
37080         t[2] += t[1] >> 57;
37081         r[i+2] = t[2] & 0x1ffffffffffffffL;
37082         t[3] += t[2] >> 57;
37083         r[i+3] = t[3] & 0x1ffffffffffffffL;
37084         t[0]  = t[3] >> 57;
37085     }
37086     t[0] += (tb * a[16]) + r[16];
37087     t[1]  = (tb * a[17]) + r[17];
37088     r[16] = t[0] & 0x1ffffffffffffffL;
37089     t[1] += t[0] >> 57;
37090     r[17] = t[1] & 0x1ffffffffffffffL;
37091     r[18] +=  (sp_digit)(t[1] >> 57);
37092 #else
37093     sp_int128 tb = b;
37094     sp_int128 t[8];
37095     int i;
37096 
37097     t[0] = tb * a[0]; r[0] += (sp_digit)(t[0] & 0x1ffffffffffffffL);
37098     for (i = 0; i < 16; i += 8) {
37099         t[1] = tb * a[i+1];
37100         r[i+1] += (sp_digit)((t[0] >> 57) + (t[1] & 0x1ffffffffffffffL));
37101         t[2] = tb * a[i+2];
37102         r[i+2] += (sp_digit)((t[1] >> 57) + (t[2] & 0x1ffffffffffffffL));
37103         t[3] = tb * a[i+3];
37104         r[i+3] += (sp_digit)((t[2] >> 57) + (t[3] & 0x1ffffffffffffffL));
37105         t[4] = tb * a[i+4];
37106         r[i+4] += (sp_digit)((t[3] >> 57) + (t[4] & 0x1ffffffffffffffL));
37107         t[5] = tb * a[i+5];
37108         r[i+5] += (sp_digit)((t[4] >> 57) + (t[5] & 0x1ffffffffffffffL));
37109         t[6] = tb * a[i+6];
37110         r[i+6] += (sp_digit)((t[5] >> 57) + (t[6] & 0x1ffffffffffffffL));
37111         t[7] = tb * a[i+7];
37112         r[i+7] += (sp_digit)((t[6] >> 57) + (t[7] & 0x1ffffffffffffffL));
37113         t[0] = tb * a[i+8];
37114         r[i+8] += (sp_digit)((t[7] >> 57) + (t[0] & 0x1ffffffffffffffL));
37115     }
37116     t[1] = tb * a[17];
37117     r[17] += (sp_digit)((t[0] >> 57) + (t[1] & 0x1ffffffffffffffL));
37118     r[18] +=  (sp_digit)(t[1] >> 57);
37119 #endif /* WOLFSSL_SP_SMALL */
37120 }
37121 
37122 /* Shift the result in the high 1024 bits down to the bottom.
37123  *
37124  * r  A single precision number.
37125  * a  A single precision number.
37126  */
sp_1024_mont_shift_18(sp_digit * r,const sp_digit * a)37127 static void sp_1024_mont_shift_18(sp_digit* r, const sp_digit* a)
37128 {
37129 #ifdef WOLFSSL_SP_SMALL
37130     int i;
37131     sp_uint64 n;
37132 
37133     n = a[17] >> 55;
37134     for (i = 0; i < 17; i++) {
37135         n += (sp_uint64)a[18 + i] << 2;
37136         r[i] = n & 0x1ffffffffffffffL;
37137         n >>= 57;
37138     }
37139     n += (sp_uint64)a[35] << 2;
37140     r[17] = n;
37141 #else
37142     sp_uint64 n;
37143     int i;
37144 
37145     n  = (sp_uint64)a[17];
37146     n  = n >> 55U;
37147     for (i = 0; i < 16; i += 8) {
37148         n += (sp_uint64)a[i+18] << 2U; r[i+0] = n & 0x1ffffffffffffffUL; n >>= 57U;
37149         n += (sp_uint64)a[i+19] << 2U; r[i+1] = n & 0x1ffffffffffffffUL; n >>= 57U;
37150         n += (sp_uint64)a[i+20] << 2U; r[i+2] = n & 0x1ffffffffffffffUL; n >>= 57U;
37151         n += (sp_uint64)a[i+21] << 2U; r[i+3] = n & 0x1ffffffffffffffUL; n >>= 57U;
37152         n += (sp_uint64)a[i+22] << 2U; r[i+4] = n & 0x1ffffffffffffffUL; n >>= 57U;
37153         n += (sp_uint64)a[i+23] << 2U; r[i+5] = n & 0x1ffffffffffffffUL; n >>= 57U;
37154         n += (sp_uint64)a[i+24] << 2U; r[i+6] = n & 0x1ffffffffffffffUL; n >>= 57U;
37155         n += (sp_uint64)a[i+25] << 2U; r[i+7] = n & 0x1ffffffffffffffUL; n >>= 57U;
37156     }
37157     n += (sp_uint64)a[34] << 2U; r[16] = n & 0x1ffffffffffffffUL; n >>= 57U;
37158     n += (sp_uint64)a[35] << 2U; r[17] = n;
37159 #endif /* WOLFSSL_SP_SMALL */
37160     XMEMSET(&r[18], 0, sizeof(*r) * 18U);
37161 }
37162 
37163 /* Reduce the number back to 1024 bits using Montgomery reduction.
37164  *
37165  * a   A single precision number to reduce in place.
37166  * m   The single precision number representing the modulus.
37167  * mp  The digit representing the negative inverse of m mod 2^n.
37168  */
sp_1024_mont_reduce_18(sp_digit * a,const sp_digit * m,sp_digit mp)37169 static void sp_1024_mont_reduce_18(sp_digit* a, const sp_digit* m, sp_digit mp)
37170 {
37171     int i;
37172     sp_digit mu;
37173 
37174     sp_1024_norm_18(a + 18);
37175 
37176 #ifdef WOLFSSL_SP_DH
37177     if (mp != 1) {
37178         for (i=0; i<17; i++) {
37179             mu = (a[i] * mp) & 0x1ffffffffffffffL;
37180             sp_1024_mul_add_18(a+i, m, mu);
37181             a[i+1] += a[i] >> 57;
37182         }
37183         mu = (a[i] * mp) & 0x7fffffffffffffL;
37184         sp_1024_mul_add_18(a+i, m, mu);
37185         a[i+1] += a[i] >> 57;
37186         a[i] &= 0x1ffffffffffffffL;
37187     }
37188     else {
37189         for (i=0; i<17; i++) {
37190             mu = a[i] & 0x1ffffffffffffffL;
37191             sp_1024_mul_add_18(a+i, m, mu);
37192             a[i+1] += a[i] >> 57;
37193         }
37194         mu = a[i] & 0x7fffffffffffffL;
37195         sp_1024_mul_add_18(a+i, m, mu);
37196         a[i+1] += a[i] >> 57;
37197         a[i] &= 0x1ffffffffffffffL;
37198     }
37199 #else
37200     for (i=0; i<17; i++) {
37201         mu = (a[i] * mp) & 0x1ffffffffffffffL;
37202         sp_1024_mul_add_18(a+i, m, mu);
37203         a[i+1] += a[i] >> 57;
37204     }
37205     mu = (a[i] * mp) & 0x7fffffffffffffL;
37206     sp_1024_mul_add_18(a+i, m, mu);
37207     a[i+1] += a[i] >> 57;
37208     a[i] &= 0x1ffffffffffffffL;
37209 #endif
37210     sp_1024_mont_shift_18(a, a);
37211     sp_1024_cond_sub_18(a, a, m, 0 - (((a[17] - m[17]) > 0) ?
37212             (sp_digit)1 : (sp_digit)0));
37213     sp_1024_norm_18(a);
37214 }
37215 
37216 /* Multiply two Montgomery form numbers mod the modulus (prime).
37217  * (r = a * b mod m)
37218  *
37219  * r   Result of multiplication.
37220  * a   First number to multiply in Montgomery form.
37221  * b   Second number to multiply in Montgomery form.
37222  * m   Modulus (prime).
37223  * mp  Montgomery mulitplier.
37224  */
sp_1024_mont_mul_18(sp_digit * r,const sp_digit * a,const sp_digit * b,const sp_digit * m,sp_digit mp)37225 static void sp_1024_mont_mul_18(sp_digit* r, const sp_digit* a,
37226         const sp_digit* b, const sp_digit* m, sp_digit mp)
37227 {
37228     sp_1024_mul_18(r, a, b);
37229     sp_1024_mont_reduce_18(r, m, mp);
37230 }
37231 
37232 /* Square the Montgomery form number. (r = a * a mod m)
37233  *
37234  * r   Result of squaring.
37235  * a   Number to square in Montgomery form.
37236  * m   Modulus (prime).
37237  * mp  Montgomery mulitplier.
37238  */
sp_1024_mont_sqr_18(sp_digit * r,const sp_digit * a,const sp_digit * m,sp_digit mp)37239 static void sp_1024_mont_sqr_18(sp_digit* r, const sp_digit* a,
37240         const sp_digit* m, sp_digit mp)
37241 {
37242     sp_1024_sqr_18(r, a);
37243     sp_1024_mont_reduce_18(r, m, mp);
37244 }
37245 
37246 /* Mod-2 for the P1024 curve. */
37247 static const uint8_t p1024_mod_minus_2[] = {
37248      6,0x06,  7,0x0f,  7,0x0b,  6,0x0c,  7,0x1e,  9,0x09,  7,0x0c,  7,0x1f,
37249      6,0x16,  6,0x06,  7,0x0e,  8,0x10,  6,0x03,  8,0x11,  6,0x0d,  7,0x14,
37250      9,0x12,  6,0x0f,  7,0x04,  9,0x0d,  6,0x00,  7,0x13,  6,0x01,  6,0x07,
37251      8,0x0d,  8,0x00,  6,0x06,  9,0x17,  6,0x14,  6,0x15,  6,0x11,  6,0x0b,
37252      9,0x0c,  6,0x1e, 13,0x14,  7,0x0e,  6,0x1d, 12,0x0a,  6,0x0b,  8,0x07,
37253      6,0x18,  6,0x0f,  6,0x10,  8,0x1c,  7,0x16,  7,0x02,  6,0x01,  6,0x13,
37254     10,0x15,  7,0x06,  8,0x14,  6,0x0c,  6,0x19,  7,0x10,  6,0x19,  6,0x19,
37255      9,0x16,  7,0x19,  6,0x1f,  6,0x17,  6,0x12,  8,0x02,  6,0x01,  6,0x04,
37256      6,0x15,  7,0x16,  6,0x04,  6,0x1f,  6,0x09,  7,0x06,  7,0x13,  7,0x09,
37257      6,0x0d, 10,0x18,  6,0x06,  6,0x11,  6,0x04,  6,0x01,  6,0x13,  8,0x06,
37258      6,0x0d,  8,0x13,  7,0x08,  6,0x08,  6,0x05,  7,0x0c,  7,0x0e,  7,0x15,
37259      6,0x05,  7,0x14, 10,0x19,  6,0x10,  6,0x16,  6,0x15,  7,0x1f,  6,0x14,
37260      6,0x0a, 10,0x11,  6,0x01,  7,0x05,  7,0x08,  8,0x0a,  7,0x1e,  7,0x1c,
37261      6,0x1c,  7,0x09, 10,0x18,  7,0x1c, 10,0x06,  6,0x0a,  6,0x07,  6,0x19,
37262      7,0x06,  6,0x0d,  7,0x0f,  7,0x0b,  7,0x05,  6,0x11,  6,0x1c,  7,0x1f,
37263      6,0x1e,  7,0x18,  6,0x1e,  6,0x00,  6,0x03,  6,0x02,  7,0x10,  6,0x0b,
37264      6,0x1b,  7,0x10,  6,0x00,  8,0x11,  7,0x1b,  6,0x18,  6,0x01,  7,0x0c,
37265      7,0x1d,  7,0x13,  6,0x08,  7,0x1b,  8,0x13,  7,0x16, 13,0x1d,  7,0x1f,
37266      6,0x0a,  6,0x01,  7,0x1f,  6,0x14,  1,0x01
37267 };
37268 
37269 /* Invert the number, in Montgomery form, modulo the modulus (prime) of the
37270  * P1024 curve. (r = 1 / a mod m)
37271  *
37272  * r   Inverse result.
37273  * a   Number to invert.
37274  * td  Temporary data.
37275  */
sp_1024_mont_inv_18(sp_digit * r,const sp_digit * a,sp_digit * td)37276 static void sp_1024_mont_inv_18(sp_digit* r, const sp_digit* a,
37277         sp_digit* td)
37278 {
37279     sp_digit* t = td;
37280     int i;
37281     int j;
37282     sp_digit table[32][2 * 18];
37283 
37284     XMEMCPY(table[0], a, sizeof(sp_digit) * 18);
37285     for (i = 1; i < 6; i++) {
37286         sp_1024_mont_sqr_18(table[0], table[0], p1024_mod, p1024_mp_mod);
37287     }
37288     for (i = 1; i < 32; i++) {
37289         sp_1024_mont_mul_18(table[i], table[i-1], a, p1024_mod, p1024_mp_mod);
37290     }
37291 
37292     XMEMCPY(t, table[p1024_mod_minus_2[1]], sizeof(sp_digit) * 18);
37293     for (i = 2; i < (int)sizeof(p1024_mod_minus_2) - 2; i += 2) {
37294         for (j = 0; j < p1024_mod_minus_2[i]; j++) {
37295             sp_1024_mont_sqr_18(t, t, p1024_mod, p1024_mp_mod);
37296         }
37297         sp_1024_mont_mul_18(t, t, table[p1024_mod_minus_2[i+1]], p1024_mod,
37298             p1024_mp_mod);
37299     }
37300     sp_1024_mont_sqr_18(t, t, p1024_mod, p1024_mp_mod);
37301     sp_1024_mont_mul_18(r, t, a, p1024_mod, p1024_mp_mod);
37302 }
37303 
37304 /* Map the Montgomery form projective coordinate point to an affine point.
37305  *
37306  * r  Resulting affine coordinate point.
37307  * p  Montgomery form projective coordinate point.
37308  * t  Temporary ordinate data.
37309  */
sp_1024_map_18(sp_point_1024 * r,const sp_point_1024 * p,sp_digit * t)37310 static void sp_1024_map_18(sp_point_1024* r, const sp_point_1024* p,
37311     sp_digit* t)
37312 {
37313     sp_digit* t1 = t;
37314     sp_digit* t2 = t + 2*18;
37315     sp_int64 n;
37316 
37317     sp_1024_mont_inv_18(t1, p->z, t + 2*18);
37318 
37319     sp_1024_mont_sqr_18(t2, t1, p1024_mod, p1024_mp_mod);
37320     sp_1024_mont_mul_18(t1, t2, t1, p1024_mod, p1024_mp_mod);
37321 
37322     /* x /= z^2 */
37323     sp_1024_mont_mul_18(r->x, p->x, t2, p1024_mod, p1024_mp_mod);
37324     XMEMSET(r->x + 18, 0, sizeof(r->x) / 2U);
37325     sp_1024_mont_reduce_18(r->x, p1024_mod, p1024_mp_mod);
37326     /* Reduce x to less than modulus */
37327     n = sp_1024_cmp_18(r->x, p1024_mod);
37328     sp_1024_cond_sub_18(r->x, r->x, p1024_mod, 0 - ((n >= 0) ?
37329                 (sp_digit)1 : (sp_digit)0));
37330     sp_1024_norm_18(r->x);
37331 
37332     /* y /= z^3 */
37333     sp_1024_mont_mul_18(r->y, p->y, t1, p1024_mod, p1024_mp_mod);
37334     XMEMSET(r->y + 18, 0, sizeof(r->y) / 2U);
37335     sp_1024_mont_reduce_18(r->y, p1024_mod, p1024_mp_mod);
37336     /* Reduce y to less than modulus */
37337     n = sp_1024_cmp_18(r->y, p1024_mod);
37338     sp_1024_cond_sub_18(r->y, r->y, p1024_mod, 0 - ((n >= 0) ?
37339                 (sp_digit)1 : (sp_digit)0));
37340     sp_1024_norm_18(r->y);
37341 
37342     XMEMSET(r->z, 0, sizeof(r->z));
37343     r->z[0] = 1;
37344 
37345 }
37346 
37347 /* Add two Montgomery form numbers (r = a + b % m).
37348  *
37349  * r   Result of addition.
37350  * a   First number to add in Montgomery form.
37351  * b   Second number to add in Montgomery form.
37352  * m   Modulus (prime).
37353  */
sp_1024_mont_add_18(sp_digit * r,const sp_digit * a,const sp_digit * b,const sp_digit * m)37354 static void sp_1024_mont_add_18(sp_digit* r, const sp_digit* a, const sp_digit* b,
37355         const sp_digit* m)
37356 {
37357     (void)sp_1024_add_18(r, a, b);
37358     sp_1024_norm_18(r);
37359     sp_1024_cond_sub_18(r, r, m, 0 - (((r[17] - m[17]) > 0) ?
37360                 (sp_digit)1 : (sp_digit)0));
37361     sp_1024_norm_18(r);
37362 }
37363 
37364 /* Double a Montgomery form number (r = a + a % m).
37365  *
37366  * r   Result of doubling.
37367  * a   Number to double in Montgomery form.
37368  * m   Modulus (prime).
37369  */
sp_1024_mont_dbl_18(sp_digit * r,const sp_digit * a,const sp_digit * m)37370 static void sp_1024_mont_dbl_18(sp_digit* r, const sp_digit* a, const sp_digit* m)
37371 {
37372     (void)sp_1024_add_18(r, a, a);
37373     sp_1024_norm_18(r);
37374     sp_1024_cond_sub_18(r, r, m, 0 - (((r[17] - m[17]) > 0) ?
37375                 (sp_digit)1 : (sp_digit)0));
37376     sp_1024_norm_18(r);
37377 }
37378 
37379 /* Triple a Montgomery form number (r = a + a + a % m).
37380  *
37381  * r   Result of Tripling.
37382  * a   Number to triple in Montgomery form.
37383  * m   Modulus (prime).
37384  */
sp_1024_mont_tpl_18(sp_digit * r,const sp_digit * a,const sp_digit * m)37385 static void sp_1024_mont_tpl_18(sp_digit* r, const sp_digit* a, const sp_digit* m)
37386 {
37387     (void)sp_1024_add_18(r, a, a);
37388     sp_1024_norm_18(r);
37389     sp_1024_cond_sub_18(r, r, m, 0 - (((r[17] - m[17]) > 0) ?
37390                 (sp_digit)1 : (sp_digit)0));
37391     sp_1024_norm_18(r);
37392     (void)sp_1024_add_18(r, r, a);
37393     sp_1024_norm_18(r);
37394     sp_1024_cond_sub_18(r, r, m, 0 - (((r[17] - m[17]) > 0) ?
37395                 (sp_digit)1 : (sp_digit)0));
37396     sp_1024_norm_18(r);
37397 }
37398 
37399 /* Subtract two Montgomery form numbers (r = a - b % m).
37400  *
37401  * r   Result of subtration.
37402  * a   Number to subtract from in Montgomery form.
37403  * b   Number to subtract with in Montgomery form.
37404  * m   Modulus (prime).
37405  */
sp_1024_mont_sub_18(sp_digit * r,const sp_digit * a,const sp_digit * b,const sp_digit * m)37406 static void sp_1024_mont_sub_18(sp_digit* r, const sp_digit* a, const sp_digit* b,
37407         const sp_digit* m)
37408 {
37409     (void)sp_1024_sub_18(r, a, b);
37410     sp_1024_norm_18(r);
37411     sp_1024_cond_add_18(r, r, m, r[17] >> 55);
37412     sp_1024_norm_18(r);
37413 }
37414 
37415 /* Shift number left one bit.
37416  * Bottom bit is lost.
37417  *
37418  * r  Result of shift.
37419  * a  Number to shift.
37420  */
sp_1024_rshift1_18(sp_digit * r,const sp_digit * a)37421 SP_NOINLINE static void sp_1024_rshift1_18(sp_digit* r, const sp_digit* a)
37422 {
37423 #ifdef WOLFSSL_SP_SMALL
37424     int i;
37425 
37426     for (i=0; i<17; i++) {
37427         r[i] = (a[i] >> 1) + ((a[i + 1] << 56) & 0x1ffffffffffffffL);
37428     }
37429 #else
37430     r[0] = (a[0] >> 1) + ((a[1] << 56) & 0x1ffffffffffffffL);
37431     r[1] = (a[1] >> 1) + ((a[2] << 56) & 0x1ffffffffffffffL);
37432     r[2] = (a[2] >> 1) + ((a[3] << 56) & 0x1ffffffffffffffL);
37433     r[3] = (a[3] >> 1) + ((a[4] << 56) & 0x1ffffffffffffffL);
37434     r[4] = (a[4] >> 1) + ((a[5] << 56) & 0x1ffffffffffffffL);
37435     r[5] = (a[5] >> 1) + ((a[6] << 56) & 0x1ffffffffffffffL);
37436     r[6] = (a[6] >> 1) + ((a[7] << 56) & 0x1ffffffffffffffL);
37437     r[7] = (a[7] >> 1) + ((a[8] << 56) & 0x1ffffffffffffffL);
37438     r[8] = (a[8] >> 1) + ((a[9] << 56) & 0x1ffffffffffffffL);
37439     r[9] = (a[9] >> 1) + ((a[10] << 56) & 0x1ffffffffffffffL);
37440     r[10] = (a[10] >> 1) + ((a[11] << 56) & 0x1ffffffffffffffL);
37441     r[11] = (a[11] >> 1) + ((a[12] << 56) & 0x1ffffffffffffffL);
37442     r[12] = (a[12] >> 1) + ((a[13] << 56) & 0x1ffffffffffffffL);
37443     r[13] = (a[13] >> 1) + ((a[14] << 56) & 0x1ffffffffffffffL);
37444     r[14] = (a[14] >> 1) + ((a[15] << 56) & 0x1ffffffffffffffL);
37445     r[15] = (a[15] >> 1) + ((a[16] << 56) & 0x1ffffffffffffffL);
37446     r[16] = (a[16] >> 1) + ((a[17] << 56) & 0x1ffffffffffffffL);
37447 #endif
37448     r[17] = a[17] >> 1;
37449 }
37450 
37451 /* Divide the number by 2 mod the modulus (prime). (r = a / 2 % m)
37452  *
37453  * r  Result of division by 2.
37454  * a  Number to divide.
37455  * m  Modulus (prime).
37456  */
sp_1024_div2_18(sp_digit * r,const sp_digit * a,const sp_digit * m)37457 static void sp_1024_div2_18(sp_digit* r, const sp_digit* a, const sp_digit* m)
37458 {
37459     sp_1024_cond_add_18(r, a, m, 0 - (a[0] & 1));
37460     sp_1024_norm_18(r);
37461     sp_1024_rshift1_18(r, r);
37462 }
37463 
37464 /* Double the Montgomery form projective point p.
37465  *
37466  * r  Result of doubling point.
37467  * p  Point to double.
37468  * t  Temporary ordinate data.
37469  */
37470 #ifdef WOLFSSL_SP_NONBLOCK
37471 typedef struct sp_1024_proj_point_dbl_18_ctx {
37472     int state;
37473     sp_digit* t1;
37474     sp_digit* t2;
37475     sp_digit* x;
37476     sp_digit* y;
37477     sp_digit* z;
37478 } sp_1024_proj_point_dbl_18_ctx;
37479 
sp_1024_proj_point_dbl_18_nb(sp_ecc_ctx_t * sp_ctx,sp_point_1024 * r,const sp_point_1024 * p,sp_digit * t)37480 static int sp_1024_proj_point_dbl_18_nb(sp_ecc_ctx_t* sp_ctx, sp_point_1024* r, const sp_point_1024* p, sp_digit* t)
37481 {
37482     int err = FP_WOULDBLOCK;
37483     sp_1024_proj_point_dbl_18_ctx* ctx = (sp_1024_proj_point_dbl_18_ctx*)sp_ctx->data;
37484 
37485     typedef char ctx_size_test[sizeof(sp_1024_proj_point_dbl_18_ctx) >= sizeof(*sp_ctx) ? -1 : 1];
37486     (void)sizeof(ctx_size_test);
37487 
37488     switch (ctx->state) {
37489     case 0:
37490         ctx->t1 = t;
37491         ctx->t2 = t + 2*18;
37492         ctx->x = r->x;
37493         ctx->y = r->y;
37494         ctx->z = r->z;
37495 
37496         /* Put infinity into result. */
37497         if (r != p) {
37498             r->infinity = p->infinity;
37499         }
37500         ctx->state = 1;
37501         break;
37502     case 1:
37503         /* T1 = Z * Z */
37504         sp_1024_mont_sqr_18(ctx->t1, p->z, p1024_mod, p1024_mp_mod);
37505         ctx->state = 2;
37506         break;
37507     case 2:
37508         /* Z = Y * Z */
37509         sp_1024_mont_mul_18(ctx->z, p->y, p->z, p1024_mod, p1024_mp_mod);
37510         ctx->state = 3;
37511         break;
37512     case 3:
37513         /* Z = 2Z */
37514         sp_1024_mont_dbl_18(ctx->z, ctx->z, p1024_mod);
37515         ctx->state = 4;
37516         break;
37517     case 4:
37518         /* T2 = X - T1 */
37519         sp_1024_mont_sub_18(ctx->t2, p->x, ctx->t1, p1024_mod);
37520         ctx->state = 5;
37521         break;
37522     case 5:
37523         /* T1 = X + T1 */
37524         sp_1024_mont_add_18(ctx->t1, p->x, ctx->t1, p1024_mod);
37525         ctx->state = 6;
37526         break;
37527     case 6:
37528         /* T2 = T1 * T2 */
37529         sp_1024_mont_mul_18(ctx->t2, ctx->t1, ctx->t2, p1024_mod, p1024_mp_mod);
37530         ctx->state = 7;
37531         break;
37532     case 7:
37533         /* T1 = 3T2 */
37534         sp_1024_mont_tpl_18(ctx->t1, ctx->t2, p1024_mod);
37535         ctx->state = 8;
37536         break;
37537     case 8:
37538         /* Y = 2Y */
37539         sp_1024_mont_dbl_18(ctx->y, p->y, p1024_mod);
37540         ctx->state = 9;
37541         break;
37542     case 9:
37543         /* Y = Y * Y */
37544         sp_1024_mont_sqr_18(ctx->y, ctx->y, p1024_mod, p1024_mp_mod);
37545         ctx->state = 10;
37546         break;
37547     case 10:
37548         /* T2 = Y * Y */
37549         sp_1024_mont_sqr_18(ctx->t2, ctx->y, p1024_mod, p1024_mp_mod);
37550         ctx->state = 11;
37551         break;
37552     case 11:
37553         /* T2 = T2/2 */
37554         sp_1024_div2_18(ctx->t2, ctx->t2, p1024_mod);
37555         ctx->state = 12;
37556         break;
37557     case 12:
37558         /* Y = Y * X */
37559         sp_1024_mont_mul_18(ctx->y, ctx->y, p->x, p1024_mod, p1024_mp_mod);
37560         ctx->state = 13;
37561         break;
37562     case 13:
37563         /* X = T1 * T1 */
37564         sp_1024_mont_sqr_18(ctx->x, ctx->t1, p1024_mod, p1024_mp_mod);
37565         ctx->state = 14;
37566         break;
37567     case 14:
37568         /* X = X - Y */
37569         sp_1024_mont_sub_18(ctx->x, ctx->x, ctx->y, p1024_mod);
37570         ctx->state = 15;
37571         break;
37572     case 15:
37573         /* X = X - Y */
37574         sp_1024_mont_sub_18(ctx->x, ctx->x, ctx->y, p1024_mod);
37575         ctx->state = 16;
37576         break;
37577     case 16:
37578         /* Y = Y - X */
37579         sp_1024_mont_sub_18(ctx->y, ctx->y, ctx->x, p1024_mod);
37580         ctx->state = 17;
37581         break;
37582     case 17:
37583         /* Y = Y * T1 */
37584         sp_1024_mont_mul_18(ctx->y, ctx->y, ctx->t1, p1024_mod, p1024_mp_mod);
37585         ctx->state = 18;
37586         break;
37587     case 18:
37588         /* Y = Y - T2 */
37589         sp_1024_mont_sub_18(ctx->y, ctx->y, ctx->t2, p1024_mod);
37590         ctx->state = 19;
37591         /* fall-through */
37592     case 19:
37593         err = MP_OKAY;
37594         break;
37595     }
37596 
37597     if (err == MP_OKAY && ctx->state != 19) {
37598         err = FP_WOULDBLOCK;
37599     }
37600 
37601     return err;
37602 }
37603 #endif /* WOLFSSL_SP_NONBLOCK */
37604 
sp_1024_proj_point_dbl_18(sp_point_1024 * r,const sp_point_1024 * p,sp_digit * t)37605 static void sp_1024_proj_point_dbl_18(sp_point_1024* r, const sp_point_1024* p, sp_digit* t)
37606 {
37607     sp_digit* t1 = t;
37608     sp_digit* t2 = t + 2*18;
37609     sp_digit* x;
37610     sp_digit* y;
37611     sp_digit* z;
37612 
37613     x = r->x;
37614     y = r->y;
37615     z = r->z;
37616     /* Put infinity into result. */
37617     if (r != p) {
37618         r->infinity = p->infinity;
37619     }
37620 
37621     /* T1 = Z * Z */
37622     sp_1024_mont_sqr_18(t1, p->z, p1024_mod, p1024_mp_mod);
37623     /* Z = Y * Z */
37624     sp_1024_mont_mul_18(z, p->y, p->z, p1024_mod, p1024_mp_mod);
37625     /* Z = 2Z */
37626     sp_1024_mont_dbl_18(z, z, p1024_mod);
37627     /* T2 = X - T1 */
37628     sp_1024_mont_sub_18(t2, p->x, t1, p1024_mod);
37629     /* T1 = X + T1 */
37630     sp_1024_mont_add_18(t1, p->x, t1, p1024_mod);
37631     /* T2 = T1 * T2 */
37632     sp_1024_mont_mul_18(t2, t1, t2, p1024_mod, p1024_mp_mod);
37633     /* T1 = 3T2 */
37634     sp_1024_mont_tpl_18(t1, t2, p1024_mod);
37635     /* Y = 2Y */
37636     sp_1024_mont_dbl_18(y, p->y, p1024_mod);
37637     /* Y = Y * Y */
37638     sp_1024_mont_sqr_18(y, y, p1024_mod, p1024_mp_mod);
37639     /* T2 = Y * Y */
37640     sp_1024_mont_sqr_18(t2, y, p1024_mod, p1024_mp_mod);
37641     /* T2 = T2/2 */
37642     sp_1024_div2_18(t2, t2, p1024_mod);
37643     /* Y = Y * X */
37644     sp_1024_mont_mul_18(y, y, p->x, p1024_mod, p1024_mp_mod);
37645     /* X = T1 * T1 */
37646     sp_1024_mont_sqr_18(x, t1, p1024_mod, p1024_mp_mod);
37647     /* X = X - Y */
37648     sp_1024_mont_sub_18(x, x, y, p1024_mod);
37649     /* X = X - Y */
37650     sp_1024_mont_sub_18(x, x, y, p1024_mod);
37651     /* Y = Y - X */
37652     sp_1024_mont_sub_18(y, y, x, p1024_mod);
37653     /* Y = Y * T1 */
37654     sp_1024_mont_mul_18(y, y, t1, p1024_mod, p1024_mp_mod);
37655     /* Y = Y - T2 */
37656     sp_1024_mont_sub_18(y, y, t2, p1024_mod);
37657 }
37658 
37659 /* Compare two numbers to determine if they are equal.
37660  * Constant time implementation.
37661  *
37662  * a  First number to compare.
37663  * b  Second number to compare.
37664  * returns 1 when equal and 0 otherwise.
37665  */
sp_1024_cmp_equal_18(const sp_digit * a,const sp_digit * b)37666 static int sp_1024_cmp_equal_18(const sp_digit* a, const sp_digit* b)
37667 {
37668     return ((a[0] ^ b[0]) | (a[1] ^ b[1]) | (a[2] ^ b[2]) |
37669             (a[3] ^ b[3]) | (a[4] ^ b[4]) | (a[5] ^ b[5]) |
37670             (a[6] ^ b[6]) | (a[7] ^ b[7]) | (a[8] ^ b[8]) |
37671             (a[9] ^ b[9]) | (a[10] ^ b[10]) | (a[11] ^ b[11]) |
37672             (a[12] ^ b[12]) | (a[13] ^ b[13]) | (a[14] ^ b[14]) |
37673             (a[15] ^ b[15]) | (a[16] ^ b[16]) | (a[17] ^ b[17])) == 0;
37674 }
37675 
37676 /* Add two Montgomery form projective points.
37677  *
37678  * r  Result of addition.
37679  * p  First point to add.
37680  * q  Second point to add.
37681  * t  Temporary ordinate data.
37682  */
37683 
37684 #ifdef WOLFSSL_SP_NONBLOCK
37685 typedef struct sp_1024_proj_point_add_18_ctx {
37686     int state;
37687     sp_1024_proj_point_dbl_18_ctx dbl_ctx;
37688     const sp_point_1024* ap[2];
37689     sp_point_1024* rp[2];
37690     sp_digit* t1;
37691     sp_digit* t2;
37692     sp_digit* t3;
37693     sp_digit* t4;
37694     sp_digit* t5;
37695     sp_digit* x;
37696     sp_digit* y;
37697     sp_digit* z;
37698 } sp_1024_proj_point_add_18_ctx;
37699 
sp_1024_proj_point_add_18_nb(sp_ecc_ctx_t * sp_ctx,sp_point_1024 * r,const sp_point_1024 * p,const sp_point_1024 * q,sp_digit * t)37700 static int sp_1024_proj_point_add_18_nb(sp_ecc_ctx_t* sp_ctx, sp_point_1024* r,
37701     const sp_point_1024* p, const sp_point_1024* q, sp_digit* t)
37702 {
37703     int err = FP_WOULDBLOCK;
37704     sp_1024_proj_point_add_18_ctx* ctx = (sp_1024_proj_point_add_18_ctx*)sp_ctx->data;
37705 
37706     /* Ensure only the first point is the same as the result. */
37707     if (q == r) {
37708         const sp_point_1024* a = p;
37709         p = q;
37710         q = a;
37711     }
37712 
37713     typedef char ctx_size_test[sizeof(sp_1024_proj_point_add_18_ctx) >= sizeof(*sp_ctx) ? -1 : 1];
37714     (void)sizeof(ctx_size_test);
37715 
37716     switch (ctx->state) {
37717     case 0: /* INIT */
37718         ctx->t1 = t;
37719         ctx->t2 = t + 2*18;
37720         ctx->t3 = t + 4*18;
37721         ctx->t4 = t + 6*18;
37722         ctx->t5 = t + 8*18;
37723 
37724         ctx->state = 1;
37725         break;
37726     case 1:
37727         /* Check double */
37728         (void)sp_1024_sub_18(ctx->t1, p1024_mod, q->y);
37729         sp_1024_norm_18(ctx->t1);
37730         if ((sp_1024_cmp_equal_18(p->x, q->x) & sp_1024_cmp_equal_18(p->z, q->z) &
37731             (sp_1024_cmp_equal_18(p->y, q->y) | sp_1024_cmp_equal_18(p->y, ctx->t1))) != 0)
37732         {
37733             XMEMSET(&ctx->dbl_ctx, 0, sizeof(ctx->dbl_ctx));
37734             ctx->state = 2;
37735         }
37736         else {
37737             ctx->state = 3;
37738         }
37739         break;
37740     case 2:
37741         err = sp_1024_proj_point_dbl_18_nb((sp_ecc_ctx_t*)&ctx->dbl_ctx, r, p, t);
37742         if (err == MP_OKAY)
37743             ctx->state = 27; /* done */
37744         break;
37745     case 3:
37746     {
37747         int i;
37748         ctx->rp[0] = r;
37749 
37750         /*lint allow cast to different type of pointer*/
37751         ctx->rp[1] = (sp_point_1024*)t; /*lint !e9087 !e740*/
37752         XMEMSET(ctx->rp[1], 0, sizeof(sp_point_1024));
37753         ctx->x = ctx->rp[p->infinity | q->infinity]->x;
37754         ctx->y = ctx->rp[p->infinity | q->infinity]->y;
37755         ctx->z = ctx->rp[p->infinity | q->infinity]->z;
37756 
37757         ctx->ap[0] = p;
37758         ctx->ap[1] = q;
37759         for (i=0; i<18; i++) {
37760             r->x[i] = ctx->ap[p->infinity]->x[i];
37761         }
37762         for (i=0; i<18; i++) {
37763             r->y[i] = ctx->ap[p->infinity]->y[i];
37764         }
37765         for (i=0; i<18; i++) {
37766             r->z[i] = ctx->ap[p->infinity]->z[i];
37767         }
37768         r->infinity = ctx->ap[p->infinity]->infinity;
37769 
37770         ctx->state = 4;
37771         break;
37772     }
37773     case 4:
37774         /* U1 = X1*Z2^2 */
37775         sp_1024_mont_sqr_18(ctx->t1, q->z, p1024_mod, p1024_mp_mod);
37776         ctx->state = 5;
37777         break;
37778     case 5:
37779         sp_1024_mont_mul_18(ctx->t3, ctx->t1, q->z, p1024_mod, p1024_mp_mod);
37780         ctx->state = 6;
37781         break;
37782     case 6:
37783         sp_1024_mont_mul_18(ctx->t1, ctx->t1, ctx->x, p1024_mod, p1024_mp_mod);
37784         ctx->state = 7;
37785         break;
37786     case 7:
37787         /* U2 = X2*Z1^2 */
37788         sp_1024_mont_sqr_18(ctx->t2, ctx->z, p1024_mod, p1024_mp_mod);
37789         ctx->state = 8;
37790         break;
37791     case 8:
37792         sp_1024_mont_mul_18(ctx->t4, ctx->t2, ctx->z, p1024_mod, p1024_mp_mod);
37793         ctx->state = 9;
37794         break;
37795     case 9:
37796         sp_1024_mont_mul_18(ctx->t2, ctx->t2, q->x, p1024_mod, p1024_mp_mod);
37797         ctx->state = 10;
37798         break;
37799     case 10:
37800         /* S1 = Y1*Z2^3 */
37801         sp_1024_mont_mul_18(ctx->t3, ctx->t3, ctx->y, p1024_mod, p1024_mp_mod);
37802         ctx->state = 11;
37803         break;
37804     case 11:
37805         /* S2 = Y2*Z1^3 */
37806         sp_1024_mont_mul_18(ctx->t4, ctx->t4, q->y, p1024_mod, p1024_mp_mod);
37807         ctx->state = 12;
37808         break;
37809     case 12:
37810         /* H = U2 - U1 */
37811         sp_1024_mont_sub_18(ctx->t2, ctx->t2, ctx->t1, p1024_mod);
37812         ctx->state = 13;
37813         break;
37814     case 13:
37815         /* R = S2 - S1 */
37816         sp_1024_mont_sub_18(ctx->t4, ctx->t4, ctx->t3, p1024_mod);
37817         ctx->state = 14;
37818         break;
37819     case 14:
37820         /* Z3 = H*Z1*Z2 */
37821         sp_1024_mont_mul_18(ctx->z, ctx->z, q->z, p1024_mod, p1024_mp_mod);
37822         ctx->state = 15;
37823         break;
37824     case 15:
37825         sp_1024_mont_mul_18(ctx->z, ctx->z, ctx->t2, p1024_mod, p1024_mp_mod);
37826         ctx->state = 16;
37827         break;
37828     case 16:
37829         /* X3 = R^2 - H^3 - 2*U1*H^2 */
37830         sp_1024_mont_sqr_18(ctx->x, ctx->t4, p1024_mod, p1024_mp_mod);
37831         ctx->state = 17;
37832         break;
37833     case 17:
37834         sp_1024_mont_sqr_18(ctx->t5, ctx->t2, p1024_mod, p1024_mp_mod);
37835         ctx->state = 18;
37836         break;
37837     case 18:
37838         sp_1024_mont_mul_18(ctx->y, ctx->t1, ctx->t5, p1024_mod, p1024_mp_mod);
37839         ctx->state = 19;
37840         break;
37841     case 19:
37842         sp_1024_mont_mul_18(ctx->t5, ctx->t5, ctx->t2, p1024_mod, p1024_mp_mod);
37843         ctx->state = 20;
37844         break;
37845     case 20:
37846         sp_1024_mont_sub_18(ctx->x, ctx->x, ctx->t5, p1024_mod);
37847         ctx->state = 21;
37848         break;
37849     case 21:
37850         sp_1024_mont_dbl_18(ctx->t1, ctx->y, p1024_mod);
37851         ctx->state = 22;
37852         break;
37853     case 22:
37854         sp_1024_mont_sub_18(ctx->x, ctx->x, ctx->t1, p1024_mod);
37855         ctx->state = 23;
37856         break;
37857     case 23:
37858         /* Y3 = R*(U1*H^2 - X3) - S1*H^3 */
37859         sp_1024_mont_sub_18(ctx->y, ctx->y, ctx->x, p1024_mod);
37860         ctx->state = 24;
37861         break;
37862     case 24:
37863         sp_1024_mont_mul_18(ctx->y, ctx->y, ctx->t4, p1024_mod, p1024_mp_mod);
37864         ctx->state = 25;
37865         break;
37866     case 25:
37867         sp_1024_mont_mul_18(ctx->t5, ctx->t5, ctx->t3, p1024_mod, p1024_mp_mod);
37868         ctx->state = 26;
37869         break;
37870     case 26:
37871         sp_1024_mont_sub_18(ctx->y, ctx->y, ctx->t5, p1024_mod);
37872         ctx->state = 27;
37873         /* fall-through */
37874     case 27:
37875         err = MP_OKAY;
37876         break;
37877     }
37878 
37879     if (err == MP_OKAY && ctx->state != 27) {
37880         err = FP_WOULDBLOCK;
37881     }
37882     return err;
37883 }
37884 #endif /* WOLFSSL_SP_NONBLOCK */
37885 
sp_1024_proj_point_add_18(sp_point_1024 * r,const sp_point_1024 * p,const sp_point_1024 * q,sp_digit * t)37886 static void sp_1024_proj_point_add_18(sp_point_1024* r,
37887         const sp_point_1024* p, const sp_point_1024* q, sp_digit* t)
37888 {
37889     const sp_point_1024* ap[2];
37890     sp_point_1024* rp[2];
37891     sp_digit* t1 = t;
37892     sp_digit* t2 = t + 2*18;
37893     sp_digit* t3 = t + 4*18;
37894     sp_digit* t4 = t + 6*18;
37895     sp_digit* t5 = t + 8*18;
37896     sp_digit* x;
37897     sp_digit* y;
37898     sp_digit* z;
37899     int i;
37900 
37901     /* Ensure only the first point is the same as the result. */
37902     if (q == r) {
37903         const sp_point_1024* a = p;
37904         p = q;
37905         q = a;
37906     }
37907 
37908     /* Check double */
37909     (void)sp_1024_mont_sub_18(t1, p1024_mod, q->y, p1024_mod);
37910     sp_1024_norm_18(t1);
37911     if ((sp_1024_cmp_equal_18(p->x, q->x) & sp_1024_cmp_equal_18(p->z, q->z) &
37912         (sp_1024_cmp_equal_18(p->y, q->y) | sp_1024_cmp_equal_18(p->y, t1))) != 0) {
37913         sp_1024_proj_point_dbl_18(r, p, t);
37914     }
37915     else {
37916         rp[0] = r;
37917 
37918         /*lint allow cast to different type of pointer*/
37919         rp[1] = (sp_point_1024*)t; /*lint !e9087 !e740*/
37920         XMEMSET(rp[1], 0, sizeof(sp_point_1024));
37921         x = rp[p->infinity | q->infinity]->x;
37922         y = rp[p->infinity | q->infinity]->y;
37923         z = rp[p->infinity | q->infinity]->z;
37924 
37925         ap[0] = p;
37926         ap[1] = q;
37927         for (i=0; i<18; i++) {
37928             r->x[i] = ap[p->infinity]->x[i];
37929         }
37930         for (i=0; i<18; i++) {
37931             r->y[i] = ap[p->infinity]->y[i];
37932         }
37933         for (i=0; i<18; i++) {
37934             r->z[i] = ap[p->infinity]->z[i];
37935         }
37936         r->infinity = ap[p->infinity]->infinity;
37937 
37938         /* U1 = X1*Z2^2 */
37939         sp_1024_mont_sqr_18(t1, q->z, p1024_mod, p1024_mp_mod);
37940         sp_1024_mont_mul_18(t3, t1, q->z, p1024_mod, p1024_mp_mod);
37941         sp_1024_mont_mul_18(t1, t1, x, p1024_mod, p1024_mp_mod);
37942         /* U2 = X2*Z1^2 */
37943         sp_1024_mont_sqr_18(t2, z, p1024_mod, p1024_mp_mod);
37944         sp_1024_mont_mul_18(t4, t2, z, p1024_mod, p1024_mp_mod);
37945         sp_1024_mont_mul_18(t2, t2, q->x, p1024_mod, p1024_mp_mod);
37946         /* S1 = Y1*Z2^3 */
37947         sp_1024_mont_mul_18(t3, t3, y, p1024_mod, p1024_mp_mod);
37948         /* S2 = Y2*Z1^3 */
37949         sp_1024_mont_mul_18(t4, t4, q->y, p1024_mod, p1024_mp_mod);
37950         /* H = U2 - U1 */
37951         sp_1024_mont_sub_18(t2, t2, t1, p1024_mod);
37952         /* R = S2 - S1 */
37953         sp_1024_mont_sub_18(t4, t4, t3, p1024_mod);
37954         /* Z3 = H*Z1*Z2 */
37955         sp_1024_mont_mul_18(z, z, q->z, p1024_mod, p1024_mp_mod);
37956         sp_1024_mont_mul_18(z, z, t2, p1024_mod, p1024_mp_mod);
37957         /* X3 = R^2 - H^3 - 2*U1*H^2 */
37958         sp_1024_mont_sqr_18(x, t4, p1024_mod, p1024_mp_mod);
37959         sp_1024_mont_sqr_18(t5, t2, p1024_mod, p1024_mp_mod);
37960         sp_1024_mont_mul_18(y, t1, t5, p1024_mod, p1024_mp_mod);
37961         sp_1024_mont_mul_18(t5, t5, t2, p1024_mod, p1024_mp_mod);
37962         sp_1024_mont_sub_18(x, x, t5, p1024_mod);
37963         sp_1024_mont_dbl_18(t1, y, p1024_mod);
37964         sp_1024_mont_sub_18(x, x, t1, p1024_mod);
37965         /* Y3 = R*(U1*H^2 - X3) - S1*H^3 */
37966         sp_1024_mont_sub_18(y, y, x, p1024_mod);
37967         sp_1024_mont_mul_18(y, y, t4, p1024_mod, p1024_mp_mod);
37968         sp_1024_mont_mul_18(t5, t5, t3, p1024_mod, p1024_mp_mod);
37969         sp_1024_mont_sub_18(y, y, t5, p1024_mod);
37970     }
37971 }
37972 
37973 #ifdef WOLFSSL_SP_SMALL
37974 /* Multiply the point by the scalar and return the result.
37975  * If map is true then convert result to affine coordinates.
37976  *
37977  * Small implementation using add and double that is cache attack resistant but
37978  * allocates memory rather than use large stacks.
37979  * 1024 adds and doubles.
37980  *
37981  * r     Resulting point.
37982  * g     Point to multiply.
37983  * k     Scalar to multiply by.
37984  * map   Indicates whether to convert result to affine.
37985  * ct    Constant time required.
37986  * heap  Heap to use for allocation.
37987  * returns MEMORY_E when memory allocation fails and MP_OKAY on success.
37988  */
37989 
37990 #ifdef WOLFSSL_SP_NONBLOCK
37991 typedef struct sp_1024_ecc_mulmod_18_ctx {
37992     int state;
37993     union {
37994         sp_1024_proj_point_dbl_18_ctx dbl_ctx;
37995         sp_1024_proj_point_add_18_ctx add_ctx;
37996     };
37997     sp_point_1024 t[3];
37998     sp_digit tmp[2 * 18 * 5];
37999     sp_digit n;
38000     int i;
38001     int c;
38002     int y;
38003 } sp_1024_ecc_mulmod_18_ctx;
38004 
sp_1024_ecc_mulmod_18_nb(sp_ecc_ctx_t * sp_ctx,sp_point_1024 * r,const sp_point_1024 * g,const sp_digit * k,int map,int ct,void * heap)38005 static int sp_1024_ecc_mulmod_18_nb(sp_ecc_ctx_t* sp_ctx, sp_point_1024* r,
38006     const sp_point_1024* g, const sp_digit* k, int map, int ct, void* heap)
38007 {
38008     int err = FP_WOULDBLOCK;
38009     sp_1024_ecc_mulmod_18_ctx* ctx = (sp_1024_ecc_mulmod_18_ctx*)sp_ctx->data;
38010 
38011     typedef char ctx_size_test[sizeof(sp_1024_ecc_mulmod_18_ctx) >= sizeof(*sp_ctx) ? -1 : 1];
38012     (void)sizeof(ctx_size_test);
38013 
38014     /* Implementation is constant time. */
38015     (void)ct;
38016 
38017     switch (ctx->state) {
38018     case 0: /* INIT */
38019         XMEMSET(ctx->t, 0, sizeof(sp_point_1024) * 3);
38020         ctx->i = 17;
38021         ctx->c = 55;
38022         ctx->n = k[ctx->i--] << (57 - ctx->c);
38023 
38024         /* t[0] = {0, 0, 1} * norm */
38025         ctx->t[0].infinity = 1;
38026         ctx->state = 1;
38027         break;
38028     case 1: /* T1X */
38029         /* t[1] = {g->x, g->y, g->z} * norm */
38030         err = sp_1024_mod_mul_norm_18(ctx->t[1].x, g->x, p1024_mod);
38031         ctx->state = 2;
38032         break;
38033     case 2: /* T1Y */
38034         err = sp_1024_mod_mul_norm_18(ctx->t[1].y, g->y, p1024_mod);
38035         ctx->state = 3;
38036         break;
38037     case 3: /* T1Z */
38038         err = sp_1024_mod_mul_norm_18(ctx->t[1].z, g->z, p1024_mod);
38039         ctx->state = 4;
38040         break;
38041     case 4: /* ADDPREP */
38042         if (ctx->c == 0) {
38043             if (ctx->i == -1) {
38044                 ctx->state = 7;
38045                 break;
38046             }
38047 
38048             ctx->n = k[ctx->i--];
38049             ctx->c = 57;
38050         }
38051         ctx->y = (ctx->n >> 56) & 1;
38052         ctx->n <<= 1;
38053         XMEMSET(&ctx->add_ctx, 0, sizeof(ctx->add_ctx));
38054         ctx->state = 5;
38055         break;
38056     case 5: /* ADD */
38057         err = sp_1024_proj_point_add_18_nb((sp_ecc_ctx_t*)&ctx->add_ctx,
38058             &ctx->t[ctx->y^1], &ctx->t[0], &ctx->t[1], ctx->tmp);
38059         if (err == MP_OKAY) {
38060             XMEMCPY(&ctx->t[2], (void*)(((size_t)&ctx->t[0] & addr_mask[ctx->y^1]) +
38061                                         ((size_t)&ctx->t[1] & addr_mask[ctx->y])),
38062                     sizeof(sp_point_1024));
38063             XMEMSET(&ctx->dbl_ctx, 0, sizeof(ctx->dbl_ctx));
38064             ctx->state = 6;
38065         }
38066         break;
38067     case 6: /* DBL */
38068         err = sp_1024_proj_point_dbl_18_nb((sp_ecc_ctx_t*)&ctx->dbl_ctx, &ctx->t[2],
38069             &ctx->t[2], ctx->tmp);
38070         if (err == MP_OKAY) {
38071             XMEMCPY((void*)(((size_t)&ctx->t[0] & addr_mask[ctx->y^1]) +
38072                             ((size_t)&ctx->t[1] & addr_mask[ctx->y])), &ctx->t[2],
38073                     sizeof(sp_point_1024));
38074             ctx->state = 4;
38075             ctx->c--;
38076         }
38077         break;
38078     case 7: /* MAP */
38079         if (map != 0) {
38080             sp_1024_map_18(r, &ctx->t[0], ctx->tmp);
38081         }
38082         else {
38083             XMEMCPY(r, &ctx->t[0], sizeof(sp_point_1024));
38084         }
38085         err = MP_OKAY;
38086         break;
38087     }
38088 
38089     if (err == MP_OKAY && ctx->state != 7) {
38090         err = FP_WOULDBLOCK;
38091     }
38092     if (err != FP_WOULDBLOCK) {
38093         ForceZero(ctx->tmp, sizeof(ctx->tmp));
38094         ForceZero(ctx->t, sizeof(ctx->t));
38095     }
38096 
38097     (void)heap;
38098 
38099     return err;
38100 }
38101 
38102 #endif /* WOLFSSL_SP_NONBLOCK */
38103 
sp_1024_ecc_mulmod_18(sp_point_1024 * r,const sp_point_1024 * g,const sp_digit * k,int map,int ct,void * heap)38104 static int sp_1024_ecc_mulmod_18(sp_point_1024* r, const sp_point_1024* g,
38105         const sp_digit* k, int map, int ct, void* heap)
38106 {
38107 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
38108     sp_point_1024* t = NULL;
38109     sp_digit* tmp = NULL;
38110 #else
38111     sp_point_1024 t[3];
38112     sp_digit tmp[2 * 18 * 5];
38113 #endif
38114     sp_digit n;
38115     int i;
38116     int c;
38117     int y;
38118     int err = MP_OKAY;
38119 
38120     /* Implementation is constant time. */
38121     (void)ct;
38122     (void)heap;
38123 
38124 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
38125     t = (sp_point_1024*)XMALLOC(sizeof(sp_point_1024) * 3, heap,
38126                                      DYNAMIC_TYPE_ECC);
38127     if (t == NULL)
38128         err = MEMORY_E;
38129     if (err == MP_OKAY) {
38130         tmp = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 18 * 5, heap,
38131                                  DYNAMIC_TYPE_ECC);
38132         if (tmp == NULL)
38133             err = MEMORY_E;
38134     }
38135 #endif
38136 
38137     if (err == MP_OKAY) {
38138         XMEMSET(t, 0, sizeof(sp_point_1024) * 3);
38139 
38140         /* t[0] = {0, 0, 1} * norm */
38141         t[0].infinity = 1;
38142         /* t[1] = {g->x, g->y, g->z} * norm */
38143         err = sp_1024_mod_mul_norm_18(t[1].x, g->x, p1024_mod);
38144     }
38145     if (err == MP_OKAY)
38146         err = sp_1024_mod_mul_norm_18(t[1].y, g->y, p1024_mod);
38147     if (err == MP_OKAY)
38148         err = sp_1024_mod_mul_norm_18(t[1].z, g->z, p1024_mod);
38149 
38150     if (err == MP_OKAY) {
38151         i = 17;
38152         c = 55;
38153         n = k[i--] << (57 - c);
38154         for (; ; c--) {
38155             if (c == 0) {
38156                 if (i == -1)
38157                     break;
38158 
38159                 n = k[i--];
38160                 c = 57;
38161             }
38162 
38163             y = (n >> 56) & 1;
38164             n <<= 1;
38165 
38166             sp_1024_proj_point_add_18(&t[y^1], &t[0], &t[1], tmp);
38167 
38168             XMEMCPY(&t[2], (void*)(((size_t)&t[0] & addr_mask[y^1]) +
38169                                    ((size_t)&t[1] & addr_mask[y])),
38170                     sizeof(sp_point_1024));
38171             sp_1024_proj_point_dbl_18(&t[2], &t[2], tmp);
38172             XMEMCPY((void*)(((size_t)&t[0] & addr_mask[y^1]) +
38173                             ((size_t)&t[1] & addr_mask[y])), &t[2],
38174                     sizeof(sp_point_1024));
38175         }
38176 
38177         if (map != 0) {
38178             sp_1024_map_18(r, &t[0], tmp);
38179         }
38180         else {
38181             XMEMCPY(r, &t[0], sizeof(sp_point_1024));
38182         }
38183     }
38184 
38185 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
38186     if (tmp != NULL)
38187 #endif
38188     {
38189         ForceZero(tmp, sizeof(sp_digit) * 2 * 18 * 5);
38190     #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
38191         XFREE(tmp, heap, DYNAMIC_TYPE_ECC);
38192     #endif
38193     }
38194 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
38195     if (t != NULL)
38196 #endif
38197     {
38198         ForceZero(t, sizeof(sp_point_1024) * 3);
38199     #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
38200         XFREE(t, heap, DYNAMIC_TYPE_ECC);
38201     #endif
38202     }
38203 
38204     return err;
38205 }
38206 
38207 #else
38208 /* A table entry for pre-computed points. */
38209 typedef struct sp_table_entry_1024 {
38210     sp_digit x[18];
38211     sp_digit y[18];
38212 } sp_table_entry_1024;
38213 
38214 /* Conditionally copy a into r using the mask m.
38215  * m is -1 to copy and 0 when not.
38216  *
38217  * r  A single precision number to copy over.
38218  * a  A single precision number to copy.
38219  * m  Mask value to apply.
38220  */
sp_1024_cond_copy_18(sp_digit * r,const sp_digit * a,const sp_digit m)38221 static void sp_1024_cond_copy_18(sp_digit* r, const sp_digit* a, const sp_digit m)
38222 {
38223     sp_digit t[18];
38224 #ifdef WOLFSSL_SP_SMALL
38225     int i;
38226 
38227     for (i = 0; i < 18; i++) {
38228         t[i] = r[i] ^ a[i];
38229     }
38230     for (i = 0; i < 18; i++) {
38231         r[i] ^= t[i] & m;
38232     }
38233 #else
38234     t[ 0] = r[ 0] ^ a[ 0];
38235     t[ 1] = r[ 1] ^ a[ 1];
38236     t[ 2] = r[ 2] ^ a[ 2];
38237     t[ 3] = r[ 3] ^ a[ 3];
38238     t[ 4] = r[ 4] ^ a[ 4];
38239     t[ 5] = r[ 5] ^ a[ 5];
38240     t[ 6] = r[ 6] ^ a[ 6];
38241     t[ 7] = r[ 7] ^ a[ 7];
38242     t[ 8] = r[ 8] ^ a[ 8];
38243     t[ 9] = r[ 9] ^ a[ 9];
38244     t[10] = r[10] ^ a[10];
38245     t[11] = r[11] ^ a[11];
38246     t[12] = r[12] ^ a[12];
38247     t[13] = r[13] ^ a[13];
38248     t[14] = r[14] ^ a[14];
38249     t[15] = r[15] ^ a[15];
38250     t[16] = r[16] ^ a[16];
38251     t[17] = r[17] ^ a[17];
38252     r[ 0] ^= t[ 0] & m;
38253     r[ 1] ^= t[ 1] & m;
38254     r[ 2] ^= t[ 2] & m;
38255     r[ 3] ^= t[ 3] & m;
38256     r[ 4] ^= t[ 4] & m;
38257     r[ 5] ^= t[ 5] & m;
38258     r[ 6] ^= t[ 6] & m;
38259     r[ 7] ^= t[ 7] & m;
38260     r[ 8] ^= t[ 8] & m;
38261     r[ 9] ^= t[ 9] & m;
38262     r[10] ^= t[10] & m;
38263     r[11] ^= t[11] & m;
38264     r[12] ^= t[12] & m;
38265     r[13] ^= t[13] & m;
38266     r[14] ^= t[14] & m;
38267     r[15] ^= t[15] & m;
38268     r[16] ^= t[16] & m;
38269     r[17] ^= t[17] & m;
38270 #endif /* WOLFSSL_SP_SMALL */
38271 }
38272 
38273 /* Double the Montgomery form projective point p a number of times.
38274  *
38275  * r  Result of repeated doubling of point.
38276  * p  Point to double.
38277  * n  Number of times to double
38278  * t  Temporary ordinate data.
38279  */
sp_1024_proj_point_dbl_n_18(sp_point_1024 * p,int n,sp_digit * t)38280 static void sp_1024_proj_point_dbl_n_18(sp_point_1024* p, int n,
38281     sp_digit* t)
38282 {
38283     sp_digit* w = t;
38284     sp_digit* a = t + 2*18;
38285     sp_digit* b = t + 4*18;
38286     sp_digit* t1 = t + 6*18;
38287     sp_digit* t2 = t + 8*18;
38288     sp_digit* x;
38289     sp_digit* y;
38290     sp_digit* z;
38291 
38292     x = p->x;
38293     y = p->y;
38294     z = p->z;
38295 
38296     /* Y = 2*Y */
38297     sp_1024_mont_dbl_18(y, y, p1024_mod);
38298     /* W = Z^4 */
38299     sp_1024_mont_sqr_18(w, z, p1024_mod, p1024_mp_mod);
38300     sp_1024_mont_sqr_18(w, w, p1024_mod, p1024_mp_mod);
38301 
38302 #ifndef WOLFSSL_SP_SMALL
38303     while (--n > 0)
38304 #else
38305     while (--n >= 0)
38306 #endif
38307     {
38308         /* A = 3*(X^2 - W) */
38309         sp_1024_mont_sqr_18(t1, x, p1024_mod, p1024_mp_mod);
38310         sp_1024_mont_sub_18(t1, t1, w, p1024_mod);
38311         sp_1024_mont_tpl_18(a, t1, p1024_mod);
38312         /* B = X*Y^2 */
38313         sp_1024_mont_sqr_18(t1, y, p1024_mod, p1024_mp_mod);
38314         sp_1024_mont_mul_18(b, t1, x, p1024_mod, p1024_mp_mod);
38315         /* X = A^2 - 2B */
38316         sp_1024_mont_sqr_18(x, a, p1024_mod, p1024_mp_mod);
38317         sp_1024_mont_dbl_18(t2, b, p1024_mod);
38318         sp_1024_mont_sub_18(x, x, t2, p1024_mod);
38319         /* Z = Z*Y */
38320         sp_1024_mont_mul_18(z, z, y, p1024_mod, p1024_mp_mod);
38321         /* t2 = Y^4 */
38322         sp_1024_mont_sqr_18(t1, t1, p1024_mod, p1024_mp_mod);
38323 #ifdef WOLFSSL_SP_SMALL
38324         if (n != 0)
38325 #endif
38326         {
38327             /* W = W*Y^4 */
38328             sp_1024_mont_mul_18(w, w, t1, p1024_mod, p1024_mp_mod);
38329         }
38330         /* y = 2*A*(B - X) - Y^4 */
38331         sp_1024_mont_sub_18(y, b, x, p1024_mod);
38332         sp_1024_mont_mul_18(y, y, a, p1024_mod, p1024_mp_mod);
38333         sp_1024_mont_dbl_18(y, y, p1024_mod);
38334         sp_1024_mont_sub_18(y, y, t1, p1024_mod);
38335     }
38336 #ifndef WOLFSSL_SP_SMALL
38337     /* A = 3*(X^2 - W) */
38338     sp_1024_mont_sqr_18(t1, x, p1024_mod, p1024_mp_mod);
38339     sp_1024_mont_sub_18(t1, t1, w, p1024_mod);
38340     sp_1024_mont_tpl_18(a, t1, p1024_mod);
38341     /* B = X*Y^2 */
38342     sp_1024_mont_sqr_18(t1, y, p1024_mod, p1024_mp_mod);
38343     sp_1024_mont_mul_18(b, t1, x, p1024_mod, p1024_mp_mod);
38344     /* X = A^2 - 2B */
38345     sp_1024_mont_sqr_18(x, a, p1024_mod, p1024_mp_mod);
38346     sp_1024_mont_dbl_18(t2, b, p1024_mod);
38347     sp_1024_mont_sub_18(x, x, t2, p1024_mod);
38348     /* Z = Z*Y */
38349     sp_1024_mont_mul_18(z, z, y, p1024_mod, p1024_mp_mod);
38350     /* t2 = Y^4 */
38351     sp_1024_mont_sqr_18(t1, t1, p1024_mod, p1024_mp_mod);
38352     /* y = 2*A*(B - X) - Y^4 */
38353     sp_1024_mont_sub_18(y, b, x, p1024_mod);
38354     sp_1024_mont_mul_18(y, y, a, p1024_mod, p1024_mp_mod);
38355     sp_1024_mont_dbl_18(y, y, p1024_mod);
38356     sp_1024_mont_sub_18(y, y, t1, p1024_mod);
38357 #endif
38358     /* Y = Y/2 */
38359     sp_1024_div2_18(y, y, p1024_mod);
38360 }
38361 
38362 /* Double the Montgomery form projective point p a number of times.
38363  *
38364  * r  Result of repeated doubling of point.
38365  * p  Point to double.
38366  * n  Number of times to double
38367  * t  Temporary ordinate data.
38368  */
sp_1024_proj_point_dbl_n_store_18(sp_point_1024 * r,const sp_point_1024 * p,int n,int m,sp_digit * t)38369 static void sp_1024_proj_point_dbl_n_store_18(sp_point_1024* r,
38370         const sp_point_1024* p, int n, int m, sp_digit* t)
38371 {
38372     sp_digit* w = t;
38373     sp_digit* a = t + 2*18;
38374     sp_digit* b = t + 4*18;
38375     sp_digit* t1 = t + 6*18;
38376     sp_digit* t2 = t + 8*18;
38377     sp_digit* x = r[2*m].x;
38378     sp_digit* y = r[(1<<n)*m].y;
38379     sp_digit* z = r[2*m].z;
38380     int i;
38381     int j;
38382 
38383     for (i=0; i<18; i++) {
38384         x[i] = p->x[i];
38385     }
38386     for (i=0; i<18; i++) {
38387         y[i] = p->y[i];
38388     }
38389     for (i=0; i<18; i++) {
38390         z[i] = p->z[i];
38391     }
38392 
38393     /* Y = 2*Y */
38394     sp_1024_mont_dbl_18(y, y, p1024_mod);
38395     /* W = Z^4 */
38396     sp_1024_mont_sqr_18(w, z, p1024_mod, p1024_mp_mod);
38397     sp_1024_mont_sqr_18(w, w, p1024_mod, p1024_mp_mod);
38398     j = m;
38399     for (i=1; i<=n; i++) {
38400         j *= 2;
38401 
38402         /* A = 3*(X^2 - W) */
38403         sp_1024_mont_sqr_18(t1, x, p1024_mod, p1024_mp_mod);
38404         sp_1024_mont_sub_18(t1, t1, w, p1024_mod);
38405         sp_1024_mont_tpl_18(a, t1, p1024_mod);
38406         /* B = X*Y^2 */
38407         sp_1024_mont_sqr_18(t2, y, p1024_mod, p1024_mp_mod);
38408         sp_1024_mont_mul_18(b, t2, x, p1024_mod, p1024_mp_mod);
38409         x = r[j].x;
38410         /* X = A^2 - 2B */
38411         sp_1024_mont_sqr_18(x, a, p1024_mod, p1024_mp_mod);
38412         sp_1024_mont_dbl_18(t1, b, p1024_mod);
38413         sp_1024_mont_sub_18(x, x, t1, p1024_mod);
38414         /* Z = Z*Y */
38415         sp_1024_mont_mul_18(r[j].z, z, y, p1024_mod, p1024_mp_mod);
38416         z = r[j].z;
38417         /* t2 = Y^4 */
38418         sp_1024_mont_sqr_18(t2, t2, p1024_mod, p1024_mp_mod);
38419         if (i != n) {
38420             /* W = W*Y^4 */
38421             sp_1024_mont_mul_18(w, w, t2, p1024_mod, p1024_mp_mod);
38422         }
38423         /* y = 2*A*(B - X) - Y^4 */
38424         sp_1024_mont_sub_18(y, b, x, p1024_mod);
38425         sp_1024_mont_mul_18(y, y, a, p1024_mod, p1024_mp_mod);
38426         sp_1024_mont_dbl_18(y, y, p1024_mod);
38427         sp_1024_mont_sub_18(y, y, t2, p1024_mod);
38428 
38429         /* Y = Y/2 */
38430         sp_1024_div2_18(r[j].y, y, p1024_mod);
38431         r[j].infinity = 0;
38432     }
38433 }
38434 
38435 /* Add two Montgomery form projective points.
38436  *
38437  * ra  Result of addition.
38438  * rs  Result of subtraction.
38439  * p   First point to add.
38440  * q   Second point to add.
38441  * t   Temporary ordinate data.
38442  */
sp_1024_proj_point_add_sub_18(sp_point_1024 * ra,sp_point_1024 * rs,const sp_point_1024 * p,const sp_point_1024 * q,sp_digit * t)38443 static void sp_1024_proj_point_add_sub_18(sp_point_1024* ra,
38444         sp_point_1024* rs, const sp_point_1024* p, const sp_point_1024* q,
38445         sp_digit* t)
38446 {
38447     sp_digit* t1 = t;
38448     sp_digit* t2 = t + 2*18;
38449     sp_digit* t3 = t + 4*18;
38450     sp_digit* t4 = t + 6*18;
38451     sp_digit* t5 = t + 8*18;
38452     sp_digit* t6 = t + 10*18;
38453     sp_digit* x = ra->x;
38454     sp_digit* y = ra->y;
38455     sp_digit* z = ra->z;
38456     sp_digit* xs = rs->x;
38457     sp_digit* ys = rs->y;
38458     sp_digit* zs = rs->z;
38459 
38460 
38461     XMEMCPY(x, p->x, sizeof(p->x) / 2);
38462     XMEMCPY(y, p->y, sizeof(p->y) / 2);
38463     XMEMCPY(z, p->z, sizeof(p->z) / 2);
38464     ra->infinity = 0;
38465     rs->infinity = 0;
38466 
38467     /* U1 = X1*Z2^2 */
38468     sp_1024_mont_sqr_18(t1, q->z, p1024_mod, p1024_mp_mod);
38469     sp_1024_mont_mul_18(t3, t1, q->z, p1024_mod, p1024_mp_mod);
38470     sp_1024_mont_mul_18(t1, t1, x, p1024_mod, p1024_mp_mod);
38471     /* U2 = X2*Z1^2 */
38472     sp_1024_mont_sqr_18(t2, z, p1024_mod, p1024_mp_mod);
38473     sp_1024_mont_mul_18(t4, t2, z, p1024_mod, p1024_mp_mod);
38474     sp_1024_mont_mul_18(t2, t2, q->x, p1024_mod, p1024_mp_mod);
38475     /* S1 = Y1*Z2^3 */
38476     sp_1024_mont_mul_18(t3, t3, y, p1024_mod, p1024_mp_mod);
38477     /* S2 = Y2*Z1^3 */
38478     sp_1024_mont_mul_18(t4, t4, q->y, p1024_mod, p1024_mp_mod);
38479     /* H = U2 - U1 */
38480     sp_1024_mont_sub_18(t2, t2, t1, p1024_mod);
38481     /* RS = S2 + S1 */
38482     sp_1024_mont_add_18(t6, t4, t3, p1024_mod);
38483     /* R = S2 - S1 */
38484     sp_1024_mont_sub_18(t4, t4, t3, p1024_mod);
38485     /* Z3 = H*Z1*Z2 */
38486     /* ZS = H*Z1*Z2 */
38487     sp_1024_mont_mul_18(z, z, q->z, p1024_mod, p1024_mp_mod);
38488     sp_1024_mont_mul_18(z, z, t2, p1024_mod, p1024_mp_mod);
38489     XMEMCPY(zs, z, sizeof(p->z)/2);
38490     /* X3 = R^2 - H^3 - 2*U1*H^2 */
38491     /* XS = RS^2 - H^3 - 2*U1*H^2 */
38492     sp_1024_mont_sqr_18(x, t4, p1024_mod, p1024_mp_mod);
38493     sp_1024_mont_sqr_18(xs, t6, p1024_mod, p1024_mp_mod);
38494     sp_1024_mont_sqr_18(t5, t2, p1024_mod, p1024_mp_mod);
38495     sp_1024_mont_mul_18(y, t1, t5, p1024_mod, p1024_mp_mod);
38496     sp_1024_mont_mul_18(t5, t5, t2, p1024_mod, p1024_mp_mod);
38497     sp_1024_mont_sub_18(x, x, t5, p1024_mod);
38498     sp_1024_mont_sub_18(xs, xs, t5, p1024_mod);
38499     sp_1024_mont_dbl_18(t1, y, p1024_mod);
38500     sp_1024_mont_sub_18(x, x, t1, p1024_mod);
38501     sp_1024_mont_sub_18(xs, xs, t1, p1024_mod);
38502     /* Y3 = R*(U1*H^2 - X3) - S1*H^3 */
38503     /* YS = -RS*(U1*H^2 - XS) - S1*H^3 */
38504     sp_1024_mont_sub_18(ys, y, xs, p1024_mod);
38505     sp_1024_mont_sub_18(y, y, x, p1024_mod);
38506     sp_1024_mont_mul_18(y, y, t4, p1024_mod, p1024_mp_mod);
38507     sp_1024_mont_sub_18(t6, p1024_mod, t6, p1024_mod);
38508     sp_1024_mont_mul_18(ys, ys, t6, p1024_mod, p1024_mp_mod);
38509     sp_1024_mont_mul_18(t5, t5, t3, p1024_mod, p1024_mp_mod);
38510     sp_1024_mont_sub_18(y, y, t5, p1024_mod);
38511     sp_1024_mont_sub_18(ys, ys, t5, p1024_mod);
38512 }
38513 
38514 /* Structure used to describe recoding of scalar multiplication. */
38515 typedef struct ecc_recode_1024 {
38516     /* Index into pre-computation table. */
38517     uint8_t i;
38518     /* Use the negative of the point. */
38519     uint8_t neg;
38520 } ecc_recode_1024;
38521 
38522 /* The index into pre-computation table to use. */
38523 static const uint8_t recode_index_18_7[130] = {
38524      0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15,
38525     16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
38526     32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
38527     48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
38528     64, 63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52, 51, 50, 49,
38529     48, 47, 46, 45, 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33,
38530     32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17,
38531     16, 15, 14, 13, 12, 11, 10,  9,  8,  7,  6,  5,  4,  3,  2,  1,
38532      0,  1,
38533 };
38534 
38535 /* Whether to negate y-ordinate. */
38536 static const uint8_t recode_neg_18_7[130] = {
38537      0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
38538      0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
38539      0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
38540      0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
38541      1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
38542      1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
38543      1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
38544      1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
38545      0,  0,
38546 };
38547 
38548 /* Recode the scalar for multiplication using pre-computed values and
38549  * subtraction.
38550  *
38551  * k  Scalar to multiply by.
38552  * v  Vector of operations to perform.
38553  */
sp_1024_ecc_recode_7_18(const sp_digit * k,ecc_recode_1024 * v)38554 static void sp_1024_ecc_recode_7_18(const sp_digit* k, ecc_recode_1024* v)
38555 {
38556     int i;
38557     int j;
38558     uint8_t y;
38559     int carry = 0;
38560     int o;
38561     sp_digit n;
38562 
38563     j = 0;
38564     n = k[j];
38565     o = 0;
38566     for (i=0; i<147; i++) {
38567         y = (int8_t)n;
38568         if (o + 7 < 57) {
38569             y &= 0x7f;
38570             n >>= 7;
38571             o += 7;
38572         }
38573         else if (o + 7 == 57) {
38574             n >>= 7;
38575             if (++j < 18)
38576                 n = k[j];
38577             o = 0;
38578         }
38579         else if (++j < 18) {
38580             n = k[j];
38581             y |= (uint8_t)((n << (57 - o)) & 0x7f);
38582             o -= 50;
38583             n >>= o;
38584         }
38585 
38586         y += (uint8_t)carry;
38587         v[i].i = recode_index_18_7[y];
38588         v[i].neg = recode_neg_18_7[y];
38589         carry = (y >> 7) + v[i].neg;
38590     }
38591 }
38592 
38593 /* Multiply the point by the scalar and return the result.
38594  * If map is true then convert result to affine coordinates.
38595  *
38596  * Window technique of 7 bits. (Add-Sub variation.)
38597  * Calculate 0..64 times the point. Use function that adds and
38598  * subtracts the same two points.
38599  * Recode to add or subtract one of the computed points.
38600  * Double to push up.
38601  * NOT a sliding window.
38602  *
38603  * r     Resulting point.
38604  * g     Point to multiply.
38605  * k     Scalar to multiply by.
38606  * map   Indicates whether to convert result to affine.
38607  * ct    Constant time required.
38608  * heap  Heap to use for allocation.
38609  * returns MEMORY_E when memory allocation fails and MP_OKAY on success.
38610  */
sp_1024_ecc_mulmod_win_add_sub_18(sp_point_1024 * r,const sp_point_1024 * g,const sp_digit * k,int map,int ct,void * heap)38611 static int sp_1024_ecc_mulmod_win_add_sub_18(sp_point_1024* r, const sp_point_1024* g,
38612         const sp_digit* k, int map, int ct, void* heap)
38613 {
38614 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
38615     sp_point_1024* t = NULL;
38616     sp_digit* tmp = NULL;
38617 #else
38618     sp_point_1024 t[65+2];
38619     sp_digit tmp[2 * 18 * 6];
38620 #endif
38621     sp_point_1024* rt = NULL;
38622     sp_point_1024* p = NULL;
38623     sp_digit* negy;
38624     int i;
38625     ecc_recode_1024 v[147];
38626     int err = MP_OKAY;
38627 
38628     /* Constant time used for cache attack resistance implementation. */
38629     (void)ct;
38630     (void)heap;
38631 
38632 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
38633     t = (sp_point_1024*)XMALLOC(sizeof(sp_point_1024) *
38634         (65+2), heap, DYNAMIC_TYPE_ECC);
38635     if (t == NULL)
38636         err = MEMORY_E;
38637     if (err == MP_OKAY) {
38638         tmp = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 18 * 6,
38639                                  heap, DYNAMIC_TYPE_ECC);
38640         if (tmp == NULL)
38641             err = MEMORY_E;
38642     }
38643 #endif
38644 
38645     if (err == MP_OKAY) {
38646         rt = t + 65;
38647         p  = t + 65+1;
38648 
38649         /* t[0] = {0, 0, 1} * norm */
38650         XMEMSET(&t[0], 0, sizeof(t[0]));
38651         t[0].infinity = 1;
38652         /* t[1] = {g->x, g->y, g->z} * norm */
38653         err = sp_1024_mod_mul_norm_18(t[1].x, g->x, p1024_mod);
38654     }
38655     if (err == MP_OKAY) {
38656         err = sp_1024_mod_mul_norm_18(t[1].y, g->y, p1024_mod);
38657     }
38658     if (err == MP_OKAY) {
38659         err = sp_1024_mod_mul_norm_18(t[1].z, g->z, p1024_mod);
38660     }
38661 
38662     if (err == MP_OKAY) {
38663         t[1].infinity = 0;
38664         /* t[2] ... t[64]  */
38665         sp_1024_proj_point_dbl_n_store_18(t, &t[ 1], 6, 1, tmp);
38666         sp_1024_proj_point_add_18(&t[ 3], &t[ 2], &t[ 1], tmp);
38667         sp_1024_proj_point_dbl_18(&t[ 6], &t[ 3], tmp);
38668         sp_1024_proj_point_add_sub_18(&t[ 7], &t[ 5], &t[ 6], &t[ 1], tmp);
38669         sp_1024_proj_point_dbl_18(&t[10], &t[ 5], tmp);
38670         sp_1024_proj_point_add_sub_18(&t[11], &t[ 9], &t[10], &t[ 1], tmp);
38671         sp_1024_proj_point_dbl_18(&t[12], &t[ 6], tmp);
38672         sp_1024_proj_point_dbl_18(&t[14], &t[ 7], tmp);
38673         sp_1024_proj_point_add_sub_18(&t[15], &t[13], &t[14], &t[ 1], tmp);
38674         sp_1024_proj_point_dbl_18(&t[18], &t[ 9], tmp);
38675         sp_1024_proj_point_add_sub_18(&t[19], &t[17], &t[18], &t[ 1], tmp);
38676         sp_1024_proj_point_dbl_18(&t[20], &t[10], tmp);
38677         sp_1024_proj_point_dbl_18(&t[22], &t[11], tmp);
38678         sp_1024_proj_point_add_sub_18(&t[23], &t[21], &t[22], &t[ 1], tmp);
38679         sp_1024_proj_point_dbl_18(&t[24], &t[12], tmp);
38680         sp_1024_proj_point_dbl_18(&t[26], &t[13], tmp);
38681         sp_1024_proj_point_add_sub_18(&t[27], &t[25], &t[26], &t[ 1], tmp);
38682         sp_1024_proj_point_dbl_18(&t[28], &t[14], tmp);
38683         sp_1024_proj_point_dbl_18(&t[30], &t[15], tmp);
38684         sp_1024_proj_point_add_sub_18(&t[31], &t[29], &t[30], &t[ 1], tmp);
38685         sp_1024_proj_point_dbl_18(&t[34], &t[17], tmp);
38686         sp_1024_proj_point_add_sub_18(&t[35], &t[33], &t[34], &t[ 1], tmp);
38687         sp_1024_proj_point_dbl_18(&t[36], &t[18], tmp);
38688         sp_1024_proj_point_dbl_18(&t[38], &t[19], tmp);
38689         sp_1024_proj_point_add_sub_18(&t[39], &t[37], &t[38], &t[ 1], tmp);
38690         sp_1024_proj_point_dbl_18(&t[40], &t[20], tmp);
38691         sp_1024_proj_point_dbl_18(&t[42], &t[21], tmp);
38692         sp_1024_proj_point_add_sub_18(&t[43], &t[41], &t[42], &t[ 1], tmp);
38693         sp_1024_proj_point_dbl_18(&t[44], &t[22], tmp);
38694         sp_1024_proj_point_dbl_18(&t[46], &t[23], tmp);
38695         sp_1024_proj_point_add_sub_18(&t[47], &t[45], &t[46], &t[ 1], tmp);
38696         sp_1024_proj_point_dbl_18(&t[48], &t[24], tmp);
38697         sp_1024_proj_point_dbl_18(&t[50], &t[25], tmp);
38698         sp_1024_proj_point_add_sub_18(&t[51], &t[49], &t[50], &t[ 1], tmp);
38699         sp_1024_proj_point_dbl_18(&t[52], &t[26], tmp);
38700         sp_1024_proj_point_dbl_18(&t[54], &t[27], tmp);
38701         sp_1024_proj_point_add_sub_18(&t[55], &t[53], &t[54], &t[ 1], tmp);
38702         sp_1024_proj_point_dbl_18(&t[56], &t[28], tmp);
38703         sp_1024_proj_point_dbl_18(&t[58], &t[29], tmp);
38704         sp_1024_proj_point_add_sub_18(&t[59], &t[57], &t[58], &t[ 1], tmp);
38705         sp_1024_proj_point_dbl_18(&t[60], &t[30], tmp);
38706         sp_1024_proj_point_dbl_18(&t[62], &t[31], tmp);
38707         sp_1024_proj_point_add_sub_18(&t[63], &t[61], &t[62], &t[ 1], tmp);
38708 
38709         negy = t[0].y;
38710 
38711         sp_1024_ecc_recode_7_18(k, v);
38712 
38713         i = 146;
38714         XMEMCPY(rt, &t[v[i].i], sizeof(sp_point_1024));
38715         for (--i; i>=0; i--) {
38716             sp_1024_proj_point_dbl_n_18(rt, 7, tmp);
38717             XMEMCPY(p, &t[v[i].i], sizeof(sp_point_1024));
38718             sp_1024_mont_sub_18(negy, p1024_mod, p->y, p1024_mod);
38719             sp_1024_norm_18(negy);
38720             sp_1024_cond_copy_18(p->y, negy, (sp_digit)0 - v[i].neg);
38721             sp_1024_proj_point_add_18(rt, rt, p, tmp);
38722         }
38723 
38724         if (map != 0) {
38725             sp_1024_map_18(r, rt, tmp);
38726         }
38727         else {
38728             XMEMCPY(r, rt, sizeof(sp_point_1024));
38729         }
38730     }
38731 
38732 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
38733     if (t != NULL)
38734         XFREE(t, heap, DYNAMIC_TYPE_ECC);
38735     if (tmp != NULL)
38736         XFREE(tmp, heap, DYNAMIC_TYPE_ECC);
38737 #endif
38738 
38739     return err;
38740 }
38741 
38742 #ifdef FP_ECC
38743 #endif /* FP_ECC */
38744 /* Add two Montgomery form projective points. The second point has a q value of
38745  * one.
38746  * Only the first point can be the same pointer as the result point.
38747  *
38748  * r  Result of addition.
38749  * p  First point to add.
38750  * q  Second point to add.
38751  * t  Temporary ordinate data.
38752  */
sp_1024_proj_point_add_qz1_18(sp_point_1024 * r,const sp_point_1024 * p,const sp_point_1024 * q,sp_digit * t)38753 static void sp_1024_proj_point_add_qz1_18(sp_point_1024* r, const sp_point_1024* p,
38754         const sp_point_1024* q, sp_digit* t)
38755 {
38756     const sp_point_1024* ap[2];
38757     sp_point_1024* rp[2];
38758     sp_digit* t1 = t;
38759     sp_digit* t2 = t + 2*18;
38760     sp_digit* t3 = t + 4*18;
38761     sp_digit* t4 = t + 6*18;
38762     sp_digit* t5 = t + 8*18;
38763     sp_digit* x;
38764     sp_digit* y;
38765     sp_digit* z;
38766     int i;
38767 
38768     /* Check double */
38769     (void)sp_1024_mont_sub_18(t1, p1024_mod, q->y, p1024_mod);
38770     sp_1024_norm_18(t1);
38771     if ((sp_1024_cmp_equal_18(p->x, q->x) & sp_1024_cmp_equal_18(p->z, q->z) &
38772         (sp_1024_cmp_equal_18(p->y, q->y) | sp_1024_cmp_equal_18(p->y, t1))) != 0) {
38773         sp_1024_proj_point_dbl_18(r, p, t);
38774     }
38775     else {
38776         rp[0] = r;
38777 
38778         /*lint allow cast to different type of pointer*/
38779         rp[1] = (sp_point_1024*)t; /*lint !e9087 !e740*/
38780         XMEMSET(rp[1], 0, sizeof(sp_point_1024));
38781         x = rp[p->infinity | q->infinity]->x;
38782         y = rp[p->infinity | q->infinity]->y;
38783         z = rp[p->infinity | q->infinity]->z;
38784 
38785         ap[0] = p;
38786         ap[1] = q;
38787         for (i=0; i<18; i++) {
38788             r->x[i] = ap[p->infinity]->x[i];
38789         }
38790         for (i=0; i<18; i++) {
38791             r->y[i] = ap[p->infinity]->y[i];
38792         }
38793         for (i=0; i<18; i++) {
38794             r->z[i] = ap[p->infinity]->z[i];
38795         }
38796         r->infinity = ap[p->infinity]->infinity;
38797 
38798         /* U2 = X2*Z1^2 */
38799         sp_1024_mont_sqr_18(t2, z, p1024_mod, p1024_mp_mod);
38800         sp_1024_mont_mul_18(t4, t2, z, p1024_mod, p1024_mp_mod);
38801         sp_1024_mont_mul_18(t2, t2, q->x, p1024_mod, p1024_mp_mod);
38802         /* S2 = Y2*Z1^3 */
38803         sp_1024_mont_mul_18(t4, t4, q->y, p1024_mod, p1024_mp_mod);
38804         /* H = U2 - X1 */
38805         sp_1024_mont_sub_18(t2, t2, x, p1024_mod);
38806         /* R = S2 - Y1 */
38807         sp_1024_mont_sub_18(t4, t4, y, p1024_mod);
38808         /* Z3 = H*Z1 */
38809         sp_1024_mont_mul_18(z, z, t2, p1024_mod, p1024_mp_mod);
38810         /* X3 = R^2 - H^3 - 2*X1*H^2 */
38811         sp_1024_mont_sqr_18(t1, t4, p1024_mod, p1024_mp_mod);
38812         sp_1024_mont_sqr_18(t5, t2, p1024_mod, p1024_mp_mod);
38813         sp_1024_mont_mul_18(t3, x, t5, p1024_mod, p1024_mp_mod);
38814         sp_1024_mont_mul_18(t5, t5, t2, p1024_mod, p1024_mp_mod);
38815         sp_1024_mont_sub_18(x, t1, t5, p1024_mod);
38816         sp_1024_mont_dbl_18(t1, t3, p1024_mod);
38817         sp_1024_mont_sub_18(x, x, t1, p1024_mod);
38818         /* Y3 = R*(X1*H^2 - X3) - Y1*H^3 */
38819         sp_1024_mont_sub_18(t3, t3, x, p1024_mod);
38820         sp_1024_mont_mul_18(t3, t3, t4, p1024_mod, p1024_mp_mod);
38821         sp_1024_mont_mul_18(t5, t5, y, p1024_mod, p1024_mp_mod);
38822         sp_1024_mont_sub_18(y, t3, t5, p1024_mod);
38823     }
38824 }
38825 
38826 #if defined(FP_ECC) || !defined(WOLFSSL_SP_SMALL)
38827 /* Convert the projective point to affine.
38828  * Ordinates are in Montgomery form.
38829  *
38830  * a  Point to convert.
38831  * t  Temporary data.
38832  */
sp_1024_proj_to_affine_18(sp_point_1024 * a,sp_digit * t)38833 static void sp_1024_proj_to_affine_18(sp_point_1024* a, sp_digit* t)
38834 {
38835     sp_digit* t1 = t;
38836     sp_digit* t2 = t + 2 * 18;
38837     sp_digit* tmp = t + 4 * 18;
38838 
38839     sp_1024_mont_inv_18(t1, a->z, tmp);
38840 
38841     sp_1024_mont_sqr_18(t2, t1, p1024_mod, p1024_mp_mod);
38842     sp_1024_mont_mul_18(t1, t2, t1, p1024_mod, p1024_mp_mod);
38843 
38844     sp_1024_mont_mul_18(a->x, a->x, t2, p1024_mod, p1024_mp_mod);
38845     sp_1024_mont_mul_18(a->y, a->y, t1, p1024_mod, p1024_mp_mod);
38846     XMEMCPY(a->z, p1024_norm_mod, sizeof(p1024_norm_mod));
38847 }
38848 
38849 /* Generate the pre-computed table of points for the base point.
38850  *
38851  * width = 8
38852  * 256 entries
38853  * 128 bits between
38854  *
38855  * a      The base point.
38856  * table  Place to store generated point data.
38857  * tmp    Temporary data.
38858  * heap  Heap to use for allocation.
38859  */
sp_1024_gen_stripe_table_18(const sp_point_1024 * a,sp_table_entry_1024 * table,sp_digit * tmp,void * heap)38860 static int sp_1024_gen_stripe_table_18(const sp_point_1024* a,
38861         sp_table_entry_1024* table, sp_digit* tmp, void* heap)
38862 {
38863 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
38864     sp_point_1024* t = NULL;
38865 #else
38866     sp_point_1024 t[3];
38867 #endif
38868     sp_point_1024* s1 = NULL;
38869     sp_point_1024* s2 = NULL;
38870     int i;
38871     int j;
38872     int err = MP_OKAY;
38873 
38874     (void)heap;
38875 
38876 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
38877     t = (sp_point_1024*)XMALLOC(sizeof(sp_point_1024) * 3, heap,
38878                                      DYNAMIC_TYPE_ECC);
38879     if (t == NULL)
38880         err = MEMORY_E;
38881 #endif
38882 
38883     if (err == MP_OKAY) {
38884         s1 = t + 1;
38885         s2 = t + 2;
38886 
38887         err = sp_1024_mod_mul_norm_18(t->x, a->x, p1024_mod);
38888     }
38889     if (err == MP_OKAY) {
38890         err = sp_1024_mod_mul_norm_18(t->y, a->y, p1024_mod);
38891     }
38892     if (err == MP_OKAY) {
38893         err = sp_1024_mod_mul_norm_18(t->z, a->z, p1024_mod);
38894     }
38895     if (err == MP_OKAY) {
38896         t->infinity = 0;
38897         sp_1024_proj_to_affine_18(t, tmp);
38898 
38899         XMEMCPY(s1->z, p1024_norm_mod, sizeof(p1024_norm_mod));
38900         s1->infinity = 0;
38901         XMEMCPY(s2->z, p1024_norm_mod, sizeof(p1024_norm_mod));
38902         s2->infinity = 0;
38903 
38904         /* table[0] = {0, 0, infinity} */
38905         XMEMSET(&table[0], 0, sizeof(sp_table_entry_1024));
38906         /* table[1] = Affine version of 'a' in Montgomery form */
38907         XMEMCPY(table[1].x, t->x, sizeof(table->x));
38908         XMEMCPY(table[1].y, t->y, sizeof(table->y));
38909 
38910         for (i=1; i<8; i++) {
38911             sp_1024_proj_point_dbl_n_18(t, 128, tmp);
38912             sp_1024_proj_to_affine_18(t, tmp);
38913             XMEMCPY(table[1<<i].x, t->x, sizeof(table->x));
38914             XMEMCPY(table[1<<i].y, t->y, sizeof(table->y));
38915         }
38916 
38917         for (i=1; i<8; i++) {
38918             XMEMCPY(s1->x, table[1<<i].x, sizeof(table->x));
38919             XMEMCPY(s1->y, table[1<<i].y, sizeof(table->y));
38920             for (j=(1<<i)+1; j<(1<<(i+1)); j++) {
38921                 XMEMCPY(s2->x, table[j-(1<<i)].x, sizeof(table->x));
38922                 XMEMCPY(s2->y, table[j-(1<<i)].y, sizeof(table->y));
38923                 sp_1024_proj_point_add_qz1_18(t, s1, s2, tmp);
38924                 sp_1024_proj_to_affine_18(t, tmp);
38925                 XMEMCPY(table[j].x, t->x, sizeof(table->x));
38926                 XMEMCPY(table[j].y, t->y, sizeof(table->y));
38927             }
38928         }
38929     }
38930 
38931 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
38932     if (t != NULL)
38933         XFREE(t, heap, DYNAMIC_TYPE_ECC);
38934 #endif
38935 
38936     return err;
38937 }
38938 
38939 #endif /* FP_ECC | !WOLFSSL_SP_SMALL */
38940 /* Multiply the point by the scalar and return the result.
38941  * If map is true then convert result to affine coordinates.
38942  *
38943  * Stripe implementation.
38944  * Pre-generated: 2^0, 2^128, ...
38945  * Pre-generated: products of all combinations of above.
38946  * 8 doubles and adds (with qz=1)
38947  *
38948  * r      Resulting point.
38949  * k      Scalar to multiply by.
38950  * table  Pre-computed table.
38951  * map    Indicates whether to convert result to affine.
38952  * ct     Constant time required.
38953  * heap   Heap to use for allocation.
38954  * returns MEMORY_E when memory allocation fails and MP_OKAY on success.
38955  */
sp_1024_ecc_mulmod_stripe_18(sp_point_1024 * r,const sp_point_1024 * g,const sp_table_entry_1024 * table,const sp_digit * k,int map,int ct,void * heap)38956 static int sp_1024_ecc_mulmod_stripe_18(sp_point_1024* r, const sp_point_1024* g,
38957         const sp_table_entry_1024* table, const sp_digit* k, int map,
38958         int ct, void* heap)
38959 {
38960 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
38961     sp_point_1024* rt = NULL;
38962     sp_digit* t = NULL;
38963 #else
38964     sp_point_1024 rt[2];
38965     sp_digit t[2 * 18 * 5];
38966 #endif
38967     sp_point_1024* p = NULL;
38968     int i;
38969     int j;
38970     int y;
38971     int x;
38972     int err = MP_OKAY;
38973 
38974     (void)g;
38975     /* Constant time used for cache attack resistance implementation. */
38976     (void)ct;
38977     (void)heap;
38978 
38979 
38980 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
38981     rt = (sp_point_1024*)XMALLOC(sizeof(sp_point_1024) * 2, heap,
38982                                       DYNAMIC_TYPE_ECC);
38983     if (rt == NULL)
38984         err = MEMORY_E;
38985     if (err == MP_OKAY) {
38986         t = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 18 * 5, heap,
38987                                DYNAMIC_TYPE_ECC);
38988         if (t == NULL)
38989             err = MEMORY_E;
38990     }
38991 #endif
38992 
38993     if (err == MP_OKAY) {
38994         p = rt + 1;
38995 
38996         XMEMCPY(p->z, p1024_norm_mod, sizeof(p1024_norm_mod));
38997         XMEMCPY(rt->z, p1024_norm_mod, sizeof(p1024_norm_mod));
38998 
38999         y = 0;
39000         x = 127;
39001         for (j=0; j<8; j++) {
39002             y |= (int)(((k[x / 57] >> (x % 57)) & 1) << j);
39003             x += 128;
39004         }
39005         XMEMCPY(rt->x, table[y].x, sizeof(table[y].x));
39006         XMEMCPY(rt->y, table[y].y, sizeof(table[y].y));
39007         rt->infinity = !y;
39008         for (i=126; i>=0; i--) {
39009             y = 0;
39010             x = i;
39011             for (j=0; j<8; j++) {
39012                 y |= (int)(((k[x / 57] >> (x % 57)) & 1) << j);
39013                 x += 128;
39014             }
39015 
39016             sp_1024_proj_point_dbl_18(rt, rt, t);
39017             XMEMCPY(p->x, table[y].x, sizeof(table[y].x));
39018             XMEMCPY(p->y, table[y].y, sizeof(table[y].y));
39019             p->infinity = !y;
39020             sp_1024_proj_point_add_qz1_18(rt, rt, p, t);
39021         }
39022 
39023         if (map != 0) {
39024             sp_1024_map_18(r, rt, t);
39025         }
39026         else {
39027             XMEMCPY(r, rt, sizeof(sp_point_1024));
39028         }
39029     }
39030 
39031 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
39032     if (t != NULL)
39033         XFREE(t, heap, DYNAMIC_TYPE_ECC);
39034     if (rt != NULL)
39035         XFREE(rt, heap, DYNAMIC_TYPE_ECC);
39036 #endif
39037 
39038     return err;
39039 }
39040 
39041 #ifdef FP_ECC
39042 #ifndef FP_ENTRIES
39043     #define FP_ENTRIES 16
39044 #endif
39045 
39046 /* Cache entry - holds precomputation tables for a point. */
39047 typedef struct sp_cache_1024_t {
39048     /* X ordinate of point that table was generated from. */
39049     sp_digit x[18];
39050     /* Y ordinate of point that table was generated from. */
39051     sp_digit y[18];
39052     /* Precomputation table for point. */
39053     sp_table_entry_1024 table[256];
39054     /* Count of entries in table. */
39055     uint32_t cnt;
39056     /* Point and table set in entry. */
39057     int set;
39058 } sp_cache_1024_t;
39059 
39060 /* Cache of tables. */
39061 static THREAD_LS_T sp_cache_1024_t sp_cache_1024[FP_ENTRIES];
39062 /* Index of last entry in cache. */
39063 static THREAD_LS_T int sp_cache_1024_last = -1;
39064 /* Cache has been initialized. */
39065 static THREAD_LS_T int sp_cache_1024_inited = 0;
39066 
39067 #ifndef HAVE_THREAD_LS
39068     static volatile int initCacheMutex_1024 = 0;
39069     static wolfSSL_Mutex sp_cache_1024_lock;
39070 #endif
39071 
39072 /* Get the cache entry for the point.
39073  *
39074  * g      [in]   Point scalar multipling.
39075  * cache  [out]  Cache table to use.
39076  */
sp_ecc_get_cache_1024(const sp_point_1024 * g,sp_cache_1024_t ** cache)39077 static void sp_ecc_get_cache_1024(const sp_point_1024* g, sp_cache_1024_t** cache)
39078 {
39079     int i;
39080     int j;
39081     uint32_t least;
39082 
39083     if (sp_cache_1024_inited == 0) {
39084         for (i=0; i<FP_ENTRIES; i++) {
39085             sp_cache_1024[i].set = 0;
39086         }
39087         sp_cache_1024_inited = 1;
39088     }
39089 
39090     /* Compare point with those in cache. */
39091     for (i=0; i<FP_ENTRIES; i++) {
39092         if (!sp_cache_1024[i].set)
39093             continue;
39094 
39095         if (sp_1024_cmp_equal_18(g->x, sp_cache_1024[i].x) &
39096                            sp_1024_cmp_equal_18(g->y, sp_cache_1024[i].y)) {
39097             sp_cache_1024[i].cnt++;
39098             break;
39099         }
39100     }
39101 
39102     /* No match. */
39103     if (i == FP_ENTRIES) {
39104         /* Find empty entry. */
39105         i = (sp_cache_1024_last + 1) % FP_ENTRIES;
39106         for (; i != sp_cache_1024_last; i=(i+1)%FP_ENTRIES) {
39107             if (!sp_cache_1024[i].set) {
39108                 break;
39109             }
39110         }
39111 
39112         /* Evict least used. */
39113         if (i == sp_cache_1024_last) {
39114             least = sp_cache_1024[0].cnt;
39115             for (j=1; j<FP_ENTRIES; j++) {
39116                 if (sp_cache_1024[j].cnt < least) {
39117                     i = j;
39118                     least = sp_cache_1024[i].cnt;
39119                 }
39120             }
39121         }
39122 
39123         XMEMCPY(sp_cache_1024[i].x, g->x, sizeof(sp_cache_1024[i].x));
39124         XMEMCPY(sp_cache_1024[i].y, g->y, sizeof(sp_cache_1024[i].y));
39125         sp_cache_1024[i].set = 1;
39126         sp_cache_1024[i].cnt = 1;
39127     }
39128 
39129     *cache = &sp_cache_1024[i];
39130     sp_cache_1024_last = i;
39131 }
39132 #endif /* FP_ECC */
39133 
39134 /* Multiply the base point of P1024 by the scalar and return the result.
39135  * If map is true then convert result to affine coordinates.
39136  *
39137  * r     Resulting point.
39138  * g     Point to multiply.
39139  * k     Scalar to multiply by.
39140  * map   Indicates whether to convert result to affine.
39141  * ct    Constant time required.
39142  * heap  Heap to use for allocation.
39143  * returns MEMORY_E when memory allocation fails and MP_OKAY on success.
39144  */
sp_1024_ecc_mulmod_18(sp_point_1024 * r,const sp_point_1024 * g,const sp_digit * k,int map,int ct,void * heap)39145 static int sp_1024_ecc_mulmod_18(sp_point_1024* r, const sp_point_1024* g, const sp_digit* k,
39146         int map, int ct, void* heap)
39147 {
39148 #ifndef FP_ECC
39149     return sp_1024_ecc_mulmod_win_add_sub_18(r, g, k, map, ct, heap);
39150 #else
39151     sp_digit tmp[2 * 18 * 5];
39152     sp_cache_1024_t* cache;
39153     int err = MP_OKAY;
39154 
39155 #ifndef HAVE_THREAD_LS
39156     if (initCacheMutex_1024 == 0) {
39157          wc_InitMutex(&sp_cache_1024_lock);
39158          initCacheMutex_1024 = 1;
39159     }
39160     if (wc_LockMutex(&sp_cache_1024_lock) != 0)
39161        err = BAD_MUTEX_E;
39162 #endif /* HAVE_THREAD_LS */
39163 
39164     if (err == MP_OKAY) {
39165         sp_ecc_get_cache_1024(g, &cache);
39166         if (cache->cnt == 2)
39167             sp_1024_gen_stripe_table_18(g, cache->table, tmp, heap);
39168 
39169 #ifndef HAVE_THREAD_LS
39170         wc_UnLockMutex(&sp_cache_1024_lock);
39171 #endif /* HAVE_THREAD_LS */
39172 
39173         if (cache->cnt < 2) {
39174             err = sp_1024_ecc_mulmod_win_add_sub_18(r, g, k, map, ct, heap);
39175         }
39176         else {
39177             err = sp_1024_ecc_mulmod_stripe_18(r, g, cache->table, k,
39178                     map, ct, heap);
39179         }
39180     }
39181 
39182     return err;
39183 #endif
39184 }
39185 
39186 #endif
39187 /* Multiply the point by the scalar and return the result.
39188  * If map is true then convert result to affine coordinates.
39189  *
39190  * km    Scalar to multiply by.
39191  * p     Point to multiply.
39192  * r     Resulting point.
39193  * map   Indicates whether to convert result to affine.
39194  * heap  Heap to use for allocation.
39195  * returns MEMORY_E when memory allocation fails and MP_OKAY on success.
39196  */
sp_ecc_mulmod_1024(const mp_int * km,const ecc_point * gm,ecc_point * r,int map,void * heap)39197 int sp_ecc_mulmod_1024(const mp_int* km, const ecc_point* gm, ecc_point* r,
39198         int map, void* heap)
39199 {
39200 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
39201     sp_point_1024* point = NULL;
39202     sp_digit* k = NULL;
39203 #else
39204     sp_point_1024 point[1];
39205     sp_digit k[18];
39206 #endif
39207     int err = MP_OKAY;
39208 
39209 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
39210     point = (sp_point_1024*)XMALLOC(sizeof(sp_point_1024), heap,
39211                                          DYNAMIC_TYPE_ECC);
39212     if (point == NULL)
39213         err = MEMORY_E;
39214     if (err == MP_OKAY) {
39215         k = (sp_digit*)XMALLOC(sizeof(sp_digit) * 18, heap,
39216                                DYNAMIC_TYPE_ECC);
39217         if (k == NULL)
39218             err = MEMORY_E;
39219     }
39220 #endif
39221 
39222     if (err == MP_OKAY) {
39223         sp_1024_from_mp(k, 18, km);
39224         sp_1024_point_from_ecc_point_18(point, gm);
39225 
39226             err = sp_1024_ecc_mulmod_18(point, point, k, map, 1, heap);
39227     }
39228     if (err == MP_OKAY) {
39229         err = sp_1024_point_to_ecc_point_18(point, r);
39230     }
39231 
39232 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
39233     if (k != NULL)
39234         XFREE(k, heap, DYNAMIC_TYPE_ECC);
39235     if (point != NULL)
39236         XFREE(point, heap, DYNAMIC_TYPE_ECC);
39237 #endif
39238 
39239     return err;
39240 }
39241 
39242 #ifdef WOLFSSL_SP_SMALL
39243 /* Multiply the base point of P1024 by the scalar and return the result.
39244  * If map is true then convert result to affine coordinates.
39245  *
39246  * r     Resulting point.
39247  * k     Scalar to multiply by.
39248  * map   Indicates whether to convert result to affine.
39249  * heap  Heap to use for allocation.
39250  * returns MEMORY_E when memory allocation fails and MP_OKAY on success.
39251  */
sp_1024_ecc_mulmod_base_18(sp_point_1024 * r,const sp_digit * k,int map,int ct,void * heap)39252 static int sp_1024_ecc_mulmod_base_18(sp_point_1024* r, const sp_digit* k,
39253         int map, int ct, void* heap)
39254 {
39255     /* No pre-computed values. */
39256     return sp_1024_ecc_mulmod_18(r, &p1024_base, k, map, ct, heap);
39257 }
39258 
39259 #else
39260 /* Striping precomputation table.
39261  * 8 points combined into a table of 256 points.
39262  * Distance of 128 between points.
39263  */
39264 static const sp_table_entry_1024 p1024_table[256] = {
39265     /* 0 */
39266     { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
39267         0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
39268       { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
39269         0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } },
39270     /* 1 */
39271     { { 0x19c7ec6e0162bc2L,0x0637188544944dfL,0x17c27926760777bL,
39272         0x10da6b0430bab33L,0x10c5f8db9a96ea2L,0x1ae83300d763e9bL,
39273         0x15fe39cb9265633L,0x0b585ce52fa7d23L,0x18621db92da9f2fL,
39274         0x1936433ad2b3cf6L,0x0e177cb15aab052L,0x09a98d427f32466L,
39275         0x13ffa8ec11b88e7L,0x0f9fcff7890a58bL,0x19ed13a80e1a89cL,
39276         0x0692d7b36369d81L,0x00bafe528dceecdL,0x046fffcb50e24fcL },
39277       { 0x0a4753ac03c0c83L,0x14e8c55e6e6badaL,0x0e23ddd6d925a39L,
39278         0x157eb1e6a5c7073L,0x1d0bc15c803f949L,0x194c612fb8133cdL,
39279         0x05dba16fd745a3fL,0x1687edd7b318d8fL,0x120618af445e3e1L,
39280         0x1eaacc72a732049L,0x1ca0ed413fb6799L,0x17fae1b0ea2f608L,
39281         0x1f3f5addbe450caL,0x1c65a66523eb145L,0x071242000dfbcc1L,
39282         0x1b06e9c291a78d6L,0x1f3e256d3294fcfL,0x01550903def1e00L } },
39283     /* 2 */
39284     { { 0x15b6dae01900955L,0x04e60e75a32b6d4L,0x041f9cbfa56e977L,
39285         0x0f40818668a18f1L,0x1952ea6ea1ae544L,0x04b982c88c89b83L,
39286         0x1443d53fdcd0db4L,0x0e149b600e97b49L,0x0fd5306f1916440L,
39287         0x05cff39c5922916L,0x036b59e127dd885L,0x143161b9a5c828dL,
39288         0x015e1ad49287b29L,0x0ddd150d56ebf8dL,0x088cde66b18ea07L,
39289         0x07790026f38b702L,0x161f402b2f0b0e5L,0x0461f593f85f89dL },
39290       { 0x04ad3e1e513696fL,0x05d2e0c640ffd4dL,0x04d8f00cf44c0d4L,
39291         0x022f4a63783c5f8L,0x1aed610d53da6e7L,0x0ffab3a17632480L,
39292         0x144ab4cfa37dfa6L,0x1d7c955ae7c7bddL,0x0d983b465180f4dL,
39293         0x09b2934a817985aL,0x1e66aea24635fe6L,0x096ce01f8f34fc4L,
39294         0x1640bfd8c20ffe8L,0x0e9320debda2006L,0x098872f0e887485L,
39295         0x03d06f307288586L,0x110ace6500bb140L,0x03dfa0b1f128e21L } },
39296     /* 3 */
39297     { { 0x0174f88e3fd589eL,0x00bc86fcba5018eL,0x0f8cf9c1527f6d4L,
39298         0x1e2b249e69a12c4L,0x19b65ac58d091efL,0x14e167f77bce56fL,
39299         0x00af34b310988fdL,0x1bb02fb2064a59bL,0x1acf4f4d9a5f1ddL,
39300         0x030931aa808db5eL,0x112434bb4503274L,0x1d189b6d0da53eeL,
39301         0x16776b0fcc64092L,0x0f8b575b112f778L,0x0ef60a83a3007a7L,
39302         0x1c66ec506ce8309L,0x107757574e28956L,0x04c38f6e3382d3fL },
39303       { 0x10b76d5776535f7L,0x06b01131ad9dc5eL,0x0b667485bd91485L,
39304         0x0eaa2b7eeb8184bL,0x1e9f1675fd4df3aL,0x1439f3925312de2L,
39305         0x17128f0d7bedd01L,0x115deb93467765cL,0x1a971b35e806b19L,
39306         0x1ae0652d1e34876L,0x17762638788d067L,0x199d2ab5b3c951aL,
39307         0x07248d34164cecbL,0x02e057b71767a20L,0x1e03ffc6aece045L,
39308         0x1daae7e97dd0438L,0x1add14df768c272L,0x01cbf68851b8b1bL } },
39309     /* 4 */
39310     { { 0x13e0bb2755c2a27L,0x1217cacac2e2267L,0x183c64a179834e3L,
39311         0x00ec4e7a1e8d627L,0x193c569ac3ecd0cL,0x08c0c53c0078428L,
39312         0x0d8efc139d2ad0dL,0x1fd24b15471092cL,0x08456617cb8c894L,
39313         0x1e31555157cb4d0L,0x08a02d6919a3662L,0x0b1d5325e9f4cd8L,
39314         0x193f401e99bc9dfL,0x0261c6072ed85beL,0x137dacf81853f87L,
39315         0x16c31aa622a3859L,0x0a41c7575ece143L,0x020123cc2efc9ccL },
39316       { 0x1a251788f055746L,0x100200558f3707dL,0x13eeb0a49a5f16eL,
39317         0x12b69e8e81c3632L,0x1bb7ba547715211L,0x109cd2128048e84L,
39318         0x0a9f9e99d2186e6L,0x1dd75082767e6a7L,0x0afe771922443ceL,
39319         0x023469b1c23dde8L,0x1e7fd8f69250b45L,0x0383a84b68acc3eL,
39320         0x0d75ff46301563aL,0x159401649e1387eL,0x171c011081c8243L,
39321         0x05ce8d1e19b9790L,0x180ca4372fbfa03L,0x00d37e8f3645bceL } },
39322     /* 5 */
39323     { { 0x07a901a8d5116a3L,0x021ca597afa3fcbL,0x114983aebcec2e1L,
39324         0x0ec199f819c735aL,0x0c3f53f21e1be61L,0x088ddb5603f1e96L,
39325         0x0c30b760e38387bL,0x1708a8ea60e382bL,0x170dd4748920fe5L,
39326         0x1105f16f238c4b6L,0x1eb629649db1f06L,0x1987910ddc0e787L,
39327         0x176e831ac4026a1L,0x16280eb2cfedb79L,0x16a15d09a8d746aL,
39328         0x069ca15d3120a81L,0x15065dde0a4abd7L,0x014dbea6e0ab0a3L },
39329       { 0x0b3c2cbcbf4e20bL,0x1aa47ac662262a2L,0x0d516c32b07c70fL,
39330         0x0a01f00c4273013L,0x066905e00c0f02bL,0x080c4673095c480L,
39331         0x1daca3c563b5e0dL,0x1c1803b88b07eaaL,0x129803272a45492L,
39332         0x1d2b11d07fc9221L,0x08ac00a7437105dL,0x08b24f01d0f5a25L,
39333         0x030d53f272b4125L,0x12180f468f5e7c8L,0x1f41e62eb9ba900L,
39334         0x024d83cbe7e5f46L,0x17e9342c31022b4L,0x02e84940129c124L } },
39335     /* 6 */
39336     { { 0x03a2b7eff2f780dL,0x134106bebb58eacL,0x011e1bdd2bb0d34L,
39337         0x0421047fd7c7865L,0x1b5e7bf40fd4221L,0x147c66913f20bf7L,
39338         0x0efb1443526da95L,0x16ea779cfac2f03L,0x19cfe3f222f3718L,
39339         0x1a2744fecef360fL,0x1154fcfeb26d55fL,0x108dcde60179e39L,
39340         0x029f0ae6b19d2d0L,0x125c5df04bb6415L,0x0e96a9f98f6fd78L,
39341         0x0678e9958fe8b2eL,0x05dc6eb623784ddL,0x00513721a0a17f7L },
39342       { 0x081339facaa9a08L,0x18882a9237670c0L,0x05c184e4dd1d03cL,
39343         0x06485e05c312590L,0x1b5de98a8d8d410L,0x1df4a92415fe901L,
39344         0x0092627be51ad6aL,0x0f571a431726ed3L,0x1d5268e8966617cL,
39345         0x1173aa8c5be95c8L,0x11e5cffa359f0e5L,0x0a145602f8a258bL,
39346         0x1cc1a2946942e31L,0x098e3841b7a72f5L,0x1ee79428e644339L,
39347         0x015a15e9edd696eL,0x0ec68cbb175da12L,0x00ca4be30dc931bL } },
39348     /* 7 */
39349     { { 0x120b0c6417659a8L,0x15ce3c965947fb4L,0x0602da1de5ff1deL,
39350         0x03ceeb26c6ab6ceL,0x1561b1864caf58cL,0x07a4a328aadedb2L,
39351         0x02c80b9938d55e0L,0x0c1d615936e4535L,0x188594d782571bdL,
39352         0x0e6049cf1fd3c7cL,0x0d20c0ab0b4de57L,0x1ec1721e2888f71L,
39353         0x013ce4b3c1505fbL,0x0acdae0c5630874L,0x1a80888e693c9ebL,
39354         0x038f6bf4672e6f9L,0x1a6e578730b8dffL,0x04b5c8dc5a8bdfbL },
39355       { 0x1a991f49aac087cL,0x17ba7367ed946e0L,0x1e697dd8035b398L,
39356         0x09f22ff39211adfL,0x1de52dbfd781cd0L,0x0b90c03bcb7afb1L,
39357         0x04df79f6d9380bbL,0x02c1e10edecdf48L,0x13271ee643ca1f7L,
39358         0x1cd902c3e255c51L,0x05c41ce520411f2L,0x121ab318b86f974L,
39359         0x0a6f20e125df9a1L,0x1a794816865b739L,0x18b73ee8c508813L,
39360         0x186a285a51972f9L,0x09ddf261b8aa3d3L,0x039f9e98ae7fe12L } },
39361     /* 8 */
39362     { { 0x186855be6fd3673L,0x1b857ce90a5bdaeL,0x1e437311b34cc26L,
39363         0x0ab2aa21bd1a665L,0x18c1251ce553c01L,0x060de4aba3504b1L,
39364         0x0ea3f35f3a96e17L,0x0f89ff428d0005dL,0x110a3cb7022fcd7L,
39365         0x14ccefde27502f1L,0x1683413be9d5badL,0x0f3db9dabfb066eL,
39366         0x03251fd56e4d902L,0x015262f8a40c920L,0x0d0416fa1d8ce92L,
39367         0x1caf062e1a26036L,0x1fa93998b0f7247L,0x04449a7b221b5d0L },
39368       { 0x09f43b04713eabcL,0x1eec8d666e28bf8L,0x18efbc4f29f1329L,
39369         0x144b1030964fb54L,0x195dc2698b2e5a7L,0x1978a605465b096L,
39370         0x04d70d1a5d68b87L,0x1c63e5371dbc2e5L,0x0c3cbfd6ed40bc1L,
39371         0x1fa359f899311edL,0x16f9b7ec2dda074L,0x068aadb48689822L,
39372         0x18a8e43d985e31cL,0x05eeda7553e31f8L,0x153d631572c820dL,
39373         0x0d3b362d4187094L,0x0e174eacca246fdL,0x0068c4c5d8a9aa4L } },
39374     /* 9 */
39375     { { 0x0a73461e35ef043L,0x1b3ec9a4b5ab227L,0x1cef43e0e8f041eL,
39376         0x10a3a5386bac582L,0x11b1c1a4fad4b03L,0x1a1dcf1fa144153L,
39377         0x1d50d74af3d9952L,0x1838ef62b54557bL,0x15cb38a80dabe3dL,
39378         0x0fed0575240b39dL,0x05ad379ee43af85L,0x1c4a5791e7b10d3L,
39379         0x1637c4e42484f87L,0x0bd3d7ec56f681eL,0x132e4eb97b7999bL,
39380         0x1472301bb2b4543L,0x060a55cfd2546fbL,0x015ed58ee237c17L },
39381       { 0x04de22bfa6fed61L,0x0c552e646eca73dL,0x17c41c488bd7291L,
39382         0x1fcb5fe6ee7c6e5L,0x0a738e6d06a4b44L,0x18f89b5e1685d3aL,
39383         0x0a444691c38757cL,0x10aefff2675c205L,0x08b380a50310c78L,
39384         0x19e01143c1fe2d6L,0x1a249511c9741a7L,0x1c2cb5908443d8cL,
39385         0x0fcfda6e8a878f0L,0x1c66955d4d1d78dL,0x1b43ab8060fb4ddL,
39386         0x0c82a659b7ac104L,0x120b3234661cbeeL,0x01a9f5c495ce080L } },
39387     /* 10 */
39388     { { 0x0fdcad610b5521eL,0x0da202973817864L,0x00363ff69270684L,
39389         0x1597e6d75ac604dL,0x0c10a2d7cdb9654L,0x1873f03dac6708aL,
39390         0x0a04c79747df798L,0x0ff197c7afacec1L,0x1eb35866b6480d7L,
39391         0x0394679bf81b10cL,0x0197b50aa29d5d6L,0x1e3b20d450e1babL,
39392         0x04a51f906b283f1L,0x0a1d90543cf11fdL,0x079dd53cab1ba0dL,
39393         0x02ddc9e16c6f370L,0x07d57fbc0d48400L,0x046d103b8f310dbL },
39394       { 0x0855004ecce65ecL,0x0868fdba40c2f1eL,0x0f29e1e5eb49db4L,
39395         0x00efca955ac97cfL,0x1e0df0ff43444dbL,0x0843520bdb5864dL,
39396         0x1568e3f1095b015L,0x171f2a58877fae9L,0x0501e005a01c4edL,
39397         0x08b96fe252bf194L,0x0339394d75bb8f5L,0x1cb818ca1231b68L,
39398         0x07857561fcbaef1L,0x1a5112637428a2fL,0x103828b91a14da8L,
39399         0x007f8d351c44e1dL,0x15fb3f52247242bL,0x04317aaf161df5eL } },
39400     /* 11 */
39401     { { 0x16a390f226049feL,0x152bc6e5de4fd96L,0x12925d8d3edf324L,
39402         0x0c7bd4b1274a5fdL,0x0a49e9162b340cbL,0x0f20f9d1cf99c51L,
39403         0x1f9009acb7cf652L,0x1458e38f9b60cb4L,0x04a9b84a0468281L,
39404         0x1f75a81b98f7765L,0x0244d1db2edc958L,0x13537294cf19cdaL,
39405         0x1b808fd9f10cf97L,0x1057e2dcda26c61L,0x096f9a79836984fL,
39406         0x1ce9ea5b9cfbc7dL,0x1903a5d6864dc1eL,0x038d594489de403L },
39407       { 0x1618fc43b5b60adL,0x1af18250618c267L,0x0732f100cc082beL,
39408         0x07b63818cda4470L,0x06112a8d33cf895L,0x0b3d434e4ca726dL,
39409         0x134a75eab8b0f46L,0x1f7851aa926b6f5L,0x18075bd136c9a57L,
39410         0x0e01b9f4e4213fcL,0x12863464c897d72L,0x1a2688580318597L,
39411         0x07fbb3a72773777L,0x0cb16e0c75f2f6aL,0x1022019c10df524L,
39412         0x1e6b9e7383c125bL,0x06503e9c6f715ffL,0x046843ddb2f1b05L } },
39413     /* 12 */
39414     { { 0x02123023fdc1844L,0x113f7882f562b5fL,0x181bc5a28d21bb2L,
39415         0x1bc3af499643074L,0x1ef5d43e295f807L,0x1812e3b92353193L,
39416         0x138fab850c8171dL,0x0ea97bf8f95e690L,0x0ec939895df52c0L,
39417         0x1732afb6bd4e560L,0x17f8822ebb76c20L,0x0fc8a4fbce6330bL,
39418         0x1c313de1ea79c81L,0x0627b65d986707dL,0x0ec833677e56e27L,
39419         0x1f603e55dbe3debL,0x1ecfc1e0a891a8cL,0x0112f69a531f6dbL },
39420       { 0x013154dbabb1a85L,0x06d738f352b2d1fL,0x155aad2c403f4f6L,
39421         0x1dd78f1c35a642fL,0x08e73d37d44d934L,0x0f21e5810a990daL,
39422         0x02416ef242fe880L,0x1427847e3a04ea0L,0x02a2e5000c86691L,
39423         0x0595d693032c20eL,0x1072bcc009ad802L,0x05e8a4ed9cc22baL,
39424         0x0715932ffb1712cL,0x153a657900e261fL,0x014de91e25384f5L,
39425         0x192fc05adebbe18L,0x07ba8fb7602c2b1L,0x03095b072e8443eL } },
39426     /* 13 */
39427     { { 0x1d495cfba245d6bL,0x065dbd1671ffb77L,0x0b037fd7fbb973cL,
39428         0x119e518d4649b45L,0x0308a56b90c914fL,0x0b901a397eda86aL,
39429         0x127a40f6fdde44fL,0x1039f4bd9230455L,0x10dde73c83aea3eL,
39430         0x02dd4b13314489cL,0x1d922f29ab2f4d5L,0x0edd3140d0754a5L,
39431         0x0ca378ed52ff6f2L,0x042d60ec929b69dL,0x0f2129cd4f0b152L,
39432         0x082cf95fea5b401L,0x06e3971f81c3768L,0x007b99a70e96bccL },
39433       { 0x1bb5c836596067eL,0x0a70c9c60cc0357L,0x059ce72c3730cf9L,
39434         0x1a84806bf3050bbL,0x1fef90952b53f43L,0x07ab8d1c6298fc6L,
39435         0x09e1e43efa3936cL,0x04134183da54739L,0x02fecc1d6606f26L,
39436         0x0e44858b95be5a5L,0x129bef32ede1a27L,0x0105fce7dc93867L,
39437         0x17fcb66c48d1b11L,0x0370a2b9ac85be8L,0x0fab6164d5ac29aL,
39438         0x061f6ebad05880aL,0x149b2ae55fac54dL,0x033b1b5397c5774L } },
39439     /* 14 */
39440     { { 0x18063bcb91d6beaL,0x11d17491f65cb31L,0x064b189eb29ab89L,
39441         0x14ef5f3cfd3af61L,0x04aafebbc6ed001L,0x02ad48490a56679L,
39442         0x126768d592e59e0L,0x14a01333639c04eL,0x1e413a4e1e46a06L,
39443         0x02e89fb1728f7f3L,0x01f4d26ea10efa8L,0x104a63062b3c6bdL,
39444         0x1a546019230a633L,0x1bfe8e793011f45L,0x1cbf54e6c41dc86L,
39445         0x15e708d6aa857fbL,0x165b314f4f81c18L,0x00437cc3b305644L },
39446       { 0x07019548cbb9850L,0x05b98510696463bL,0x015d4cd59c31884L,
39447         0x0a064975d48109aL,0x076ee9b43ecdc59L,0x07fd32303fe2f96L,
39448         0x118f3ce4f403d10L,0x1cfc0222f2c5b82L,0x0f00b82519c7725L,
39449         0x0f3039b2de8e8c3L,0x015530b3dcaab0dL,0x1fbddf4692fbe7bL,
39450         0x0cf646ad11b4dd0L,0x0fbdc756eb89134L,0x01b7f941f082beeL,
39451         0x0a934c612d3a9f8L,0x01076b7df1c7245L,0x0340fca01f30d74L } },
39452     /* 15 */
39453     { { 0x0ad5163c9a0623bL,0x014abb3fd5c6a3eL,0x03b206bdf1f36feL,
39454         0x11d2cdab8459956L,0x10d4e41c469e38cL,0x159ace1a2186a97L,
39455         0x0049d0981d68a94L,0x082485ba7c6677aL,0x0cda3f6359fed23L,
39456         0x0f99b986bea97fdL,0x1d5bc1d9030fbd3L,0x0438377bcaf8bffL,
39457         0x0aeb8bb3364783cL,0x15684202ec3c251L,0x0d8af507b1f14cfL,
39458         0x1a95e96fe2847f3L,0x10a5543145c7075L,0x0064ef4a55d302cL },
39459       { 0x0d7273595d5682bL,0x0214197613b76c7L,0x1b562cda8349c47L,
39460         0x090931511fa3e95L,0x0480f45162ab40cL,0x0e7ff12c647e312L,
39461         0x0d6762f23292edeL,0x0bb2156b078e034L,0x0aee31a733fd5d1L,
39462         0x152acbde489199eL,0x072b92db0f8f080L,0x085853270110203L,
39463         0x1df47c8199e5130L,0x195007490700141L,0x1d6b8ee435a3963L,
39464         0x06164d3c5be834eL,0x196b8d2eca5871cL,0x0399ee5075d8ef1L } },
39465     /* 16 */
39466     { { 0x1b495d04b59213aL,0x1901cc6b810077aL,0x0698ad9dc707299L,
39467         0x08573d619697961L,0x0cdba21226adeedL,0x044868f5aa23aa4L,
39468         0x11ad0386aff37c2L,0x070a4a132c6d31cL,0x1e1bff0b082e9c1L,
39469         0x0c4f266a884cd38L,0x0326f326e4731e8L,0x0fb826fd897c46cL,
39470         0x01d1519f6e9bd4dL,0x07c19281e81ab29L,0x1ba8ad2fd7db5e3L,
39471         0x06339c86020631bL,0x1d7c3132494ef4cL,0x01559dea3878fd3L },
39472       { 0x153b680922c9fbbL,0x13ee4078b6368abL,0x04d6eb05bbf21a7L,
39473         0x0908da3b370688aL,0x12d62c214326a3bL,0x14956ada8bff71dL,
39474         0x0b04da416be882cL,0x11a54ae2634595bL,0x0cd904d8febdbcaL,
39475         0x1f6d4379f9b2fd9L,0x1ec82371faa8737L,0x150948bcef80e12L,
39476         0x0ccf5d118e89a35L,0x0fb74cf420bd031L,0x1e821f4f03012a0L,
39477         0x055a5888e096174L,0x0296f8a27d13ea2L,0x049d25a0b2613e9L } },
39478     /* 17 */
39479     { { 0x0271bc11f1efb7aL,0x1347319fe6606eaL,0x03c6c47d42a2b93L,
39480         0x1f5e0ec1133b379L,0x043d0e035430398L,0x11ea60a2f1217daL,
39481         0x0b425cfb09467dbL,0x01f56e1ef217537L,0x0de612ad5f9add1L,
39482         0x01bf2a70a74a15aL,0x095b4f76e2da2aeL,0x0678358548102ebL,
39483         0x10f0c80f94e85b2L,0x04c6da7cfc7fb61L,0x09f73752dfcfedeL,
39484         0x0712b458c089e8bL,0x163f3abb2f6fe3dL,0x01a16706b99773bL },
39485       { 0x1261394cf491b1fL,0x1776b8c84f1caf5L,0x156a7f936fab72aL,
39486         0x1a927ac09bb9880L,0x1ce5ebef17a6611L,0x0c4e5add222d1d0L,
39487         0x0101ba0b8a1638eL,0x0ab72de850507ebL,0x099877b99a156cfL,
39488         0x1c83533270b3507L,0x074d4eca5db44ebL,0x1e4e6d8c34039d4L,
39489         0x13b0f55d86efc16L,0x0759a600ed82621L,0x1980a00f2d2c9a6L,
39490         0x07d8a71a0fef055L,0x12043ac3bcb43beL,0x022afa579f0ab7eL } },
39491     /* 18 */
39492     { { 0x057f262754ec21cL,0x06a64f1d0dd1c60L,0x034445b07fa4fabL,
39493         0x09d599156c74042L,0x0a6f32cae4ea4e9L,0x1cbae718e0064d7L,
39494         0x087a572d88e761aL,0x116ca9abb19429dL,0x1230d31f45067fcL,
39495         0x05dc865b1aaff65L,0x007b3b705cba392L,0x01519600ce6ef1fL,
39496         0x01e162d01228838L,0x02d78a2e0cd8170L,0x0b70d503821e81bL,
39497         0x180cde09b916f6eL,0x1b7f70ef2148de3L,0x0278a412189804fL },
39498       { 0x0004fce6e2055e2L,0x123f543619033afL,0x16557e76aa8a278L,
39499         0x1f9d6fec769d797L,0x063784a0d15f212L,0x1b0128af662e0fcL,
39500         0x0a5514ece002dd5L,0x033d726038714d4L,0x00f16ba18a13cddL,
39501         0x189e928c43e1692L,0x08d6166a504fda0L,0x0bcdfc7faf8bf32L,
39502         0x1416e0ee0542340L,0x1fd6d55833c5759L,0x02111c47cef9eecL,
39503         0x05fecf203f45905L,0x10bc950db304d66L,0x03a6ae96a1e008bL } },
39504     /* 19 */
39505     { { 0x1002dc02b5bfe11L,0x1a086a96990f3d1L,0x1d9659e6ea241ccL,
39506         0x08d0b646dc2b241L,0x146f60400e248c1L,0x038bf8467d5aca1L,
39507         0x115da7d5ebedd03L,0x08e1b756518cc08L,0x10fa099689cdc32L,
39508         0x0f0157161187682L,0x185553916fbdd10L,0x13059c9af6de1b2L,
39509         0x075e62d22e9688aL,0x1e965d147d6f7d6L,0x1f1d27ebc544a9aL,
39510         0x0b4d6f10d1cc57cL,0x02988048d81ae9fL,0x0358d2a2162c2bdL },
39511       { 0x15ab9ad43242066L,0x178da966651574fL,0x1b1e623b71382bfL,
39512         0x02068361ab63687L,0x150aab370d0c00fL,0x13254ca6b45c7bdL,
39513         0x1a13a6a3939bfceL,0x0b8330671f6fe34L,0x18bc0e748351a0fL,
39514         0x0567966ed62228aL,0x14e6657a7fddacbL,0x167e2c7260ab829L,
39515         0x05888d837654a01L,0x19193bd8b561f75L,0x076eefee1366a69L,
39516         0x0e2f132264d23c2L,0x0c8597717aeabb6L,0x026109a9345d8a5L } },
39517     /* 20 */
39518     { { 0x06fe0a695532833L,0x111476b13683397L,0x0f659279cef6af2L,
39519         0x15e0789818455deL,0x15169b452083a87L,0x083544f4aa73ae9L,
39520         0x13e415dd427b9d1L,0x12293964edc55d5L,0x108275d77fa409fL,
39521         0x0f5b79ef85deb5cL,0x080b2f904c9c118L,0x184363893163290L,
39522         0x08361fee5935f3fL,0x087028f9bb6345dL,0x039c10a8632ef65L,
39523         0x03d16470950f263L,0x134292abead80ddL,0x032b89e14ae1be1L },
39524       { 0x0cca8e9ceb77b9aL,0x1f39391db4a34eeL,0x1b9a8075aca0be5L,
39525         0x1ab57d9bfd8ed57L,0x09290d703925203L,0x18a21c44a240411L,
39526         0x11f0fe64c5092c0L,0x04e08413be2f9a8L,0x17c6f2059c855c8L,
39527         0x0bebc312b607034L,0x16dbf904b653136L,0x0b23329883bab53L,
39528         0x01c89e21a319a64L,0x03501f87091a455L,0x05bfab35a412d43L,
39529         0x0d276ab82a2ad4cL,0x0384e36d1b57cc7L,0x035874cb61dd71eL } },
39530     /* 21 */
39531     { { 0x0789fabcceced00L,0x1f38d72dbd53319L,0x09a4b77af37cc8dL,
39532         0x016c3b5b1f0f65cL,0x135f803cb724512L,0x128786f08f2f246L,
39533         0x0ae4bed37d75e63L,0x07ac1dcd16979a5L,0x198ab2f5c1ce336L,
39534         0x0dd1ced3e6a1323L,0x15cbae0fd3ecfc5L,0x1d11cade11b634cL,
39535         0x1e172562c20f77dL,0x052c787a0ba1bb0L,0x1475b8af8d27fe2L,
39536         0x1e769c09b4e3709L,0x1f8368f03429e9fL,0x020115102b3c111L },
39537       { 0x07bbd0583847375L,0x0b5b11fa28d7829L,0x09352cb1fc60eb9L,
39538         0x168a4b731ac331eL,0x0e0884b5ee323f5L,0x0963bb54ec69cd0L,
39539         0x1055340175fdbecL,0x179ae38907ce117L,0x18ca6fd28742541L,
39540         0x179ee66fc1cbeedL,0x14c494fb33c90c2L,0x0210b1b0371b701L,
39541         0x0171391f68c743aL,0x19ddb2bf9fa4759L,0x191f8c524ebfe20L,
39542         0x0f3ec3a2bdacc0fL,0x15610159b11e082L,0x01890bce5925354L } },
39543     /* 22 */
39544     { { 0x14cc3ca07615ac2L,0x12f32090d6ac0d4L,0x05be9e61ade6161L,
39545         0x173abc1e3b5c8ecL,0x1d9457ea395a40eL,0x1432ecd48a19321L,
39546         0x0ba32379b5a8fe8L,0x1960ee3b72c2029L,0x077a7cce6976a87L,
39547         0x1ef21708a1d07b0L,0x0f3027664f64d29L,0x0d2731d8987bc40L,
39548         0x183a25df4b92018L,0x115816b5ebbaa36L,0x169c6242b67ad1dL,
39549         0x04377f555e411a0L,0x1ea5238181f4312L,0x020beb63c399a88L },
39550       { 0x0bd81b70e91e9a8L,0x0020c61b86b599eL,0x042a3aa88dcdccdL,
39551         0x08d8facead04bb6L,0x14c33ded8f2b09eL,0x0af1fdf144774dcL,
39552         0x1a22336109aec5aL,0x0c54c2ed90db9d3L,0x13f4c89226165e3L,
39553         0x0a7208fb031fd84L,0x1eb08323e781314L,0x0d39bfa55ac2d20L,
39554         0x048452199acef74L,0x09561a315d185d7L,0x0b520b4c1a04a4cL,
39555         0x0132a0237d0e792L,0x00aff4cbf89e833L,0x0010c4ea968a385L } },
39556     /* 23 */
39557     { { 0x1e419dd92599c69L,0x0110dbff6196539L,0x0f4826efeff56e5L,
39558         0x08c7db12b7657f3L,0x1f486f7961ea97aL,0x0a0d1cb3048a359L,
39559         0x104d6f471e817f4L,0x0f78f3d919f07acL,0x17f8fd42f988350L,
39560         0x1e5a9db8bd9e813L,0x1637359f296886bL,0x01599a292f0d0ccL,
39561         0x0e34b95067a6a6cL,0x0fa24ac60b79eb8L,0x0a00848dc48238fL,
39562         0x058e3a5bac9cdd8L,0x0fa33b2c4ab3078L,0x03ddfc55ea908bbL },
39563       { 0x09e4aafa78b981aL,0x1a71b182764145fL,0x1ce4e5677a8de22L,
39564         0x064816738e188b9L,0x08383b7d70a9bddL,0x1d081324ce6bee9L,
39565         0x1c6ccc1a42cb8c1L,0x09044c5ab31dd25L,0x0c62d77deb4725aL,
39566         0x0b792de3de1d507L,0x162d97457bdfea8L,0x043a172dad1ec5bL,
39567         0x03a00f1906d9792L,0x15ba63a05c9442eL,0x15d888be91dae6fL,
39568         0x0a09e42fbb76b8eL,0x16bc2782c305788L,0x0430684b67c0938L } },
39569     /* 24 */
39570     { { 0x0bc337d4d79bbf9L,0x1f55c34fba7c07fL,0x0254cc41354d754L,
39571         0x1432df172ffe6d4L,0x15ce69092ab820dL,0x141baa4b0e9e8fbL,
39572         0x12e6ec65fb01011L,0x1474d19c37f274dL,0x1503456ffc5f021L,
39573         0x08516d8c4a07fedL,0x143e3fbc010826dL,0x02ee092cb0eaef8L,
39574         0x198bb8770ad635dL,0x103c729f392bb36L,0x1f20de23866c0a2L,
39575         0x073406c9a9995f3L,0x1201a3df411f0ddL,0x03f40722101d6fcL },
39576       { 0x15f8a57539a1ddfL,0x073d7772432b125L,0x047605808787492L,
39577         0x17fa6da58838f69L,0x0aec00d92e7b871L,0x09f8d9ed1c5a820L,
39578         0x1e35bca09d84986L,0x066d387fd0df63eL,0x156c8b786e827acL,
39579         0x143fb639a43e47bL,0x1c885c677b96f05L,0x0e7ffe732831571L,
39580         0x14a9027c8004e84L,0x150e971479c2600L,0x197bbc6659efa6aL,
39581         0x106f90d2d0da7c0L,0x063737c6b08c7bdL,0x02ee55ae8cf45ecL } },
39582     /* 25 */
39583     { { 0x184283a9a7d772bL,0x0f292f2a04acd83L,0x002219052ad5ad2L,
39584         0x053ae96552a8d76L,0x003b0b1bd444816L,0x09fc35933c48569L,
39585         0x00f1c79ea0af323L,0x19e26a57f6bb0b5L,0x1f29f16e3fad07cL,
39586         0x01531dc20f0621fL,0x1c8b15acde7fbf0L,0x0ca762489e4d209L,
39587         0x1f3a28bdea19d8aL,0x1b6a2ae7331adb6L,0x1fcdcd462da2147L,
39588         0x17b56e958503139L,0x098ad40f9df8b2cL,0x0046616cf56e4eaL },
39589       { 0x06a6866c170c84bL,0x04f45ad24d24217L,0x03834132264aee6L,
39590         0x10c3674846f61c0L,0x10d0189955ad347L,0x0806599e4a92285L,
39591         0x1db438e4885578cL,0x0a6324cb6dde064L,0x00fe8595a76d42bL,
39592         0x14b6f707e31a9dbL,0x18372091be24f82L,0x057de14e9974ec3L,
39593         0x043fdfad9b4ec90L,0x07edb4bab080434L,0x1dd642975a98391L,
39594         0x0146e7ea75590fdL,0x1b0d29e6be01287L,0x04c8fd6e0aad52aL } },
39595     /* 26 */
39596     { { 0x0bc4b0fb4844ffeL,0x1138a307c5c38c1L,0x0389338fc7cdce4L,
39597         0x082c6a33d915800L,0x08288b5ff0d548bL,0x0e4d383d57c215cL,
39598         0x1f59e7a2c3130afL,0x18740daa2a4974bL,0x0d0b1afa0f93cdeL,
39599         0x004aadd6fc4fc78L,0x0fa4b7ba8cb248aL,0x1f327fc0b7c90d9L,
39600         0x15fa6919aa0cae3L,0x17078dc5f930384L,0x1b3e6203d51d079L,
39601         0x123ae55da3ee861L,0x1e99296f76b7349L,0x03367c69412cf87L },
39602       { 0x101905b226f5868L,0x174460b484f4f4dL,0x045928dfad53040L,
39603         0x119302c64657a11L,0x06bac53cf72253eL,0x15557b9bfc274ecL,
39604         0x011b8b8d49152bfL,0x05ccf90deee5940L,0x086bce50e666337L,
39605         0x151d4b05b4a8502L,0x06535ff06aea4fdL,0x02578264dcdcc3fL,
39606         0x042e56b0051957cL,0x02c93a064db2c7fL,0x1fc9a96734a5ff2L,
39607         0x05d76eca99d362eL,0x048aaa699dba79dL,0x02fe5062d0765b2L } },
39608     /* 27 */
39609     { { 0x06e25f3569a6663L,0x0bf73f3552653f1L,0x169a3462e030256L,
39610         0x0a4524ce604b499L,0x07387209450602bL,0x199d29cd7afb280L,
39611         0x0a547fbbb6cd099L,0x1341eb9ced10caeL,0x1872a360b8398aeL,
39612         0x01a3d4015987b61L,0x04ec8c685885618L,0x1f25dcd8dbd9a42L,
39613         0x085cbcf9e66fd9cL,0x15d1ff4242f852dL,0x1b35c9f5e969b90L,
39614         0x0342155fcce40a3L,0x0b4e09c6bb2a208L,0x032bd65f85cb9d8L },
39615       { 0x130466fc274c8d4L,0x128bb1854ca6898L,0x0329c1e50d7d09dL,
39616         0x0dd712f40c42e4bL,0x161ee1304485040L,0x0bbc5df9c6ff772L,
39617         0x0e7a447d3eb3ea8L,0x064ecb8cc2f7357L,0x1b135499bd8f109L,
39618         0x075b19bd39dc8acL,0x0733c5bdfa2dab0L,0x007430fbdea7e58L,
39619         0x09830b9c625b32cL,0x1788729c44d68eaL,0x17d56f05cd7ab8cL,
39620         0x1b61b6397b3853aL,0x1bb42428c47e539L,0x01e96d209642959L } },
39621     /* 28 */
39622     { { 0x1702b6e871f2865L,0x1b1cf8a14906b4bL,0x0a8116d618455b2L,
39623         0x03e7627024650a4L,0x112206e8f3943adL,0x06acf5736110053L,
39624         0x1dd670a24396a8dL,0x0cf56a5fa81ed6fL,0x0f522c8de180bf5L,
39625         0x00f4bd9566771cbL,0x1d606713a972ec6L,0x0bd156a3a7dfc06L,
39626         0x0abcb50fd80d998L,0x0bf0e406f1364b6L,0x058d5f7ee75ac4eL,
39627         0x18ff6b0563029efL,0x06189a7822107f4L,0x001577796e01abfL },
39628       { 0x1a7926f2c7ec9beL,0x1983f392c590095L,0x08431be9ad28a4bL,
39629         0x13c5798b56e9cc5L,0x1bb8c07380c0854L,0x0f8ca6da0b06dc3L,
39630         0x12a7357bc14a4caL,0x1a21d71b428dbb4L,0x00b5d43d215ea23L,
39631         0x075f7817e1a5fd7L,0x0d9342121d5e9dbL,0x06d05a69994759aL,
39632         0x021d2d95e2c1401L,0x1c37551404e533aL,0x0597fb30ff475b9L,
39633         0x124073d6226db45L,0x0b048871baac077L,0x035a23600a58ad7L } },
39634     /* 29 */
39635     { { 0x019eb2e25e8fe80L,0x1bc834c11c50be4L,0x065a07906124ad7L,
39636         0x0d31d4da8bade3dL,0x1fd02e4058ad8adL,0x0920b6add72d6a5L,
39637         0x1f28405b70c9ea0L,0x1231663530b4668L,0x10b4da61082a653L,
39638         0x05c8d96da461afdL,0x1a05f34aabe3107L,0x09079bfb9b813d2L,
39639         0x0112b692541a630L,0x1c51504bb82ac9bL,0x1314a057f735c4bL,
39640         0x0c12ab356c4746bL,0x12f30c8ebe0932bL,0x04309a125d84702L },
39641       { 0x0902063b2231d8aL,0x11194ecd30b3394L,0x1f9c1c6a7c9ec3dL,
39642         0x00c07e08fd55f41L,0x1d92a1c36bcd896L,0x0a41db08c6653b7L,
39643         0x14988d05398adc7L,0x0b5424799bb74e0L,0x11a576437fd9b5cL,
39644         0x0980de1264687d1L,0x02b51040909f369L,0x0bc1a754d8052deL,
39645         0x00072a39960e6fbL,0x02069fd6e6c6244L,0x047550536bf284aL,
39646         0x0e69a53e9947bbdL,0x17c0037c5988441L,0x043199d4cce67f2L } },
39647     /* 30 */
39648     { { 0x013a751ecf53b40L,0x1637917bc52a169L,0x038bc4eb95b73fcL,
39649         0x1e1cc2e91c1eb3eL,0x172c414591f8ccbL,0x0e6e5b8556f65ceL,
39650         0x1f1c1acbb614932L,0x0051c016e583d5fL,0x089b24285aa7281L,
39651         0x13f53f05b3ce57dL,0x0e30993c29bdbeaL,0x02e61d00872eba5L,
39652         0x05c85730497ed7bL,0x04c3749f2d49f5aL,0x08302bf24afd750L,
39653         0x1875ea4d6b538d4L,0x0c90adf47c9b99dL,0x009592ff15d1016L },
39654       { 0x1b8d78a33eea395L,0x09b0c7b19fe2e04L,0x18a49c3b3bbf1eaL,
39655         0x118c51da18fd042L,0x01d68939524779bL,0x176e4848edae50dL,
39656         0x1cefe189b863961L,0x039fc047d17fd67L,0x06279fde1025017L,
39657         0x09763ee2af0b96fL,0x1a1a571b5329179L,0x10f17b7821e288bL,
39658         0x086fc3835e42de3L,0x1f085b291588a6fL,0x039e3fa7eae9159L,
39659         0x015948223b05472L,0x174576b61c2aedfL,0x010b13cd4ba5665L } },
39660     /* 31 */
39661     { { 0x14cdabf4047f747L,0x1119ee098ad0f60L,0x0f4d0397429c0f2L,
39662         0x13768270d2b3cf9L,0x0f01fbd81fd0c4eL,0x15c11e8c4e84588L,
39663         0x002854112710a9dL,0x1c9038449427316L,0x108084e4f8e8179L,
39664         0x0c57cca34c720f4L,0x038df15842fcbbfL,0x087f4fa4f21e3c6L,
39665         0x0cb31953884e6a0L,0x01bccefececb730L,0x1fe40bf9d7e61b4L,
39666         0x082dc76951e23f1L,0x15efa9453787588L,0x010341f1fcc13a9L },
39667       { 0x1582e26d0378878L,0x0a611d3ca2bc3e5L,0x02fe3d9a22ce788L,
39668         0x0a80a2a4e027a00L,0x00111f5d7548d4fL,0x1ffc813889e0aeaL,
39669         0x11730efd6949aa2L,0x00b7b4d60213692L,0x183dcc74ebc2f3aL,
39670         0x177b14221f7efd0L,0x183ba559716fd0aL,0x021ab25e4875a5cL,
39671         0x121bc3bf514f0faL,0x102bb53a3572c59L,0x1cc206a04ec21a1L,
39672         0x1dcb2178047f09aL,0x1959fd03aa032dcL,0x02f20b5fa93eb63L } },
39673     /* 32 */
39674     { { 0x0313760026cc23cL,0x0d5775ad9482c12L,0x0be3174bb85fe06L,
39675         0x17dcb988055244eL,0x17def07d8048e7cL,0x17c10f6de3eb773L,
39676         0x0ee25875a4913daL,0x148bef2cddb32d9L,0x0f81b17ea96a155L,
39677         0x16cf7b801f9f6abL,0x19641ba20a96cacL,0x00e55d28e300bcdL,
39678         0x11658c76f486fa1L,0x0581ad501a6cfe2L,0x0f992067d80f703L,
39679         0x153df6f673fd6ebL,0x1e3ca87554acf04L,0x027fb417643da7eL },
39680       { 0x125627fd0a10ad5L,0x02e394b4737a298L,0x15ae01a8458dff5L,
39681         0x1bbca067c653037L,0x1f4f8988b92de1cL,0x13f0ee1da25a2f5L,
39682         0x161e3286e625b6bL,0x08ea42cdcb40ef1L,0x182d472bea51168L,
39683         0x1ee9c157944aa22L,0x14580975bb1327eL,0x16396caa560445dL,
39684         0x13a1e6210f3614eL,0x010d3a53b1e2efbL,0x172f537a4580a14L,
39685         0x1c533489948018cL,0x07c48cb187e0f15L,0x028f5c0c71a0128L } },
39686     /* 33 */
39687     { { 0x1c1d178b92100abL,0x11eb04b02dc1c8fL,0x0956dc7967437cbL,
39688         0x0a29f97c08254f8L,0x19fd06af3f8b667L,0x01068387451c9aaL,
39689         0x1ef9558c9940848L,0x0a8cd2df9a2a51cL,0x16588514b0c7b76L,
39690         0x06c07c62c8952daL,0x1fbc13cc932dfc3L,0x1d9f8db47aeb175L,
39691         0x1831d1df2f6b53eL,0x19c095b6f6f7a46L,0x18980c7ccdae595L,
39692         0x1e137905d5c95dcL,0x07f300abd32d244L,0x045857caa98ecb2L },
39693       { 0x170180a2e603544L,0x19d61910d66cf5bL,0x19958901c0c8ad5L,
39694         0x1b7135787a742feL,0x1793225aad3e74aL,0x012b25c51e971d6L,
39695         0x14ad515eee813bcL,0x1d110eaca5ff85bL,0x0d2905d15e67143L,
39696         0x0c425a1017246b8L,0x0648671d8da95dbL,0x08426bc6f1be0dfL,
39697         0x1d10c64a02a8dc3L,0x060abd334ae0eb9L,0x0928d5335a93b3bL,
39698         0x0653b75b983911cL,0x0d08024f1b29839L,0x029b1f2a4a6d245L } },
39699     /* 34 */
39700     { { 0x15523b7e23fc641L,0x07397c33338318fL,0x17d6380274bff95L,
39701         0x1f18afebc252942L,0x116d64dcf203997L,0x1517fdd114b9265L,
39702         0x03b59a5ef93f52eL,0x06c7ea0fc8c14ddL,0x00afe3a5d785085L,
39703         0x177b66ecaa04104L,0x1f6227cb108df3bL,0x1074b870a4a6e03L,
39704         0x0d72a212f1496d8L,0x0ffbc7e6f12e33fL,0x1bd05192d059e0cL,
39705         0x00d2fd32ce00982L,0x0c3fa45c3a1c45bL,0x03199a00c1fde98L },
39706       { 0x1c9a0cca2fbbbceL,0x1b72e55065ba21cL,0x0438d0e3b38e1dbL,
39707         0x1c27005b0539cc0L,0x1cd45a1b0aad148L,0x07e0f04e1f2e304L,
39708         0x137421d72e165efL,0x057633fef21b0b0L,0x12598b81ed81c2aL,
39709         0x0c5ef97815f03f1L,0x1f23bae5d973a44L,0x1b11649f2b5c0e9L,
39710         0x1c0c98f09d125e9L,0x105ba5939dd8966L,0x001df3929abb81eL,
39711         0x004de8e47a5f381L,0x173959447d6bea8L,0x049d383ae0b1405L } },
39712     /* 35 */
39713     { { 0x0bbefe2715b27f9L,0x0d2f11514049193L,0x0ebff56289aaa4dL,
39714         0x0cf8270d28bbbe4L,0x092a215354c83e1L,0x0684faa23ccde4cL,
39715         0x1a9a139b91c426eL,0x16d8c75ec2dab11L,0x05e896706883ab1L,
39716         0x009c9d01e90499bL,0x1ca4864b08f768fL,0x16f5b9edd487a05L,
39717         0x08791559e1ab70cL,0x16b87f858921a75L,0x0cae914101a036dL,
39718         0x1971e3421fca450L,0x1fdd69f9c08e5f0L,0x00d3a11562258a0L },
39719       { 0x1a9dd2e9f40b675L,0x03301fe638f9ce1L,0x098465238d08a9fL,
39720         0x11da15690831273L,0x0e31ca6b8f3b615L,0x146db1d1d53ecbfL,
39721         0x18b92f07a197bdeL,0x01e62bf181258f8L,0x1a260788f9f5c6dL,
39722         0x0c19894a5b79f62L,0x16f358dad36126cL,0x112178d33536e75L,
39723         0x182a1175e766e14L,0x1e29e527df9bc86L,0x1fd8245fd0d816bL,
39724         0x1056caefed88f0fL,0x19c827c7552600cL,0x004a26b184e92acL } },
39725     /* 36 */
39726     { { 0x1deb63ee6ab9620L,0x07d36bc366c0467L,0x1609158c82cf7fdL,
39727         0x058928722a28bdbL,0x173b3f872ae5f86L,0x17cbd4ca847409dL,
39728         0x06d88ef6017cf94L,0x1f9ee36b8519305L,0x0b394c70e86e0ceL,
39729         0x1a7d8d491ded9b7L,0x1d618b6f89f9694L,0x1be70756c2d3ac9L,
39730         0x1127c828cbbae23L,0x1d183d456eb6f8dL,0x0777d986406267cL,
39731         0x076ee6d990cb302L,0x176a3cb77747994L,0x03ec4f9c1b7ec32L },
39732       { 0x0564242c9f92b2bL,0x0353ae237195efcL,0x02ddfe669715c03L,
39733         0x1006292ad127cedL,0x02ce6709b6efe85L,0x176249ddff450ceL,
39734         0x10a35c868ec6fb9L,0x03a4ddddd5386e3L,0x1d798115e15177eL,
39735         0x1df9de7583452d2L,0x1688811b4ad2cb5L,0x12b6b37d3bf9bf1L,
39736         0x1c77640b793df09L,0x0d15e9e2e4b44bdL,0x0bf9d133833d309L,
39737         0x013762de8badd13L,0x0e6b53f3acb3a85L,0x0224d7c0fb1f953L } },
39738     /* 37 */
39739     { { 0x0fcf132a16d9377L,0x1bbd9bf0d17cf61L,0x04ba1b466b966acL,
39740         0x0da0277762e5c34L,0x0b5f66bad2b12e6L,0x0f55a804b9702aeL,
39741         0x17b0b44778700e6L,0x12783e629fb8cbeL,0x0fc3118418a9ff5L,
39742         0x1b9e0f670292373L,0x144d8c589415b77L,0x17aedf64bc33851L,
39743         0x04845cd2d730a9dL,0x09b74296824f692L,0x0322a0f1de6e0ffL,
39744         0x100670b46bf8fedL,0x0f5299bf1e1c95eL,0x007430be190448dL },
39745       { 0x172060267c81b5cL,0x04ee6f39bc39e29L,0x02c2a0513f40beaL,
39746         0x0e4c41190654e86L,0x18ea40f53006c5aL,0x1209d2270333306L,
39747         0x0527e774097e625L,0x1857be701988d72L,0x1801566190a125cL,
39748         0x06b51dba93c9e1bL,0x004dd1ade98bc81L,0x04d0b0bab2f16c0L,
39749         0x188395fe66a9cfeL,0x035930fb6e56865L,0x0764862ead1a3f1L,
39750         0x04805941debdf3bL,0x087c507d4a85e45L,0x037a2027899367bL } },
39751     /* 38 */
39752     { { 0x1e1920b4febd3ffL,0x11a6c7efe95dd51L,0x1cab866a60a7298L,
39753         0x018deb78416fa35L,0x1aa39ca923de161L,0x063855f1026df9eL,
39754         0x0dc2ca8b7a6e1b6L,0x01c4e5c186ef93aL,0x080914c06e56551L,
39755         0x108f3d42be5db58L,0x1f1bbf6099a9badL,0x09dc612b00380edL,
39756         0x02b9e24063dfac3L,0x1c3d52e2b4ffa05L,0x11c334a9ee8c6a5L,
39757         0x1e0e81c9a3fbe67L,0x1e2903e31326895L,0x0482bb8fc3fdb38L },
39758       { 0x199ba0da4062beeL,0x191c64a6becfca8L,0x06f078248b00639L,
39759         0x03625b0abfea7e5L,0x0d68ca29de9b2a8L,0x0604bfb24f9f76bL,
39760         0x0628192b7f0d314L,0x049032c95733b67L,0x000d59c477a5872L,
39761         0x0ff51cb3a62c81dL,0x1f63b85410f7402L,0x14dcbe3d9840d55L,
39762         0x030db9b7b4c5721L,0x13646a955b6b524L,0x120a89c1bff185dL,
39763         0x1ef507bc483ad59L,0x0cc0605f05227f2L,0x035114a9db2026fL } },
39764     /* 39 */
39765     { { 0x0452d8f74fce389L,0x11a60157d2ab249L,0x12efc3b5e094165L,
39766         0x166ee31c1b26ef9L,0x1fa69a4d89f4045L,0x0ad85d0883a73ecL,
39767         0x1b79975c2ec1dcaL,0x0f7645aa95be20fL,0x15c39a3d8a1a29cL,
39768         0x191b6016bcaf1d5L,0x00b400ad626544dL,0x0b7caf217dc5ee5L,
39769         0x11a8e65ea25e226L,0x1000e75ec8f0750L,0x071500839c69c21L,
39770         0x0d3022d201eb458L,0x027c3b2d5c0357fL,0x029464f5030cf1aL },
39771       { 0x0dc86b45f26c577L,0x1a3844a1c5ea28fL,0x004de4960a9fe01L,
39772         0x01bc3cad3e5bfc2L,0x1a55a356e08eacaL,0x0bb10b2fca977d4L,
39773         0x1c7ca93602d4f92L,0x1e1a56cb0ab9abaL,0x0246704bf66cea3L,
39774         0x09fb20fa49191e5L,0x0615726b6c4c946L,0x059c5a33aca54d0L,
39775         0x105b82ed7b86d52L,0x070a8694a9b04f8L,0x04fa244ec3c0252L,
39776         0x16892475b17f616L,0x157cbb1556cf794L,0x01007c849b9c5e7L } },
39777     /* 40 */
39778     { { 0x1b22fc58388387fL,0x178b8147441e2fcL,0x0e4346de5cf33c9L,
39779         0x05edd922e288f95L,0x030cdbc08d5d4eaL,0x111e15970b7a4c6L,
39780         0x11517724a443121L,0x161d629236061b7L,0x0631deb2e14de21L,
39781         0x051083317f4187aL,0x1a5e70de707cfc1L,0x16d1f60d4f2b498L,
39782         0x1a1619dfa98a732L,0x06df164d9d22193L,0x0627faa468c1f4eL,
39783         0x0663f273791a407L,0x1dc3daabaf20f4aL,0x02e183f4c6e87aaL },
39784       { 0x1c4e0c435b233daL,0x14842917b7cc2ddL,0x1486a2c091a38f4L,
39785         0x1352d22dcf33ba5L,0x014bcced978f40eL,0x083b160193ec363L,
39786         0x1cbb657a5540acaL,0x0661ffa432f50f3L,0x0c436513750e0bdL,
39787         0x1618a450413e262L,0x004aa0ff3f02c89L,0x02fc63250b138f3L,
39788         0x1e8830f42dc3d8dL,0x0583fc1fc5ab967L,0x144523df367fe49L,
39789         0x1f358663952a014L,0x185d0c539684c59L,0x00ef8b6fd60a1a3L } },
39790     /* 41 */
39791     { { 0x07bb4ac68bcacc3L,0x169a7a187ac67e6L,0x1d3f518615681b7L,
39792         0x088b93e1798b3f3L,0x0375c892f549199L,0x02cc1d6e2fbf632L,
39793         0x1421c6e1c23c4f2L,0x01f6654b98905f9L,0x1efdcdc352d6b4cL,
39794         0x1d9278245637d96L,0x0b53d4ce4191c52L,0x0a5f70747588b30L,
39795         0x082337a223162ebL,0x05e1ede9b8986f9L,0x19eb03b739ee00bL,
39796         0x0e2fd1672b2b248L,0x01721d3d2e81b56L,0x0394d3fa8232893L },
39797       { 0x14ed1aa8420f90aL,0x070cf07f2642ac3L,0x0aaac2f9d2bd8daL,
39798         0x01194c19536c5a9L,0x1645a86776fcc48L,0x18d92679885ad2bL,
39799         0x16d104c6eb26f76L,0x09ddeefae3a5bd4L,0x04706d21072fcc6L,
39800         0x0dc9348b39ebbf8L,0x002fcfa278198caL,0x19a6e80efa8045cL,
39801         0x0d829232e2472d0L,0x1c6e42999f10820L,0x0e3d99cbe45b7ecL,
39802         0x1c33a91776b3629L,0x15c19de9f4ad44bL,0x03fb69b249196ceL } },
39803     /* 42 */
39804     { { 0x1d064de6e794819L,0x1b4a77c175ed09dL,0x1f82e478a01169aL,
39805         0x060f4879a43e02fL,0x030433e9190d31fL,0x1fee5a361379133L,
39806         0x04702e9222a9c2aL,0x100831b210b48c8L,0x11b934fe6bffb58L,
39807         0x0e8f11bf1007c24L,0x1358fe95504f6ddL,0x1aebc4767eefbe0L,
39808         0x0b0f91bd30e216eL,0x1b94e284d02c336L,0x0aacb5e130e5765L,
39809         0x1ad0dd92fc3108aL,0x06c8cb7c1f90093L,0x0168191cab14784L },
39810       { 0x01c94074a44b4c5L,0x0343ce638164c54L,0x0a1f3ac3725ee61L,
39811         0x0cdc75464396a04L,0x04c256c23030112L,0x0da422e05643b1fL,
39812         0x1cd6d940d348395L,0x1b9552d4081e481L,0x0046d26d37cf7eeL,
39813         0x152d4709dc0832bL,0x112e5e0f5c30ad8L,0x1f10b3c9b51f0c0L,
39814         0x1a5457f5d12fbafL,0x1a98dbabc94ec80L,0x13a5ce74a787acaL,
39815         0x137b2429b57b93cL,0x19b5bd724fc4eaaL,0x039a609598f7cddL } },
39816     /* 43 */
39817     { { 0x0fe3c2e92f9b086L,0x0dc9f59fea2a24cL,0x022d700b1971190L,
39818         0x0389e064848f9c4L,0x079d29f68a52dcaL,0x037afa5af60becbL,
39819         0x0a044474bfb4250L,0x07e4c1ec7b81b37L,0x0de2b056f15472aL,
39820         0x18b86cf80394873L,0x08fa36dad723e46L,0x10739e6987dd45cL,
39821         0x011b973ee2345a2L,0x1d9268e2cdee2a3L,0x185068596f69b0aL,
39822         0x164032faa574678L,0x09f47bb16129d2eL,0x03e2ac54390fdf2L },
39823       { 0x1485a523f350fecL,0x13c62b51c6a605cL,0x1a88356a9934059L,
39824         0x05b2db45c91de68L,0x0f647b3cb85daa0L,0x0f4a36422f62752L,
39825         0x1d2af03469b2835L,0x00683b1a3829f53L,0x143972cc59c8b13L,
39826         0x1f0fa46a1a7fdfdL,0x13a4ea06748c619L,0x0120dbbde47e6a1L,
39827         0x19200cf12c49f53L,0x1202197e1e17367L,0x125ad4909a47305L,
39828         0x12f7d7ffee968e4L,0x14844527c9f020aL,0x01a66bee53d9e21L } },
39829     /* 44 */
39830     { { 0x031761a59e7fe87L,0x1718d0023e6b978L,0x19a3eb8c3d8ac7aL,
39831         0x1b6e3b62864f205L,0x0e0038f4a666f48L,0x1eebb6baf7333c0L,
39832         0x13570ed16b19c0aL,0x0221a5f705141adL,0x027ce7f1d9d8c5bL,
39833         0x00ff0720905af4bL,0x06e612e499f0dc5L,0x0b13ac06259b2b4L,
39834         0x0eda5493565206eL,0x03863a560c339a1L,0x15ec2ccdd1482e4L,
39835         0x118284e07976b2aL,0x087f621f59ca6edL,0x03e758e6155fbdcL },
39836       { 0x047a5bbdb7fd65bL,0x02e601b64a2be03L,0x076e7849c62b635L,
39837         0x09d274ff638db53L,0x1d1566a1ed1dbbfL,0x00648ca28964ae5L,
39838         0x149a52186e8036fL,0x15c78d985313cfeL,0x1671961500941aaL,
39839         0x1e7ae87e4629c71L,0x1a64a68969547efL,0x130a2f941e4d5adL,
39840         0x0afa89ef7e90710L,0x18d5a2a4ba1dbc7L,0x1470db4e757a8c5L,
39841         0x0ad1ae885e7e7cdL,0x15c25a683e0059dL,0x00fb14d4c913e76L } },
39842     /* 45 */
39843     { { 0x125ddace45a1c3eL,0x149b2a0fbaa2fc4L,0x1f2cdf9fe0a1cb4L,
39844         0x067c98f3a48ac45L,0x1c2645d68823451L,0x04015caeffd7c24L,
39845         0x07e80c1e3d37665L,0x198acd24fe13a67L,0x19a500a1e9fd91dL,
39846         0x10040c0055855ebL,0x04d68e0653977f3L,0x060f315be111b2eL,
39847         0x189a45a2a79e876L,0x1c45a1cc9dd780dL,0x1ea65f5bfb58551L,
39848         0x11ddb301cae45ceL,0x1a2aac90ffa2a37L,0x0253afed145ec02L },
39849       { 0x09a8fbb55e74cbcL,0x19c677d58c792e8L,0x0b5a5d93b0e9cddL,
39850         0x17cfc15a621f847L,0x0481cc9bc5a7d35L,0x05761a73af03477L,
39851         0x18f13c30baa64f5L,0x059e2649fd01a94L,0x15dbb7c1699b059L,
39852         0x016b3a6d3f07a35L,0x159b1e8c03eba91L,0x104266675906b4bL,
39853         0x0e8c408496e83dcL,0x0cf7afe0b877c09L,0x0d3a18a5b8772daL,
39854         0x00fb0dc56ee362eL,0x19a04629cdc5835L,0x02c0cfcd711ec0bL } },
39855     /* 46 */
39856     { { 0x19691216aa78811L,0x1747a1081f3e1ecL,0x01c08ae79a63d93L,
39857         0x1c9eb059bdbbe02L,0x0ecfac1ae6001f9L,0x1c9804925304579L,
39858         0x0a445bbd31e1018L,0x140a4c5d5cdd7eeL,0x1ddbd0af58c4ee5L,
39859         0x1ad7fc8766c3de3L,0x16cd31bc93c4521L,0x0503d0cbe2e45fbL,
39860         0x06886c1b9a48104L,0x0f7a118fcab4921L,0x09fa0b9bd7cc822L,
39861         0x12b915eb0f59fa1L,0x150d65719179ac3L,0x03a2cb01e09b253L },
39862       { 0x02475bff41ae519L,0x00fd8a57c79288eL,0x134abbecb0f4d10L,
39863         0x16a39b5e10e1bbfL,0x0208bb199b2d385L,0x19f9fb4298e12b4L,
39864         0x05da45b2277d930L,0x1758479f53248aeL,0x12339b51e86d010L,
39865         0x06d87469131c189L,0x0785e403fb7adc2L,0x1b9746d0fde3eedL,
39866         0x03914764753fd96L,0x0622e46ee682359L,0x0d0f5e3cffc8190L,
39867         0x1dd21dfa2cf7b70L,0x145493ccb6d4b77L,0x019812a89d9e7bdL } },
39868     /* 47 */
39869     { { 0x0f0046935eaaca1L,0x025bac488c8811bL,0x19979b4a553030eL,
39870         0x1363d3adaf966eaL,0x029c2757cb9199bL,0x139c683ac291a4eL,
39871         0x0909e272f46eae3L,0x113371b7d20b247L,0x1a237793e18fe18L,
39872         0x0138babd3a17041L,0x05e7493baf584e9L,0x00a9a9e59eef189L,
39873         0x11958705de40325L,0x19ecccdd51dc504L,0x03fb8786c646f64L,
39874         0x1be2975fdf74876L,0x01cb3bad1843facL,0x0499456d821c3abL },
39875       { 0x1e84e80f906b872L,0x091d03c131332d5L,0x09f8ce6333ddc15L,
39876         0x1beab6a647b138dL,0x0554dea82fab551L,0x0ac4e6d02bc7650L,
39877         0x15d43bc9948f4ddL,0x1fdb1fac4850c95L,0x093f27fc5178fe1L,
39878         0x19f37984efc3a11L,0x0b9278dd434151eL,0x0d64bb80714250cL,
39879         0x0284db682b7d90cL,0x0c40c98560d0d71L,0x1cf82911fcf6adeL,
39880         0x04b8a61cd7aa575L,0x1e70680025bf62dL,0x00550f9e7d6e86aL } },
39881     /* 48 */
39882     { { 0x182219022a10453L,0x15c8e1501d085d4L,0x16565991bcef747L,
39883         0x09e716df8d5f76bL,0x18cfca1da58de34L,0x186d026723e1f2dL,
39884         0x0bb5bf36385b43dL,0x11d58886937b44cL,0x09320d87bc56e2fL,
39885         0x071f5040c89c72cL,0x18b7fe8ac8db027L,0x14b91cfdf61b4b0L,
39886         0x0b16ac78eb6b0f9L,0x184da8d7a5a9a19L,0x14658a1bfd0c415L,
39887         0x0075a11c46df11eL,0x05e1f93f176eed4L,0x02ac99bf04b1b2aL },
39888       { 0x0ddf738d8fd807aL,0x0764ed589891118L,0x136d896bef0fd38L,
39889         0x093e25f12a2945eL,0x0c3044fdd5b7060L,0x000a47da379e11dL,
39890         0x195506c8cb47fd5L,0x0eac368b1ea7369L,0x1f694b24a0dd70bL,
39891         0x1e3214c944ac0ecL,0x1526fbb97f88b43L,0x08fed4317ec780bL,
39892         0x027f1929d67af34L,0x00aa8f4674b50eeL,0x1753e89abf980a3L,
39893         0x059684fb595e656L,0x0d34a1631bc545cL,0x04980387cd8648aL } },
39894     /* 49 */
39895     { { 0x0f32c5e69a9bc05L,0x00ce32c4e25b9e9L,0x197a51997e70297L,
39896         0x0779f6987212b93L,0x1ddb7c318ab0f29L,0x19c0245c83843b8L,
39897         0x166f6253a59619aL,0x0d3e335219ec0d7L,0x1cc1d58dfb6fd2dL,
39898         0x036e627230ec534L,0x1709dfe73920c62L,0x132cecbf150588aL,
39899         0x0cc3badc8d749a5L,0x088966d597fe334L,0x10f1f2ce0060e5aL,
39900         0x04449530f2b8764L,0x0148775f310010aL,0x0021d10a0ac3dafL },
39901       { 0x1be9dbc3a873752L,0x049fa17a217f73dL,0x0b2306308607b85L,
39902         0x01c52ed3cf30394L,0x1e768c5f00ce309L,0x0bb3bf5a3135646L,
39903         0x05398cfa73918d3L,0x17ff138595bc1f5L,0x004f5cc1141f5b5L,
39904         0x0b2fb9b11146096L,0x1dc1a8301733949L,0x1fff7c90f89fe37L,
39905         0x09a499f1a45d07fL,0x0c6ca4001f621e0L,0x0fc4be13d39e6eeL,
39906         0x01adb1466b42c0eL,0x0e84bb5eaf70f97L,0x00c683a3df92685L } },
39907     /* 50 */
39908     { { 0x0d3c77c84601fafL,0x12df1578e0fb92cL,0x1e63445b601b251L,
39909         0x0dab61b279fec4cL,0x1ec6723a3996c0cL,0x1d29a497d0d6baaL,
39910         0x1362a59aa05100eL,0x0cbb89928445586L,0x1ddf471deed6758L,
39911         0x05652cbca9ea947L,0x118ed493afd9f76L,0x10e2fc4b69a765cL,
39912         0x1a43159daa25824L,0x019abaa011e2d6dL,0x0e2c6995163e71aL,
39913         0x1a4639ed0bb4ff2L,0x059981a4fdacefeL,0x0388849f6845dafL },
39914       { 0x0aa3fc6401f161aL,0x0c2b04ba62f4389L,0x0bec5ed77e0bdcdL,
39915         0x0f491cc5329544aL,0x09dd847db0b82b0L,0x14e2d30011a0ab9L,
39916         0x1d4e3c795340114L,0x1979838a73cdb31L,0x136162b5328d3abL,
39917         0x0d1bc9c15427866L,0x1ea06d37b9d211dL,0x0bf698477e37ee2L,
39918         0x1f787e8b3e16cf3L,0x0cdbcd583fe8e14L,0x1db182edf69f9a1L,
39919         0x0916a0e4201410bL,0x1d431840159e7edL,0x00bc4c5ed26ce4bL } },
39920     /* 51 */
39921     { { 0x18483d8ae1b8cf8L,0x0a5a174d1442b66L,0x013c81292f08c8fL,
39922         0x1194f4d3f4ec66bL,0x1757bab24e0b222L,0x02fce5457ded45fL,
39923         0x0570e16c90221b3L,0x0d68ff69027a835L,0x13f1bc53cc2aabeL,
39924         0x1166d1f8d68acceL,0x1b02070c7aa6c7cL,0x009602c29582365L,
39925         0x09c6afa7ab048f3L,0x00a06e1ee718e77L,0x1a2aee956bdd8cdL,
39926         0x07dfd096f566fb9L,0x0b250de7648c7cfL,0x039d446e78a9ab5L },
39927       { 0x186828806e83b39L,0x12209cfa201be9fL,0x0c3c5f6f21051deL,
39928         0x1ea9a2ea93f20b1L,0x12307ffe2db64f4L,0x093130d11e75357L,
39929         0x1fc98e4fbf5553cL,0x06a5e9ccb1421e6L,0x1a4437ce3f4ee1eL,
39930         0x077a153d49e6f45L,0x0f27d24e6aa4059L,0x1ad47af6b9a83bdL,
39931         0x11f88a3acc44223L,0x16304516bc4d350L,0x1d5b0195bee77e0L,
39932         0x14601cf3b71c777L,0x01e73c56af2668fL,0x02979958bd71cb5L } },
39933     /* 52 */
39934     { { 0x0f524c1e714f71aL,0x109314d6ec28cabL,0x0761972b6f8f06fL,
39935         0x10b41f6c935b231L,0x01d192d9d88bf5cL,0x1925b7cf7d35491L,
39936         0x046738ffa0e25bdL,0x181d87f5c4964a0L,0x14b6af9f62ae0d3L,
39937         0x1e75d05eb0cb126L,0x0c24acbf6db8ea3L,0x06ec64c79a52fb8L,
39938         0x1ef95c43bdc91daL,0x06f5a26c98603b0L,0x1034c76244d9003L,
39939         0x1133ffafb9d0887L,0x0c178fec3b19871L,0x03cf0a69477efacL },
39940       { 0x18222359bb40c55L,0x1901687683d2171L,0x06a520e307d0289L,
39941         0x0fb0c94f1c91cd8L,0x0c6c55c92b5f24aL,0x096a843f3f8a050L,
39942         0x0784398b0412b38L,0x1ab361434fd8236L,0x0fd8a275fafbb3dL,
39943         0x1f9aa7f4d1db598L,0x0176791980a8077L,0x169b2776cbeeb42L,
39944         0x0b0f82fdeb3d371L,0x0f2342a2ed2e5f8L,0x0f545f918048a6fL,
39945         0x1e924a0bc21738eL,0x0e277cfa541672fL,0x006c761454cab36L } },
39946     /* 53 */
39947     { { 0x14cf73ecbeee995L,0x1c45e6a48f40600L,0x12b766ae9752cbaL,
39948         0x072609909ac2b4dL,0x0ab03c9a2f7d463L,0x1d5dca5d0280e94L,
39949         0x15dcb23dc8f7a46L,0x129910bf2eea080L,0x0b5e1d2b3c7fcb0L,
39950         0x0f73ccaefcb638dL,0x036aacd19126798L,0x1bbabec0f265719L,
39951         0x01b1243587db425L,0x0fe3a1a038128e5L,0x00ab2249b5f4efaL,
39952         0x14e9f182f262192L,0x0fc72522c154559L,0x043000f13e1b9a5L },
39953       { 0x1b00ba5e7693947L,0x0320f0096031589L,0x0383a15242a191eL,
39954         0x1fb2ae9abdc3487L,0x1bd3ba615173dbbL,0x1f503aca9975c64L,
39955         0x04ae47d06f2e17cL,0x1695839848f1977L,0x00f34648e1ef901L,
39956         0x0c94e8f6959d977L,0x1c7aaf0f5d6ff37L,0x0dee2739e9a48e1L,
39957         0x0df04249535cdbcL,0x03fe59c1e6c322aL,0x17e4c30781e6049L,
39958         0x1780173e413682fL,0x0c14225fc31114eL,0x00102c8e59a3ca3L } },
39959     /* 54 */
39960     { { 0x1003721275e0af4L,0x0a0f7f3c52525f1L,0x13db45d5d215c84L,
39961         0x0e2d1ccb3cccd9fL,0x0e2842ee5fa1d73L,0x05eafb131f1f2a0L,
39962         0x0412ab7b30f5252L,0x030033bc07a48d6L,0x1f8a9e903f343d8L,
39963         0x1abdd252d860698L,0x1b14194789d97f2L,0x0a3eca337ecf048L,
39964         0x00f2119a0180c57L,0x1c10ea7a2f82e10L,0x070e819f9921ee1L,
39965         0x0c0a44c5f29544cL,0x1ef56cfe4897214L,0x0288ccc2fd0ef82L },
39966       { 0x019497db18586c0L,0x00aeb637755312cL,0x1ada5f368a2c011L,
39967         0x10f8328b28f8d48L,0x0ed3a5069a149b2L,0x04a65a5ab1b4fd2L,
39968         0x1bb89c24aa9990fL,0x012ab79ce7553d3L,0x034bb2870778935L,
39969         0x17cafd80375a993L,0x140c8e58e3d2162L,0x04d0b74eb7f10f9L,
39970         0x1d9d42d58129376L,0x12e36b26f996b79L,0x137b506932b55d1L,
39971         0x140cf30bea1f765L,0x19acf34ce0e9006L,0x02cf57932ac52bfL } },
39972     /* 55 */
39973     { { 0x1407efb6ec3876fL,0x03091f87a43243dL,0x1bfefe24c0e5e03L,
39974         0x008b5235605576aL,0x18811b829592eaaL,0x0f9fe4e72dc26bbL,
39975         0x184ee1a9c68d07eL,0x10182ffbb0de1cfL,0x088ed8297655a08L,
39976         0x0eb6e3a40eaf333L,0x1277d8745c5e5ddL,0x191bc7ef3c3fdffL,
39977         0x1d2046192e36ad4L,0x13a7ed316d8a98bL,0x1766451e327e9e8L,
39978         0x12e3809d9249f05L,0x1fb059d1e383a64L,0x01da2287513105dL },
39979       { 0x1b7a955c776dcdbL,0x052be40e45d239eL,0x000d415d83ecd71L,
39980         0x03675d86a75c50aL,0x07117be5e3e8069L,0x1667b09c019adf2L,
39981         0x1e45b8711f8e815L,0x1c24a79fbd6672eL,0x03decdfbaf5cb7eL,
39982         0x1e4bca7be7a5b82L,0x05a0327fe0518bcL,0x1c237c7b553e480L,
39983         0x1769f91d8a4e440L,0x05af4e2ee2e821bL,0x0df4935041b1ea3L,
39984         0x169443232134267L,0x014e893c8383764L,0x0253ff1866214dbL } },
39985     /* 56 */
39986     { { 0x18f3a702455c7c5L,0x11b74380abbaa73L,0x1491d88c98b16ddL,
39987         0x1c378f018fe6588L,0x115ed8772c98b11L,0x0932fa6a4757564L,
39988         0x0803eec134f0066L,0x1d0d6a563379f4aL,0x1c46a098193ea3fL,
39989         0x016399edd3ac02cL,0x12ef58625aab336L,0x05f99d1d9aa3a64L,
39990         0x1d02fc44b3ac09aL,0x1550bc25a94c8c7L,0x0882173c311792aL,
39991         0x0fac26ac4c681fcL,0x12353cbb676c50cL,0x041fd0f51b28935L },
39992       { 0x0ac86da10ccc646L,0x031bfbd8228f4b0L,0x18c228221840b38L,
39993         0x12406933057779eL,0x1c0bcda023c1901L,0x0a7ebeb83fe1ce7L,
39994         0x0eeedfd347c546fL,0x0c1ad4c9ce888e2L,0x157bdc676c5ac9eL,
39995         0x0b629819bdb08b4L,0x144e5b73d028751L,0x184a932fa58fa68L,
39996         0x04c2c4a739f3edeL,0x1535697129a574dL,0x1a57e045004e5f9L,
39997         0x1f57e40ed3a9a47L,0x1e0cee007c6de98L,0x030a04bbcc98e28L } },
39998     /* 57 */
39999     { { 0x1db32db15156623L,0x1bfde55bd33e11eL,0x1d41bc678f09a04L,
40000         0x05132498c24c023L,0x06804c1c34218b0L,0x157353a4950587eL,
40001         0x0f987596f9c1abeL,0x0d27627a47c1a03L,0x144545b47f87f4cL,
40002         0x0111b71026e0d51L,0x149874f14587b35L,0x14c77b11780ec26L,
40003         0x161599d7201eb46L,0x14dd7879bc636c1L,0x01ca083da557f85L,
40004         0x068148cfdd7ac2eL,0x1882f1b8a2a3e3aL,0x031b6d63b1685afL },
40005       { 0x0280db9b4c80af3L,0x04e68a71c4955caL,0x0b83451df772686L,
40006         0x10d1f3e29e4dce0L,0x00baa0b2e91aee3L,0x18a51494327b1d4L,
40007         0x1f2dab3607dce2dL,0x1fa61c370e18bfcL,0x1883ea1c3b10837L,
40008         0x0d13ca9b590244fL,0x0ca9a1628b697cbL,0x17e40751f42875dL,
40009         0x15dc70b1c4e2330L,0x14cb3c7a5ae2445L,0x17d9d7029e31364L,
40010         0x1a6d04677a1304bL,0x13f37b5c0767b67L,0x017b6deff2685f7L } },
40011     /* 58 */
40012     { { 0x18472fd2e4da7c7L,0x07e48d733bc9917L,0x0228f709a389c23L,
40013         0x00f33448486c95eL,0x11d58bff0f10dfeL,0x04b17377c896ac3L,
40014         0x1a829afcd77f262L,0x1825172df52be8fL,0x0734a79eaaad308L,
40015         0x0b9819bcfa1bdddL,0x12f639b3d53dd65L,0x1b9fcec65dd8005L,
40016         0x0b5319310447606L,0x0567b94ea025af6L,0x177c7782b8225f0L,
40017         0x0e89112c5170c77L,0x14eeced154ef87dL,0x02e5b70cba2c6aeL },
40018       { 0x0cef197008c75edL,0x04e9f7b77557c4cL,0x180861d7a5b5f3dL,
40019         0x1dbb361b143adf3L,0x19576daafcec2cfL,0x13eddc1c530e7f5L,
40020         0x053d04000fce4daL,0x0a766f870d04770L,0x09fb66dcbb80e31L,
40021         0x13f175d02cc23d4L,0x118ff4d69c9dc27L,0x1b23f93c1da149dL,
40022         0x14d515baa4311f3L,0x10466a719e0ee04L,0x157baa9d681baf2L,
40023         0x0583f56c2e4705dL,0x0e52e82bbb0e1f5L,0x010a4eb1828baebL } },
40024     /* 59 */
40025     { { 0x01a8e6f5f9311f6L,0x11e4fdd5e0fc2f7L,0x14bad250826b25fL,
40026         0x1832ee9fc29f4f8L,0x0555844f04c2f51L,0x039d59ae77e8914L,
40027         0x067f2d4e18a8ed6L,0x134ed1dfbad97daL,0x0cdc12479ee5846L,
40028         0x091bf189ec0604eL,0x128a4301130a304L,0x02f57a8fc50fbaeL,
40029         0x08ad0ffeef9ee65L,0x00c6940fe121091L,0x1b0378509cc223eL,
40030         0x17ae7d78e897887L,0x06c5b26eccfb415L,0x00a7179a86583e1L },
40031       { 0x08d2a104216946bL,0x00f83bd25ec96aaL,0x028d0da54581ba0L,
40032         0x1ec7432f92b32daL,0x061f77c90f1b5c2L,0x1fbd913ced1e278L,
40033         0x048fc707358d24fL,0x078bcc36ca14468L,0x0826b34c5f28403L,
40034         0x0c5c8746179a10aL,0x0d5882ba01bb15cL,0x068bc64953694beL,
40035         0x1e8b53cb51a2faeL,0x1ccb2bbc4605dcaL,0x077bccb253dab0bL,
40036         0x11e4e0fd8c0fad7L,0x04f63bf1dbad0edL,0x02c29bf016e5b0fL } },
40037     /* 60 */
40038     { { 0x164b06464f80ba2L,0x02af382acd22d8fL,0x0cd3c7d2d8d3a38L,
40039         0x1fbd190905864c5L,0x030c780aef4f7d5L,0x10f349ceaaef506L,
40040         0x10d2c5d02bee73eL,0x1dc59fcd4cce8c1L,0x0f66959411187c1L,
40041         0x1c1793bafcba6caL,0x02b390011527ac4L,0x167f757bda04394L,
40042         0x064e3653eaf8244L,0x02ae2fc1e1b7a68L,0x1af3a43aae7c373L,
40043         0x0284bb27739df59L,0x10d16658e721906L,0x0242bc1afc16bcbL },
40044       { 0x0d525bcd2576210L,0x1c553ea8daa21eeL,0x1c5c6f60e6527cdL,
40045         0x07e7158c43fd2f7L,0x018408cc930d0f6L,0x07a9fb57c7960bcL,
40046         0x1d7909a4b21f898L,0x06e1dc8a80fb614L,0x10ec47ae5ffdb1bL,
40047         0x14894ee3d535225L,0x04cac8b902dd75dL,0x09a12bde76ef6dfL,
40048         0x1568bc63e8e0676L,0x0e000a60147ea3fL,0x065763b46041252L,
40049         0x10b5f21c5a7fbafL,0x128eb39a05d6c2aL,0x036013bded10f98L } },
40050     /* 61 */
40051     { { 0x01b7086b509e7efL,0x1763d9ebfcfc8f2L,0x1e51549ae22e210L,
40052         0x080a3ba1579a50bL,0x174f1ceb6e44e06L,0x1f330dc80cc6083L,
40053         0x11f65bb2afa6048L,0x1dc8902226c65ecL,0x11dd82b4526c52aL,
40054         0x128483fc9cee4eaL,0x1bbbcbf35156ff5L,0x09bb1a5cbaf97abL,
40055         0x1288bc9f2a7815aL,0x0bd1d9912d6a764L,0x0e72f6f1bc4342dL,
40056         0x09dd1d1a183ce41L,0x18f5a0b071a9b77L,0x01833de4d7917e7L },
40057       { 0x0e589f2b7ca9326L,0x0837ed89127b1f0L,0x1485d1e95ef45e8L,
40058         0x1ac561105d646a8L,0x0391ffcf2614982L,0x072206bf9d7aa22L,
40059         0x0c1c46aa8cdeea1L,0x0a851d46f612837L,0x1a957dcb42e4a7fL,
40060         0x1d5b3160d356afdL,0x178e07df0da8839L,0x1019375416d7a26L,
40061         0x0c94e4671f42e79L,0x05849171a11b818L,0x169627c93318ffeL,
40062         0x1fed9a21aa4f288L,0x195bb99d316a870L,0x01c8641e554cb60L } },
40063     /* 62 */
40064     { { 0x0d3fa82ffc4a73fL,0x0eb1a9dea9981a8L,0x1e28992eddf4999L,
40065         0x1c45ae7b090140dL,0x0323b8aa81c04a6L,0x0626ad1204e7fa8L,
40066         0x07064c773885e31L,0x1706e95501c181fL,0x10b25a38700186bL,
40067         0x05bbd085578a43fL,0x0e6b56ad2637874L,0x1b4c3541822c2beL,
40068         0x1d96e25ce892e32L,0x0f43236891471edL,0x1ec71a2d5f22371L,
40069         0x1bd8ace5622c84cL,0x13a5d0d807f600bL,0x01f52003e911f2bL },
40070       { 0x16debd0a595d0a3L,0x0bb65d7f859da6bL,0x153e6c6f6e5e9afL,
40071         0x0898e298e37e582L,0x021af66362b19abL,0x0a0f7b64df99dc9L,
40072         0x03db48f61f12632L,0x1824ab00987af3eL,0x16f1a10052a7acbL,
40073         0x0d5bcecaa829457L,0x1e9bc32345884d7L,0x16dbbcbc2053faeL,
40074         0x12f95da12b40508L,0x1ac545d0ecad607L,0x18323ee2182bdc5L,
40075         0x09a6816329906e2L,0x0a0a40e6c80ce00L,0x004fc150bb58a55L } },
40076     /* 63 */
40077     { { 0x0abe588c21366dcL,0x00527d7baed7cb0L,0x1f66b2e4fb51ca7L,
40078         0x1d0f42dae0e0a03L,0x18e7361bb97e744L,0x1aa679d217053d4L,
40079         0x041e06b36bfc8a2L,0x1cfe10f99776f7bL,0x1da6f3983663250L,
40080         0x16b49f75d783e04L,0x0bd30e32ebc55d9L,0x1c0fbf9533a0f37L,
40081         0x07f26d8dab5a984L,0x1f5d1b7cd5a6992L,0x0374859342f9c05L,
40082         0x09e066f773cca1dL,0x05a72aa4e24531cL,0x03be8f4c25ba9ecL },
40083       { 0x1373239d8e62367L,0x0c245dcc10678ecL,0x0d116a725f10cd8L,
40084         0x1c29f2c1f8018fcL,0x140474b59a0ec9aL,0x1032eae7a0f867bL,
40085         0x0184297bb7a3fb3L,0x0bb63bcb49d3d01L,0x117c44ae4ae0cf7L,
40086         0x1d2b191b58a4685L,0x09d03f4a7fcb70bL,0x17151196425cc9fL,
40087         0x0d6a863016c605eL,0x103da60bf963b8dL,0x1525e15b5844b9dL,
40088         0x1c1cbfd21d80e81L,0x1b0599be18be256L,0x0273755f6652a56L } },
40089     /* 64 */
40090     { { 0x10323d3fb99cfe6L,0x0de136499a0bc4aL,0x1905f2f7edbdec2L,
40091         0x09134eaec0c8223L,0x10919cb09114174L,0x15fe97a6319efc8L,
40092         0x18b6dc57f1f1ce5L,0x15919432a251956L,0x0306724734db81aL,
40093         0x13d1235da6262a5L,0x1a83eafc8a591b9L,0x0be3f4b6bae1aefL,
40094         0x05c2f192f35bed1L,0x1fb34856d2b436dL,0x0942df77b2b1ca9L,
40095         0x15a5e1895e54595L,0x056f44631c16049L,0x0192e93cb027678L },
40096       { 0x011fb554848c144L,0x11492db53d79977L,0x0384da783e69381L,
40097         0x0d94a7643c24b6dL,0x0e98ea1bad9bdaeL,0x17d1cafa86b02e1L,
40098         0x0cbd6f6e7854e7cL,0x1ae8ae1c65bd22aL,0x1810698ae46a250L,
40099         0x1ecaa3656cec8a2L,0x19dc8447a5e979fL,0x0faa493f05d357eL,
40100         0x099851df63ca29fL,0x18e871f2d4e29cdL,0x074ad5bf613552dL,
40101         0x012d5a3c08b3808L,0x1d3ceb3eb6efd80L,0x00cea42a371953cL } },
40102     /* 65 */
40103     { { 0x019ee8fb540f5e5L,0x152978273468bffL,0x16c2b6f721c61b4L,
40104         0x11a074ff91a4641L,0x08bcb916a83ad5aL,0x08f4202a5fc1e38L,
40105         0x1777c2484cfa8b9L,0x10779c7084996a5L,0x0d5c7be40310635L,
40106         0x0f5dcefa2c718bbL,0x0658e6f136aeff0L,0x1fc980ae4b515f6L,
40107         0x1484e1cd2436350L,0x00a2dc6f5625031L,0x120c8deb7dcc553L,
40108         0x04e40154dbb3d66L,0x1b0a3345c3dcbffL,0x00d9d67365a7229L },
40109       { 0x143e5e990a8bdc5L,0x1dfceb183504481L,0x08d63921483a880L,
40110         0x1dbcfa3a0d30913L,0x1f795d3fbd17debL,0x1d851fc7d7d36baL,
40111         0x1abea933ad8c0e1L,0x005c02cd665ffbbL,0x0a2fe20547e764eL,
40112         0x0d5cc127438f982L,0x14daee54bb11795L,0x0909521a4195457L,
40113         0x0775bcfb537b4c1L,0x14c16272a98cf9cL,0x00a4874d08e2929L,
40114         0x162fd4576c38f42L,0x0141e061b64db3aL,0x029c7619f0c9785L } },
40115     /* 66 */
40116     { { 0x13496fea19b56cfL,0x0bbfa3ddccd668cL,0x1ea15f42a20598fL,
40117         0x0410506bfb1e095L,0x1d82cec7cced3daL,0x004e42bf10fd76aL,
40118         0x08c1db85d6e67e0L,0x105b38dc6365a0bL,0x196948d4a81487dL,
40119         0x175e9f96a37b32aL,0x146aa1dcf331261L,0x1e45162c814d0d0L,
40120         0x0841a20b753e220L,0x08560537cf8371dL,0x0facfecb3fff97aL,
40121         0x1c593eb5363b51dL,0x0012587d9976e08L,0x037eb014c01f4faL },
40122       { 0x0709f8d8eb7516aL,0x0c53a5ee2cc55aaL,0x16621fa0073a0c1L,
40123         0x01a2f7152da469bL,0x0e90f6abfd0f9d9L,0x1f6aadd50f2a4fbL,
40124         0x13064925bfe0169L,0x0ea1b3ecaf4d84aL,0x03cdea49cb89625L,
40125         0x142d1f816ff93efL,0x039ff76e2f012edL,0x01ff30e46d6078aL,
40126         0x1dbb0d5055904ffL,0x10a5f46824a14c7L,0x0f4c358d2cce1b7L,
40127         0x1fbb2f5a69d38f8L,0x1c01f2b32bde159L,0x04267d11e63b0f2L } },
40128     /* 67 */
40129     { { 0x1bc11eb8b99b964L,0x006052c717e2389L,0x11275326952e38aL,
40130         0x057edc41f50e1f7L,0x17c88cfa37a334aL,0x0578ed772c1e86eL,
40131         0x1e2981780a6a3bdL,0x0c4daabc468185dL,0x161b6fdfe209e9bL,
40132         0x18ed6935dc70407L,0x0f058a4e4bf068eL,0x1fcc155c7e9cb5bL,
40133         0x1ac2bf4d5b02ac0L,0x01417f6946ccc00L,0x0b6ccfc8ccfe4ffL,
40134         0x0a5ce2db962196aL,0x18e09f90f84c557L,0x0143ea628e42506L },
40135       { 0x1a582010e9867daL,0x0c4d98d43a66d2fL,0x1f17ef7b88b9851L,
40136         0x0bcc257b5000bc4L,0x0d3635f9e357fefL,0x092d432706df6f9L,
40137         0x08b958af9c391bcL,0x1a3413731081b29L,0x17eb99a1528b5e5L,
40138         0x0dca0b73a88145aL,0x0dff5f81b4b3108L,0x0a2ffd41308a362L,
40139         0x06ffcecbd76fa1fL,0x0197a29f1dd0f4bL,0x09a3e875322692aL,
40140         0x12b460f63c55fd9L,0x013d0fb44534bd3L,0x0009951ee6c77cfL } },
40141     /* 68 */
40142     { { 0x13c7785576374c2L,0x09368c239382072L,0x17208a328113981L,
40143         0x05e39c2627140cdL,0x0deb0c5d1fe1c1bL,0x1fc137957764196L,
40144         0x096269d659a6672L,0x0a99a311d03bcefL,0x0e5ce0fe0118d12L,
40145         0x0a154c203c85c35L,0x1c10fce6b0a33a8L,0x05210fbcb009c51L,
40146         0x12f639a8c54eef8L,0x0c43bca7c1e18d9L,0x0c6ce475c11529dL,
40147         0x18f2b94c6baa031L,0x025cefea07631d9L,0x009e5f73b5b7c55L },
40148       { 0x1cabe0f8d3f34f3L,0x0e18e51b0bff1bcL,0x188f76509a86f6aL,
40149         0x0fe539220964dbdL,0x02c6cd3be9dd962L,0x1d10cb019f58b4fL,
40150         0x120f229cfd24bf2L,0x16f25c6fc1770b1L,0x0e4f2aca623b3fbL,
40151         0x080fd8f325f0051L,0x1e09aa523d91220L,0x0f6920e4c1cf234L,
40152         0x10e30bb83541406L,0x04cce0377bba552L,0x0821447e48b2a03L,
40153         0x009e0d70c6b7217L,0x167bf936b5c25faL,0x027050d6d701744L } },
40154     /* 69 */
40155     { { 0x0ca66708ba29c4dL,0x12067114c404a00L,0x099c5b769d4b020L,
40156         0x0b5777f468438b9L,0x1ed28b72689c0e4L,0x02b55a0ebaa2fe9L,
40157         0x075957c8846635fL,0x112967b1ee870ebL,0x093490dfb8fe50bL,
40158         0x120faebf4075d0bL,0x1697ade6b2d4dedL,0x092e183abcbcf61L,
40159         0x0da5da429aab6b1L,0x17b69792919c734L,0x0c3ce9f804310dcL,
40160         0x0117844de2da4caL,0x199efb0f7b6cbefL,0x0399f186ccfcce4L },
40161       { 0x0fe1582a42a38f9L,0x16ac723985a8076L,0x0a9f7a5dacb2bb0L,
40162         0x0b52d383765dc5eL,0x1cecdb4af0539dbL,0x14748118caa0b47L,
40163         0x1507fcbdcd22b9eL,0x0a43ab1af986242L,0x15d25b75c2202aeL,
40164         0x154cb2d7a041ad3L,0x0da9054a6d391b7L,0x16df7a4f5b367fdL,
40165         0x00261f900b5c97fL,0x026ad8cf6c3aaa6L,0x0866e72d0c0c764L,
40166         0x0179e67abd37196L,0x00c7a43d4923ee0L,0x02b7d659cdbcd2eL } },
40167     /* 70 */
40168     { { 0x19165a2a3018bfaL,0x035924ffd6cc200L,0x07d954d06a6c403L,
40169         0x0e4bb8999377e36L,0x0bfffe60e6bd1d9L,0x0a84d5a942876a9L,
40170         0x167c493a64b31f9L,0x091fed8a05c99d6L,0x02f0b35731aa7d1L,
40171         0x0860eeef3f1d523L,0x127d174450a203aL,0x1a4ccb7cbbab75dL,
40172         0x0e1febce13475cfL,0x004a169841d5d8aL,0x1fa0b21aae920a6L,
40173         0x0431a3c3646ba52L,0x0bbb771cdbe50d8L,0x0442cc9336ca6b6L },
40174       { 0x0847290155ccaf2L,0x0f5e3be2dbb9f04L,0x1746cb7423b619eL,
40175         0x1d0fa8ebb751165L,0x0694d02a960a180L,0x1fcf4b407edb5bbL,
40176         0x0db10fa1d6324fcL,0x0fb7b47edf495b0L,0x19400c58132fb38L,
40177         0x0d3c2a112a81007L,0x1f0d45ddbb3c609L,0x08dcacdb6b34552L,
40178         0x0026545eda03ebfL,0x07ba55a223a1d14L,0x12cfda7b45a7613L,
40179         0x0e32d7557263b11L,0x11970ae932cd825L,0x03cb9125350604bL } },
40180     /* 71 */
40181     { { 0x12923f8441f3567L,0x018b417125f8eb1L,0x09aedd9c7fff047L,
40182         0x0ef4bc3444972eeL,0x1addb417601746aL,0x0cdc2329eeef501L,
40183         0x1ffdd5e19e8f1fdL,0x1516025530ead9aL,0x01bd5fec9f19ba9L,
40184         0x081bcd17c1833a4L,0x0d1176ae301745dL,0x0836f207e854eecL,
40185         0x0da903e46d5d7f4L,0x16e89360e008b3aL,0x1156d006c74f136L,
40186         0x06add44ea5558c2L,0x12c4da42a68555cL,0x01ff84e0aec1042L },
40187       { 0x00a1bcef9cb7784L,0x09cde12117982a6L,0x07f431052a9ebb1L,
40188         0x19ffa85788be81fL,0x0f358e15d3aa316L,0x113b41217ad2619L,
40189         0x1b3b802f7367b5bL,0x0ba0d3ef13ff14bL,0x18078018e05e14fL,
40190         0x1d9f249c5a063a0L,0x123075e45fdcb4aL,0x0cc998ae2a18bb7L,
40191         0x1ac3fa8920e0eeaL,0x0e3cb8b2512f662L,0x12b45acf086c3d4L,
40192         0x03b351e1345e4c6L,0x04c8e730fc55839L,0x023f78c02a7efd7L } },
40193     /* 72 */
40194     { { 0x165f3d13da285e4L,0x0a6dd1d00f1fa4cL,0x04e984852b42e9fL,
40195         0x0a4472ea928e708L,0x1a730b92d3b7d53L,0x168b2ed29edee7aL,
40196         0x1fbd0c4c364acccL,0x16c89450a8305f2L,0x1bf62221c44dce1L,
40197         0x1d09c2c3f150764L,0x0cb2372feb6662eL,0x1e7f6bfda89667eL,
40198         0x05c66217bb409e5L,0x1e6fb8d4ae19463L,0x0481e22c036da7fL,
40199         0x08c974478544371L,0x061f8ab28e63ae6L,0x00d35b74e5c6f04L },
40200       { 0x16ec2b606af77aaL,0x07ae6d443f832d7L,0x10027d263158b98L,
40201         0x13f9755e970fa42L,0x071ab855db595b5L,0x1a4d8607dac9509L,
40202         0x032728338439750L,0x1b73ac30fb110fbL,0x103ee95f9154bd6L,
40203         0x1f29909ae8364ccL,0x1ef0c3eda993423L,0x1e1acd4996c1e94L,
40204         0x0f5d37367c3d22aL,0x0cbec72a8b4a967L,0x05ccb41bc3a9cd2L,
40205         0x07285688f8e1ee6L,0x1d000ab3034a9cbL,0x03cee80c0142887L } },
40206     /* 73 */
40207     { { 0x0e0033a3ac7424eL,0x15b44307ed26802L,0x1d9af2ddcbef6c1L,
40208         0x17e52f9b4846d52L,0x1b013c6e294a8e2L,0x11d1d6a58555c2eL,
40209         0x129acf4abb2621cL,0x13c195c659a2790L,0x021888f5e70ec16L,
40210         0x1cb19dea1544131L,0x11e4b9ed8366e1cL,0x0e4420ed3fc2d15L,
40211         0x06d24bed3489f2bL,0x11f59255479fe7fL,0x131c1af4d7bee22L,
40212         0x19c1bbbd9f47e90L,0x0367cc119a9929eL,0x043f2d6a2c6a02aL },
40213       { 0x099aa9d7d1000a7L,0x057fe57411c19ddL,0x18a37ee0f7162e5L,
40214         0x0308b4831b90452L,0x1d4170542f59fe1L,0x1b8ac0d45cb87c2L,
40215         0x1745e24630995caL,0x181c9de8efb81a3L,0x1b50b4cf33afad7L,
40216         0x0dd753c80c3852dL,0x021fe6ece8a1a08L,0x063c2494b39b8eeL,
40217         0x0f57f4323978575L,0x00b264a576ba613L,0x052fdd357d6b894L,
40218         0x1d464cc116fc5e1L,0x045f4cdb5bafdceL,0x005b8928ccc8660L } },
40219     /* 74 */
40220     { { 0x0290ca188d5c64dL,0x16ba4d3a4929a2dL,0x14f4a803a494165L,
40221         0x1995ef6cd740961L,0x0cdded83082cd02L,0x18b2374895a8617L,
40222         0x1fe5604f3a77bfcL,0x02ac55ce18f8ebfL,0x16f6852e07e2a46L,
40223         0x107ebe801c027e8L,0x0a93760863a364cL,0x0df75f8c8baf634L,
40224         0x01e8d9fdbe4918aL,0x02385b777d8407dL,0x05d3bdccf534229L,
40225         0x1cba5a57440eedbL,0x16d8ecb95a769daL,0x03d1fa11d3eb4acL },
40226       { 0x02d2ca69a929387L,0x1bac0e58e0fff9bL,0x127df946db2eaf6L,
40227         0x04749c263fb125dL,0x1bd87561ee8d863L,0x13f399234071f8aL,
40228         0x1fbfb8e965f8753L,0x016798e56f8ab03L,0x1f3e77f8aca8caeL,
40229         0x063ebee2f17ea57L,0x09154884d56de7fL,0x09e54580e2efba7L,
40230         0x0d0689621f546b2L,0x1fbc0b1f20ada99L,0x15fb484afa6bd44L,
40231         0x052864fac773667L,0x0f4ab019ef29680L,0x016d2fe2a8b11fdL } },
40232     /* 75 */
40233     { { 0x0429cf3c8a5c600L,0x006111ff19f3e31L,0x1d00295f772e9eaL,
40234         0x1b24b618e93ffb4L,0x0b100eb0d1ae156L,0x0a1e4084bd21fcbL,
40235         0x13c905a7a5173beL,0x06743ee69ca2251L,0x004387c4a419f01L,
40236         0x003c34580822012L,0x05aafe40d673cb0L,0x1fdc8f1aa9c7ca8L,
40237         0x0642a2173ef9c76L,0x0ff180a0b310cedL,0x1bc91f98780c55aL,
40238         0x0cb2541feb9c727L,0x0d3811792ba072bL,0x042af810cb8642aL },
40239       { 0x1fbfb6c847314c4L,0x030aaf5a2dcb530L,0x0519ae8abeb25e4L,
40240         0x0b57292f02e205cL,0x0110c4feed51f97L,0x1abb33ce97ad8beL,
40241         0x1139deb2339c2bfL,0x18fce6cd442dd64L,0x0dd1bbcec551c65L,
40242         0x092830570d42cefL,0x1205d22e9f4b9edL,0x0a83571d5188f40L,
40243         0x036fdff078e1a2cL,0x0a43a582373c126L,0x0c7dccde6d27f1cL,
40244         0x1cd9e455c66fe0dL,0x1971c3521926f8fL,0x014911b67a92e83L } },
40245     /* 76 */
40246     { { 0x1b8d80a7d8b29dcL,0x110120475324566L,0x117aba4afa4745eL,
40247         0x11fb4e5f78fb625L,0x1e760c6f1f347d1L,0x11c6c8889ba5a04L,
40248         0x107d1cd87a3c763L,0x09cee297d3ae735L,0x1c1f9701cb4df5cL,
40249         0x089c76c37b96570L,0x1f87ddab4603136L,0x0b7d3c5b7f3838fL,
40250         0x097c70c44df8c18L,0x1868adafc1aed93L,0x199517be65f3faaL,
40251         0x09cbca20288b4c3L,0x1aa16b068842518L,0x03e7d61acba90f3L },
40252       { 0x11821673c0bc53aL,0x0f6f1bf3a89b3c0L,0x17f68d95e86212dL,
40253         0x09743fbb307944aL,0x05da77d8096abbfL,0x19a162ce741b4feL,
40254         0x167c7c9ee6b9eaaL,0x1d20d9237ad2e40L,0x0ee0dab30914ecfL,
40255         0x1b23fddc9fa9f89L,0x0e29ebfe95f83aeL,0x0ddf3e55ac0e618L,
40256         0x07bb99dcc9517d0L,0x02304050a4b946cL,0x0e705f6c00d2bc5L,
40257         0x045419902187e25L,0x0bd7225f14f772aL,0x03671ee3f8eefc1L } },
40258     /* 77 */
40259     { { 0x07cd835a4397830L,0x094867a39998360L,0x0ea0a6627a31376L,
40260         0x12ac7b02a5ba6baL,0x087de61b7990255L,0x1271ae793c6c88fL,
40261         0x0396671cd031c40L,0x1425a8888c2941aL,0x163e7608ff32626L,
40262         0x13d1bf4e264dd54L,0x1b7145dbfff4958L,0x1f919de5439a18aL,
40263         0x16efc559d9cb6deL,0x020e5b4965e606aL,0x0587827917cff14L,
40264         0x0ab399a0b8473caL,0x16d2a731ee95c3bL,0x0428a889151e850L },
40265       { 0x02d033586ff19e2L,0x106d50ed14301bcL,0x13f955f1fbb70b1L,
40266         0x083789d16165cf1L,0x1df35c67a8f6f98L,0x122315660fcda59L,
40267         0x182c25b84d80d1dL,0x0ad7f22172ef8f5L,0x127c7f305514359L,
40268         0x0a6d8ae7b18f572L,0x158509f9a6cd330L,0x10a2bf825fe54a3L,
40269         0x13fb887162dec82L,0x0f0a445efe67570L,0x18f9d3368ccab07L,
40270         0x00d394406e9c45dL,0x004597ea1a1f0aeL,0x04588acf93bdef6L } },
40271     /* 78 */
40272     { { 0x0f71a442f961d30L,0x0b4543d639247a5L,0x01f2c6a41b36f7eL,
40273         0x0c0957f24ba65bfL,0x19f04d4c00c10e2L,0x0b82ed5c388bacdL,
40274         0x02124035539824eL,0x0ebeeb0e86793f0L,0x02e9abade6a7a23L,
40275         0x13b6a3c4a560bd6L,0x01496f080b66715L,0x195b57f5ce7a994L,
40276         0x183405991b95b8bL,0x02c54ce191b8f69L,0x1e32198ada791e9L,
40277         0x058f8f958163056L,0x0596ceaa79be023L,0x005ec3219ac47baL },
40278       { 0x0a1a8b47e734189L,0x0d64467f2fd0befL,0x1538450dd9914b1L,
40279         0x115f3d2ea088949L,0x130c6b3bc252230L,0x16fa3bbc58e861eL,
40280         0x0375cbb6b97c131L,0x068a6263b345dd1L,0x0c4e380eeacc93eL,
40281         0x04cd8d6546d8747L,0x123059fd75275f5L,0x04ae2aad99aeee6L,
40282         0x0c2611d13dc9663L,0x1ad17ee632e7074L,0x163ea84b257f99aL,
40283         0x059304cd310650cL,0x107da87d1f431c3L,0x0233282cc7e6c8cL } },
40284     /* 79 */
40285     { { 0x06c13cc6b4a5efaL,0x0cc4d8e83d932a6L,0x1b3a2f71a703120L,
40286         0x04584a63a82172cL,0x0ad0a100f54cfaaL,0x0ed224e5af8c046L,
40287         0x00f32fad494e3b9L,0x0f14c48010b7dbbL,0x1e792dacfd6255cL,
40288         0x01b8c83103102c7L,0x057a0fb45963062L,0x164efa51aa852ccL,
40289         0x1b83b75df34b549L,0x0bfddca1757893eL,0x1df24c13d837db4L,
40290         0x0f13fa10c63b7edL,0x00c17c38f986018L,0x00621aba55cd494L },
40291       { 0x0eb324c1d20cad0L,0x16584c63088453bL,0x0e71bc1b4db6437L,
40292         0x15781b432f4dd3aL,0x107ac5ce6cd978bL,0x04bf5aaca458e02L,
40293         0x0538caf51c59315L,0x0785538981e9ab2L,0x0772c5046a759f0L,
40294         0x1eb994534d6423fL,0x15f430c122ccc39L,0x09c081ef759d51aL,
40295         0x13a85f1790e6003L,0x0e42cb9b411ec8cL,0x078408a9ba6d9b1L,
40296         0x07f48459458f4cfL,0x1b900e7a19c0902L,0x01924ccf893936aL } },
40297     /* 80 */
40298     { { 0x07eaed67c834915L,0x1d5355e2f5b26b3L,0x12d8975880467ddL,
40299         0x04d33fb384e53d7L,0x0b8d4f6c0aee24fL,0x04bb6b70f5ac3a1L,
40300         0x1a995fc49c43053L,0x0c92272066bedb3L,0x1668b704906b500L,
40301         0x0cb4d07043b7727L,0x06fcfcbe764d819L,0x0ca36933c79df20L,
40302         0x1bf2dbcaaafb1a8L,0x0b9d835b405ca9fL,0x1cdb190c4b3159aL,
40303         0x1b02a6a69b38675L,0x191e4463a5210ffL,0x02bf515a5f8c615L },
40304       { 0x0f5e1628aa0f2f2L,0x13ae287235e5500L,0x1e6a928b10b631fL,
40305         0x14297544052f568L,0x0943cc2eb4f308eL,0x0ac4025480de8a3L,
40306         0x03df2ec497fbbbbL,0x038ca0591f33a30L,0x1e53539191580c6L,
40307         0x113c03493880f71L,0x090287ea9c9c5dfL,0x1c0498eb62a6f41L,
40308         0x0b538f1c2232edcL,0x1f183e976d11b30L,0x0bb82d135447a62L,
40309         0x1e60e484edc8137L,0x1c9a78c39277ff1L,0x0302405a3753c9aL } },
40310     /* 81 */
40311     { { 0x1087d663872ece3L,0x0df3ecaadb87c18L,0x1f1e73e56ee17caL,
40312         0x1bb7ff4c436a169L,0x0022ba5dbae3b58L,0x00a24e0730e9407L,
40313         0x15215e2b9445d06L,0x01c162650819eaaL,0x1800ed1b6b8ce0bL,
40314         0x0effeeabc6aef1eL,0x108dd1a695ad1cdL,0x06d31b2215cfefcL,
40315         0x006313c7c7d5e32L,0x1496f4f2db7fa95L,0x08442ed68bf8836L,
40316         0x0de4683668fa7a2L,0x0ccc5905edb40c1L,0x003ba5069cd47c4L },
40317       { 0x0e181abe3b6c106L,0x10b1fc6f0a85b9dL,0x00bdbcd520d93afL,
40318         0x06758f582d9eeb7L,0x091722afaa0d206L,0x0a2aa9ae3403341L,
40319         0x18fddce50798445L,0x1b42e24fc717ebbL,0x132cfdf031afb41L,
40320         0x1449e48c3de4331L,0x119d1298b272671L,0x1c5b2c58328eea0L,
40321         0x1f378cdf4c96866L,0x1a03fd19244f646L,0x04a4344e981c26cL,
40322         0x044e7a6fa42b2aaL,0x14b9623d303bab9L,0x0040a8caa121900L } },
40323     /* 82 */
40324     { { 0x1236d89fb7b2108L,0x041e656bafcd57cL,0x0c56d3876844fb3L,
40325         0x1e062b86c5ef8e5L,0x1272fe3f552aeaeL,0x021f7408f0a076fL,
40326         0x0c96e675e6fda1eL,0x0e99cd6a9fa3b37L,0x1b20b0e215b1badL,
40327         0x05010a7adc26486L,0x0efd4bf29b3b255L,0x091b3c9beede8b3L,
40328         0x0ed64cf17ee363cL,0x1b156d241822fc2L,0x1d32806100a859fL,
40329         0x1885a593c37e6d4L,0x074e8cf9d41f691L,0x02d5f90bc61625cL },
40330       { 0x177966bf3b3bccdL,0x1f0785f1f065523L,0x0ece31f5410c011L,
40331         0x1f28dfabf997070L,0x09ec0e87e77e3baL,0x10c692bcdd53c2fL,
40332         0x1f3fb60f155f322L,0x0c3372dcb5e4b7dL,0x14f05d15e98c71bL,
40333         0x00fcc8d3bf316d0L,0x1b1e072ea8e0842L,0x0cbbca9b37f638dL,
40334         0x1344ed14307522fL,0x0ae57eed7ae82abL,0x1e3d6fcc0d6cc7eL,
40335         0x173b28fccfe86c6L,0x048029f7cad5270L,0x00ad68ac3a6c8b5L } },
40336     /* 83 */
40337     { { 0x0de2eceaa588ae4L,0x15e2c51b8d11900L,0x04d1c48c111154bL,
40338         0x1bc963065ba01d5L,0x1689e843afbfa67L,0x1a71741490b1a0dL,
40339         0x077147e5aeef587L,0x1a32a840d080985L,0x0c7fe382742317fL,
40340         0x050576331a418b1L,0x0e53441c00613f8L,0x12e7fc3f7b0bf85L,
40341         0x11fb07435207219L,0x023729c93245b55L,0x1e95bfc8eef6ab7L,
40342         0x04bec1b71ba3e01L,0x163104815eb8667L,0x01fce266529740cL },
40343       { 0x136b29732ce637eL,0x0af96fae92e6effL,0x14b62c0ab65e068L,
40344         0x199f7567d2343a0L,0x014eeb752e5f3bbL,0x0d3c9d306965ebbL,
40345         0x085135124610f35L,0x0cc44859eeb9b74L,0x0a20705e788b997L,
40346         0x0709660763bf099L,0x0537dad86a6c159L,0x1e08e904b6b5638L,
40347         0x013da312238fd97L,0x06986386cab0241L,0x04bb9a779219c9dL,
40348         0x1127b79571e2a38L,0x14b5dc638b4668dL,0x0323ced6b111fabL } },
40349     /* 84 */
40350     { { 0x09044f3b05f2b26L,0x114a5405cfbb62bL,0x18a10a43dabacd6L,
40351         0x0604d4b0ef1073fL,0x0e5ff9c3761cfb2L,0x08e2bb3b44935b1L,
40352         0x0fbfaeb9b34802cL,0x075b90aeeace540L,0x00cae074ae1bad6L,
40353         0x1f248d0eb84ecceL,0x177b5994076704fL,0x19438655dfeeed8L,
40354         0x15c57683e81da6eL,0x0fcc6c23a8424eaL,0x166959278e4ba73L,
40355         0x13165f5af305ec9L,0x097f7c3bdb7a37bL,0x00ff04fca784302L },
40356       { 0x1a7eaae7648cc63L,0x11288b3e7d38a24L,0x08f194fd15644faL,
40357         0x170342dd0df9172L,0x1c864674d957619L,0x0b2ccd063f40259L,
40358         0x08ca3f2204d2858L,0x13c6cdd52d214caL,0x1415329604bc902L,
40359         0x1cf0cca57155695L,0x0a3149fc42fbd7bL,0x0b0d8cf7f0c13c5L,
40360         0x1a844cc25d73dcbL,0x1a759b29fb0d21fL,0x0903c0b5d39fba9L,
40361         0x17969e66ace0dbaL,0x06aeec7694cfd83L,0x026f4abc36db129L } },
40362     /* 85 */
40363     { { 0x067d3153deac2f7L,0x03bc55b0ecd4724L,0x1e582adecb56821L,
40364         0x0d9fbe9ef3e76edL,0x11ab8f4b00b3005L,0x1bce80e8380f0a9L,
40365         0x14dc41fe5235671L,0x180f9329d7904ceL,0x01104d4ee48bad4L,
40366         0x0c6705adfe4e82cL,0x0a2634c27ea02deL,0x044b59667d5f8f9L,
40367         0x1c5b2f31750244fL,0x126bdf1a6a8f46fL,0x080ad0cf926e9aeL,
40368         0x04eb42ec1e98f7bL,0x00c37e36a7e4435L,0x00e4a20c5f31b4cL },
40369       { 0x1a2131309dc1414L,0x1b2fe21e49a9ba1L,0x01eb7d7de738181L,
40370         0x150ba99f94dfe64L,0x03e995ab6f18b1fL,0x1598017ae213973L,
40371         0x1fc5848682792a0L,0x04d056cba372e28L,0x04993c20c20a7feL,
40372         0x0e4e5cc7338b393L,0x0b59cffad102826L,0x13c24a36978ab40L,
40373         0x14a05338ea3f3faL,0x1d84fb65baede23L,0x10d1824f2d0112dL,
40374         0x1d584cecfb43100L,0x1ba97851422098cL,0x0308dfdd95aa91aL } },
40375     /* 86 */
40376     { { 0x1baa55ef00ad2a1L,0x1d42f0a51486bdeL,0x1da3a4ac5a50a7bL,
40377         0x1a23d9026076948L,0x08bd27b267111bcL,0x101e0307212b814L,
40378         0x0212bca33ca8f66L,0x04176f91a5be631L,0x1e2ea1462e3aaebL,
40379         0x1a9ac0221dc2ebbL,0x191209553ba6f4cL,0x1d3dcd54331f03dL,
40380         0x04c26c5944eb2eeL,0x01558b3e3d2d540L,0x1f8869683bcb696L,
40381         0x0531cb45568ec05L,0x08d169cb3b83370L,0x0437362a20759d5L },
40382       { 0x1e033210b793d9bL,0x1d6f08eedaf6776L,0x0a49a24c2d93de7L,
40383         0x1bfc9fa365ee7fbL,0x12a4dc8806aad97L,0x0bb6ba839d2d8ecL,
40384         0x09b022be32f62f2L,0x00cc1695762c79cL,0x19c8300a9dcb1fbL,
40385         0x1ad2ca66d4ad9e9L,0x1f5f52cdfab21ccL,0x174441ddf5563f2L,
40386         0x06f3e828c8a3d2eL,0x02d5bbc0992c648L,0x0a2d85f20c985beL,
40387         0x1705ae4b2e32518L,0x06dcd7196bc3233L,0x041c33f5c8cfd09L } },
40388     /* 87 */
40389     { { 0x14fe73e22474edbL,0x131ca0d4270d73bL,0x06b671b75b8ca9dL,
40390         0x0a29f17eba4e065L,0x12267b9000c4a41L,0x0927d71e71751beL,
40391         0x06de049d4c05447L,0x00cf829b0a84c74L,0x020c8401b1ae0b2L,
40392         0x195008d840fa4feL,0x048fee5671b7e3cL,0x18f9001c3a0c3d0L,
40393         0x1824259a9aa328dL,0x1bf7b61bac3b51bL,0x0f5327c8eb6a2d6L,
40394         0x0713e047ed6dd52L,0x19e89f5414dffb6L,0x025935dd1731459L },
40395       { 0x10b1cb45d318454L,0x1ba4feba1b65b69L,0x1c995a29d18448eL,
40396         0x063909fa3c62218L,0x08403d55c85de12L,0x0fd5fc52fc6b730L,
40397         0x17380e56db84e6cL,0x021fcdad18679fdL,0x11d90381f94b911L,
40398         0x054754096e6375bL,0x00104dfa4328afcL,0x180f9144b8b4b3dL,
40399         0x1a5d84663cbeb5fL,0x0885b53e004e129L,0x023e35402c541ceL,
40400         0x03ccb0c0fb49882L,0x1c602c3d9c3cb90L,0x026b4bde2964b0aL } },
40401     /* 88 */
40402     { { 0x0db1ef0efa8fb40L,0x10e2dadd1cc4e70L,0x0c560274677ca40L,
40403         0x06982433c351adfL,0x14ef05e26b787b7L,0x0bcb71320bf0b40L,
40404         0x1086d124d0b6e3eL,0x06c5f0f14bd7f08L,0x1e71916d7e94a45L,
40405         0x00c5dd1d708cb49L,0x1d2fa55da2013a6L,0x0e99f0849f15d8cL,
40406         0x1d466ce6ab0a260L,0x049003c5ede49dcL,0x1c3c68ecfc56a63L,
40407         0x10b4f3a21fa1a70L,0x180a61241d9e4e7L,0x03b6543d0f36466L },
40408       { 0x157fb56e02e48b7L,0x0a589e604f4e321L,0x10d4901a73c3ef4L,
40409         0x1858760353b6be4L,0x06956dadf878165L,0x0b05b472a4f3e27L,
40410         0x1194fcbfa54e2efL,0x1372a5f0ad60b3bL,0x0d3f60225b377feL,
40411         0x10639945ff48462L,0x0a8b4ef23d7cb5aL,0x08864884a0a19cdL,
40412         0x0a3d3b3ce5f7213L,0x00b3ba890bf0933L,0x1ee2529d6d790ffL,
40413         0x1c6ea2b24e0c46fL,0x1be152607532be3L,0x013f3f96336d1dbL } },
40414     /* 89 */
40415     { { 0x18f65ade6a15883L,0x1f3463357ed99b1L,0x1aaf4fc4b797529L,
40416         0x006f70f020c40f6L,0x04acf6d31c6ff95L,0x1f3c61606a26593L,
40417         0x0603858eb1807caL,0x13638c798b42c6dL,0x03e92cfe895c934L,
40418         0x19c706c20f63910L,0x075d90b57ea585dL,0x0d8387c051d2c2dL,
40419         0x06b16d54092aa77L,0x1836fa6cc9ee2b2L,0x071ae5e82c9fed5L,
40420         0x0be813d3222e19dL,0x128ea8e42be53c8L,0x00174b21bc19232L },
40421       { 0x1540addae78ea1fL,0x0dba6bdb3874b48L,0x1107dc01a099468L,
40422         0x14faea418ff326cL,0x09ce12e18f97d6eL,0x1041a107d535013L,
40423         0x110d89642b2a1e4L,0x11ef49070c6eac2L,0x007c6149ef38140L,
40424         0x19dfac26bc29a03L,0x06c0426aeedbddcL,0x093fea5141350ecL,
40425         0x182e00ae3ce4eb2L,0x10bc77fd043c0f6L,0x144e9fa19306c94L,
40426         0x00c5f983cc5453aL,0x07dedb8b94e1919L,0x039cfa9ed278b29L } },
40427     /* 90 */
40428     { { 0x05f4a88924adc5fL,0x0360b540c7ab6bdL,0x04a5de57e552559L,
40429         0x1ba338a8001d892L,0x005912b42b48753L,0x1d24a30b7d11b59L,
40430         0x14199acf597cfa1L,0x0814e2e940208bfL,0x1b635031312a5e1L,
40431         0x1ce25a254b5c311L,0x0e75966ac00f569L,0x018c704de634f46L,
40432         0x0c6f7090cdc72f3L,0x08375f125a739c8L,0x091416966b1b0daL,
40433         0x08274734fe0db77L,0x084839991e1c58cL,0x0010611ffd10707L },
40434       { 0x00e4adaafc74661L,0x1e7b193bfe03289L,0x13dadb739e64deeL,
40435         0x06f62c374282093L,0x09610fb25b8d6b5L,0x0ef3b49110c218dL,
40436         0x018c37a7b27477fL,0x097a657f49a85b0L,0x13885702a6244dfL,
40437         0x0f6e8f6a2ac96fdL,0x17d16fed3806e33L,0x1da50dc42b601c3L,
40438         0x076a937e6a8f4bdL,0x00987b91c049aa4L,0x0a087e10549e2eaL,
40439         0x09f158db88d2471L,0x0ef2207b119fd8bL,0x03b73dfa9fc934eL } },
40440     /* 91 */
40441     { { 0x112842827ebd187L,0x19055db2d56ddafL,0x1969c8961a5634cL,
40442         0x131e130d576084eL,0x0ebff503da3f33fL,0x0fb8d2a08c03d3dL,
40443         0x1c92c971ddb2a09L,0x16981bcf7dbfefbL,0x1da8b0f42165f1fL,
40444         0x19ffb9bb98f9d71L,0x075f9c64f829497L,0x15476d67748c99aL,
40445         0x17aa1f37828df84L,0x13b99d63dd425c4L,0x0606885b9e58333L,
40446         0x101da9a8dad56a1L,0x1091ec12c257cbbL,0x03cf3d69395cb77L },
40447       { 0x0d970dc8f30caaeL,0x15e7885375f7a1eL,0x18fb1c5185b6172L,
40448         0x16a33c7530c7830L,0x04cb13d61c50db0L,0x0a3db4f9cdc4b1bL,
40449         0x0c3337d9f607c89L,0x16ee2af5773acfbL,0x0ccca25ba889491L,
40450         0x144903e3d13f06eL,0x1a3ef83f50ca07dL,0x1ee6ae41d812695L,
40451         0x09cdfd7beda5d91L,0x0501cf19597b0c8L,0x0363f707b0408c9L,
40452         0x000bba787acbdb6L,0x09432c916c84fe5L,0x03fc61bd62605f5L } },
40453     /* 92 */
40454     { { 0x1ec1e5443ac05e5L,0x126d266c69c1299L,0x102e22fe78af692L,
40455         0x016a7023b90db11L,0x03c3aba434d71ddL,0x0b08df32a820695L,
40456         0x13e80af102526d8L,0x186385a84dc4f34L,0x0535a5aa23b065aL,
40457         0x1545197e2975448L,0x17b29e7f76b48b6L,0x0bfa556764deb4bL,
40458         0x1bf37cd81e911f0L,0x0868b5c62ed673eL,0x1d625383839139eL,
40459         0x14e9e2bcd15dbc9L,0x02fafe04999fc92L,0x00ebb81d54b873eL },
40460       { 0x0a4c81d3f0062a9L,0x1595c6cb5105d54L,0x037e192f44078c7L,
40461         0x0488276c28cdbb3L,0x09a555f8ba05f59L,0x05a968a8d33d06fL,
40462         0x0ac8eb30bc25cb9L,0x03756bb55d8e309L,0x0ce08b43e7c7f69L,
40463         0x1072985bb6213faL,0x1481a7908faf714L,0x13d069be299cfa6L,
40464         0x15446305ac6b5e3L,0x1f1a66e09ee5f94L,0x07d6beda0b2cb87L,
40465         0x12df3a9588ba222L,0x071c5ef63cd47f2L,0x00516207649e104L } },
40466     /* 93 */
40467     { { 0x1bc384faf5747dbL,0x0b04360355c3584L,0x00ba79f0551ceebL,
40468         0x02ab2ef57f480d1L,0x1a81deb02d5326dL,0x05b088831d4d02eL,
40469         0x1ae426a1b929d49L,0x1742805f0f49565L,0x17d0721d4d5c600L,
40470         0x117ecd4f944fedfL,0x1399b7b379bc1c6L,0x04efb573f4e7ebbL,
40471         0x1f6c474bab62171L,0x1b776819b696e24L,0x0a0974f7005f87dL,
40472         0x0bc8772e2eb809bL,0x07e6c297e3d54b0L,0x0177da2a32b64e4L },
40473       { 0x0712b008b21c064L,0x17f212538314f52L,0x0d026dd3c2bf461L,
40474         0x06fd93cc52c86b6L,0x04c60d086965aa4L,0x182bd56ed0a339eL,
40475         0x1bd802d9599c2fcL,0x02cfe0bd08079d0L,0x0c05073a904401aL,
40476         0x158f31c14a7303fL,0x00c949a73dc1185L,0x0837d19cfa7440fL,
40477         0x137577053d29411L,0x05533186e9c56c6L,0x1410d436e9a3ecfL,
40478         0x0ec17d97d5fe3d2L,0x1e49f5166d51d2dL,0x019ba9967231448L } },
40479     /* 94 */
40480     { { 0x11118533a00bb9bL,0x1fdd722fb33429fL,0x0a1752bb8934b4bL,
40481         0x1606830add35c23L,0x0731349f18ba1e1L,0x0b8adad4d640bc1L,
40482         0x14bab04f7f52951L,0x14f4bee8478bb55L,0x130a483b9535b76L,
40483         0x174d6d27fc39f4dL,0x18b611c8e841564L,0x12f71db589c02acL,
40484         0x1a39d8fa70b9354L,0x0068ac4fb0db220L,0x0817c2855075d59L,
40485         0x11210c532846fe1L,0x0bffd8b00346bb2L,0x00c9515aeea6699L },
40486       { 0x1576628365ced07L,0x1997d82ef0e8fb1L,0x06f2fd029ea80a7L,
40487         0x11376a148eda2f7L,0x195a62781b1b2a0L,0x07e0cdc9c4d5ddbL,
40488         0x01ce54b3fd83ecdL,0x1ade757292470fbL,0x0a8f053e66920ccL,
40489         0x1796ea5b1d4da78L,0x03b78547a084a4fL,0x181610717f43356L,
40490         0x0c9ffc11beafba0L,0x0ae6043c15ead3dL,0x10bc318162ff656L,
40491         0x06374d0da9147f1L,0x068c33abaaf1d9bL,0x0319711449de061L } },
40492     /* 95 */
40493     { { 0x0851d2015a1cccaL,0x114863f2915e18eL,0x155463aac14d3bfL,
40494         0x0f790bc42e16e83L,0x01cf8b29ae65619L,0x0a423c57098a0f0L,
40495         0x162b8b8b2d64d9aL,0x111d6af761f8637L,0x0decef5d6c264e7L,
40496         0x1d42b664e5cb6c3L,0x05a04c9e460f69bL,0x1040707af2d45b6L,
40497         0x1f1d0c6fedf03f3L,0x05355ecdac522b7L,0x1e5bc6495626016L,
40498         0x13d4e673ea58b07L,0x145cf6ded8fda7eL,0x03461ece0ae8e66L },
40499       { 0x1e26265e6b392b7L,0x0ecdfbbaeca84b3L,0x13535d9453df3b0L,
40500         0x041bce5c39c2d57L,0x1adfb033d86f59bL,0x122be6533721e68L,
40501         0x16a8b6cd10d0017L,0x0636cf4f22cad03L,0x1c32e7babf01147L,
40502         0x137f0b769d8f4b0L,0x18a63bd8f49b981L,0x1bb0a835badb249L,
40503         0x1f9982f9719bea0L,0x02f83b5677ca806L,0x0f4e5ad721db98fL,
40504         0x0e8f4abc255cb64L,0x0a509efbb362ec6L,0x047902af7119943L } },
40505     /* 96 */
40506     { { 0x04ab9e3b82c1af0L,0x0f4f3f965713225L,0x10298061f51bf19L,
40507         0x0bc72766c69fd55L,0x019bacce27d3f33L,0x153308ce4fbe004L,
40508         0x0ba54fdd062d6e2L,0x113ff528aae6e55L,0x0937d78048db385L,
40509         0x086436fb78fde0eL,0x1af6268bc2833b4L,0x1f446ce873d6915L,
40510         0x0b3f17d2d8ae5d5L,0x008ecc4a081d350L,0x02d9e8bc8cfda29L,
40511         0x17e0cffd9d16643L,0x02e0422540f2319L,0x0094964649a0699L },
40512       { 0x1eb55870386463dL,0x1e15901b8ecbffaL,0x15c42e06716b52eL,
40513         0x0d9e095a82366c8L,0x06939ec10cbb42dL,0x0c23f3aec0ce3b3L,
40514         0x0cb921d16b04e80L,0x1009ee0960438e4L,0x12c9e58a0acb057L,
40515         0x091dc59dab0f14aL,0x137c01e7e6e8d65L,0x1f843d552c50670L,
40516         0x0f8aea2b9078231L,0x1868e131d17562aL,0x0ce400201d7b5dcL,
40517         0x0527559689dabf6L,0x16492546ac2f011L,0x03e3c3b15f5c10bL } },
40518     /* 97 */
40519     { { 0x0f7d6fb067902b6L,0x11d21e8b9acc05cL,0x0c4965d07776ca0L,
40520         0x0e8067f2b80c59fL,0x08589b8c6e391b0L,0x1148791c18e851bL,
40521         0x07ceb8d1d352548L,0x0729b5629ac445cL,0x18f00fcde53f08dL,
40522         0x0cc8bd7383f947aL,0x0a82e81a3981f15L,0x07cfafc3f0482cdL,
40523         0x004d6a328f60271L,0x0c4866953e12aaaL,0x082c82834b8c992L,
40524         0x1c139e440f289d9L,0x01d5c98dc0752f4L,0x034a01a826c26f4L },
40525       { 0x0b7b366e5407206L,0x1aa6786c47d467cL,0x1523dc9cb9bc7b3L,
40526         0x05035688d0dfdfcL,0x0e474408d653137L,0x0839bfa965af872L,
40527         0x141c67909ace992L,0x15e4aed83369301L,0x191f346280f272cL,
40528         0x0730527a34798e4L,0x1a8ca642113625eL,0x001972a2b0570eeL,
40529         0x0514b1adbf8a557L,0x1de9a1f7d58d79bL,0x1607cd08baffe4bL,
40530         0x061c265f3f6036fL,0x146ad850e06ba6bL,0x036d4f013de2fcaL } },
40531     /* 98 */
40532     { { 0x1eee4c25c9490ceL,0x1625186fb41c090L,0x1f8292a4da3aa5bL,
40533         0x149784c5e7cd8c0L,0x060c34ffd8b0492L,0x0f99e6842351082L,
40534         0x1d84bdffde990a3L,0x002218aa0884304L,0x09d25fce9149bcdL,
40535         0x12b08e6e7e309eeL,0x1dfa225fd47395cL,0x1e629d18116a2b3L,
40536         0x1575e7538f3fa3bL,0x08e42010750ab08L,0x00ab42b4782a546L,
40537         0x11cbe1a44d1759eL,0x112a04c6ac4058bL,0x03b9da05cd9a8acL },
40538       { 0x0ff2cdc3631cfd2L,0x06169c03b9bde00L,0x05a8ce2949c0531L,
40539         0x1b665957bdac00cL,0x070b17cad0e3306L,0x19a9f719b39c755L,
40540         0x0eb4fcbd2aa35e7L,0x1c0e25ed5b2aedeL,0x0e427985289b2bcL,
40541         0x0ec7ca6ed496518L,0x0751d76124b7641L,0x0b949a2bc97b312L,
40542         0x0b254eabbd3e06aL,0x0076a89e2392ea7L,0x1eab9b0c4e52b3bL,
40543         0x1a26efc1f30b377L,0x175dc125546833fL,0x0095a31c2e2b627L } },
40544     /* 99 */
40545     { { 0x10dbebd932951deL,0x0cea12d534e4a40L,0x1013b2cbc2365a5L,
40546         0x1844a17058bf893L,0x1aec4e1dac74f0cL,0x04cd66cb521cd29L,
40547         0x0cebf0cf2ae6a41L,0x1165f99bccca9b3L,0x0f4af285c3863aeL,
40548         0x1b99b9f237f5fc4L,0x159cb0f26adfb48L,0x0261fc240418ea3L,
40549         0x0f52f3e56ec1c51L,0x12532540d6c1201L,0x1c58fc8d226adeaL,
40550         0x0662e143f6cc3b3L,0x01717c69be10e55L,0x030e0c9af3ec46aL },
40551       { 0x0722d9b3492ae43L,0x04eca829c782d17L,0x1620802aad8c7beL,
40552         0x01d749622f5cefcL,0x1a461cb82872c12L,0x09c7932e1219641L,
40553         0x1f700c56cd0d32eL,0x11a0b7e558b1898L,0x0d2e501dd596b37L,
40554         0x028364fe5c48618L,0x0bd185f0d87c32aL,0x0e30b46b975c7a1L,
40555         0x11f3fc013821f7bL,0x0592476fde881afL,0x1272b81d18a2bd6L,
40556         0x10ee71ac843a091L,0x19475e3da392ca1L,0x013d686f938e9edL } },
40557     /* 100 */
40558     { { 0x03bda79305b5aedL,0x1ea522ccc6b53cfL,0x074c3dfadc00b19L,
40559         0x1c28fa388990abcL,0x089540edc18a7e9L,0x15fe901f54cb0c6L,
40560         0x110de94ef8829f9L,0x18d9290fcc9d982L,0x17297920734ef85L,
40561         0x106a738eaf0f5eaL,0x0ac79935235adbeL,0x1c0acdc401a9fb4L,
40562         0x1a5a5366a1782a1L,0x0d239b9c151e386L,0x18083a3f8fef4acL,
40563         0x16ccbafdf180cffL,0x02fec686fdeeacfL,0x02ecdaf13b6e8aaL },
40564       { 0x037c5a5cb3e472eL,0x1ec939850a02f1bL,0x0b96d1261560854L,
40565         0x1be73410a201332L,0x15c6c56018f00ccL,0x01aa071311be08dL,
40566         0x0c611063b50204dL,0x0d7fdef97e0fcfeL,0x0ecd92366bf4857L,
40567         0x1badf0d5e4a648dL,0x1de379285889d86L,0x0fa78b8d79711c2L,
40568         0x075ab71858c52e5L,0x1fb71cfcae61c16L,0x09cd7f384b0b0a0L,
40569         0x0b32c98fc1de5acL,0x166e071deb1835aL,0x0127c48e6e5dc63L } },
40570     /* 101 */
40571     { { 0x0ef60bf6778c1e2L,0x0e01e806adf2e12L,0x01b8bc06827ffd2L,
40572         0x095c12dcb1d8233L,0x1077984c59a728aL,0x0652d2d55de76dbL,
40573         0x038f7ed1cef4a1cL,0x195192518c29bc6L,0x13fae7f9a4f67abL,
40574         0x1e15975f610d4e7L,0x1c358a7366d77a0L,0x14b38c1631bf5f4L,
40575         0x1e4049b54cadeaeL,0x16e98871eaff7bdL,0x18c8733f3baf1d9L,
40576         0x115eaee91dfc71eL,0x012fe9c32b118eeL,0x0431d61e7ea16fbL },
40577       { 0x036fca7b85a2fe2L,0x1868477214ee305L,0x08245070e513cf9L,
40578         0x0cce4e541519374L,0x1968bd06306a810L,0x1e301ef34d0aaafL,
40579         0x193eae1bdf91c54L,0x0992e0cc295deadL,0x1c0dc36b898780bL,
40580         0x1b2bff11d0e9931L,0x05ea190d548b250L,0x0feddbfdecf203fL,
40581         0x146daa17a0d9189L,0x02d667def5df18eL,0x07f0779bc5e4402L,
40582         0x02859c1b4dc651fL,0x05a1c9d53dbe1e7L,0x01f1f8d8f45c339L } },
40583     /* 102 */
40584     { { 0x1ea15c07b7fbf05L,0x188db0f8d1c415bL,0x056b477346f264bL,
40585         0x155a1efd1793bbbL,0x1ca7ab7931f5b7fL,0x12adf3149b72f5fL,
40586         0x19550c3d05f7066L,0x17e3ede9c86879bL,0x0971f5e6582f044L,
40587         0x1e1dc7221446204L,0x0b167ee01fd5d5cL,0x05bb0316b1e0c35L,
40588         0x0097a3b0d3a64eeL,0x01ca582c37bd053L,0x0cd45f62e17b320L,
40589         0x07e0d340b28e97fL,0x02589ad5977a79cL,0x04090476c380540L },
40590       { 0x093509914c4ce37L,0x1dc21d0d5245308L,0x0091603563a3cd2L,
40591         0x1366eb71750c00eL,0x0d3bde836db42c4L,0x0919db561b2a927L,
40592         0x051bd548786d192L,0x15d78f98baac9bbL,0x19c14b035bfb5b6L,
40593         0x1915d0c00a360d1L,0x0beef21c8853d5fL,0x0fef69242ec816cL,
40594         0x01cb4d6df13acfdL,0x11300548aff886dL,0x16459fd98389881L,
40595         0x14332f58fb53b03L,0x1c26e8e260cb6e7L,0x0221c1fdc406f59L } },
40596     /* 103 */
40597     { { 0x107f01de44f9af6L,0x00d26c658fd0e70L,0x0fb3edf7524cd8eL,
40598         0x144d51073fccb7cL,0x1ec789d8d0b8435L,0x062f0ff7307c8a9L,
40599         0x0a073897fa940afL,0x17008ef818afc89L,0x1349e9f83230ba5L,
40600         0x0a17997ef0c06ecL,0x0e7abd928f44737L,0x109d7d6e1075160L,
40601         0x04f12742cb80ef8L,0x190501311447306L,0x14eddfd1055b315L,
40602         0x074b39aa8fbcce4L,0x0459829a6eca601L,0x04577384786aa42L },
40603       { 0x0f22d9c32c54409L,0x1fd233af5d5620cL,0x04a218a12606a7aL,
40604         0x1ed6751c1921c5dL,0x1d77641ed0201f6L,0x0b82bae4b980b65L,
40605         0x13807e49bcbc1c0L,0x0089308091ffd81L,0x0bf696211f319d3L,
40606         0x05ae422648d4462L,0x03ef3b800c2a09dL,0x0a4bc9edaa42988L,
40607         0x0c29d67d1ebed67L,0x010e9a9b57bf23eL,0x0ca5017e8c1f6e3L,
40608         0x100bead6d88d577L,0x1a0f059a7e3033eL,0x04b87b0ff304b52L } },
40609     /* 104 */
40610     { { 0x1c53d231bec8e4aL,0x0d60a1ad301a60dL,0x076942791936202L,
40611         0x1b1491046a9dc10L,0x125864b6496ae1fL,0x06834fd0d74c319L,
40612         0x09ad2eb284fa5d3L,0x1486e7198b163b1L,0x15fa71f58e76b9dL,
40613         0x08cdf4463f58b7dL,0x03c4feb5390a772L,0x0ce24933f3dbeb9L,
40614         0x15a10d8bd74583bL,0x0bc85dbf5e71008L,0x0ade377d9b5d815L,
40615         0x0abf5262d5dbc90L,0x0a7e0d8fb2d75f8L,0x02025adca2d3ee6L },
40616       { 0x1ee682a517a15c7L,0x067de77c401017cL,0x04e5441a8d52ab9L,
40617         0x042e1fd7cf9dc58L,0x13d0c54b5de6019L,0x08495bac4f1cfebL,
40618         0x1f97c6571c4d632L,0x0f396fdaa7e14f7L,0x12bd9242af61cc9L,
40619         0x09778b629cafbecL,0x0b0729c2ccbc263L,0x04daa5a30b821a9L,
40620         0x0a942d6195a5875L,0x128058561499582L,0x0bf48c3f896a5e6L,
40621         0x04a78bf43e95cacL,0x00260f55af220daL,0x03fd508dac18a30L } },
40622     /* 105 */
40623     { { 0x0ba4f0c6e402149L,0x0660ecb1e608cd8L,0x106a9949d1d8d61L,
40624         0x0b92ae2be4ee81bL,0x1f89fb0e3f77ff7L,0x0df1ffd9791a569L,
40625         0x1fa09545640cbbeL,0x127f93f643a0846L,0x1eb2eff38a153edL,
40626         0x0ea9d7008020e89L,0x19516dfc6f60a22L,0x0f9c872a7d4b9e5L,
40627         0x14d85e75c8dd4a2L,0x120df0e1806972eL,0x1080cb7ae4fb588L,
40628         0x1ce023ca7e4be04L,0x0bfb9957636c3a4L,0x00a5b1d2976cc7fL },
40629       { 0x010b55371c43336L,0x1ea5311d24125bbL,0x0b800a18146c677L,
40630         0x191ebe3db6f72f4L,0x1b67daad86abbb9L,0x0ffd7db3d2bebbcL,
40631         0x0f18e2b3941b735L,0x0a10bb53f2b1358L,0x0081cbaa875a3d1L,
40632         0x19a9ec7f49a3769L,0x0d87c687e680b40L,0x126e74cb38e3655L,
40633         0x0b4f5df8a1b0cb0L,0x15bead0edbf0718L,0x03973c1df131d07L,
40634         0x0e3591e08d938e5L,0x05532dd0bc7f7c1L,0x001242c39c1b693L } },
40635     /* 106 */
40636     { { 0x140dd2375a4cd8dL,0x05219cbde5d3c66L,0x1610963587d44cbL,
40637         0x13b43d1cd0618b9L,0x1d65d40a0a7ec05L,0x1a86bb03d478b88L,
40638         0x0b90a1a79957bd0L,0x1a17319cde0b307L,0x17b61391d9d8bebL,
40639         0x1294f12d8dd2ea4L,0x1ccba47dacb3d8eL,0x18d47f476c528deL,
40640         0x0cc3ef0ed2bd66eL,0x0f845a3b1cbca87L,0x16838bbba40232dL,
40641         0x1790ffad7c84b2cL,0x1ae78ed513c1177L,0x033cc676fff2896L },
40642       { 0x1e3f8fd1b97c5c6L,0x1d59f3c61d99fa4L,0x104903d656e8e7eL,
40643         0x12bafa86ec884e8L,0x19c44777174225bL,0x0b5922c4059fe63L,
40644         0x1861370eb2a0ccaL,0x0e4ab227bee2e69L,0x1a4db23d39c9344L,
40645         0x15d9b99e8a10508L,0x0833e7cd822f733L,0x19ec619fc27f73aL,
40646         0x115f30874ca618aL,0x0f8002d2baf8359L,0x0ff276d41bbf9feL,
40647         0x0f883155d4f1803L,0x195f9179255f78eL,0x01f53d7692974b1L } },
40648     /* 107 */
40649     { { 0x0617e045b06ae25L,0x00a46e5aba877ccL,0x1c398130ae8af2bL,
40650         0x16ed6f12eb23d45L,0x051da18100c19f6L,0x02b82dbcdcdb683L,
40651         0x16fc7cc896faf25L,0x0da61686be6b800L,0x1440b4482bc24d8L,
40652         0x1c784cb6b1b9bbbL,0x15b1587112d370aL,0x1dcc6120d332cbfL,
40653         0x0408aa1ec1e9405L,0x1e97944a8cff849L,0x1d19e5fbbcc91a8L,
40654         0x0befc02d86ecb78L,0x04462d2569fd070L,0x0354569ce029280L },
40655       { 0x05f020d46be7282L,0x0d7f6909c078972L,0x16f75769ab42501L,
40656         0x08ff17cc3c99b94L,0x196b8178c2d6f18L,0x06fcaa100994a9aL,
40657         0x0ad3634ec79edeaL,0x0aceaf8c37672aeL,0x0d749b57b80cc3bL,
40658         0x0c87fc99bd9fff6L,0x0ed94c517725365L,0x0c0c466bcae6737L,
40659         0x17f763feba70c1cL,0x0630db994e17396L,0x1cfcb291da39093L,
40660         0x0b19aeefa5f4d54L,0x1aadee4dbaac5cbL,0x00d0c08bcce7d70L } },
40661     /* 108 */
40662     { { 0x16ff62f77575ed0L,0x0a7d4be8ed4cdb7L,0x1beda7bf5fd863cL,
40663         0x17bb850c665ce55L,0x186c5834c45ab4cL,0x1baeec587106a42L,
40664         0x112634e5c0468e5L,0x1b002619011e826L,0x12d408ebaf5115eL,
40665         0x083502e01306f6cL,0x0dcd88672ae4471L,0x118dd0d2750d3cbL,
40666         0x1fcc7736174cf50L,0x0aec4e51a738922L,0x1eef260bdc6a87eL,
40667         0x0ffa49774f8d4c0L,0x1a8f3a515e7212bL,0x03e96ee3ac9187aL },
40668       { 0x105816d4ed2cae8L,0x15e3edce001bb9eL,0x039991ac235133dL,
40669         0x0297380301847d3L,0x0f9179c1f9ee6c6L,0x0cb445708e4d09fL,
40670         0x1c29e96d851fa3bL,0x0eaf5fd6c91a0ccL,0x0d670333c176852L,
40671         0x04eecb4bafcf479L,0x1c8a34de9a2b7aaL,0x1abc8a99630d76aL,
40672         0x0f063dd55021a05L,0x065b6579a4080acL,0x152af9e4b753c21L,
40673         0x13aece189b0a4f0L,0x0ba845969dc6e72L,0x02d297c3d58dfa0L } },
40674     /* 109 */
40675     { { 0x1019e9109ecacbdL,0x0011ebdc4def576L,0x1c2d5c1cdc79951L,
40676         0x082d91c42ef98a3L,0x01259ab514832b0L,0x11b0ea58d533414L,
40677         0x170a9b8403e488fL,0x04dcb27ddd3c752L,0x1699b6bbd16c10eL,
40678         0x0a43c39ca39d09fL,0x053716c9d261f2bL,0x00ea4ab3c5d3e38L,
40679         0x1dc3d47ad257dc0L,0x0ea93bc9c224c24L,0x1f56e660f7c9e2bL,
40680         0x00540ee1c7d91ddL,0x1fe2ae5844676bdL,0x00bf813b21f382fL },
40681       { 0x1a4010d29abea1fL,0x1cb4a9203d6266eL,0x04a410cc862d8daL,
40682         0x162c7aa6952d4c0L,0x0cc20565f221fc3L,0x142abb82dd0adf6L,
40683         0x0134c48e3953658L,0x1c8362884af0f10L,0x196fbf304a89a9fL,
40684         0x053f83625f32158L,0x0883a1b8ac217b2L,0x0f85fe94b23bba3L,
40685         0x13a4a343b88f7f2L,0x1d8b9ea6e0bd83aL,0x101eef9a12c7a22L,
40686         0x03aee7599d4887bL,0x17edb15c88d4c44L,0x00778184d29f2caL } },
40687     /* 110 */
40688     { { 0x1c25721fa8e5b60L,0x09c56b48e05d927L,0x0dd82c28892191aL,
40689         0x04fbc2d0efc8da9L,0x0721c630863f9acL,0x13fd81281ddb779L,
40690         0x0f4e7e306677c2dL,0x1b4f183dae5c0f5L,0x1cf9deb7bb32f0dL,
40691         0x1fb9378361e44f9L,0x022cb465c8896abL,0x022e9e28beb96e0L,
40692         0x0c457c4f378f5a6L,0x0e229e32270737cL,0x1a4b2022ef6a910L,
40693         0x06ac2af7c64db4dL,0x12aa9bc3fd95d77L,0x01e9db6635d9bdbL },
40694       { 0x06f12cc9722c880L,0x1b5739435b444b7L,0x026eb4bebfb0e86L,
40695         0x14877717df74398L,0x17c3f4c3ad64ad7L,0x09d48dd2d7b5004L,
40696         0x0fdacabf2c3670dL,0x1219427f956d399L,0x1699a1391f2abc1L,
40697         0x0deaaa111d123f2L,0x18603e55223668bL,0x17fe24899879c40L,
40698         0x1e87d3a365ba9e7L,0x1d2652f11494bd5L,0x0f86db10153e8e3L,
40699         0x034896720c47acfL,0x0e71fa67c5778f4L,0x0174a3721e3daa2L } },
40700     /* 111 */
40701     { { 0x180fddfc60934aeL,0x13f7f8b21036894L,0x1e5905bb5d68b0fL,
40702         0x06b9a165b9eebcfL,0x1faad87bfac60cfL,0x04f2eeeee25f670L,
40703         0x1c6b9d4fea1f261L,0x0978baa2d465837L,0x1565dbea814732bL,
40704         0x03f5f1d672434b5L,0x09d35b36e5da500L,0x04e0cbc9cf7c819L,
40705         0x013aac4ebc3f5cdL,0x01eb61d0ba423e0L,0x1e81da99d8b80d1L,
40706         0x0cefad21b192a8cL,0x0c2768d78d61edaL,0x004cbe72a80c0ecL },
40707       { 0x097746c965a0b81L,0x0c5f372f096fd49L,0x0f11c57d0dfd22dL,
40708         0x0f6acb88b2aae76L,0x1582797ce425e90L,0x12a3a7a7a1fa890L,
40709         0x012b3976be9be3aL,0x10655d71f7c27bcL,0x0ed7f95f0e8a07cL,
40710         0x1009537331604ffL,0x1ba6e31d0b3c5cfL,0x0b35c514388b7f2L,
40711         0x145cf4e2f38ea57L,0x1c80d00ca3aca0dL,0x045acb9f74f00b7L,
40712         0x17311cf49bdd4e1L,0x1e650b272b52fa9L,0x04b7cf84fe848bfL } },
40713     /* 112 */
40714     { { 0x0e8aac42c310a96L,0x0c181fbd1539a3cL,0x00f48e58881ccaaL,
40715         0x1db2a8250188d95L,0x0cabe911ad131e6L,0x0db6342bc8fe2f1L,
40716         0x021e1432ddfae10L,0x19d5ff27bd47a79L,0x106541f1df1007bL,
40717         0x17394e12ae6f8feL,0x1c4c5cc8f8e5c93L,0x14835a9a1183c1eL,
40718         0x1fa35e22bfa2de7L,0x04d81992d4c8955L,0x145353a814048aeL,
40719         0x1c157173ca3e80cL,0x0a5423c7aad79d3L,0x038ccc713205c7fL },
40720       { 0x0140fcdceb6ed78L,0x079bb8c29a28b20L,0x196ba358373194fL,
40721         0x0d3b58abf008a16L,0x0e05686cce6c1a7L,0x1892b1454b5496dL,
40722         0x05094bf911d8849L,0x184e8f796a149e7L,0x0f0ec6ff2fc531fL,
40723         0x0be1a23887f4ff8L,0x021e0e71e4b3ff2L,0x049004df6033f69L,
40724         0x1cd804c290552c5L,0x1ae46539a000d14L,0x1977e81d0ad6b60L,
40725         0x0956386f03e2eddL,0x0acca6b85f03dfaL,0x041c4ca0d058699L } },
40726     /* 113 */
40727     { { 0x0f062a2de067dffL,0x193485e5c00b160L,0x04341c1e8af753cL,
40728         0x11f5c94723319b3L,0x132ad8145afc63bL,0x0cefd8b4278dbddL,
40729         0x16122c28b738bc6L,0x0c444c1c2fe91e4L,0x17393db00c2d5e8L,
40730         0x1447c2a19c678b8L,0x1e50a40ab3d48a7L,0x1970d06b5e7a00cL,
40731         0x12b8a2614c19157L,0x09a7623617d537cL,0x1ea04d413fe57d4L,
40732         0x08e099e00c4ddf6L,0x025454b3d05b37aL,0x00fdfed18934a76L },
40733       { 0x1ebb657c8f69c77L,0x013c5d1efc47d7eL,0x15c707ede2d24aaL,
40734         0x14238e34668c76aL,0x089958b0d2066a1L,0x0eb3d3086440a18L,
40735         0x1ee3ee5d71f833eL,0x0c3b54ba410e606L,0x15ee5005d40bf58L,
40736         0x0073673bedd34d4L,0x10f2cf258b31d0cL,0x0c5299f080ab127L,
40737         0x1a225c9d700ac98L,0x1c8f23f4053f7b1L,0x0be12fbf86121a6L,
40738         0x0f17e373afbd718L,0x19e67788915c0e2L,0x027ca4465621378L } },
40739     /* 114 */
40740     { { 0x10dfcd4dd51b8ceL,0x1c93c1b11874030L,0x1c70d9665588215L,
40741         0x17c595d0efdb8ffL,0x07967608905ead4L,0x1c493650e192ecfL,
40742         0x02938f8e7b776f4L,0x149b52590d0bedeL,0x1e16f800af47a0fL,
40743         0x05a6dadf2fb0555L,0x1504be60e14f4d4L,0x04a136f2f1386ccL,
40744         0x184e0e72b264b62L,0x12aae15df52b002L,0x0a4b846aef52407L,
40745         0x0431e6f08334e2eL,0x1926e0b5aaae174L,0x03447034247bcb5L },
40746       { 0x1fef641313b8f64L,0x08dbdca163a3166L,0x0ddd70362af6bbcL,
40747         0x015e8083520cf9fL,0x0935210f608ea5fL,0x08bd0411eadec13L,
40748         0x0b4856ae413f09eL,0x13f0bb763fc8ba4L,0x0c3d5e5094d3615L,
40749         0x15da9470e9cdc79L,0x12a0a3d12b3bc2bL,0x15be418af4a9babL,
40750         0x1378f95f4424209L,0x1499be9baba15a1L,0x133f6df447e9f66L,
40751         0x02fd9acd418138cL,0x06556e55b8f9bb8L,0x00b91e3f1f26209L } },
40752     /* 115 */
40753     { { 0x06486d8dc8b43f3L,0x1073093204f344dL,0x10df66d1800ff0fL,
40754         0x0ac509d8f631138L,0x0a9dbaea3a85033L,0x1c499e2d1b32e23L,
40755         0x05241efda5077a5L,0x05a3dab4a20d268L,0x1664a7b7a8cb800L,
40756         0x01fbb723076852cL,0x01ae8c7d3afc9d8L,0x1a83e58714ff87cL,
40757         0x19cf1db08a296ceL,0x06f3d1db1560c7bL,0x1da2c1b2467a20bL,
40758         0x0f96a2bcefa53b7L,0x13a21978baa4e94L,0x0425faa15bb184cL },
40759       { 0x1decda9e364f21eL,0x079a280972abf60L,0x0121623e438435bL,
40760         0x17c76209717448dL,0x03aef57a9f6dda4L,0x193f54b5fbd1a37L,
40761         0x19b1c840a67fba0L,0x08b5533e90fb52bL,0x024ff813ed2cdf6L,
40762         0x0edd96945ea0a5cL,0x0406bf2be869874L,0x173539bd7b480caL,
40763         0x15e41039e47d9f4L,0x02856fa157a0d9cL,0x07a79278fa79aebL,
40764         0x0fe469e42675c68L,0x1534968c0f3cb15L,0x01c1fc13ded0340L } },
40765     /* 116 */
40766     { { 0x0c46a216583ff4cL,0x02d14a56b84f397L,0x073f013284a9399L,
40767         0x0922c14fcbb8cddL,0x169c762e82f128fL,0x16dc73dfd913d8aL,
40768         0x1da23e031e58f0bL,0x1994fb5fc0c9341L,0x0b7e417542d14b8L,
40769         0x1062e29c36f205fL,0x014a1876de4cc4eL,0x1cd3f7fc0e37e1aL,
40770         0x16210e9903b902cL,0x1b81f5dc30f234aL,0x17de2dbebbe1d3bL,
40771         0x1d475ecd128fdbaL,0x0256fe865475af5L,0x01d890f8aa1fca3L },
40772       { 0x126e847659275e9L,0x00e7eb687e7282dL,0x0ff62a8fc7bd1d6L,
40773         0x0bc909cc1cabeb9L,0x1e9698e41e7be31L,0x1823c26c78d107fL,
40774         0x16cf89751b6a5eaL,0x0134a4db6eb0699L,0x01fd408d98d08a0L,
40775         0x00025902dae540bL,0x18eecd9792efa3fL,0x024aeb376ddeb67L,
40776         0x17c2fac737f50ccL,0x0939ca8d782fd40L,0x12ccd9e7b840b4bL,
40777         0x0a2be551ca817fdL,0x083673446fb2a6aL,0x02a82f0e89b9486L } },
40778     /* 117 */
40779     { { 0x03014a1d15e68a6L,0x18593326e9af286L,0x10b40eb59fe5be7L,
40780         0x1da58289083186eL,0x0d41a3cb74818c0L,0x0f9f4f628c08b48L,
40781         0x04e19972320ff12L,0x139364c18c2584fL,0x0f6086faeced04eL,
40782         0x1d96675febe23acL,0x10c4ce40a5ff629L,0x09d012e03590967L,
40783         0x07508b3762ca826L,0x0c1d46ff4fcbb54L,0x15663a575609c52L,
40784         0x1a6906a1a4cd3b3L,0x17c85cb89cb0f6fL,0x030bec06a52ba18L },
40785       { 0x0ef267e70022b67L,0x1b5da9bb45ca526L,0x159b49e1118a014L,
40786         0x087048723262a74L,0x1df78c4a49054d4L,0x10f1ad4688f0b92L,
40787         0x18c766c94a9c756L,0x01c0f0cd90102e3L,0x00a8501db1b38a0L,
40788         0x16c995c673b811bL,0x1dd8263b6bdf40bL,0x1b5772600dd345aL,
40789         0x04bbfeb0363aee5L,0x0710d9c5fd7fe46L,0x0a381a41dee59e1L,
40790         0x108e2923f8b3fb9L,0x00b3f624f550e93L,0x028ab7a843e68bcL } },
40791     /* 118 */
40792     { { 0x0234e220206e8d0L,0x17aea3f8ad7992cL,0x0a2758e2543fd7dL,
40793         0x12fa892be95f56eL,0x08da80a966ec4d0L,0x1c51b5d6c4862ebL,
40794         0x1717f92a8248193L,0x062f33c4afc1e9aL,0x044c677ae24495eL,
40795         0x101c3d9d2dc71a9L,0x1e43d1d68a1ee5cL,0x198b8783e5eee06L,
40796         0x1b41a7fa4154895L,0x18058045dc3407cL,0x191cf2ff351d162L,
40797         0x1c3342939907174L,0x1ba78ed5f7aac9bL,0x0292a2cce599bb2L },
40798       { 0x0739679a21b54c4L,0x167155b24bece84L,0x0a4b212219000a7L,
40799         0x1fd3f4f3b3e29e3L,0x06c208dbae48dcfL,0x11fb4f0a5c88e12L,
40800         0x0e0e16ac3efcb6bL,0x176301590fda3dbL,0x0146fd718188586L,
40801         0x0875b2a2a33e5e8L,0x0e5020599f3fb88L,0x18356e7a34c1544L,
40802         0x00881c1cbedb125L,0x1be181196f34298L,0x0f23463f8d31c4cL,
40803         0x09d078d8c0e1cdeL,0x14507e365bab4afL,0x0117853f6ee7c15L } },
40804     /* 119 */
40805     { { 0x062791fea7f1b7fL,0x0c62eee7f84ea71L,0x070ce71f716270fL,
40806         0x0e84edd1810d855L,0x09fe1d564dad401L,0x1408648548c7acfL,
40807         0x13712e35e59c0aaL,0x05dd6f5106c954bL,0x0fc4c23bbe7afa7L,
40808         0x0ddae4f25643484L,0x0e404da831f9bd3L,0x0002938431a46fcL,
40809         0x0794b324a2855d7L,0x1143d038f23ade3L,0x0d0c8f3262a3719L,
40810         0x113d272b45336bfL,0x046e186c3ee0c03L,0x03cfc0f378b39a6L },
40811       { 0x1f2c1f3364f3c4eL,0x1956289b3f0a5c1L,0x13f164cf90f54daL,
40812         0x0a21b2c3fc894dbL,0x1e3f2aae34e5947L,0x153f928411a7673L,
40813         0x084932e4b802af7L,0x0743df749e14f23L,0x0c2086fd21192d5L,
40814         0x160687e5a8e457bL,0x06cb2b703c6d7ffL,0x111f025b7c3291aL,
40815         0x0adedbdd45b07a3L,0x0b812c4d20439d3L,0x189ed92f0a849a3L,
40816         0x0dd0b77edc7502fL,0x00073ee56636d38L,0x02217669bcef3e0L } },
40817     /* 120 */
40818     { { 0x0cd1ae68a2f90a6L,0x1ea0eb7ad68665aL,0x031100752e3bc9dL,
40819         0x09b06ecc62d4705L,0x15e1124be817a13L,0x15caf20a15bac6fL,
40820         0x078f897ef1a77f5L,0x19d46193ebfae95L,0x15ac0f163d89663L,
40821         0x154f77b86731c36L,0x043a9763b55510cL,0x1fe1311284f4f4dL,
40822         0x05eaaced585de23L,0x09f0c232bad69b5L,0x024e440d4529b07L,
40823         0x0add07b22c586feL,0x11e5c10add9e33dL,0x0428bb5b9835534L },
40824       { 0x12110fa28a21e38L,0x11bceabb9ea9c51L,0x0efcb40837125edL,
40825         0x072c30679ba6d2fL,0x05fa85165917759L,0x155ae936b822fd7L,
40826         0x16dc0ce43ca69e1L,0x18d5817b461b89eL,0x1cca0240adcc615L,
40827         0x10f8b81628a36c8L,0x11cb429cb3be1e3L,0x0e1016cd37439d6L,
40828         0x1d7e61aa0a84840L,0x0334ab05bcd847cL,0x03adc78e20582f9L,
40829         0x0b2184726b85b29L,0x0b3d7fd83c09431L,0x04558aa5db72bb4L } },
40830     /* 121 */
40831     { { 0x0686003353c4a96L,0x03074482e6c1a94L,0x0d923d9be331397L,
40832         0x113f599f3d7ab22L,0x032639e5b6b80b9L,0x0556f5de0e0fd77L,
40833         0x080b4bd8e5b489eL,0x06a014f2da03130L,0x018ab548f3a4748L,
40834         0x0682b61d98d871fL,0x09a374059144b6bL,0x0db29607e7782b7L,
40835         0x0bd8f206c520383L,0x0f8bbcdb6b27653L,0x0acd2a24c68d87aL,
40836         0x05c45b04d21f8a5L,0x0a9342bb8e09292L,0x00dfe6ec2700581L },
40837       { 0x10b9a4375a365d9L,0x0f0af046c7d8198L,0x0f5f5d0b7e0f52bL,
40838         0x09bc630e85392eaL,0x1360ace0cf7309dL,0x134b21891471091L,
40839         0x1694c410f48e3ddL,0x12ff855b7dbf21eL,0x041d64cb77b5f93L,
40840         0x100598562236808L,0x0190b48c5c83f94L,0x045b735440eb879L,
40841         0x12041eae47fcc01L,0x14643b5242b71d8L,0x0d81ac516191155L,
40842         0x0af7e3438f08446L,0x0f19b766d1f2277L,0x012dbc51dfbdceaL } },
40843     /* 122 */
40844     { { 0x0835718156707ceL,0x011cc218a7c8548L,0x016a2f95f6f66f7L,
40845         0x0b5ac7497002f91L,0x15aacffdd4bba22L,0x0aa3912e738dc30L,
40846         0x14f757c9991d5caL,0x1ae1501e3ee9e15L,0x0010538a3fc352eL,
40847         0x0532022a101e365L,0x11ea20cc31ced3eL,0x1dcc05b95836565L,
40848         0x0fed2b17c7b3433L,0x1eb194e397024ceL,0x1eb70de7e1a0692L,
40849         0x112b6712f328c6dL,0x0f0dc5650c892b7L,0x03855cab832d28eL },
40850       { 0x0778ec47b585d93L,0x09b085319ff2723L,0x15393a80c46b29bL,
40851         0x177ac8005e43b42L,0x191cb7a9af22190L,0x141bebcf319d63eL,
40852         0x1ba2bb44f0c7fb9L,0x02db4940fae2c2dL,0x0d78a27323afcd6L,
40853         0x0334b72dd0a6b4aL,0x1d535d37d610830L,0x009c4ef1c792e66L,
40854         0x0c55b5a5c2e85e5L,0x051d65ae182ad50L,0x0223b68c4f7d4e2L,
40855         0x0bbbcb12d596a54L,0x0befc8842a084c8L,0x02ff64fbca8eef3L } },
40856     /* 123 */
40857     { { 0x0bc2c7cfe519f99L,0x15ec072a081a9afL,0x100a28e623cf8e5L,
40858         0x0bac037b435bdb2L,0x14ce64ac1c03b73L,0x1201487e98101b0L,
40859         0x025f560dfafa404L,0x073955d43474aa8L,0x1dce73d25b0b881L,
40860         0x0f6a095f658485cL,0x0a7fdf58f6acf0dL,0x0fb20c5b60e3320L,
40861         0x1642a4c11d55543L,0x127e488493be97aL,0x06495351dfe9914L,
40862         0x0c318f625d36e4fL,0x1957ad2ae22d84cL,0x00546ab31e74768L },
40863       { 0x1ac51630a21fde1L,0x1aeeb3481ec24a1L,0x07b97f758a073f3L,
40864         0x00ef493468da493L,0x0875c06f4dedc6fL,0x1dc023235ed1601L,
40865         0x00dbf438383d8d1L,0x08420b02d36bccfL,0x0c961912ade8a80L,
40866         0x19ff505549d9e99L,0x0e3b6c315daf177L,0x1addb1a6fc8f3e2L,
40867         0x19cce5e7cb7971aL,0x0e9015a0755c2b9L,0x087f49a2292d0d0L,
40868         0x0df22bb084aafc7L,0x09f872fabd5b3a8L,0x04adc9a49b55231L } },
40869     /* 124 */
40870     { { 0x198a70199f951deL,0x0f2cb782c6da2ccL,0x107bcf40f74e3ebL,
40871         0x1a676283a69a8f3L,0x0cfe8a406e928d5L,0x077d1ecd232c005L,
40872         0x1c9bb4422b4bf07L,0x13ec972d243c026L,0x0b9b6a6b68e83bbL,
40873         0x0f8f36e092172a2L,0x03d9d8bd9659acaL,0x012cbc20b683a7fL,
40874         0x1a16011e1ca34ddL,0x128aaa0dea7489cL,0x08859b7ba9371a0L,
40875         0x0c248df00615990L,0x07dbdc7ae1d31d1L,0x01712f7a8b10d7dL },
40876       { 0x133cf8fdd8e7357L,0x1d10c75676edc12L,0x0c741e134ab0cceL,
40877         0x0de50095c4d1c7cL,0x17e7ad7e1c927f3L,0x1fbc5000a19e913L,
40878         0x09eb82d0073c161L,0x16b3bf9e06d5400L,0x0c9e46c8b1d9a46L,
40879         0x136f2430f944699L,0x1b68bc6e2810f6aL,0x01cbe5a176adbaaL,
40880         0x0419defb5634623L,0x10e9643a0cf85b7L,0x03916cd57b0df34L,
40881         0x1d0a47b7e072f6eL,0x1d6f0862a8dac7cL,0x043cbcf53f0a0f9L } },
40882     /* 125 */
40883     { { 0x17e7b3f7f1c747fL,0x1260ee37319b4cdL,0x1dc2cdcb6e80546L,
40884         0x09a7dca9fc84e7fL,0x133cae0fca6d223L,0x0b7886097e47066L,
40885         0x073e49cca14e177L,0x12390de7f7be035L,0x05322677fe36caeL,
40886         0x0d3801997f7f522L,0x128ca33a2bc85ceL,0x0eeded4e63e8593L,
40887         0x1f66a96813c0256L,0x06d976d46343d9eL,0x113faf4652aac4aL,
40888         0x08365bc61b8b5ddL,0x016c052236a9792L,0x01f64c401611ea6L },
40889       { 0x19e760c4072f74dL,0x1586f55aca02c87L,0x090326c0270b9e3L,
40890         0x00716b35cbb67bdL,0x0b4daa0647e875fL,0x079bc47a075a1b1L,
40891         0x0be2e69a93e4824L,0x0addfd7d35fdb7fL,0x1f87f96a59867e2L,
40892         0x137f691bad5b575L,0x09e0a8ff6c4f2c7L,0x0e3ce1f44c422feL,
40893         0x0cfd4c0dbe5102cL,0x181a394bae95837L,0x19f9e014df309a0L,
40894         0x1b4651b7ebc5656L,0x1142f633f3aba25L,0x01f498af477d764L } },
40895     /* 126 */
40896     { { 0x055cfa5239a9ea9L,0x1e34805f19d3149L,0x0d2e72d90af483cL,
40897         0x0c0175ce30eb3ddL,0x13410f843316c54L,0x1894db43a53b6afL,
40898         0x07c7048ed40ba43L,0x1195b91f350250aL,0x1f57b764a1b6240L,
40899         0x0b7600f8d403bbdL,0x1b3bc87c3771704L,0x08f9cb4d4b4ee8dL,
40900         0x0706e955ba3c49dL,0x1a2ebcd80f0aedfL,0x034421d8a7031e6L,
40901         0x045ae224f0610efL,0x19122585dc78c6aL,0x017681506853413L },
40902       { 0x10434164daa2682L,0x16995809acb12a9L,0x0d2af619c25c389L,
40903         0x17dcef5c5c89390L,0x1af6c16911a19d2L,0x0b082a1cdea94d1L,
40904         0x03f84db32970173L,0x06ac6e14b37b8d8L,0x0ca420d27b93d51L,
40905         0x03986a2aaa6228dL,0x0963265b37afcb6L,0x13214a1f340bd7aL,
40906         0x1a7b0f01510cb1bL,0x08e90bf0b4d464bL,0x0bdd7a0b30db4d0L,
40907         0x054c3e22ed114eaL,0x1dd1db01394a09bL,0x00a313c2254f7ebL } },
40908     /* 127 */
40909     { { 0x1ca3aed232803cfL,0x01cc5cd4b7f9a35L,0x15fdd2ade22f079L,
40910         0x00fcd1809b95eceL,0x1cb7cd20c3a53e0L,0x0345e52fcb4e0caL,
40911         0x0c0cbca2d969b70L,0x029c79403a63b0cL,0x09b733b8187808eL,
40912         0x0eb826cf7f30c5fL,0x1cd50ac06e51b6dL,0x033df7dbbb7e4edL,
40913         0x0b903275cee057eL,0x0407bde33e8c179L,0x11db050f3717ddeL,
40914         0x0a0e5ade07a7ef0L,0x028035f5557a9baL,0x03d65abdb5a014bL },
40915       { 0x041356944e6b07cL,0x02664f0e39a2ee9L,0x136389cee7ed147L,
40916         0x13711c69f880e88L,0x1152776dfe49607L,0x0114ce3be8c267fL,
40917         0x0a25db440cee71dL,0x04053414d08ef7eL,0x059ffdf10ee8f04L,
40918         0x10b8a36225dab6bL,0x141b0bee6ba1553L,0x05b7b27cf9ab063L,
40919         0x063c96b607b2cb8L,0x1aa4f154419c0e2L,0x12887501abb4945L,
40920         0x1f7bbdf2f1238eeL,0x16cae9807c78675L,0x0352d02dcb1b1a8L } },
40921     /* 128 */
40922     { { 0x0e71ea66a8f4f33L,0x037e326f547a549L,0x14b3fba21187cbfL,
40923         0x1c112a9a11a6ac4L,0x068ab76659b0a83L,0x07c6822deb4611aL,
40924         0x19eb900a04d5e40L,0x08230383380a570L,0x0986a516918764cL,
40925         0x180efd709abae92L,0x1a6b9564d9dedf2L,0x004a8db936322e4L,
40926         0x19c40097c8f6d17L,0x12ce203dc6f3424L,0x14a762ddb7c00c8L,
40927         0x16bec812355b22fL,0x08ca7f46d214a7aL,0x034402a5a387672L },
40928       { 0x0d168aa51a5b86cL,0x1f26c4abbb923f8L,0x01dbc5c80ca490dL,
40929         0x1b2c8f4a9d5d088L,0x0405622c0a7ac87L,0x13cf978f2cbd258L,
40930         0x055b7b7bf971bc2L,0x1ed5e7de1849aaaL,0x1917fb04eef047cL,
40931         0x1c93ccfaa5b109bL,0x1a8cbcc52f82e0dL,0x0cb6188cd6190ebL,
40932         0x0e7e218978e157cL,0x06f2c3d7e946486L,0x01defb6e43f0eebL,
40933         0x0219bba65ae3917L,0x0533b432200ca8eL,0x00010fa0ceca7b7L } },
40934     /* 129 */
40935     { { 0x191122c43519d26L,0x1d60ea0528c2290L,0x07a5522ee27ef6bL,
40936         0x182d0897f398deeL,0x178e8d559ef3375L,0x05f0e2f3bc4fbc8L,
40937         0x1790013d666d87eL,0x193011193345977L,0x18939a260893206L,
40938         0x0d725fffe698428L,0x12cffb823fabfa8L,0x0133fe295578cc9L,
40939         0x0c2a841ef961f38L,0x0bf80edb06c1ca6L,0x1aeddcdd7eb62b4L,
40940         0x04a24df868aecdbL,0x19f1e716b05a425L,0x03cc2ac4014f0f6L },
40941       { 0x0cb3aaa95106473L,0x17d20ad30ed0251L,0x0d894e558f0257eL,
40942         0x032a62570ffa792L,0x1f885c76baa4809L,0x063c6ab63f3ac15L,
40943         0x11035c3db6ad88cL,0x10d19c60a38ee8eL,0x06dbebd14ffdb61L,
40944         0x07020fd0c87204bL,0x031199bb98b8aacL,0x1c54e9e667ad742L,
40945         0x04fe7b9b6693d57L,0x036941be803556eL,0x01d07abebdcbdb0L,
40946         0x048ee63198bcd22L,0x08d9c5026096569L,0x04aec11e18e87d8L } },
40947     /* 130 */
40948     { { 0x0eebd86140528a5L,0x0615d29cbcde435L,0x0e293b0512afc9aL,
40949         0x1b054fafdb63793L,0x0e0118d81efabb0L,0x00aac778963868aL,
40950         0x19cf8c581c5a287L,0x1ba67c8516fc96fL,0x06317663783aec9L,
40951         0x0b97fdf709561aeL,0x1c2feef05eca914L,0x10e0e83f02546fbL,
40952         0x1be2888f9c4212fL,0x1ab652ae9ee765eL,0x00a3906a77056a9L,
40953         0x1b607e63231d972L,0x1547ede02856aeaL,0x00713846abc32a7L },
40954       { 0x070cc53cde20f88L,0x013962fad881c91L,0x0679772c76fe4ceL,
40955         0x136e5ae982a085cL,0x0aaaaa554b3de21L,0x1435d30b624d459L,
40956         0x05a5402110f96eeL,0x023dcd79ae4419eL,0x159ffac6ba89abdL,
40957         0x01890bdf88ab1ceL,0x0a2bcbcd32e948aL,0x07ce0e4f520dc9aL,
40958         0x1f69017766f27f0L,0x1d40891f342163cL,0x0a5cee32cd1a6f5L,
40959         0x01b7a9181e68d48L,0x078fc5784a62399L,0x0069ed59dfd94cbL } },
40960     /* 131 */
40961     { { 0x18376e6ce29c3ccL,0x083f6780b65e347L,0x065978e533872c1L,
40962         0x1ee78a1a83bd7ffL,0x0d16ce3d24fc526L,0x0098a0a76ead2a1L,
40963         0x0181aecdef76647L,0x151c6885de5c675L,0x12ae90337c0629dL,
40964         0x1fd76322c955998L,0x0e265f60ae15ed5L,0x1973466e62ec352L,
40965         0x029086751fad6c8L,0x0c60b8cb412caefL,0x1a5cd5ea07a5fecL,
40966         0x13ed3c9e914277eL,0x026a1387c2e5cb8L,0x02985a775ac3a5aL },
40967       { 0x1f275a1bab7b5aeL,0x0ee2681d2bdfa74L,0x112a9171416eedaL,
40968         0x0682d5880592e9bL,0x0ed985dc726369fL,0x0a2350b9af273c5L,
40969         0x0c0a8152361e737L,0x14d099d60d33c2dL,0x0f73f6fa4789b11L,
40970         0x150620fd95273c2L,0x1da40a4ea6da5daL,0x1c01e075156563eL,
40971         0x1b844d66c1814ccL,0x184a9100b26592aL,0x08c89c6de539f58L,
40972         0x149b3c0a5a9c87bL,0x17f5278b2e708b6L,0x0484a12a940632bL } },
40973     /* 132 */
40974     { { 0x069a14d0d5b4c2fL,0x1e2cdae45324e69L,0x0ceac38df528ae3L,
40975         0x11222206fd2b7d9L,0x14e35322fda1a76L,0x1c7d7e2c08702d4L,
40976         0x1398a8937304a85L,0x088b858c7651c7bL,0x1995c3f179452c4L,
40977         0x0998761a16a28b0L,0x16982ad3be04a4dL,0x04a5175d3827404L,
40978         0x06e2e3caf885493L,0x1b24dfa392e8d30L,0x13b17c7510246acL,
40979         0x066678fa15f7ee0L,0x0f527bd1d62bd8bL,0x0282b8088e7f30bL },
40980       { 0x0084acef534356bL,0x0ef02a5a587de68L,0x18173b81370677cL,
40981         0x106c36f1c20435fL,0x0f78d38b64bde68L,0x052f2751927e63fL,
40982         0x0665bfacdcb3bacL,0x09dde09f966cb02L,0x07dce5d505eb0abL,
40983         0x114dac411c62c37L,0x18c65ef36000dc7L,0x08a2900d739fbcbL,
40984         0x0bd18e67ab8bf5eL,0x1cfb1fd6a1984b4L,0x1062ed09a9f413bL,
40985         0x1c459438fe2476bL,0x19f485b848225dcL,0x047f859b7eaa073L } },
40986     /* 133 */
40987     { { 0x1f2e2f43ff42cffL,0x0cfce8e1a98be4cL,0x0e4aae86d5168f0L,
40988         0x0a95f53465b6e92L,0x17dcd43684232b0L,0x07cc8a85c2aea36L,
40989         0x088622b0d788117L,0x00baf9e458fe003L,0x1057d35aeed4083L,
40990         0x0d2528caa9e67e6L,0x195e4e4f8ae4e49L,0x05606845d84ebcaL,
40991         0x1e3ac53958a2033L,0x1cf4d8b1cd84802L,0x19863598a01468dL,
40992         0x1cf5f6941b813f8L,0x03e9e0e857f6748L,0x038d9477762bbebL },
40993       { 0x142b0cd99726bf8L,0x051dc8e10479e24L,0x039ec1663aa84a4L,
40994         0x1f44b52251fae52L,0x0037d7dac6a7791L,0x1141bd9699ed926L,
40995         0x18a83087bfac1c3L,0x04f7ee1b2ddc7b5L,0x143ed8191850760L,
40996         0x175855426a56bf1L,0x14407fa316dd312L,0x14dd5a4dd7bb78eL,
40997         0x086b78aa4edbfb2L,0x108acc245d40903L,0x0e9713b252aa3cbL,
40998         0x052b41a21b3b67dL,0x05ace7fec476318L,0x0394a388d1986c9L } },
40999     /* 134 */
41000     { { 0x0e4590432bbd495L,0x1a6e8df2a4b9ffeL,0x18757670fd38cc3L,
41001         0x10b374e40800d7dL,0x02c2c76840ee607L,0x1f445f60ca7e9faL,
41002         0x00842839dac4ba7L,0x18e2f9bbbb7d856L,0x0689d436b00811eL,
41003         0x1535d1b9425f4f2L,0x0e56c801f504529L,0x13e61e23ce89578L,
41004         0x08e9396402f8cdfL,0x175a3142e2ff5f6L,0x18344de29d45d0fL,
41005         0x125c7337f0f058dL,0x15f3965e170beb2L,0x0000e1cec2c00feL },
41006       { 0x0805cb9da4a0912L,0x05bb522085e527aL,0x0e3bb1c7596f49fL,
41007         0x16902d0935de7b9L,0x08b24635780fbb2L,0x02273477b538135L,
41008         0x1d2a0558972204bL,0x1c8c49846589af4L,0x081a770374b1631L,
41009         0x0727bf8edc8be17L,0x1197f47d87b6541L,0x009397bcdc7a3a0L,
41010         0x01d7131fcfb1048L,0x056d238ab1be706L,0x1a65c988b936f0aL,
41011         0x0e8a1eea618b959L,0x113a0160dccee28L,0x0489973385dc8d7L } },
41012     /* 135 */
41013     { { 0x057efe27996099dL,0x1a26dd037304640L,0x1d0342561622dc8L,
41014         0x0cf3cb5dd3d6950L,0x108a2fade53daf0L,0x1f383564ab054d4L,
41015         0x091a9fd2f84c441L,0x1ccdabe7b365060L,0x0a5f8e8da27cca3L,
41016         0x1a8ee5326147949L,0x08c43bcc77f5e3aL,0x0f845940e7ca99fL,
41017         0x14a40da68392e0cL,0x1a869c7e08178b4L,0x16b80d45aec1f31L,
41018         0x193bae07d07c575L,0x0d1ea93c066b4d3L,0x03e8581f2bcca07L },
41019       { 0x1e7ea304dd94c63L,0x180e2b9c5859d2fL,0x1e328539ad2d5fbL,
41020         0x1d4a6a64ed2a694L,0x1c22d00607622cdL,0x035904d7b4b503bL,
41021         0x0ad29ccf06219f5L,0x0992ca99976c4d8L,0x0a098d3a1a84f3cL,
41022         0x0cb7cf696b9a5baL,0x0c086975547240dL,0x1a5e3d8a247fbfaL,
41023         0x05b2c1aa39e2ba7L,0x1c759493fcb9349L,0x064a9bf4b9d743bL,
41024         0x1ca1df574e25c32L,0x060a606b43a9b83L,0x018d8bc17ed5aefL } },
41025     /* 136 */
41026     { { 0x18dba454034db92L,0x1bc80c79a6e26c3L,0x1cbb7dd530ce8e5L,
41027         0x159aac75111a009L,0x1b5ffad1eaa5954L,0x0c5edc514eb644dL,
41028         0x16d1ea2b7d956c3L,0x0b7eff7085b19b7L,0x1b72e3a0380d320L,
41029         0x19ad8593e563e54L,0x182f2f62951d770L,0x0e33d749a4bfff8L,
41030         0x180c50fca6736f7L,0x00600c801ec80e1L,0x007e1347f6b3deeL,
41031         0x17782eb9ecb1eadL,0x11f57a7e6345cefL,0x037e07df29f03f6L },
41032       { 0x16d116bb81b0e5fL,0x0e952956429dc24L,0x0b50c9ce1fc360bL,
41033         0x09752258b26afc4L,0x09d5dcc13e332a8L,0x06c2e9c5b8e321aL,
41034         0x135383260bba50eL,0x1c72172aa797effL,0x12cb39bbc38fed5L,
41035         0x1633e4e2d621481L,0x08485efc1f69568L,0x0b5b4173c9ddd7eL,
41036         0x028ee9e0c655ac0L,0x045db71f885d896L,0x011ba4573cebb95L,
41037         0x0aa7e95ce4d3916L,0x1c8cb266012aa0eL,0x0380c9ad0d4a647L } },
41038     /* 137 */
41039     { { 0x058d41da4626deaL,0x1b3650adc81cfefL,0x0290c593996c97bL,
41040         0x1ae919f99f33502L,0x0f142fa99fe6daaL,0x038bcb3d5cd35e9L,
41041         0x08e6e932e85a175L,0x0ec25a6166cd787L,0x01f46a5dc8bf450L,
41042         0x03472948a10d607L,0x01881966ee8712eL,0x0a5db4d31720f4dL,
41043         0x14e54537072b4b5L,0x0f480b2fa81cee6L,0x15177f10a81ea7aL,
41044         0x1d6615071ffe7afL,0x00041991e5a3b5cL,0x0364b0f644b4e53L },
41045       { 0x03bdc1bc4e7eb46L,0x162abacb63da438L,0x1f359abf5d375aeL,
41046         0x0acad9cde69f322L,0x124971755635510L,0x17fd969e8fda861L,
41047         0x08af7f699e0f98fL,0x1ef7af3e3e7ddf5L,0x0a4efbe5417af9eL,
41048         0x077b2312d2adbd2L,0x1cc8e069c4cc11bL,0x14ff72ac4b4622dL,
41049         0x1a0b027e96db2a2L,0x041959de3505521L,0x17eab01163f9749L,
41050         0x0ff34a46831beb5L,0x153c05a89cbc49eL,0x0418441ec34f125L } },
41051     /* 138 */
41052     { { 0x19b1c6202557389L,0x0e74bd6f7e05e4aL,0x19fe0cc3ce0d7f9L,
41053         0x1e2d9f703d12777L,0x104428fd27e0c6aL,0x0f30c137b2732deL,
41054         0x047294f7a4916deL,0x1261146278290fcL,0x065cec3b9445bceL,
41055         0x1de018a6b3f6a4fL,0x0dac90c1e08d48cL,0x1b5f275a63a4d3eL,
41056         0x10c780890cd78e5L,0x0f22f7f4f93415bL,0x12ebfa9c0570d3eL,
41057         0x198d826ba9749cdL,0x18c43a378a47e3fL,0x011bb7cbfcb31c7L },
41058       { 0x06e1ec0ae575b99L,0x065a7c0dcb86e05L,0x00934e9ce51df85L,
41059         0x03f646b53be0147L,0x1bf629440b4b9c8L,0x0b2ebd468a88afaL,
41060         0x0f8ef3f4d6d0c78L,0x0f6ba25fd4565dcL,0x0629984a6f5182eL,
41061         0x121f179e1b2e847L,0x09c244c3cdb9c93L,0x1401fa68a803326L,
41062         0x0ebaf96dce698b4L,0x11b3aaaa11e27e8L,0x0c95e12982e82b8L,
41063         0x0c942a37b585b60L,0x0968ab4190a2154L,0x046230b30b5f881L } },
41064     /* 139 */
41065     { { 0x1fca2582d1f36a5L,0x1695944a62f96f7L,0x16e10f3b613c3b7L,
41066         0x05b61c77366b4b9L,0x0719a112290f898L,0x11b16b667075780L,
41067         0x1f91f43995f90e6L,0x028aa2d4abac4d2L,0x0269e1f778e6365L,
41068         0x11ef6e5ea8134deL,0x108c0110715f157L,0x06398e0aaf1bd9dL,
41069         0x131e489eabdb83fL,0x1cafe6da0def7dbL,0x076c00482d9e33cL,
41070         0x059912119f239ffL,0x162cbebc6f455f5L,0x00aaf53115a6308L },
41071       { 0x0be2f1f876fa42eL,0x143a4bfd6f773caL,0x03d4e32196bead7L,
41072         0x09bf00b360d25ceL,0x0b5a7ac916e99b8L,0x031e958675b0374L,
41073         0x026833b48cd5cb5L,0x1be5a1e4c465534L,0x12529998c3861fbL,
41074         0x08c4453e0df1885L,0x08a714362ab78dcL,0x16f07626a67b362L,
41075         0x18ff029708dbcf9L,0x0d41f7c41e53a37L,0x0ca111296804e87L,
41076         0x095751d209a3095L,0x0c32fe84b3dbcbdL,0x047ab879212c82cL } },
41077     /* 140 */
41078     { { 0x0b66c8a2ca9c508L,0x0df6134eb5bc06fL,0x099a23ab5800b71L,
41079         0x0e93ae4c282dac2L,0x0e472e6f61841b9L,0x13d43b20f207366L,
41080         0x05e82b68909907eL,0x1e88b73fa679873L,0x1b25e8fa97c15dcL,
41081         0x09267590974b14eL,0x11cb19f6cf65580L,0x1a56f834f088751L,
41082         0x066dd027ff8e2deL,0x1f3d15e34a5584eL,0x1c31d8fe26815f5L,
41083         0x0c4255b17e44d9eL,0x01d4cb268e7c8a2L,0x01e8b8f43d96226L },
41084       { 0x02ac16e8ce49820L,0x122f1606226e49cL,0x0449cfa1631093bL,
41085         0x188c64f9f21d8cfL,0x06159c1f918cb25L,0x0a2e59a1f1c3b5eL,
41086         0x0d1fadadb8380ddL,0x082c9707356ba24L,0x172e09274a300d5L,
41087         0x1559473440e08b4L,0x003fffadd6a10c9L,0x05946b2241be94bL,
41088         0x103209f4a30a580L,0x073549c03ff7416L,0x1b8472ad46005aeL,
41089         0x09d8f7338d8e185L,0x00416105af1ab9dL,0x011a74c7c1a66c8L } },
41090     /* 141 */
41091     { { 0x143520814db9cdaL,0x1ee23cb56f6487fL,0x09bebd162db6673L,
41092         0x0ae87d546308755L,0x01735d813f1f741L,0x02caeac8af0c973L,
41093         0x0f234d10688b42bL,0x06ce0977ecf8089L,0x12f960471be23a2L,
41094         0x01931c40ae8eaabL,0x008c2ddac776533L,0x073e183914cf282L,
41095         0x0c833c910df2e54L,0x032dc26fab58a0dL,0x1c0aded19f2667eL,
41096         0x0d2a03604a3f443L,0x093de5b52609621L,0x035109871e71d0fL },
41097       { 0x01b67a04b3ca1a7L,0x176a98060674069L,0x0da24cb3c1eabd0L,
41098         0x02b84b86b44599aL,0x0dd04d0636523a8L,0x1c9d1df66e9cac4L,
41099         0x0d4c1cf68d40acbL,0x0ee98bc1879abcbL,0x0ef9f5486132687L,
41100         0x0c3ff7e0f3a1149L,0x0b0a7a89397b7bbL,0x13e067093e34db3L,
41101         0x1240f2390508abcL,0x1fc9a1a9d84d914L,0x0bad5419e441cb1L,
41102         0x170e02054c703cdL,0x0303ee0740996feL,0x01a7837d54e2694L } },
41103     /* 142 */
41104     { { 0x09dc79f2348f005L,0x02eb8efa49058c3L,0x1f29b7b992926d7L,
41105         0x09d0549f69fa36aL,0x1957836621b7f73L,0x143ecb31be5c1a5L,
41106         0x1b2af24d0406df4L,0x1c62b21f1580725L,0x0280dc3737f75f4L,
41107         0x19b7a87b530d631L,0x160c129955a36a2L,0x0553b2610e14e9eL,
41108         0x12fc8895cc80d79L,0x048a49cfb68bd8cL,0x0756e79260e4be9L,
41109         0x1056b5e6c04fba8L,0x11a452d79e25caaL,0x03b26a3d8fa08aeL },
41110       { 0x1f22303a2ee8b9cL,0x1b969c2efe6a42eL,0x060c4204e8dc6e7L,
41111         0x167bce83ead6857L,0x1303bb5be28c523L,0x0dfcd7842bb12d7L,
41112         0x16cd249bca66ab2L,0x01c437d58101a88L,0x06a523a02d6ba2cL,
41113         0x18150d8bfe71432L,0x1a88d78c0307ab8L,0x06d4f69526228a2L,
41114         0x08c0cc89f745437L,0x0076c46f69e05cfL,0x0dff1c01206413dL,
41115         0x12e709e4d36ac79L,0x01009a1d53a321bL,0x00e06ece191851cL } },
41116     /* 143 */
41117     { { 0x1aa1f67c46a7d9aL,0x0199a5f6fc8e67fL,0x09d11e90bcb991dL,
41118         0x02483ff5528b067L,0x135efe6b6798005L,0x059201b84bcd421L,
41119         0x047717c184fd7c2L,0x1f8d7645f9ac9e4L,0x0e1b8b2a3a0572cL,
41120         0x0f075a0bca850a5L,0x12eca4fadb35306L,0x164a8e144bffcc6L,
41121         0x09a3d15a0a31a04L,0x1f97f6f4d20fbd6L,0x0e52803bfb617b2L,
41122         0x142b83eb03ebf03L,0x1bcaa3996b09ef4L,0x0296c5f1cd83020L },
41123       { 0x11536f6fd631a2fL,0x173f859a8d46e5eL,0x031e6c49884a47eL,
41124         0x1e57a1e86ba34b2L,0x12b0ea7052d4875L,0x1d5c4f4d76db69cL,
41125         0x064b02f42af72e0L,0x1b504f420c513fcL,0x06566a960102a0bL,
41126         0x104181be701b40aL,0x1b5e7d618e50176L,0x136db7951bf2617L,
41127         0x06efdaa3f597201L,0x091b5c494490094L,0x1f0b9ceccdee659L,
41128         0x11b4623a7c71c51L,0x05d70787f41880eL,0x0367fb1b3ed7252L } },
41129     /* 144 */
41130     { { 0x13d0433f89a8bb4L,0x02619c9dcc7b8deL,0x1b200d1c28b5085L,
41131         0x0fcbb4113d056c2L,0x1bf5fda698fcc75L,0x1e9a662a11aa77bL,
41132         0x174346217094e7aL,0x1945c41650b7d8bL,0x0e71bbbe1782a1bL,
41133         0x0cef6984dc2a778L,0x1265e6265fe9aa5L,0x1f51b03e788a2e4L,
41134         0x1760c1115250cf8L,0x167c22f554d1da8L,0x1fb446f26c3bdf7L,
41135         0x0c10192673c4773L,0x1e7c93e9c5c2825L,0x00e96410bb09f60L },
41136       { 0x181347d987cfc93L,0x101ddf8c3fc0839L,0x1274494328c411dL,
41137         0x01760ab7e67f4d7L,0x1a3af87c480091eL,0x02a055defcaf8d1L,
41138         0x0116f89a1ddc050L,0x05b331bee61affcL,0x0b398135fb723bcL,
41139         0x01187c60af5f623L,0x1860c17d558702bL,0x1e99b4c148ffc11L,
41140         0x04e16d4bfc7c0fbL,0x1a30bf490374ae1L,0x1830839d058d255L,
41141         0x1c56c72e330d295L,0x122fe2693122131L,0x012a4371b0529bbL } },
41142     /* 145 */
41143     { { 0x18795ca53572806L,0x04a24b2b4b470b0L,0x125cfecc8ebacb2L,
41144         0x0c81378fac29385L,0x079121b3fb15de2L,0x0655ddd4866d396L,
41145         0x10495b4be853881L,0x08f979b4def22c0L,0x025086261b435f9L,
41146         0x1b4361c61417588L,0x05b58bc69e472f6L,0x1da2c3444cd8a20L,
41147         0x06271d74a66b1c7L,0x012143d2133c033L,0x193c3ced7ffb686L,
41148         0x054e997ca07ff77L,0x1f1d7f7f0beb948L,0x03a8d91ac044249L },
41149       { 0x197b9d6e9c9be68L,0x05ae233e886366aL,0x10f5dd8acbd05e5L,
41150         0x1543689c235119bL,0x0aa8eca86d94a63L,0x11ec3ffd85dddcdL,
41151         0x01d77d2c3cb4325L,0x1136ea60c58bb8eL,0x0fed726ac499339L,
41152         0x0d3031c2bfce66fL,0x10e4a9d7e31d997L,0x1b2abb8ce594443L,
41153         0x02b66ecc8dcd264L,0x0c522c5d38027f9L,0x0af594fec6aa6b8L,
41154         0x1bcf9d52c89bf17L,0x075a9378e802ba0L,0x00a266096e51636L } },
41155     /* 146 */
41156     { { 0x13a0a1d2989aa3aL,0x19141acf37326acL,0x032f4cb9ccbb60fL,
41157         0x0a78796493d2716L,0x189ea6acf4c464cL,0x167e194ba852fc7L,
41158         0x0e02519f96efcd1L,0x0db937f573a6f65L,0x0f8eb74533b339cL,
41159         0x1f00fdf1dbb36f7L,0x150953bdaba89cfL,0x1be4f7cc3621662L,
41160         0x01dd818488555c3L,0x1df38a7cb87db6cL,0x063da4f686bce92L,
41161         0x17072aebe402f3aL,0x151dc08fc6b2465L,0x043a76799b5c254L },
41162       { 0x04af83ebbb3f6beL,0x07ddc845da11eb1L,0x02eb5e1cd49fd5eL,
41163         0x114c5c0884ac476L,0x1e236f79c3659bdL,0x1f93531481d8b3fL,
41164         0x04b3d5690c31b94L,0x056444a8f5c75aeL,0x1b73890d776eb27L,
41165         0x0da7b859eb146fcL,0x184ec14fab92b25L,0x0271cfe42e9d3e1L,
41166         0x1998dbae175b4f5L,0x0228c2403aa4167L,0x1fbc570ada6ef79L,
41167         0x15e329e4f2ca595L,0x14fa0a3ef2bb6bcL,0x018fdc2c0e72631L } },
41168     /* 147 */
41169     { { 0x18306d1615cd607L,0x04fd5551961d31cL,0x016ddde44c75a03L,
41170         0x146ce11601d0f4eL,0x1445297f1031013L,0x13cdab40a7d070cL,
41171         0x0fb51c31560ea9aL,0x1a60607397e962dL,0x118a7ca8daaaaf8L,
41172         0x198acf3ae6db452L,0x039ce348e053ebcL,0x0e311a1e9f3fbd4L,
41173         0x09dcdff032eb352L,0x1ea419c5d85bb30L,0x17541e996ea3aa4L,
41174         0x0a16830089b04abL,0x054844a223e4a4aL,0x04c1918000c70cfL },
41175       { 0x0a2102757f3d5a6L,0x12b24374656e694L,0x006c09547cefff3L,
41176         0x1f26bd7be32b207L,0x0083aa6eb26cc64L,0x1267a0b0308948eL,
41177         0x0c6d73662299a23L,0x03ab0387ee7baa7L,0x078c804a977fc62L,
41178         0x0c3a1987d6e517dL,0x02369320f33c08cL,0x143b4f348e0fee0L,
41179         0x1f4a915eb5c4122L,0x08091b304d47069L,0x1ab4a828b7855f7L,
41180         0x1650a8bde8764cbL,0x0aad0a22ade188dL,0x0455df1cf491706L } },
41181     /* 148 */
41182     { { 0x04469053a2d2f01L,0x018c9aee3342e5aL,0x0efc75d2809f49fL,
41183         0x1eb6a1d83ad5211L,0x1f3c2e2601da350L,0x1b77490e9eea2f1L,
41184         0x05e73d9b84742e0L,0x068fc07211e8e97L,0x119e7c5b998b878L,
41185         0x1a0e9ff5e9e8ef4L,0x1a3a347bd8166e9L,0x12726ce9c48ec78L,
41186         0x073e7e67f69b9ffL,0x1774f1240ebea9fL,0x0f66131a6370c9aL,
41187         0x1d14ea5e47db567L,0x095f95e31b06f8fL,0x0078ada6861e85dL },
41188       { 0x12f6635790a8d85L,0x1fdd7712cad78c7L,0x1b1892d44a1d46fL,
41189         0x166468e2bba2b6fL,0x0bc5441d7639b6aL,0x082c19866ea94c9L,
41190         0x18d8152003a93dbL,0x02643dfaea5edadL,0x1c0b7ffe5192906L,
41191         0x1452c12f7544c66L,0x16ea488a60899adL,0x036177a0d765d9dL,
41192         0x004bb6b0cb678a9L,0x057c754c5921b6eL,0x0a816ef3dea679fL,
41193         0x07d63725a1cdce3L,0x1dbbf8d0471f599L,0x028aed9bc101c2eL } },
41194     /* 149 */
41195     { { 0x043eaaa6f5bef22L,0x0934c101a438977L,0x0139e8ebdb1a54bL,
41196         0x0d351928063c989L,0x1001899a18d434cL,0x07520631f2eba0aL,
41197         0x01c8548e36ef3faL,0x1d194d991a52cf3L,0x073db6aee04acbdL,
41198         0x1b49946dbfcc9e7L,0x1e6efeb5178cd2fL,0x1926f83e2c6147eL,
41199         0x1f9b00a6de8c51eL,0x096c15e1a483992L,0x1167f25279ab2d0L,
41200         0x09c76b20366da1dL,0x002cb09b7109cf3L,0x016f0243f0d5fa6L },
41201       { 0x0b722f38dd9d484L,0x049c9be3bdd660cL,0x03c64f64ae2a0cdL,
41202         0x011c7f584ab1b77L,0x145f4a7d80d78d5L,0x1e614ef82804c0bL,
41203         0x027e341caffb61dL,0x1aecf57f1e58615L,0x092c567ea9a0820L,
41204         0x12d5897451d2b9cL,0x0bebafc155486d0L,0x1e4d729d4bd382cL,
41205         0x143d71e546ee1c4L,0x01f45f0e8f20a4cL,0x07ab82c96060ee1L,
41206         0x094608922f905dfL,0x06e6813a4577387L,0x037b56038e6217cL } },
41207     /* 150 */
41208     { { 0x18822ad4dd6e3b1L,0x070e656b10434e9L,0x0114b2b37a03f1eL,
41209         0x15508d3fc7cf087L,0x067e8ef2121cc14L,0x1a3a2447479ed3fL,
41210         0x0c7d36e0f45b934L,0x02e7743bb30f30cL,0x1dfab59770a4c4cL,
41211         0x18509831f6e380fL,0x075805b363fca07L,0x0617798ab7928c9L,
41212         0x005760412a22672L,0x1947d77b0150ce3L,0x1faab671c6757c4L,
41213         0x15f6a4f972d3decL,0x0cbf342530e719bL,0x0371612667fad41L },
41214       { 0x113024badaf8793L,0x1e67881ae4a4731L,0x1ade54d402fe512L,
41215         0x0c3a22cecbd340cL,0x1fd93c787991a94L,0x172a4acad6ed974L,
41216         0x1973c174b00dfa4L,0x0e59628b6313e07L,0x181ae48ca95aa1fL,
41217         0x01f938109ad3727L,0x1bd68926ca9f548L,0x120005afe546579L,
41218         0x086c6745b00687aL,0x0328398297be991L,0x037163cf6a2a1d6L,
41219         0x0230b7c7171085dL,0x1916b48bf34dbf1L,0x02d7bfe86cbe047L } },
41220     /* 151 */
41221     { { 0x1f9b950f4a224a5L,0x022ba6628139d2aL,0x0cc190fc7f55064L,
41222         0x161ca1ef0669f02L,0x09581712996801bL,0x048e9b4336ba01cL,
41223         0x1bf9f6e69017690L,0x0d1e3c6f3be2d48L,0x08d04a93f83bf91L,
41224         0x126419a995905e5L,0x0cd2c7dca87042bL,0x12efb032bb6933aL,
41225         0x1ffba14b5d8fbc9L,0x1b6d7a3b65759efL,0x16dcbd183fbc089L,
41226         0x160c497291bfdb6L,0x0ae5185c925b6dfL,0x013d4e1c0cb04eaL },
41227       { 0x1c37346f12a93afL,0x1b83e2a9b31a6b9L,0x035526064f440a2L,
41228         0x19de436d3b1df4bL,0x0788a0e24f83a5cL,0x189e4c02e5d851dL,
41229         0x1e130040c5e0596L,0x1e5fd441cb056e6L,0x1df9713a0e50361L,
41230         0x0a24d07e866116cL,0x1d4b9df178b86ccL,0x0d7b6ce0899e306L,
41231         0x15733e177a6e44dL,0x047716118096ef4L,0x17c6525a2d259a4L,
41232         0x110dfb3760a823eL,0x04495182c716acdL,0x00e34834a7def49L } },
41233     /* 152 */
41234     { { 0x1b67d173a880026L,0x07850092ecaf92eL,0x1544fdb2de92271L,
41235         0x02b977b94a520a0L,0x172bcbd33eb231dL,0x0ad01d7c67fe4ccL,
41236         0x1f0bf2d3bd352b5L,0x14b289a8f94450cL,0x196d885480ead1aL,
41237         0x152be7c65e45822L,0x16112c01795681dL,0x1c323a31412fbfcL,
41238         0x0852923c745e9e7L,0x1faed99ccabd137L,0x0fb43234219ede5L,
41239         0x1a4784aa6811cc7L,0x1391596e5d5689aL,0x03dc609eb528261L },
41240       { 0x1c43aad52fb6901L,0x189fc8b65129d97L,0x0c29456ab718700L,
41241         0x0cfeaefb8428eb0L,0x1723c0ddc93d192L,0x1cfb6d137297477L,
41242         0x0ddb4bc783ae0faL,0x07332f3bd05e300L,0x143e28ecbb08349L,
41243         0x116a8ee51ce1c73L,0x018ea6a38fdad66L,0x1474973664e0dccL,
41244         0x02d2f8915d4cf1dL,0x08283c893729a45L,0x14e0fe979d78f81L,
41245         0x1f6535dff9cae41L,0x0d01d6d53cc8fd2L,0x0071e1f7b34b7a6L } },
41246     /* 153 */
41247     { { 0x1c337c121ee1d83L,0x047b6bc3dbbc41dL,0x1f304e3e933a5f8L,
41248         0x0f40691cb17ee13L,0x055e672dbaf7764L,0x0f62ee827c5d5e5L,
41249         0x048603b4a4675f5L,0x15f19cc97fe67d3L,0x0ac09fc5724b059L,
41250         0x03418fcee2f195dL,0x0899dd196bdaa54L,0x1ccd92fe3ff04d4L,
41251         0x16bc6087fd3c5efL,0x15476e358a8af06L,0x1e7b4a6c68e717aL,
41252         0x111707bb02d761cL,0x11c6cc13769bc37L,0x023184c71e04952L },
41253       { 0x06408c7c8bd0fa7L,0x12188e735ef249dL,0x0420a0fbdefb45dL,
41254         0x0f336bb271c62bcL,0x05a49a6b8213cc7L,0x14f268d7bf8ac0aL,
41255         0x1275b403f6c3f94L,0x0a4aba71eef9ccdL,0x0b4f7ccc01bd4b9L,
41256         0x0cbada4d7b8fcc3L,0x167f2f3593402a3L,0x0a094b4775ae256L,
41257         0x042b5c89f11860eL,0x1d1f118fb6cbb02L,0x032ea4bfb431965L,
41258         0x1c23cb02298662fL,0x05ae2e74c066698L,0x03fc7e849d1a45cL } },
41259     /* 154 */
41260     { { 0x04592cac19428afL,0x10e409d184332f9L,0x004b8c2ef5fc64aL,
41261         0x0706d8d77284b13L,0x198e498710db072L,0x16b7a5ce3d20f4aL,
41262         0x0b1122bfc5e79baL,0x07ce1f1f372eb0cL,0x06b3b02376f2198L,
41263         0x0ec1f4dcc7328a9L,0x149aa35d4486289L,0x10353ade3b4c765L,
41264         0x05a5a81f7495082L,0x12343a38c6fbc68L,0x01f63335e7b9567L,
41265         0x0d92a40c194aecfL,0x131427a84ffa847L,0x043db2628f321a8L },
41266       { 0x1f46f654b30d3c4L,0x0262e11da778a43L,0x1d998f2935a337bL,
41267         0x139e7f6adb676e8L,0x0fd7d46a1df3426L,0x14d45eea789ce20L,
41268         0x15f4a8edf1f1da9L,0x069dcad6993975bL,0x1b28ff342ac9423L,
41269         0x0237efd3c378ed1L,0x145272dc0320b80L,0x1f02a12ccb2f9cbL,
41270         0x09fcff4bddca30eL,0x024929342251030L,0x0087ce03cbd979dL,
41271         0x177a1cb6caa59a8L,0x0f577ea9c2a042dL,0x0464a933e6ce031L } },
41272     /* 155 */
41273     { { 0x055032e5fc1abb1L,0x0d7aa097f23a1b3L,0x1580a7c17bd4885L,
41274         0x0bb83237d3facaeL,0x008639b0b0e7332L,0x1f3339bd59e32f6L,
41275         0x155559d41fd4470L,0x15ac717df8790c2L,0x15d0188cf42f0c4L,
41276         0x01d180e6c4b0c36L,0x180fdecb19d07a1L,0x1819f479a3a008aL,
41277         0x1d4a40672ef7545L,0x02dcf46efb0957fL,0x048b5d15865f27dL,
41278         0x0b37f68a646fb0fL,0x016bf132e3a4b2dL,0x0457d0db9dc2535L },
41279       { 0x13596eae793ac70L,0x077c7777b6e8835L,0x1e89c108b901325L,
41280         0x1dd3cbaec724d69L,0x1512aadfc8c71dcL,0x01cbaf9a97e5b87L,
41281         0x0ec4c6dee84e2a2L,0x1a2af3227200b18L,0x19692092a97740fL,
41282         0x0d6ca2d8b05834bL,0x0d0e20420deac86L,0x0389e2e976e378cL,
41283         0x01ab1b80eb76ee1L,0x187622c53088dfeL,0x0b4cc96f20aeb21L,
41284         0x15b91ddcc024e62L,0x13cb4118b1ab240L,0x0339088c895ad04L } },
41285     /* 156 */
41286     { { 0x1e99306f55cf9bfL,0x029845235cb6cc8L,0x187679e9977e6c1L,
41287         0x038e6379775c783L,0x04d58a61453cb15L,0x03a6610a5f2913dL,
41288         0x00358e76b248a5fL,0x1be9a1ef48b045cL,0x1afeb1d51c62b03L,
41289         0x18ee1d25d50c596L,0x11c5e37cadd3c2eL,0x114d12d6d466fe7L,
41290         0x141dce055ffcd32L,0x152715c3f4af6a2L,0x16773a65fef1dadL,
41291         0x0cf83cbd8cfe3f4L,0x1fe052368accc03L,0x03e431c8b2a7251L },
41292       { 0x1e94b5eca7388cfL,0x005306019ae9c2aL,0x1e2d85be16e85f3L,
41293         0x1e2024530136d36L,0x1cfd0a79705d02eL,0x0f71a92b2d37400L,
41294         0x076b7add2a5b5f4L,0x01eb91065da84f7L,0x096ea8528e6d533L,
41295         0x06c43158c692774L,0x0e3b567fe4e7dccL,0x1344020c04a539aL,
41296         0x182303b3ff690fcL,0x0ea95a34e316c45L,0x0b4b64ff10b5e93L,
41297         0x008700df1bf4519L,0x1ad502360906092L,0x0192c13ac7e742aL } },
41298     /* 157 */
41299     { { 0x120e45f359e8c60L,0x1dc529b2650c375L,0x01c77fe384431c6L,
41300         0x069927caf00562aL,0x1829d0d8074e91dL,0x1541fd601937005L,
41301         0x08278f064896189L,0x10470f4c9abf653L,0x1caaa3d34e5ac5cL,
41302         0x16b42f2d6d16d14L,0x08099faca5943a3L,0x1632ec7005e724eL,
41303         0x0edf6b1aeaf7184L,0x12f3092e91faee8L,0x01ca86af87e8d1cL,
41304         0x1875fac50ff3a19L,0x05649aa93d2ac57L,0x00d273538aded3bL },
41305       { 0x0126ede554d1267L,0x0a2998e6815a40dL,0x013338c7ec74dfeL,
41306         0x1612fb8025ae15eL,0x16c7b6c5cf410b0L,0x048842c9870e8b9L,
41307         0x18e3e40bfb9071aL,0x1be6937494ef3f6L,0x0a16c5821acd6f8L,
41308         0x19dc1e09703b567L,0x140cef94074537eL,0x08a441e5a5b4d71L,
41309         0x0d99df18800593dL,0x0ff599d31ba9293L,0x1bbd15b28c8d472L,
41310         0x1b915b22687783eL,0x032c74857db35b9L,0x042b53e49c2da74L } },
41311     /* 158 */
41312     { { 0x007d0020d0a5583L,0x180eef6d232c550L,0x0590d364e6f8bc4L,
41313         0x014e18106d2380fL,0x1e81e540a0cb678L,0x05645c605a6fcadL,
41314         0x188e5b2ef34d175L,0x16caf8a5da0a8eaL,0x1cac2dca41805ceL,
41315         0x0af7355bc9a212aL,0x17bcc493268a9a4L,0x0c5f18258ce86cdL,
41316         0x1b7dbb7c3bbd3b9L,0x1115dcadd55b278L,0x118edd0f039154fL,
41317         0x14c624811fd7589L,0x0403ca773122a4dL,0x031444842631b6dL },
41318       { 0x057fd538cb8d208L,0x1c004aa1f836a52L,0x0553cbbfcaadea3L,
41319         0x17ee4a2fcf6cdbcL,0x19389d2cfddb28eL,0x0dc46700a4ff337L,
41320         0x10fdde7a1dcff61L,0x1808a5c1216174aL,0x1deb9b5cfb0b03fL,
41321         0x089a245362f6bbdL,0x07cf3e3ff00dc8cL,0x08dab83698946c1L,
41322         0x138fa59be92bc9cL,0x06d81348f3379dfL,0x07e23e44e5afd7fL,
41323         0x1bfc7e3d8b3a801L,0x158c29034562ad9L,0x03cec09162d6d26L } },
41324     /* 159 */
41325     { { 0x0d4e4ceaa529507L,0x1040a3a32ae800aL,0x08e13c3f11d015aL,
41326         0x146887971d81a61L,0x17f1728d8a8203eL,0x1077a919e317d84L,
41327         0x074fa28e373f6d4L,0x0a141f21abaf959L,0x128a7b0bf873ceaL,
41328         0x08ad71d363620e5L,0x05c76a84e04b074L,0x174ac49aa0fd46aL,
41329         0x097e98f42f25d4bL,0x0b5209b8c8ed694L,0x0796ddfff5ac7a6L,
41330         0x1ee0fa8d8424b6dL,0x17ac7d2b42420c4L,0x01559d7cac0a12aL },
41331       { 0x0ca074c6a5372a6L,0x1dc1f2b1495d3c3L,0x1b71ddd073d5ca3L,
41332         0x02a41de93ae8ab2L,0x01e4647270b4ceaL,0x1c562e8a397f1a3L,
41333         0x101c7d35af598feL,0x0c28dca59938217L,0x128794efe371a34L,
41334         0x042838c13b7f43bL,0x155dce6fbd6ad29L,0x13fe7e2b902bdb5L,
41335         0x058f8395c324c2dL,0x005b542a8c44a87L,0x0200f86eb90265aL,
41336         0x04bdc9ea7c45915L,0x1caaf233f61039dL,0x003ed961a928204L } },
41337     /* 160 */
41338     { { 0x1f3b8db037d4703L,0x1846fe2fa445ce3L,0x0c3e11c7500ba0dL,
41339         0x04b45f55d23f750L,0x1404fc1ea55ee8dL,0x16ab28e172df882L,
41340         0x1d7e591f5409ea8L,0x17e6f4a7818fd75L,0x07adf0bb295b30aL,
41341         0x13170ff6b2649ddL,0x1063038bbd29e16L,0x13b29a59a09efffL,
41342         0x175ea0af02139ddL,0x07f7cd67929fdd5L,0x1856a9df20403a8L,
41343         0x040d2e98a709b90L,0x159cb28682d9fe5L,0x0045b6547e7beebL },
41344       { 0x04e5bea036c3b5aL,0x130813fcf95a5f0L,0x15c0a5e5f03ce1cL,
41345         0x17050f3d4753f94L,0x007f0ddf1656180L,0x1870438a99c4ddbL,
41346         0x1ff1e668488f19eL,0x0321a3011d93b12L,0x09470711a916edfL,
41347         0x07a97958390b88cL,0x0ca7ff462222dbeL,0x058a998df200bb1L,
41348         0x05eb24877fef1e2L,0x1aa3ca92e201b0bL,0x1851a2bf6a548ccL,
41349         0x17411ac454842d0L,0x1d25d043b0774faL,0x01619bd810698d3L } },
41350     /* 161 */
41351     { { 0x12305bcea22fa65L,0x01f7a68acfb1d3dL,0x01f4fcd648fef86L,
41352         0x0d823aeea668e7bL,0x0a054cffb27fb30L,0x0c2b0cb8173f359L,
41353         0x14714f3a7e5f2bcL,0x0b706aa04869cfaL,0x1a63e3d82f356acL,
41354         0x13dbe556bb22898L,0x179abe99c7f2761L,0x1dbc560f9aefdd0L,
41355         0x10ffda51933b985L,0x14a16e1b03eacc5L,0x18862a6c43b28e6L,
41356         0x1ab942fe7b9dca0L,0x1c93d94e8d106b7L,0x0284d931a76c418L },
41357       { 0x1b9414e48caed54L,0x1c63665fa8f4bd8L,0x123537a6c961de9L,
41358         0x1923dc7af148d11L,0x030ee64c0024137L,0x0c86bc5347c91a7L,
41359         0x1a42d5cc956f220L,0x09883d1c0bf7500L,0x050038d84ec354fL,
41360         0x0c7816b6fd2940bL,0x1e401f32d8ff6acL,0x01f7d315c8ab88fL,
41361         0x025d0e319d29d48L,0x0136db8ca5622e9L,0x0d61ee741bcd5d4L,
41362         0x0ee4ee6773c4058L,0x152224839922c31L,0x00ac96ad3aa5dc3L } },
41363     /* 162 */
41364     { { 0x178d9a2cf7453f0L,0x1c4cd76c1e0f82bL,0x1b4f82a0ae9ebfeL,
41365         0x15d47aa1035cca0L,0x010aa38b32c84e1L,0x1be820cd6a94604L,
41366         0x1907ec7f6c082f4L,0x1ecf1ad97c3a0d9L,0x0d287f0f02e74b7L,
41367         0x0e692bae21dd811L,0x03cbcfe069c6cfdL,0x03eb8c67cfe8da5L,
41368         0x1cc4fc580ee65bbL,0x1dbd83d29972fe0L,0x12abceb35554e7eL,
41369         0x05a5b6b5288e387L,0x17cb958bdf44cc2L,0x00b0a5edebbd13bL },
41370       { 0x01f0230ed0ab04dL,0x03d803710417526L,0x118f10b16d7eb8dL,
41371         0x1fbc03326b3e217L,0x05dd0825b0539e6L,0x076d0b6c4dea73bL,
41372         0x128ca48983fbeefL,0x0bf1554eab9cc55L,0x0ed762fa95ec82cL,
41373         0x0f326008c3283b4L,0x15891724b8d2326L,0x14ee63d4dad0afbL,
41374         0x0b07b447360db88L,0x0b8eb87f7780095L,0x1e246c2e4d5ae50L,
41375         0x04145cd160c5007L,0x1283a54a53ab79cL,0x0244b2b63d80583L } },
41376     /* 163 */
41377     { { 0x03649ba71353c25L,0x193d089fb3f1272L,0x0ce8707ae78d45fL,
41378         0x18f1c537f2217a6L,0x0743f15d94e1c05L,0x0d16f8427f3ecbaL,
41379         0x0ef86721d242243L,0x16304807f4ea6ceL,0x17ebf5db41baea1L,
41380         0x1f0571a920c0756L,0x161cff0bd430ff3L,0x15ace0cc39b23a2L,
41381         0x19a51e8c2c16851L,0x100b084cc014b46L,0x09fa95b9f46a737L,
41382         0x18930562a791351L,0x1cb6d41b78906e3L,0x00415d974eb3b4eL },
41383       { 0x180ef46c4d6615fL,0x14ee080dcc14e30L,0x1b003ec9932bf18L,
41384         0x0c21d98589bc445L,0x1eea2c4dc5457e0L,0x0e2d964ae72ccf8L,
41385         0x043e410cfe9ca3eL,0x0a7dc06a8c59ac6L,0x084c57c3bce2e22L,
41386         0x047618d4b6c3f22L,0x1f8e4e914b169dbL,0x0281408f646a617L,
41387         0x18c018545ec592bL,0x0e0bc6233dec5f0L,0x08c016de538041dL,
41388         0x0a9e6908e328c5cL,0x0422665e237622aL,0x01b228d23480e48L } },
41389     /* 164 */
41390     { { 0x1802d1819893e71L,0x12ec5a9cd10410bL,0x08048c0bb3f285dL,
41391         0x166cb7eb3bf8d5dL,0x0d232a808d4cf51L,0x140213c3ba0eb90L,
41392         0x0e7b2b0d0facc63L,0x194aa7d965fce8eL,0x0aeca79a81a8b07L,
41393         0x04ff9912b7a559dL,0x175ca4fe8747dc2L,0x135dec55342cbd2L,
41394         0x12aa08ddc226056L,0x0dbddaa52f3bb11L,0x0f55b9e4feafb0cL,
41395         0x17dfe914412ace8L,0x0f1749cdb12eb0eL,0x0382983d234dc7eL },
41396       { 0x08e4c04e488310bL,0x137192992e6bdbdL,0x02c1260fbeb049cL,
41397         0x1805bb7226ba1fbL,0x17b9685c796e552L,0x0f9251877651fbbL,
41398         0x125e66dd9ba26c5L,0x0d8f84e6dac91dfL,0x03d619685a8021cL,
41399         0x119f13c505978f5L,0x1a61e6d9db5ac3fL,0x063235e9c17d2b8L,
41400         0x1136c4ee55a0747L,0x0cf2f9dcd17d5afL,0x12bf9b9a4e2e3fdL,
41401         0x1a2403c229b4873L,0x0ecc9595ec36a6aL,0x0407bcde82bf315L } },
41402     /* 165 */
41403     { { 0x0ef42a760af09b3L,0x0b75ec99eff0a1eL,0x0783b617aaa0f00L,
41404         0x1f9d547792e419eL,0x17106f97d4f5e99L,0x134569390b5ce95L,
41405         0x1947d97cd30db25L,0x1bd51f70578b618L,0x020f42f1cf2fda4L,
41406         0x198d596690fb2cfL,0x1ddb1e84f45863aL,0x004470cc57cb6f4L,
41407         0x10cad08e0bec441L,0x011600c06412ed3L,0x1be7ff664a641e4L,
41408         0x116a0ec477b4055L,0x119de84f4f3f5c5L,0x02fad2ed26c127fL },
41409       { 0x137257e7e8311dcL,0x0a7a8a336789b2bL,0x1916c172886b7beL,
41410         0x1805c9566f4e7c2L,0x0579165b38ea9b3L,0x0580d23bb07564cL,
41411         0x156137ff7411f09L,0x1b4311a9fa27f72L,0x0faac38b825548bL,
41412         0x13cd3782cf4ee56L,0x1dc83c2689c03c6L,0x0aa9f714fc91307L,
41413         0x0847a1fad58cbbaL,0x0d5eb5af1c50ccbL,0x1c5bb084615951dL,
41414         0x120f6ea227a63e6L,0x0891391e7814212L,0x0298ce40086e0acL } },
41415     /* 166 */
41416     { { 0x120136e6b61c3afL,0x0796f03da5db411L,0x19fce0325fc0750L,
41417         0x00d5186274ca3bdL,0x0011ca10a978ba7L,0x0fa22d9162c3eb1L,
41418         0x1139922ee8862acL,0x1f318bd5e0fca08L,0x15549f02a442fccL,
41419         0x0b23a379ec0249eL,0x093d85e70116449L,0x143157b9110e85aL,
41420         0x0aded38f8f1600fL,0x091d75a32e5c300L,0x0715e2a92fe6e42L,
41421         0x1d429ac7fdc6a3cL,0x1f0f3c9c5acebb9L,0x01e8998a6f88d27L },
41422       { 0x1cc662db4513d1eL,0x05462eaaca95ef2L,0x08ff9fe1b42b79eL,
41423         0x08f409e18bd146fL,0x0e25d06cca2d12aL,0x09b038a6334b721L,
41424         0x1872d49851a62c8L,0x0bde9a4e03713edL,0x1aafd617780efd9L,
41425         0x16b9d6262ddb483L,0x01d2b10836cd6b9L,0x1bc9e4ea3f4093dL,
41426         0x16a1fa2edd11631L,0x1bfebca6d94fb99L,0x0be4a993101a192L,
41427         0x198ece79643a7c4L,0x0adeae904e62043L,0x033f9454fd99163L } },
41428     /* 167 */
41429     { { 0x017b258ca148ab5L,0x0cbb7d9e30028beL,0x1a6323ca37e6e68L,
41430         0x09d1a8a02fd44c0L,0x0578a42287b2cc7L,0x1f63991b92b9948L,
41431         0x0ef120757b8945eL,0x1fdae823f9e3a91L,0x146217e6b487f5cL,
41432         0x1803d62a0f5c70dL,0x115e9b816803232L,0x1a57a5f3f533883L,
41433         0x1b40941cad1f954L,0x1c14a84e9b85eaeL,0x1b297bb921e1e70L,
41434         0x1f73c9826eaa4b9L,0x1b2e8ef7fa4fd3eL,0x02ff848ba0de8deL },
41435       { 0x11912a4579c6632L,0x0d227dc51040abcL,0x0e114d58e74eec6L,
41436         0x177879379de9f2fL,0x119e6410e57e2bcL,0x0becd689159f95fL,
41437         0x1fd987c0627684dL,0x098ceaae776f3cbL,0x1444e5c98ef2f3cL,
41438         0x17b0f1002688398L,0x08d9beb1d758d75L,0x190c590a9e461bfL,
41439         0x1e0ad0850b9fc47L,0x17b906196025721L,0x14ef27573a53d90L,
41440         0x074c6cfdf5ccb4eL,0x046c27d30d3b037L,0x03340809d14b90bL } },
41441     /* 168 */
41442     { { 0x185d913e84509dfL,0x05f6ee799c9bb09L,0x174cd08e8523a5eL,
41443         0x07dd196af25be84L,0x11c4553c43fa0aeL,0x1f8ea4780a9b4e9L,
41444         0x09128173c22ef7eL,0x0675bfe97cd2888L,0x001635f81a35ddaL,
41445         0x02e44a4f3b7d5beL,0x1ff37859cdde0c2L,0x0a5944a9f1a497aL,
41446         0x06413ec985fd8cbL,0x1d481366310b453L,0x18786dfcb6e5d05L,
41447         0x1ffbc72c5dcaca1L,0x11fbee0a346d3beL,0x01d9adb9785efd5L },
41448       { 0x1f8de9f535c3749L,0x0f907c56ece245fL,0x0def23e3d98c8f0L,
41449         0x0bd1e75c9352eb6L,0x1d5e26282529e47L,0x03178ee197886a8L,
41450         0x0f8d96b034a5d9eL,0x0c4278f26710a99L,0x148f004ef4b67e4L,
41451         0x11bd0a872e88770L,0x11de374a0a2283eL,0x14cd9f6e7e9a92eL,
41452         0x130780495296830L,0x0bb05b4a4fa2200L,0x0dd726608cf1c26L,
41453         0x1f3390681994a4bL,0x0853f62e40bc771L,0x023e850f5e6cae3L } },
41454     /* 169 */
41455     { { 0x06f4fff652811f1L,0x05549b177980113L,0x0955432e832baabL,
41456         0x1400fea8ced870fL,0x002f2673a350142L,0x0e3732e3fe88151L,
41457         0x18f6576bb95c0cfL,0x03cc0d05d860c94L,0x146cf0bb0462b25L,
41458         0x1018652aed49b73L,0x0983c90d0996d43L,0x0576d369d1eb90fL,
41459         0x0c7ad7770a9637bL,0x169d0ad3300fdacL,0x057a5847c851fdbL,
41460         0x0742c0b68fabc53L,0x05ccb0ca9b38321L,0x047a5b0a524cad4L },
41461       { 0x0a8ec194b4eb3c1L,0x04d6210191d382dL,0x0c893db31aaa315L,
41462         0x168bf34b4601a92L,0x0897abbb0e53b9bL,0x166be8723778880L,
41463         0x0d623fa1cf95f5eL,0x1a2f9f99fca1ef9L,0x00ea53d65c85557L,
41464         0x0ecf5a239447971L,0x17b7eb03ada2a3fL,0x08e010c07419565L,
41465         0x0900feb06c58221L,0x12f2e55634a3234L,0x1246ba60133d6fcL,
41466         0x0bd5db0ab30b13fL,0x001ed9378b173c4L,0x047ca168129264cL } },
41467     /* 170 */
41468     { { 0x11ec3028e845808L,0x15ffd5bbd5fe28fL,0x12e7e365f71f0c0L,
41469         0x087558b2964d5faL,0x074d94dc3d3a83cL,0x12c88e71dba5e8bL,
41470         0x0b3491192dcdf2aL,0x1fcc524aee70e38L,0x1419f24853b4440L,
41471         0x0d35079f02956beL,0x0a035a11b21b037L,0x13f5f0649e84c8aL,
41472         0x0807cf117aa2568L,0x06ee4edbe3a568fL,0x1bf2175589b7a82L,
41473         0x1d6a6a4c406e72cL,0x0cbe0ad57c3f3b1L,0x01c1801294a4e0dL },
41474       { 0x0ef5a405e744723L,0x1e7ba8d704240d0L,0x0333fb07ddbf6d6L,
41475         0x03f566ff8d57f5bL,0x08fedb78fba5d83L,0x09f9885f1cf1246L,
41476         0x17092973eb57eb6L,0x1eae8ffb63d227aL,0x1052a47c94518b7L,
41477         0x11046b63e7da193L,0x172e71c394e2fa7L,0x0eb2b762f22d626L,
41478         0x005b3106c736352L,0x0104dd8351603c4L,0x11412b74b50a81bL,
41479         0x1c0696a4b68e3a7L,0x1a5c9f4b368822cL,0x00af8c3cb75a0c2L } },
41480     /* 171 */
41481     { { 0x14dea060aee4684L,0x10f833e6dede404L,0x0526c64c4c650acL,
41482         0x03034fb74d4873cL,0x1c2ae80fea4bdd4L,0x011ee163109b831L,
41483         0x046c6d62c259c4aL,0x108e887aa2b064cL,0x02e16f83113c203L,
41484         0x071026b15ecc969L,0x16f35bd064e22c3L,0x1a3a3a6ef18e933L,
41485         0x0fc5ddae73492deL,0x0ca5b12cceadebaL,0x01b29a35204f54aL,
41486         0x18558323b39ec1dL,0x038562179eaf3e9L,0x030a378f9cff709L },
41487       { 0x106d33e078e2aa6L,0x17bfbcef74932deL,0x1e076a903a11a4eL,
41488         0x11373480fdaadc1L,0x0de9951905fbbb8L,0x16dd1cee7a256e7L,
41489         0x1dd2dfdc7e34c24L,0x1d6ceb6bb4a8462L,0x07456a251a5f605L,
41490         0x018ea57c3d1cd4fL,0x0c001816d1d2f64L,0x17e56ccb5523b68L,
41491         0x156631eeb4bda5dL,0x111bbe2c2e8d1efL,0x1742ffc0a0527bdL,
41492         0x0cbbc5c35e9d2d0L,0x050e0ea087582a4L,0x04aaa1fcf035e80L } },
41493     /* 172 */
41494     { { 0x1cbc6f485d7c6efL,0x00426b1d8de127bL,0x1a22fe32e98b2b6L,
41495         0x0d68ab8325bf219L,0x174fc6ed98e4b68L,0x11003bb0a35c6abL,
41496         0x094a5c388e279ebL,0x1eaa48388f2c384L,0x17d2215103884e5L,
41497         0x16906710bf14139L,0x067d453c99d3e35L,0x00aae18023b7c62L,
41498         0x19fcfb760e85459L,0x0f46150cefd5baeL,0x1f52c9e5518d8aaL,
41499         0x0d31896da7f1494L,0x0ffa5c87104ee5dL,0x036da1a3c15d14bL },
41500       { 0x04864935c3f0d95L,0x1edc1273a444a83L,0x1d89acbcf912245L,
41501         0x0856feae97ee7fbL,0x0f732723c60edc5L,0x1688a65f0e04d15L,
41502         0x0bfe5f4d19a75f2L,0x0392c8cc0146435L,0x0b94e2bbaed0cd6L,
41503         0x1370d20ef623a87L,0x1a6436c6a27d621L,0x1ad9e4eb2d27437L,
41504         0x00c0e0dddfc39e4L,0x0cce452088e7dbcL,0x070c143c2bf35ffL,
41505         0x18dc99d7ff5b6dcL,0x0944f3981b096d2L,0x003d3c8f395713dL } },
41506     /* 173 */
41507     { { 0x10e90471e9f0300L,0x09d6cde66fc8273L,0x0277fc14c1e3809L,
41508         0x1d5d1268c4a3805L,0x04846845f1ef092L,0x0d6a5a1648548d5L,
41509         0x19ec8651bb683c7L,0x029e0eca1e667beL,0x1c6e988db0b15a0L,
41510         0x17063375aa1787cL,0x0d8c478300de3dcL,0x1b555d0d2a1aba9L,
41511         0x0db35f1c8f548baL,0x0a268d6a3400b1cL,0x11c74c84a78c85aL,
41512         0x09bbd32a3759080L,0x0ac03cc29f385e9L,0x036b5661722a1f6L },
41513       { 0x1999e9557b2d299L,0x1e6cdf1eb90e6f5L,0x013eed32d110e8aL,
41514         0x13b80c1f545cc07L,0x0c987cdeae17770L,0x1b7df6ba787369cL,
41515         0x1effe688df3e041L,0x108d35e2a26f307L,0x06c3f7a1d323f95L,
41516         0x110e567b6db21ccL,0x004d3e59c0f648fL,0x131f70727eecf9bL,
41517         0x1c2e82522207558L,0x1c92553e0dad945L,0x109ea2ade1e6705L,
41518         0x129243b66f1e502L,0x0eed5a451b1ff28L,0x03ce8c1091e9e23L } },
41519     /* 174 */
41520     { { 0x03edff9109d5589L,0x0975a014da24c8dL,0x14c2d2d52b7f7b5L,
41521         0x0344f7fece27d73L,0x07f0f4604f9214cL,0x1287142640bf73bL,
41522         0x188deeb7e360f0eL,0x1838bb807932804L,0x15f29581b966647L,
41523         0x05b5044c50343f9L,0x01f3b0c58d145c4L,0x174ac5cea3115cfL,
41524         0x0745e2c3fb2001dL,0x1b3e99caaaea70dL,0x1a10bbaff2b37aeL,
41525         0x0b01743415f3978L,0x1c850590a2b3e88L,0x039882248d3c266L },
41526       { 0x0ca2cdf2648d676L,0x0f652a78d8958a2L,0x1250a60387ae6a1L,
41527         0x1235915512373b5L,0x0719e195f30d370L,0x181bcbb983955beL,
41528         0x19fdae9463208bdL,0x04f58121c295800L,0x10e6cfc708dcd29L,
41529         0x1ac44f110f3ed31L,0x0a902e0dc71f193L,0x17c51ef0f193695L,
41530         0x0bd84caf3f1f9daL,0x0f070ec97bc576bL,0x0909370f0e7741eL,
41531         0x00132d017cbf624L,0x14ff41b214d0bdcL,0x03547c7e4a8c062L } },
41532     /* 175 */
41533     { { 0x0a1ed6353235132L,0x119f8acedd445b1L,0x1148a47bf76076cL,
41534         0x0f64a2235d0ac4aL,0x1d701bd8c750529L,0x1a7a2edac90d7c8L,
41535         0x1cffed34175ca5dL,0x070dc7a98bde31cL,0x0897d985f899b30L,
41536         0x14e187de44d8aacL,0x0b468d344c60722L,0x0d744446641c792L,
41537         0x0201ceed02292e8L,0x0c1f984fe7922a6L,0x03f468c9e917dd1L,
41538         0x0ea70eb4c20595aL,0x1d7db4f45d2cb9cL,0x023a96c60ed941fL },
41539       { 0x14d6cead5dff4d5L,0x0afeda2d413fa28L,0x18313f1c4d79d33L,
41540         0x1037caef1c20e14L,0x18dc6b08dec0bb7L,0x1e124b138f0966aL,
41541         0x062b2dd94226d52L,0x064dbbe58c6c321L,0x1fd6ebac6675288L,
41542         0x1516812e1284578L,0x0b36a1373f07c3aL,0x0d508aa217c0278L,
41543         0x0d1a8868011c783L,0x17d792a29c82344L,0x0c2a23590c4caaaL,
41544         0x168e092d0aaee50L,0x152569491ca8744L,0x01d328c79bafdc2L } },
41545     /* 176 */
41546     { { 0x0a8ed50224042a0L,0x071d8122978f355L,0x1d31da084761b2dL,
41547         0x13de9aba7fdb94bL,0x122d46e54e0fe3fL,0x0233ba99d471522L,
41548         0x1406d6663887fc5L,0x072292d8a1deb25L,0x069104c2f83a677L,
41549         0x03385e5a395df80L,0x020ec940c5def4aL,0x180afa4e25451d5L,
41550         0x17b439c994c5d8bL,0x0e6d0d7fa0f7c98L,0x0e3dbee60074ea3L,
41551         0x1f041ad0ddd6ae0L,0x017e80c5cd0fbfbL,0x02a0561b1f6e12cL },
41552       { 0x11969a9fe7f43dfL,0x09c04160dcf2653L,0x1f621670a45f999L,
41553         0x0b2d5488095b2ceL,0x1f1297dabaca954L,0x1753ef074ec2affL,
41554         0x0fe387d8625ec8aL,0x1bf2ddb99fa6de2L,0x0627d307016e200L,
41555         0x14f839b64c4c452L,0x0979825fc8c749cL,0x0437ec090ea52bcL,
41556         0x094019b299af7f2L,0x135a58eceb34130L,0x1375e8c76677824L,
41557         0x02bd3d88f9ecc35L,0x14f4de9f2b36ebeL,0x00bed99767d0b4bL } },
41558     /* 177 */
41559     { { 0x1ef69196cf40599L,0x086fd806010753aL,0x19eff2abd9e5fa8L,
41560         0x0711bbacf07b4b5L,0x055bcfcd0d663caL,0x025e3f2d10fc7f1L,
41561         0x018cba70fd4e38dL,0x09a6bec563aa91cL,0x1654f242543c6e6L,
41562         0x1aad3d3134c9b13L,0x1f17dec3d04c931L,0x1ef2744301e7476L,
41563         0x111e81675b05697L,0x129a147ab67c2fdL,0x14a2c09b4f36cd7L,
41564         0x1f6f1c7542b22a5L,0x05da8470255f7a3L,0x02305e80dd0ca22L },
41565       { 0x034dc23c24d8077L,0x05ac0263906965eL,0x0445bd747ffa0bdL,
41566         0x0124f079c5453b5L,0x15904af3578af52L,0x1508c8714fa8d5dL,
41567         0x177c11b15c35fdeL,0x0a294a45f74ae37L,0x1bf4e2a06ae89bbL,
41568         0x0cd9ae62cf9a226L,0x0a0d9c9b30955deL,0x130b5f9d82ef860L,
41569         0x0b7c36cbd094a4eL,0x1ae9c83bd6d7beeL,0x0f892f3b4c6de1dL,
41570         0x08436a5ad209e5aL,0x18dc5ca26691f95L,0x03e9a161e0b9a43L } },
41571     /* 178 */
41572     { { 0x1cf2c0a11fd127fL,0x1b5dc08cf262f72L,0x0949bbd5ab0d9b4L,
41573         0x1dca860ceac4356L,0x0c3e961930cfeaeL,0x1e7338976f13e95L,
41574         0x130f5904d44ebe3L,0x130c2b38c360ebeL,0x1d447efe959069dL,
41575         0x1c6b7b4753b5754L,0x17186c3d6f4592bL,0x08dc3d11773158bL,
41576         0x161ba92320dbab4L,0x1c4c4c32b0c5c58L,0x02dfa0a83abecf1L,
41577         0x0c17618f5798581L,0x1a710f09b6e20d1L,0x02df057d3472631L },
41578       { 0x0ab6d381bbbf49cL,0x0e724c60381ff41L,0x0d77843d098cf82L,
41579         0x03b4b48a65d94b1L,0x1618f7b7d9cc658L,0x07bff383f0c43b7L,
41580         0x01af81066978c94L,0x0d376353d21bcd7L,0x0584a7deb373591L,
41581         0x0759a44a8a4ed96L,0x11a8cec3aeaee0eL,0x016185f1152428aL,
41582         0x070a2db0190067fL,0x031f379f5ef06ffL,0x081beb6e946c1b3L,
41583         0x1b81543224f73d2L,0x0aee4eb5e87fe80L,0x00f37e67aea6f18L } },
41584     /* 179 */
41585     { { 0x17dff66aa8ac924L,0x0d698e14c59f45aL,0x0ca597ec20301baL,
41586         0x1a3b2b927fa281cL,0x0a180caa7dab211L,0x06f6b4b6b46c214L,
41587         0x1187c6a4a502288L,0x065502a2ea671beL,0x1ff5604ae60eae9L,
41588         0x00dcf24bed72605L,0x0ea5ff7898ba264L,0x1349e21093068aeL,
41589         0x0f64724f1ded69dL,0x1542d0afc7fd011L,0x114de5357c70b93L,
41590         0x00fba98c4d9d202L,0x03780440cd6bf09L,0x022916a30aeed54L },
41591       { 0x095f079ebfbe7c5L,0x10ef6c2779a2344L,0x1adb5286ae58c3aL,
41592         0x04a14618d0e2d53L,0x0043bbaa1a4a5d2L,0x0872faad0b318e0L,
41593         0x0155af441d40940L,0x0337ffc7d3a7b18L,0x131b30b18077724L,
41594         0x07fbf78425c114bL,0x0df5d7c868630e4L,0x0c6aacb771f0018L,
41595         0x0a45e3bceb18d0aL,0x11f85846dd60ed1L,0x0f16b1470e3a430L,
41596         0x03f8de3743544bfL,0x0ba09d5256bdda7L,0x01a3280d4b6bf20L } },
41597     /* 180 */
41598     { { 0x0be448ccc2b0f1dL,0x1a2e4d6261b81c3L,0x19767f25aeff8faL,
41599         0x12b5c4ffb4a70feL,0x1bc18089cef3c4eL,0x050c50d0047bbb0L,
41600         0x0cdc7cdd282108bL,0x0a9dd105084a76eL,0x1cb6fc6d87cc093L,
41601         0x044f60db0a4b6b5L,0x10a6e5278c97121L,0x14a4f7bd82cd525L,
41602         0x0edcea281315c6cL,0x1d108aa7caa2277L,0x041873cd1a0faccL,
41603         0x081771f64df31a7L,0x16dc3b08aa806c9L,0x03e0ea167f2aa64L },
41604       { 0x06e703fdc110aa7L,0x1bcebf9b171bc3bL,0x1d756ab728f2adeL,
41605         0x12c17c66e7a4b38L,0x06c4e8ff2a6eca7L,0x1b82dffa3a25258L,
41606         0x12d4eca10b33bceL,0x1703475eb555c60L,0x17bbfa2011b2d31L,
41607         0x05d375d25f7446cL,0x1597395972e0e71L,0x0d2db5efd9d05a6L,
41608         0x07e695974524808L,0x14a7cc1b963e667L,0x0468c9bbf5bacf3L,
41609         0x1274c1467699e70L,0x19014203f43fffaL,0x0018f4c1439e18eL } },
41610     /* 181 */
41611     { { 0x1efecfc765a17ffL,0x19c4468948532a7L,0x111a4e3680e2827L,
41612         0x1b42d35a8d7e4cbL,0x03a62fe84bb6145L,0x04305299e7c10a1L,
41613         0x0e31158b7d5c6afL,0x0eb7e5521f502b8L,0x145ba1d6e17eda8L,
41614         0x0cec40d4a37d2f0L,0x0f9e12e43d68edeL,0x06f9621fea54d83L,
41615         0x04a4f4fd360910aL,0x07169dd061c60ffL,0x1e9861f0c603f16L,
41616         0x06b847c5fe0a162L,0x11c3a00059b943aL,0x024a69b22d14662L },
41617       { 0x18426b64ba021f8L,0x04841bcb6f5b61cL,0x0e55f8db1d8b453L,
41618         0x14ea39e42cda5caL,0x19b24a198f556ecL,0x1061576d650f000L,
41619         0x09ccd1e21f6912cL,0x1af27da999bfe83L,0x18d717c445c7c0cL,
41620         0x02431a548dfb804L,0x051be4ed66eebf3L,0x1673cac49e2b43eL,
41621         0x0d303f8443dd38bL,0x05f8827e4b6a0d5L,0x1c19609ad9c3c0dL,
41622         0x001ea0a07f3da52L,0x0f3768e1f47b342L,0x01e7ee62f5dea63L } },
41623     /* 182 */
41624     { { 0x16c2a86b523e13dL,0x0522c1490685029L,0x11e39d5c4a58405L,
41625         0x0cfd6a37d47aa56L,0x07b0e9190574606L,0x144474384fbc30cL,
41626         0x1f3500a2bb621a1L,0x1e6f35013afb295L,0x050c6032fe2129aL,
41627         0x0f25f394c1e2041L,0x0c6eedeacefa39dL,0x06596c318e51306L,
41628         0x013f59c4a4d31a0L,0x16a7b0f11b6ec2dL,0x15c5c576fb38d17L,
41629         0x1d7af74f5599a3cL,0x0a1138c58da64a1L,0x04494b6879e8d77L },
41630       { 0x165288fcca82c97L,0x160968a13f46e58L,0x1c1d30fb76a49b1L,
41631         0x1dd5403d7ccd529L,0x10f5e86d94600e1L,0x02b5188a55e73e1L,
41632         0x10b09d075c0832dL,0x0d1560b54264f3eL,0x070b60fafd42384L,
41633         0x0c77f6098c69cf3L,0x1fc6b22482cc628L,0x1751b0733c07d60L,
41634         0x0e3c81a30101e3cL,0x066333ec32fc499L,0x1a181f2ba2f29f7L,
41635         0x142599dc35cf344L,0x0543182e64ccac0L,0x04919d17b958d26L } },
41636     /* 183 */
41637     { { 0x17e8df60acbee17L,0x0ace12e127e6e38L,0x021f953ff2c03c2L,
41638         0x15a50a22d68de13L,0x1ba1fa51b993decL,0x190c1f05fd527c5L,
41639         0x1dde6724927bf43L,0x043f27966b12d08L,0x1284bfb7f2322d4L,
41640         0x066384d6a157804L,0x1c89d26ec758550L,0x1674e2f878d58d3L,
41641         0x05bb9c5eeb76f50L,0x123c1dafc590f4cL,0x1870f9d63ec66baL,
41642         0x035900990d736a5L,0x091aca59092f297L,0x015d9353490f6c1L },
41643       { 0x0a3443515f81416L,0x13973d57fadda4cL,0x13780c5c987021bL,
41644         0x18b81439fc7a3ecL,0x1368340131c0786L,0x1cda66aa17526c5L,
41645         0x09fc4bddc9ce868L,0x1b829fcfdc397deL,0x1ee7fc09e16bb27L,
41646         0x06e660ba0872ee3L,0x199d08650ecf770L,0x16c07e63836f468L,
41647         0x19c22c107092934L,0x1ccfcb3580c36f6L,0x06c224e8dfba2e9L,
41648         0x1a9bc1e77f96849L,0x108bae614472e92L,0x049be59fc70cb75L } },
41649     /* 184 */
41650     { { 0x1c0e77c16fbfdceL,0x1a664e4c6a6602bL,0x15c9095cb483a80L,
41651         0x1800335079cec0dL,0x115971629861b55L,0x107ebdc05d1401fL,
41652         0x0aa883d05077416L,0x1d910cb2276961bL,0x0e6685746aa3848L,
41653         0x168ad2d1f0242e9L,0x031dd0eda417745L,0x16fb0315e575038L,
41654         0x14d2b74b78cec31L,0x0a1f1794406c78cL,0x0c1f073299676c9L,
41655         0x09180637074fb3fL,0x01186537fdc1f10L,0x026abdd83bc2c35L },
41656       { 0x04b768a53b396b6L,0x1926249da8ed65eL,0x07ae8c2b86cef22L,
41657         0x0b28a28f8a67ca2L,0x179fe3ce893bbd9L,0x0905ea366430188L,
41658         0x18580d2c2859cfeL,0x107665225d6d64aL,0x0bc69a2a49d168dL,
41659         0x04a4f3d7786e894L,0x0d066a1c9a6786dL,0x08ef7e426ed64c2L,
41660         0x09a4f9714706c58L,0x1dcdba2ff2ad8c8L,0x17cf2158f5badd5L,
41661         0x1f5c76a6cb65211L,0x0a80e257e4355fcL,0x00833e08c4bcf95L } },
41662     /* 185 */
41663     { { 0x045508432bf8883L,0x0943537e83333e4L,0x1e3ddf08cd751d5L,
41664         0x145e945929ae161L,0x1118acf5678e60dL,0x0dc86cd2346c566L,
41665         0x044133a4e0c2efdL,0x149d49638e9da9dL,0x0ac67316d27776eL,
41666         0x0c56bae1b0dd589L,0x0f520a64489146eL,0x0440a614875d864L,
41667         0x0e3292d5a526440L,0x0ff678de1d22299L,0x19ee2e36d21a52dL,
41668         0x0d5bdc9c0a2dd8cL,0x125b3aa595fa430L,0x03f27b848f9a74bL },
41669       { 0x13816e9b7f70919L,0x10b768b5801fa9fL,0x1fd1de326795d94L,
41670         0x10614a30208d8d9L,0x05e728dbe6a5abeL,0x0677eb77b7a4f32L,
41671         0x1cfddbf75cfab2bL,0x187d8729cdf186fL,0x173320802b6407fL,
41672         0x04747bd4b312e5eL,0x048d8df2afec026L,0x13be80fe6b35065L,
41673         0x05ccbfae50258baL,0x1f128c09ff80d77L,0x1c72e87efabab3bL,
41674         0x19b6b38d3e2c307L,0x0bd512c58ad9eadL,0x015724e6a366674L } },
41675     /* 186 */
41676     { { 0x039b0e3c40849f2L,0x15266d22084c609L,0x0a67951fd92544dL,
41677         0x08f537758cc2a6bL,0x13547af692e4bdcL,0x03d3a50cad0b232L,
41678         0x08aca17b2cc662dL,0x05a4f0aa7f93bcdL,0x1471c038a0e2ba5L,
41679         0x15d0dc41ade5d49L,0x1d4369bcc7b2884L,0x07ed0056658da97L,
41680         0x113c64c8c4d146eL,0x1769094b864e009L,0x1a14c3eb4c3c4b7L,
41681         0x1bca336eb7ff738L,0x1b723c0ad3e8918L,0x00c074ea9539bb8L },
41682       { 0x116542f29ab77b0L,0x08ece7bd7731461L,0x1a14d4f0bd03750L,
41683         0x089615c99e08980L,0x15fc266f638dc7eL,0x17f5bed04920c2cL,
41684         0x05e618e7699c7f4L,0x054ad0b1daabd47L,0x17a694f3158f383L,
41685         0x0a119e3698b6c18L,0x0b2c98c28d69eeaL,0x0fbbe3fee2765f9L,
41686         0x0559eee2f3fef8fL,0x0ab6832545cda29L,0x173f3f346d3e46cL,
41687         0x1d6822ef0cd845eL,0x1b412bc25663777L,0x010e5379e6c55c2L } },
41688     /* 187 */
41689     { { 0x0162b13a3e66635L,0x10515954fbb5787L,0x08c11b6ccd587bcL,
41690         0x0ef005771b568e7L,0x0699b44c0840bd7L,0x1103f8adb5d7af5L,
41691         0x004171b8464006cL,0x009cbbc2d52f216L,0x122b12f15db67f0L,
41692         0x02fd6a2c5012e92L,0x1da54f7c2845086L,0x0537e8a06981799L,
41693         0x001c277bff4c421L,0x14054f0c07ba020L,0x0aa8ad1b9102d30L,
41694         0x1b29eecfbd1eb08L,0x0353de20ab805e8L,0x02d7fac2c90113bL },
41695       { 0x05acd20a8458e40L,0x0abec0a4b995ec0L,0x04c57c729cb5695L,
41696         0x192a56a6478e0e8L,0x0494fadf7f2e269L,0x1e93332e2c92ab3L,
41697         0x0a19454edeb3469L,0x0d74dbe0c7b0dfcL,0x11e91db1357d53bL,
41698         0x0caddc4f49f5680L,0x0786bca58eff9a4L,0x1385104f110c7aeL,
41699         0x123b859b6ffab2bL,0x1b814ee8bbc1b34L,0x0611585b9a545d3L,
41700         0x1b0938f30f0ecf7L,0x17764fb4f1d5907L,0x01f55bf0e446c54L } },
41701     /* 188 */
41702     { { 0x13a94b652e5718bL,0x17d2a7a6770f4e3L,0x198d54fbb7ab8ebL,
41703         0x16be759434ca9d3L,0x0d083316f2541e1L,0x1fca876b894a448L,
41704         0x0f929e596bd8fedL,0x179b1f93c1b8e9cL,0x0b4ee48d2eaf79eL,
41705         0x02c543545bbc3f3L,0x1d887fdf33abc29L,0x1dffbecf301bb18L,
41706         0x02f91067278228eL,0x183f1b149086a3aL,0x1c78a7647d8d406L,
41707         0x1714a882ec38cf2L,0x144c0ccc65f03a3L,0x01a48ed279c704aL },
41708       { 0x106d046cb062eaeL,0x0db9aae843bb6b3L,0x0148a48c574bb9fL,
41709         0x05880577b701bd0L,0x06ed33374078566L,0x0b4769afc9a92e1L,
41710         0x02c79b3a85359f5L,0x0eb22d42312cd11L,0x00fbd52055dc716L,
41711         0x19e883bf22baef9L,0x0c402bb0248cd60L,0x1a02d9b0a7129d2L,
41712         0x05432263682f9e1L,0x0dd267ebf75e9b9L,0x13160e100745cacL,
41713         0x02fbc6efb573aaeL,0x018aeaa695880d5L,0x006421efeb568adL } },
41714     /* 189 */
41715     { { 0x15811ffc9373300L,0x099954cfee18022L,0x0070d4f2d95470eL,
41716         0x152d507a4fc3377L,0x12ee3f1a774b924L,0x06ab63e5fe47e5dL,
41717         0x0bde6bc9e3b1004L,0x17edfbcd05fc157L,0x07566d0727339aeL,
41718         0x09ad6aeb8902edbL,0x0f9a51c1472742fL,0x0901a7460cf96b7L,
41719         0x14572d7530577dbL,0x1036c29e96387faL,0x0afed77a1856bb3L,
41720         0x11daee33339960bL,0x169eeefc96bea0aL,0x016e6234e9afb6fL },
41721       { 0x0a6cd06c65f0e77L,0x03cc05eb8d8a566L,0x1e2cf24f3003773L,
41722         0x075d197eaf6c443L,0x16f8e63fddfcd5bL,0x10995bde494b9fbL,
41723         0x1278ba61228d01bL,0x034998b3407aa3dL,0x19c9d32bb3a3308L,
41724         0x009082940742335L,0x000ca86ef9ca540L,0x0ae449270891856L,
41725         0x0eb6bba0ffdbfc6L,0x0054a40174b9506L,0x0762f1fd830293fL,
41726         0x14171ec588398b3L,0x1fc820c96ee312dL,0x02d0d32ede6defcL } },
41727     /* 190 */
41728     { { 0x1ba691a42485684L,0x08b5c94e23864dfL,0x05c798a8146584cL,
41729         0x0cbfe933b569603L,0x05238efff3245aaL,0x0eaa8ae177c3fa5L,
41730         0x0b2b305b71aeb32L,0x196b4fe44fc5b7bL,0x18dedaac4a9bbaeL,
41731         0x1984536973e4c42L,0x1cbf0b9a25564ffL,0x050a2efc0c2298dL,
41732         0x06300b1bee3655fL,0x09e0bdaa531f468L,0x05d098afb4339e4L,
41733         0x0806f94957c6b89L,0x1d9f4b44a17bc4eL,0x02d74a84cf7f2fdL },
41734       { 0x02e5ee7804f7455L,0x124cb9103334109L,0x10c5de578cccd06L,
41735         0x19c91df9db2fa49L,0x19fbc21c12f4123L,0x11d1d77439c6c90L,
41736         0x09b6eecef718419L,0x0ea6c07b1850b27L,0x1926227f2e3c1acL,
41737         0x15495602f55728cL,0x05bc2ff5a04ab3fL,0x1089f85505b8b6bL,
41738         0x1a63522b273ce7eL,0x09433c4a9c20240L,0x1621a220d8222c5L,
41739         0x0f95843ff6f984cL,0x0980ca331612f4aL,0x02088333f51f6e9L } },
41740     /* 191 */
41741     { { 0x1830357c2d04b63L,0x0d1a6fa494d0c40L,0x1b688b46577cff1L,
41742         0x13968648e78e77eL,0x0997f13814df2f8L,0x0b027a1a2d7f2e7L,
41743         0x02b97638fd7e62eL,0x1e75af285d2a182L,0x0cefd5447eed25fL,
41744         0x1b4728f0739e066L,0x0b5646ad53e932fL,0x020a256c3918b63L,
41745         0x13b5abf7608bbc1L,0x00f3cb24ddc9948L,0x0332f9f6c48c6f8L,
41746         0x0db73a1507d2208L,0x1ea3dde426f90a9L,0x00e675b229a6f88L },
41747       { 0x1210c4f0c6d0f55L,0x0fb0dce339e4e96L,0x0466a738feedb2bL,
41748         0x192760c7c9baff3L,0x145a93be135f494L,0x0977be2c05ed9e0L,
41749         0x0eda9361c8cc83dL,0x1dce9b0edd11029L,0x14f6f723ac7a97dL,
41750         0x0f15c781f1e6c19L,0x0bc20ab9c809c1fL,0x05a9bbf490dcc2cL,
41751         0x198d3a17c6e88ecL,0x1cc00b8d6cb2e42L,0x1bdac898b967950L,
41752         0x16406156c50bb77L,0x0a33cf451954d48L,0x00f8ba919a7512fL } },
41753     /* 192 */
41754     { { 0x08a765b3467ea91L,0x119777e96ce22c0L,0x11b673caf1bcfd1L,
41755         0x006b30275cf6ebbL,0x044cbd8defc8d24L,0x092b1111f65904fL,
41756         0x1866966e8438c85L,0x1eff429b2687e3dL,0x1df97c21bfb0c48L,
41757         0x073144875186a1bL,0x1b8a919451d70b1L,0x03c824cce54b650L,
41758         0x1c31aab3b8291f0L,0x10be91764e37ed2L,0x13c2eb6dc9de96bL,
41759         0x125c37b11db0722L,0x02bd0b05d1b6a23L,0x0265c57c832c49eL },
41760       { 0x0b02057bb4b1953L,0x045a27acbfb7751L,0x166d79904b21338L,
41761         0x1b679a92330a9ebL,0x0e42bb5d1913262L,0x073fb04813b1723L,
41762         0x105b20d57239b5eL,0x0311df55048716dL,0x0d0173790e550f6L,
41763         0x0c57a3172bebbc7L,0x0b57a1c56d1c504L,0x0d8683bd49f342dL,
41764         0x12280ca61090059L,0x1ba632d0954abe1L,0x0201050bebba000L,
41765         0x01f43b620a24ea0L,0x0fc8c1db931ff08L,0x024352e12ebcc3cL } },
41766     /* 193 */
41767     { { 0x121e213941b4f36L,0x07d8a7c01da7c82L,0x08b94a952ea2eabL,
41768         0x151fc8f2d9fbe3cL,0x18dbacb6acfabbbL,0x0efd28d703c46daL,
41769         0x05bbb7e635cdb06L,0x0362ab850d46b4eL,0x0be7d46769c8646L,
41770         0x05b1c07b1d3252fL,0x1064527d8249894L,0x0fa145bf8b66296L,
41771         0x15cef466ac0919aL,0x14c35576622a6d2L,0x09273b64fe92891L,
41772         0x0eb5aa12162e2e3L,0x054602f1d6cc1faL,0x02e934fc4bc7260L },
41773       { 0x074030c14920419L,0x0ec34484b439c9dL,0x1313badc3e98211L,
41774         0x1bb3f8b79703732L,0x158f8f2dabcaa06L,0x0e29550329ca13fL,
41775         0x06ea8d7217d9ec7L,0x068b4fb1ae45922L,0x14041005caec2d8L,
41776         0x0c345223d4729a3L,0x18602e37944b0edL,0x0dca4222d1d609dL,
41777         0x0b2317cd8a4daa6L,0x108b26fb605eaedL,0x0eb5f2687506175L,
41778         0x04d0759db944c3bL,0x10f0fe4b5ac09b0L,0x04564ccad136caaL } },
41779     /* 194 */
41780     { { 0x0c8dc9b2640a39dL,0x1859c76f064fcd9L,0x06f687b2e82887fL,
41781         0x1a101a082ee9e8dL,0x149946048a902ccL,0x1b558af4ab7d197L,
41782         0x1d248d23e173e5dL,0x0cf843f8ddc00cdL,0x135b1ebfefeeef3L,
41783         0x0022c0e2309f2f6L,0x1fa39ba9ae81c5eL,0x14652a1ae7db97bL,
41784         0x161da48889ddfcaL,0x0dd7fde8e4ba3c9L,0x0ebab9f3a19f233L,
41785         0x02591a4ce863e39L,0x04d682550458979L,0x0063e0eee6bf50fL },
41786       { 0x1aa30cc1ce963a7L,0x17b266262fd6f29L,0x0be0a0a2befdcd4L,
41787         0x0d9442420e57354L,0x05a576dc64273c5L,0x1ae3be556ebb2a4L,
41788         0x1ce6d865ab0fa42L,0x18841a87d3fa355L,0x1fc392062cd05cbL,
41789         0x00b1c392607f97eL,0x0ae360aba087985L,0x12867f4f47e19e6L,
41790         0x0df644ca925f58fL,0x0c8c53afd75f8e9L,0x01d84603018558cL,
41791         0x04882f3136bdad7L,0x1abbf342445ad41L,0x0127fe4d70efb19L } },
41792     /* 195 */
41793     { { 0x1fcdc0593c7cb2bL,0x01dcaac8029fdc4L,0x0f3d8608d0f3049L,
41794         0x1ecd8314c6c03bdL,0x0c913287364546eL,0x1c4618d2948380fL,
41795         0x1df5f0d6e009be5L,0x0510a570c5525a3L,0x11809cb050aa797L,
41796         0x0bea33e51e59002L,0x11df027bd6e51a2L,0x1885e4483309e41L,
41797         0x0df35bb206c3372L,0x14e0a05aed029f0L,0x15beccef09b1b42L,
41798         0x072d0c39f981996L,0x1a41c3cf9ef299bL,0x044f269e8a0310dL },
41799       { 0x15e80e7a45a9be3L,0x152bc039ab7dee9L,0x18bae59ef0bf136L,
41800         0x1c8f9a2dc6030daL,0x1f30ce9ba702679L,0x0327a865178e012L,
41801         0x0759bc4816d187eL,0x13cffadaf2f0a0cL,0x047edc4f68a0880L,
41802         0x0d60224cd269d71L,0x119929b47e76a17L,0x1d09af5074e3f08L,
41803         0x0ceaac33f19f30cL,0x0a431155f49c15dL,0x1a07ac87c0ce0c6L,
41804         0x16b8f606f4975eeL,0x0fbd156a90899a1L,0x033ae9f37f378e8L } },
41805     /* 196 */
41806     { { 0x1767ffd707193e5L,0x05548c081ac72ecL,0x07fcca363bdf91eL,
41807         0x10db77b34eac69fL,0x1e215686913a0eeL,0x0ced1c1bcd94b43L,
41808         0x0d34a40fd042a27L,0x16bb3f1af723626L,0x09fe74229bd82efL,
41809         0x1ab45b11c01e3bcL,0x068d434f494d136L,0x0b60e4892fd127dL,
41810         0x16a169e23b559c3L,0x062da634e2396a1L,0x11fd4c4261918cbL,
41811         0x0f1113edaeb3b07L,0x04ba91cf1db1e49L,0x02fbfc97f30578dL },
41812       { 0x18a1cc60545167eL,0x1170157fd447078L,0x1d450ca9ef3d57bL,
41813         0x054ea210cc499bfL,0x00511af77382da4L,0x178a11f44a608faL,
41814         0x14abaa93938c4aaL,0x06b187a6de1ec7bL,0x1fc5c9550d76606L,
41815         0x0929b989bf53f55L,0x135660e6e543d80L,0x0c0281cc688454bL,
41816         0x0ef2ac704595a0fL,0x023587b9c82f11cL,0x1215e2912eb3039L,
41817         0x0f00699a840dd88L,0x18d367b1aaaa5bdL,0x012df676c8515a2L } },
41818     /* 197 */
41819     { { 0x19a73820c33a8fbL,0x1b6688792ee0e83L,0x0fe31b520adb3efL,
41820         0x180f7f08949ff8eL,0x199162f03e51f18L,0x009c08d3b2891b2L,
41821         0x06282b1669d3850L,0x1632af4d0cbcaa0L,0x1e1ec51bde3ca09L,
41822         0x0063f59d4b0129fL,0x0ff451f780fe12fL,0x1da2a5f7b613d07L,
41823         0x1dcea15ec1c0540L,0x05930983b5d2976L,0x0e5c81bcf4c3b55L,
41824         0x0e75537af75d1d0L,0x163f20d86920963L,0x00530b525e1d85fL },
41825       { 0x075f3ed6e1339c9L,0x150395fc5805310L,0x120af3366d1debeL,
41826         0x1e0194a98fbf5fdL,0x18bc31ae4713158L,0x06fe45224881789L,
41827         0x15352be63c560c4L,0x18993de40eab3d2L,0x1e8021af9c527a0L,
41828         0x140093bbd0c9011L,0x1d4e31fec08dddbL,0x0e9fd193d2a2c6bL,
41829         0x0d15cc90975df19L,0x1bd288ae0143fd7L,0x0b188f7e81ca3c3L,
41830         0x1741321b7f7cc1fL,0x04ca8d40fd40311L,0x043b68aa703e323L } },
41831     /* 198 */
41832     { { 0x1a4d6d2c2d3ea8aL,0x1340dd421300769L,0x0037901c19c8dafL,
41833         0x1cd4faf4f78a7e2L,0x1d5e1a83e3e5b6fL,0x04be153734ca7caL,
41834         0x040441f2b3489d8L,0x04825b31b754cf2L,0x0ddfc4461102e0eL,
41835         0x00aede16a499395L,0x03992ea50d9a592L,0x163465657f20fc7L,
41836         0x05d928e28b4960eL,0x1503be4f6d22ba9L,0x1587401cbdd6ce4L,
41837         0x028ac4eec1976ffL,0x100af235d1b0f4bL,0x01820611df3b68bL },
41838       { 0x10dc55b4efa9a70L,0x120a7a9f4330858L,0x044c27e289ff537L,
41839         0x0a0ccc3a787b2b8L,0x00eb513e505109aL,0x1e99c5e5514ca53L,
41840         0x19c7cfb9054dc79L,0x1689fa28bf88ca3L,0x051bbf838cbc313L,
41841         0x01cf03c0f5c90a8L,0x05ad1052fd6b1ecL,0x031117c1a919d0dL,
41842         0x15dd8f2b6f2d667L,0x15c53fc55f49d97L,0x1dd4717077f479fL,
41843         0x0e97d0c567bb321L,0x1a21eb1ad58a32aL,0x02a436bcd0f5de4L } },
41844     /* 199 */
41845     { { 0x12e34ffa1359e13L,0x0c6df940cb028e5L,0x08f48d592d7880bL,
41846         0x0c85ed5825d2bc0L,0x1653725dfb1340bL,0x123356aa1dd4295L,
41847         0x1ca2e06bb735a34L,0x0cb7ef00448a8f8L,0x1559f8a119569fbL,
41848         0x02dbd316fd91764L,0x01d5027bb579494L,0x0510533ede220e2L,
41849         0x013db6f8c79c899L,0x19e53cd4d3eb493L,0x08582c0c3adfeceL,
41850         0x0813595733771f6L,0x18bd2012568d28bL,0x01c078d87ad622fL },
41851       { 0x0b99e6be6a0068fL,0x1e79564539ba9e0L,0x1522cbebadf12d9L,
41852         0x126804c1874d934L,0x0c0f739e7f417f9L,0x04a4ed4772b42aeL,
41853         0x1bbffc22d443de0L,0x17762ee1f851ab8L,0x0b4f5abeefd96a7L,
41854         0x03d889b79332d15L,0x0e0292d80773e68L,0x0c282c57d98c5f6L,
41855         0x16ee6b83b3cc803L,0x1460bf759a4c7dcL,0x1dfbf0baa6c3f5aL,
41856         0x0167cb0696b7542L,0x05e929044f55b11L,0x0255f6ef6f5eb94L } },
41857     /* 200 */
41858     { { 0x155e1b9700ef376L,0x12ecd3366d5ff99L,0x15d51fa1d91b55bL,
41859         0x1401ef26d367b84L,0x00c52e2928f44b8L,0x14d9c90461958f5L,
41860         0x08e7569e37848dcL,0x0d68308a33564daL,0x123f6b4b7e0ce4aL,
41861         0x1afb7c5565954fcL,0x0f1153881929648L,0x006837e60c5d771L,
41862         0x1b94dff6f937efdL,0x0553fd0335d6341L,0x02cdd170cd92c7aL,
41863         0x1f61e0c2cee559cL,0x0d346f08d08d1e3L,0x0351055d98c7099L },
41864       { 0x08310166a85cbc7L,0x084a349a7cd53f5L,0x02239de3c6cf426L,
41865         0x1e448f6f3384422L,0x054484ce7ea4ff8L,0x0c61b2598b8eb8aL,
41866         0x05160a500e5253eL,0x02cbb5223e72fbeL,0x0a6b58093094391L,
41867         0x0fca84d0ba11c5eL,0x1460860825d635dL,0x004348f24ba1fd6L,
41868         0x14af8a315eae0c6L,0x15d6825b874a334L,0x1c911f6b9ebe28dL,
41869         0x0dffc8982bcffe0L,0x1775184668aa545L,0x022f1a9d3df9b5cL } },
41870     /* 201 */
41871     { { 0x005676493092f71L,0x15b617adc96b8bbL,0x126f8b22db17ad9L,
41872         0x1441806c7d3b662L,0x03cd7097f62f583L,0x1c8b56344566998L,
41873         0x06c3a174303e3aeL,0x1a237ee8c590983L,0x1c76ed5f97c4a6aL,
41874         0x045c45d688cf9b4L,0x00dc6faf942e0fbL,0x0a110cce0d4cb37L,
41875         0x03f8373d2c0cc69L,0x152d017da98e3adL,0x0e6874138734e8cL,
41876         0x0667dd04e8ef1b4L,0x136edfc5bbb75daL,0x00aca0f92653cdeL },
41877       { 0x0e8c0f8a77dd512L,0x1acd38ee1b2fb21L,0x133421d4e18aa46L,
41878         0x1ba4e5f595d01a2L,0x0027cb5a1624230L,0x17cf81f751f60b2L,
41879         0x0523705c02d6707L,0x1e3a823824e1b46L,0x1801ee448c4181aL,
41880         0x0f942accf1d4805L,0x1ec2f43426bff7bL,0x1f2d166e0048bacL,
41881         0x00e6f836b8d839dL,0x1e9900e49db183fL,0x0740aed4e0b9622L,
41882         0x083d2c6db14d6f4L,0x10370b7db769686L,0x0368be1a508c7d6L } },
41883     /* 202 */
41884     { { 0x1608841c181c99bL,0x0e480e43dee57e7L,0x111cdc836afad97L,
41885         0x0ca6eea2b768c16L,0x0a96c2774c79c39L,0x007a206a23f9170L,
41886         0x00eb4365484c0abL,0x141066164d7920bL,0x0e25e977a928904L,
41887         0x0f57fecc2e2858cL,0x16f2de96b57da87L,0x00339146fdab9e9L,
41888         0x101e9850b6cbcd0L,0x185c7302bc236ecL,0x04cbe406b20652aL,
41889         0x1c51772e50ae268L,0x14e4ce9f149f56eL,0x00d5cdad21f4f0eL },
41890       { 0x06dab92314fa7a3L,0x1787823c7fcb190L,0x1c4e41367f6f312L,
41891         0x1625808bfc999c2L,0x1d8f6d7dac20a2eL,0x1db7fd227e2a3c7L,
41892         0x1dd6221b9cb1729L,0x1aaff48a536dfadL,0x14df1d1b192a820L,
41893         0x0c097cf93c4f8a4L,0x0bc20eaaed4f48fL,0x073654075665308L,
41894         0x10b151250226485L,0x198fb5eab18e704L,0x0db98d384a53455L,
41895         0x0cd5f64526c3b28L,0x1ed8c4281c43ca9L,0x01259a4ab610d59L } },
41896     /* 203 */
41897     { { 0x1bdcb86659824e2L,0x067242709f3a624L,0x0899aef87ba9b71L,
41898         0x0e3c7d88af49803L,0x0f5a8e4b47b2b8eL,0x19a986bf458af01L,
41899         0x1480ba07adb9b8cL,0x13f59746d3c2f48L,0x081241431d70e4cL,
41900         0x0c857a59f095f5cL,0x1c148c47d21bf70L,0x03c253f6579ca64L,
41901         0x0bb70f6c089f6c4L,0x1ff5a23bdf3143fL,0x13c62ec51e61428L,
41902         0x1a081f9fbf62337L,0x1f9925c292fda80L,0x01096b2f2bf1e2dL },
41903       { 0x1adb386ca15cf08L,0x1256240f0b97591L,0x1e4d350b430137eL,
41904         0x06e8809b8f3a3b7L,0x0932bfcdd9cf607L,0x14154c30284220fL,
41905         0x073026ba4432871L,0x0612a51f8308358L,0x0e6a120aedbbed6L,
41906         0x07070f618667928L,0x12e953962efcbe5L,0x169f3f54882bfd0L,
41907         0x07ecee7ce5c66d0L,0x17d3439d062c78fL,0x07c4d21e8750fadL,
41908         0x0f56f2d8d8b4073L,0x047e6ef9aaae672L,0x03357d2aa4d2e12L } },
41909     /* 204 */
41910     { { 0x05aaba8c980e91dL,0x07a84b564c77d6dL,0x182a368c998aa4fL,
41911         0x0001028a7d61321L,0x1d71de8401d2153L,0x0cd00915d8699f1L,
41912         0x0e39d197db600f8L,0x118b205fe98f150L,0x174e2afb7193134L,
41913         0x04993abce7d82bdL,0x1a9908eb40fe3e9L,0x048ab1ff4814ec3L,
41914         0x1977a87e30b7d4cL,0x04e426935af4e06L,0x0658e834717b6ebL,
41915         0x17e1bd95107347aL,0x1dfbc6f2f35ebf6L,0x000f7831886ac55L },
41916       { 0x1f903163ecdcbb0L,0x16b9413e0e4aa95L,0x00c255d724c0678L,
41917         0x132d3072613ca4eL,0x1cd082df0dc1c5aL,0x0bf028f7cfc07fbL,
41918         0x06d57364541d77eL,0x189e50dfffd398cL,0x1352db38f80f24cL,
41919         0x0cdccf61b291d71L,0x0a32a042c412a7bL,0x1fce60a4075a213L,
41920         0x0e769400f5c2700L,0x170622961517712L,0x1c0a90756574e67L,
41921         0x0616e156ebad5efL,0x002341080990db7L,0x00727affeaf4689L } },
41922     /* 205 */
41923     { { 0x11c64440ff14c38L,0x1acfd576708f95eL,0x169c8abd8cc2696L,
41924         0x15055e49dd548c0L,0x0b9a1159ddc9f65L,0x142757fa7725ff7L,
41925         0x0ab38918f41d9d3L,0x1971197c3c01c17L,0x17ca568ead5fabdL,
41926         0x0c06a9262bf5cceL,0x195cb3a6fa61cefL,0x1b9ae60170bd388L,
41927         0x1240f54176918a1L,0x1ad8a11b2491098L,0x0d3c5abdf8c93feL,
41928         0x1b2f881bb4a0248L,0x02008833421a133L,0x019ea08b0843b78L },
41929       { 0x131a36b9878e5ecL,0x1f190a348c1193aL,0x08cf428c1191778L,
41930         0x0f542e6cb3a2bf3L,0x1925d4fe734c1b8L,0x11587a56104a517L,
41931         0x172f10f25968709L,0x000eb39207c88faL,0x092af215e052393L,
41932         0x1fdb6af8fac9f9aL,0x10ed2f0f376d7ffL,0x05397fbaa810cb2L,
41933         0x0b198d76c09d03aL,0x00793dacc7be6d3L,0x0d6333f01e4288bL,
41934         0x09fb974aaf50919L,0x0665922052d76c5L,0x0169ef3d523db5aL } },
41935     /* 206 */
41936     { { 0x0de746265add3b7L,0x0479ad5f9261555L,0x072b8695f64f962L,
41937         0x1c58edef7fa82a9L,0x1e3202b30e22e18L,0x0e878533f944755L,
41938         0x0b462de699ae874L,0x1d21c156e925103L,0x17d424086c7adb0L,
41939         0x186196294210997L,0x11dfc563e6827a1L,0x06e5d804ab130b0L,
41940         0x1ca5098777422a9L,0x0bb3002c5f21462L,0x1fcdf3d16de5591L,
41941         0x0c512d8ff8c632aL,0x0a68b7023ddd631L,0x023801ddb2d8e09L },
41942       { 0x19401c1c91c1c96L,0x0e6fc93d094b86cL,0x185f0f0a441ea97L,
41943         0x0f47fc8e2075725L,0x0ee998ee26fce8fL,0x1d20fc58684eaf2L,
41944         0x0941abe98881238L,0x0a56380254b44d9L,0x12c6f734c99b572L,
41945         0x049ebcfa897bff0L,0x0241bab3b866984L,0x07020ada3d4c5e6L,
41946         0x16eff35f216bff8L,0x00d6911230e3ac2L,0x083f7a1b81fa5e3L,
41947         0x1d0365994d942d6L,0x0e6ab4d6d2d633fL,0x039effa82583516L } },
41948     /* 207 */
41949     { { 0x1615805d8e20fb8L,0x039f2415a99f845L,0x00055aa15329f1aL,
41950         0x19966d2422a40beL,0x07f092b787fec6aL,0x02ff260fd1e0766L,
41951         0x1c4496cd991fba1L,0x0dfa8f03d0bf163L,0x0c65268398b0f1aL,
41952         0x175c6366e5c75c9L,0x1c3ab6397db54b3L,0x1c4791b269b8267L,
41953         0x1d428ac45a31883L,0x0ddfe54290a76adL,0x196b84fddf2924bL,
41954         0x00bf7be8227fc0fL,0x13563e4a0d272abL,0x03aa2685bb8a47aL },
41955       { 0x1e8d13480797aceL,0x0b55057c36cbf27L,0x1a23bd69a3f085bL,
41956         0x0b3f364d09b7e14L,0x0999d2fc18b26f4L,0x011caaa97f7e7d4L,
41957         0x0de0356be360989L,0x15f1e2468d3ec74L,0x12933454fdcd4feL,
41958         0x1400c5bd39dae84L,0x07c9db9554b062eL,0x0e7bfe4d763935eL,
41959         0x1006dd4f44c5d47L,0x0f9cdd24cf7a4a0L,0x1b293cab63c4be5L,
41960         0x1eb34aecfedb9ecL,0x149ba8773f17922L,0x0110040f560f216L } },
41961     /* 208 */
41962     { { 0x043d573ba37a0baL,0x018de6e8bb6fb18L,0x13f31081c3dc169L,
41963         0x1ccf85a21206645L,0x0bf8bcfa5cabd30L,0x03d8859b164aef6L,
41964         0x179935d9f49dddeL,0x01cc25922bcdd80L,0x19e669631ce69c3L,
41965         0x1e4eec7b417131aL,0x087c4a57ff30e09L,0x1cf31455b944f20L,
41966         0x044b5d500a06a8eL,0x06c06b62c70073cL,0x17c43321dd1bf1eL,
41967         0x0dfb048c0a77d22L,0x133844e328b219fL,0x03102a0d608de9bL },
41968       { 0x17fd382509e5a29L,0x06be85a19298f07L,0x0d5334e20ee61d2L,
41969         0x0917f762f51ee92L,0x05f2d2c5c6b8ac7L,0x058dc1d230b5330L,
41970         0x0996acf6598946fL,0x0b19eea62085fdcL,0x0c70d73fbdb2250L,
41971         0x108ea1a78616aabL,0x01876152c966cc4L,0x00db88567efb0c4L,
41972         0x05e86a4949ffe46L,0x0b0776d6262e42cL,0x03890801377322cL,
41973         0x02cac30099cceadL,0x09791f3855a4214L,0x03f9bc0cc7c995fL } },
41974     /* 209 */
41975     { { 0x0374bdadfa6639aL,0x0a46a0155b9c8cdL,0x08d91c0c78b432fL,
41976         0x19a0b33a3eb8bdeL,0x00d38443b49ee2bL,0x09c9746942f5b07L,
41977         0x14e3f6efaa4bc9aL,0x0d1228abf7f7178L,0x0ae259ff1e469b7L,
41978         0x0e7658fa0ef2b41L,0x1bc1c6654b46bb0L,0x0303cf7ee88d90eL,
41979         0x06282ad2f11ce25L,0x15d277b3e5c9d6cL,0x01ea8fa3e8f34c5L,
41980         0x16c11f9cd1409caL,0x0d0ced74170a61bL,0x036f38b59fb5608L },
41981       { 0x0e58d04172d6dc5L,0x166f331cbe32e6aL,0x1860327ad3a2fb4L,
41982         0x10ebf45db6f5cefL,0x091e67385627546L,0x0e4597259819275L,
41983         0x0a21d808ea1588dL,0x16b3bedad8551f2L,0x0ec2c185ff6f5e8L,
41984         0x04970959d6aba45L,0x0ed3cb552bbef1eL,0x0891dd0d1042f5dL,
41985         0x11b1d9bd5b14915L,0x17f806fbd1362fbL,0x16c77bb97334598L,
41986         0x1eee9d7933e2f72L,0x1b0909836163fe1L,0x028fc84185d9e92L } },
41987     /* 210 */
41988     { { 0x1376fa1f2922461L,0x0d8e18b286868a4L,0x10cc376182376ecL,
41989         0x166d71320d25723L,0x1f5600523e612c4L,0x1512a2f0cbbd85eL,
41990         0x0f63be2bffdc18dL,0x1759b4fa4f022e4L,0x00b0bc4bb81bde7L,
41991         0x058405976952bc7L,0x0834345c6cb808fL,0x119f2837735cb7bL,
41992         0x1bc14a65c5f6df3L,0x00ceecc742eec0eL,0x081be4dfe6320b7L,
41993         0x17cf18c26e8fea4L,0x1e79e13a2c25f5bL,0x02f7690c70551a5L },
41994       { 0x156575401d4dc0bL,0x12f93fab35d83f0L,0x0faee088975686bL,
41995         0x182313d8d7d30bdL,0x0cce4d9d5f3ad21L,0x1b2dac8bed28c67L,
41996         0x1dc732128b4fb5aL,0x0f4ff3102eb1ff4L,0x150d6ae122ac69aL,
41997         0x1bf9858e3734236L,0x08e9816f42ec4f2L,0x1d9bae7e480f180L,
41998         0x0ce5f0a9969a10fL,0x1ec7ac034628ac6L,0x1691b8749afd856L,
41999         0x1a6115e65d50f22L,0x054eaf74e810287L,0x0460a5d03531321L } },
42000     /* 211 */
42001     { { 0x0877895b17ee201L,0x15238c472bd3b86L,0x1d8e5e08915b016L,
42002         0x019387743a3387cL,0x14389ebe0be6f8cL,0x13fddb7f42fa7fdL,
42003         0x1b1914e2f333833L,0x0850edd5654ca4cL,0x15c9ac690cf9a38L,
42004         0x1ae79d8e6647cc0L,0x1ef9aa73da1f7a7L,0x01f90706b82bf42L,
42005         0x1b150ef2ebfcfc1L,0x04252973043587eL,0x1347ae27e5fb366L,
42006         0x0077482dcdf4561L,0x05ee2bd15993eccL,0x0322e052ef55d8bL },
42007       { 0x14c420550aa7e31L,0x06f8617c28ed2ecL,0x0424f1c9b9aabb2L,
42008         0x0c4c337f3532c8dL,0x0253fbd572dbdc3L,0x184f030da130707L,
42009         0x1b16e5f0967ee31L,0x1d3f57ef9779bb5L,0x1b4d5e8b1e4b703L,
42010         0x18372b7039a77eeL,0x1293e47d57e2946L,0x11747eacb91a05aL,
42011         0x12816d1d947f860L,0x0e73d89b4117a3eL,0x1410908330d8559L,
42012         0x0cfedc8ddcbde63L,0x091b2a65f706835L,0x013f4ffa0697d36L } },
42013     /* 212 */
42014     { { 0x1251893d7e952e7L,0x182c1e39adf8c3aL,0x064a5bf8124456cL,
42015         0x1100da5f94e656bL,0x1b885ed92745185L,0x0faaf638d5bb500L,
42016         0x0ea72f73a765db6L,0x0567b4c164091e5L,0x16977c086592b13L,
42017         0x16e54e584c828ebL,0x0aac8f4622b896dL,0x1e7fc4155e7bb38L,
42018         0x0f5aad74d09f469L,0x1154f59dede8fbeL,0x1c04310f57bf970L,
42019         0x004c118bdbf4426L,0x176ada2217b5787L,0x027f772b39ed64bL },
42020       { 0x0e18d52b5d3d780L,0x0dae9838b33a218L,0x01b969d0855936bL,
42021         0x1d1ad7770c641a7L,0x0d263dd15d8c290L,0x0c231b4c0d21919L,
42022         0x0b2c4cf439f2a62L,0x1fea270f09b4a33L,0x0832e3fabdddc81L,
42023         0x013c2ca18ccd21dL,0x12af3cc9d0c58ffL,0x017ae9f29f4eb69L,
42024         0x1d5694a6279fa01L,0x05b2bd1261453a1L,0x1a897ab074aa223L,
42025         0x0c3fefdde4a07d0L,0x00eed11a5d304c5L,0x027f40c73ce4f6fL } },
42026     /* 213 */
42027     { { 0x0252c9d7fc1c7ffL,0x0a0cecfd44d6880L,0x09290193a732a6fL,
42028         0x1087285d9992742L,0x0749695b384cbcbL,0x08b2df802610fecL,
42029         0x04409a720767d08L,0x09bc464ac51bbc0L,0x1ec9374575a9b00L,
42030         0x199a35ffb6e7e10L,0x16992d34dcb1f7eL,0x15a7e40929c5589L,
42031         0x15e867c150cecb7L,0x015b91ec2b1620dL,0x194c8c4a64e573bL,
42032         0x0cb2f9235bf8afdL,0x1fce06f1161f10bL,0x040c8aa94dba69fL },
42033       { 0x0c124316ed9d4eeL,0x1d0aa344d7f80c7L,0x127caa268fd0f7fL,
42034         0x05a8cfdf6495746L,0x039102e22db1e8eL,0x1784158c6f51aa0L,
42035         0x1751d08aae14f94L,0x1dce2614583da6dL,0x1ca60e86d0295d1L,
42036         0x15634043e3fad69L,0x0f3b3f7a1919639L,0x18428c3a24ca1f0L,
42037         0x10bd38509972e66L,0x13319144ff77a0aL,0x0b71e543c60fceaL,
42038         0x0ee044ea8a97cf2L,0x0f32744c11b1136L,0x03e835e63f47537L } },
42039     /* 214 */
42040     { { 0x12859427090212fL,0x1bea62a90f42244L,0x108af8b6ee49a46L,
42041         0x1b7b03f10098070L,0x0c89bc36317721eL,0x078026e09b65f75L,
42042         0x02ae13dc6d82deeL,0x09a4d2265a09c43L,0x1b0e2496ee6cc81L,
42043         0x196718bbafd6e0aL,0x0f02119b488f142L,0x154c98c25f1705cL,
42044         0x0ba4b653559721cL,0x03e9ece8acd3a8fL,0x0350918d0ceab57L,
42045         0x079543cc373a5d0L,0x192149f655ffc67L,0x0245a95cce87ce5L },
42046       { 0x1915399efdc05beL,0x06d8c09f04af4d1L,0x0ba7376cff6b79cL,
42047         0x04340128a288f0cL,0x03920ea3a2b0316L,0x1dc7f5a593cc061L,
42048         0x05b52b14e53c688L,0x1342c7ee4ac7cacL,0x0aa0ff93fb71421L,
42049         0x137cb6949eb123aL,0x04baa1f73f89db4L,0x1e5e8e071a2bba4L,
42050         0x05f418168eab27bL,0x19954c4d72c6419L,0x127c4ef8dc1088aL,
42051         0x1095b46d287217fL,0x0ecf16e26060d06L,0x00be06f43cec63bL } },
42052     /* 215 */
42053     { { 0x0a5f453dcc01958L,0x02caa0e7441c9deL,0x0285587d6db5f65L,
42054         0x0cfc5a6d78bcc6aL,0x05ac3a6c291c3c8L,0x000366fb63f6c25L,
42055         0x1b0ede44f102f66L,0x153ef17610eace3L,0x11c928f6eb43e89L,
42056         0x0f946f9d70f50f6L,0x0e96c6e492cad7fL,0x0e0a3422dc0ac57L,
42057         0x17167ed3e3491d2L,0x0de058230476015L,0x175fd678a473dedL,
42058         0x1336e61ca02d318L,0x1d70c7c350df5c7L,0x034315cf1056370L },
42059       { 0x0c6f4e79ffa1f64L,0x1548d50f121a4abL,0x183336dd48cbfb5L,
42060         0x0e0645ac0fd341dL,0x062fef87bfc90b3L,0x1fe79a14a405692L,
42061         0x18e3ff08525a70aL,0x138dca423c14a73L,0x02a59ec2612a514L,
42062         0x0aff1096b835a99L,0x1ec423a67210a46L,0x1d46bb900905eefL,
42063         0x0bbd92d29874ceaL,0x15750af752d3018L,0x01c4272b50b7296L,
42064         0x1ec93ad58778e93L,0x06cc64e1c40290aL,0x02849fd16a8fc6fL } },
42065     /* 216 */
42066     { { 0x0cf32804c2d553bL,0x15f111dcb3614e2L,0x12708a5a452b706L,
42067         0x0b3332ed92aad4aL,0x176e83f3d8c9f8bL,0x02f62be1162bdebL,
42068         0x187d53ca50aadf2L,0x091de680fcadc58L,0x1f005e8caf213dbL,
42069         0x186429ef9934c63L,0x12235f2b02952d1L,0x17dac16ea03dcdeL,
42070         0x06714a4bd9b6bd6L,0x1704c44a7808188L,0x1e4a8014a16f0edL,
42071         0x1e495d80ce835ebL,0x03832f16426ef7eL,0x0097ce226b63bd2L },
42072       { 0x151e96483313a1cL,0x0e9ed19e2c59b8cL,0x1d4b1eb1011263bL,
42073         0x0e1b96bdd09db77L,0x0dd422f8866ca6fL,0x10f6177605747abL,
42074         0x148f041def15019L,0x07cda732275a844L,0x1d105e1e858e7cbL,
42075         0x1e49cbfe4bcdda2L,0x0752a4265ed6491L,0x1147d12a5fce644L,
42076         0x074e9462410ef62L,0x0cbc07a06846ac1L,0x18443b1932fb43dL,
42077         0x1634627af844e11L,0x118d186d8667679L,0x0017baf2713570eL } },
42078     /* 217 */
42079     { { 0x1637ebf47f307d7L,0x02535680a0a3b8dL,0x1594b816a031ad9L,
42080         0x07fda0f66305467L,0x1696e597c8f1a0fL,0x1fe00f604f73fc9L,
42081         0x1cee736a9fb0f1fL,0x112a93f11fdf1e6L,0x1c88d1961c3bb89L,
42082         0x09527f4efe553dbL,0x1e7b88eb92ac836L,0x0c83ebd9634a25fL,
42083         0x1fe32fb47df5aeaL,0x12e842e073b491bL,0x11d568a5a971080L,
42084         0x12e47b9224ab04dL,0x141580b985f9bceL,0x03958dab331cb0cL },
42085       { 0x1708a08790e5558L,0x1b0208344d7c04eL,0x0e2908c4ed7e614L,
42086         0x04ab493a35d0bcfL,0x0c371b0be6ba129L,0x07370caf3b62585L,
42087         0x0688561413ce64eL,0x19d1ba82844c15dL,0x1d8b04e9b968485L,
42088         0x0a625d2c43f7f21L,0x1a399fc47179cfeL,0x1c519ed73388224L,
42089         0x087a0a966292623L,0x06501769f968555L,0x18ed546c999dca9L,
42090         0x16b6ad1dd1c9c5aL,0x1adcdebb2992e78L,0x02ef8c90b70b912L } },
42091     /* 218 */
42092     { { 0x0027e1e8df2e7e3L,0x1e6346c6d03ef10L,0x09a52d2b9a52c60L,
42093         0x1e794c5d119c6b7L,0x12efed2c896d97dL,0x1e84279ef2389daL,
42094         0x048ef401b10389aL,0x1603d36e377f903L,0x09991c7b61aacc6L,
42095         0x08649b247b2b420L,0x1587461fd1d4919L,0x16237ffa7944270L,
42096         0x0ffa191418610f2L,0x0aaf2984cb48afdL,0x01cb5e63c48db7aL,
42097         0x14916c2797dd543L,0x0327f7b44ea66a2L,0x0229132e170544eL },
42098       { 0x0d5ec7925430010L,0x1c37ff5e8486025L,0x13fc82a74fd72b1L,
42099         0x0547db8cbf4bf3eL,0x0cf3eb11fcbf411L,0x12db80441241ce0L,
42100         0x02ae2e375b53a2aL,0x01dc44e3bfb6eadL,0x0e43ec373b74456L,
42101         0x0757c930e7ba94bL,0x06b838fea5b66deL,0x1a5bb84bbfaa301L,
42102         0x146bab77110b312L,0x1af678f235c7bc5L,0x07fb2a81a7bf236L,
42103         0x17bc3832a575cc1L,0x15543e302ed5f4dL,0x00a5815fc8f03c2L } },
42104     /* 219 */
42105     { { 0x071c768b87e5b57L,0x03c7bfa98d2ab96L,0x1e2fdd65f7202f3L,
42106         0x1a273c2ebe9ff27L,0x0b94ca6cb28e026L,0x1cfbfe35c1db93eL,
42107         0x145c0babf8ec801L,0x0d85594a9bd9e77L,0x017c4133c6af0dcL,
42108         0x150f332e67af1afL,0x046920d154171afL,0x17a1cc2017134cdL,
42109         0x06c17d03882633aL,0x0d067c864b36338L,0x0b75931ebbffef8L,
42110         0x1548c9b08f7cfa1L,0x0a5d49bcdfbaea2L,0x042f03f3a1663e8L },
42111       { 0x1aae0a60bc25bcaL,0x12af8f227b27611L,0x1b62d81eddcdba3L,
42112         0x0da600b213c3cd2L,0x0cbc4990aa90a74L,0x0717ae83958e669L,
42113         0x03b24343f9b1b1aL,0x183241d8be0a7c5L,0x179b21fb4f0040cL,
42114         0x19bade9fe625163L,0x177be786eb1f769L,0x1af26b81f1a7ebeL,
42115         0x102cacd318dc315L,0x14937b8e388be0bL,0x00bce69bca08f13L,
42116         0x1264671b6b177daL,0x030e5b492317db6L,0x004b201cfc6a4faL } },
42117     /* 220 */
42118     { { 0x1774f1656999ebaL,0x17143d8ef318290L,0x1c9b782c99a4f63L,
42119         0x127f128543b035eL,0x0a03e13c3744693L,0x1139e7de7b5b0afL,
42120         0x1715b4c3030d653L,0x1449fa674ad8ce4L,0x1a57534ada8be97L,
42121         0x0c921533e115128L,0x06f6d674317125eL,0x0d998d484ed09caL,
42122         0x0cd426bf59d7cd7L,0x1374df5948a04bdL,0x05b8fa5650128b1L,
42123         0x0cda08e71fd30b9L,0x056bcbb3e0eaad6L,0x0313587e931de2fL },
42124       { 0x1217dbae1a1ec42L,0x173edd5ad662823L,0x0c7a194cc746a9aL,
42125         0x007a6024df6fc35L,0x1ee61851b845307L,0x144aa2140324f06L,
42126         0x1d8ca201bd28fa9L,0x09e977c875b96adL,0x0036b9bdabcaff9L,
42127         0x0ca0f32de831bdfL,0x1e7511a1bceaec3L,0x025955ad5fad042L,
42128         0x1eff7e153414869L,0x15c37ecb4d1dc48L,0x1e4a30e23109b3bL,
42129         0x13c016adcd50222L,0x0c1933e71359639L,0x004ddeeecd0bdb5L } },
42130     /* 221 */
42131     { { 0x1e39c1de4fd3673L,0x06ce8d32e4703baL,0x0771ca271ffbe20L,
42132         0x1c6a53a4008e4b8L,0x1c747af35b6735eL,0x177efae0fc79769L,
42133         0x070e573ce663e44L,0x0bbdae44c30930bL,0x123793a2f0e6979L,
42134         0x1355c6b4358e953L,0x0057788aa20b922L,0x0df9f3b71afc019L,
42135         0x1202267547be77dL,0x04e0876e04437d9L,0x00fb532d89a1f51L,
42136         0x0cdd53e387c2ef9L,0x124e6d5d7f05af3L,0x0175500dc68f7d6L },
42137       { 0x047fb701f357c74L,0x02e2554f1dbca2fL,0x1ccdba16a4164c2L,
42138         0x1f7c0489929e130L,0x03b5660df53808fL,0x1caf6b48eeefc9dL,
42139         0x083522dd8ddefceL,0x1e72372236f7672L,0x07ccf08bf86a13cL,
42140         0x1f6c7cbf500c72cL,0x090d0de31546514L,0x1bd3c1a5ab4d63dL,
42141         0x0f9b96259a8e6adL,0x1778beeefe15924L,0x1fe72165baf3abbL,
42142         0x17751ed296886aaL,0x06b48cd150f07d5L,0x001698ef4da60ccL } },
42143     /* 222 */
42144     { { 0x0bb9e1ede79499dL,0x147fc7e87e156d3L,0x03a069f64d5bdb2L,
42145         0x1fd1e0c64f7d81fL,0x1b300bebbc3d1c9L,0x1e0c0dc02e390b9L,
42146         0x074040108282104L,0x1ad3d342cfde195L,0x0076c909d1aeeddL,
42147         0x050ccbfc71d4539L,0x1fde9e9ded0a799L,0x17e8b929a7d279cL,
42148         0x07e6d48407aac0fL,0x148c90f3f9bb4a5L,0x076ef5bd599e78aL,
42149         0x1f533e47fc1e7dcL,0x165c7917566cbf9L,0x04b2c3079707a6bL },
42150       { 0x134702b7fa5f79cL,0x1ea132d796936f3L,0x0e61b1cf833a4c2L,
42151         0x1a9dc8945a8b7b1L,0x156c8a1a7dbe7beL,0x06fc076094f0124L,
42152         0x0966dbf7016b1dfL,0x15ee14d7456b139L,0x0fc484021999825L,
42153         0x09425aa3d11f85bL,0x084290a282a2bc7L,0x16625655edb163bL,
42154         0x1a33935ee3b1eb1L,0x077fd3767828a21L,0x1899531e81fac9aL,
42155         0x1dc982ddc810dacL,0x0527a7bc5014549L,0x0328408190fd4c5L } },
42156     /* 223 */
42157     { { 0x1f0e460b67ed9b2L,0x107e861b6c9e924L,0x0fa6231d7870336L,
42158         0x06c297819376b2cL,0x1a768605757bbe9L,0x16e2a24d4dc400cL,
42159         0x16616a2df8abd23L,0x0993cefdb3d6a34L,0x0dd025274ebbf02L,
42160         0x0c5b1440aa2e31bL,0x16bb4120036e816L,0x027303c54474737L,
42161         0x1c550cb4f27fc20L,0x1a903463ee337eaL,0x1a7e856b49c0cbeL,
42162         0x151459341795d02L,0x12f60606f213a7cL,0x04c14a8234c3132L },
42163       { 0x03746002e11c128L,0x1d72e8736e53f1fL,0x1b8b65548992037L,
42164         0x051016e287c8802L,0x126b881cf65f88fL,0x1c357f651e946a2L,
42165         0x1e563e71677477eL,0x09ea910c18498e9L,0x0d06ea43c9cb69fL,
42166         0x1a1e4d7399a7676L,0x0b3358d4ca5c4d4L,0x0806be74d818b98L,
42167         0x0cb372653ba95ffL,0x1128291e9700d0eL,0x089fac8c5443f7eL,
42168         0x19a21ddca71c54cL,0x14beadfc8a0ca23L,0x025bf370d9f3c7aL } },
42169     /* 224 */
42170     { { 0x1c9076fdb5f928bL,0x085db5b9a3e763cL,0x1e62b003b107989L,
42171         0x153b2c338ea96ceL,0x19e4343f900d20bL,0x0c9aebf6a160682L,
42172         0x00738f7ce7a1514L,0x1584c722304c9eeL,0x0ce8f2554e1f87aL,
42173         0x0eeb3c4b2fc8d55L,0x1458fe8c914e7ffL,0x1e589759d32b2d9L,
42174         0x0aa94f9ea55c815L,0x1792722aebc6461L,0x17709a9eacabfd3L,
42175         0x05045e1dac81239L,0x058954a420b00caL,0x00308e262e994bbL },
42176       { 0x192001ca9e81829L,0x199900451416678L,0x17863e77b66f7b4L,
42177         0x1b6f11200617fafL,0x1577a5dd6793ac0L,0x169e15dd806c8e9L,
42178         0x0405385e88e9e00L,0x00fff2bf119f6a9L,0x17cd1bf4bc71b6eL,
42179         0x11d925011ac4645L,0x0cd6e2904481d8bL,0x00bd880ada6136aL,
42180         0x0ce916a1b52481cL,0x0280bcfa2ae3a08L,0x1344822ef80c9c6L,
42181         0x1fca02bcd82ef67L,0x166509a24c090cbL,0x04103ca948e0842L } },
42182     /* 225 */
42183     { { 0x12d3cff1c7d353eL,0x1f666bef0671daeL,0x1d7db2a1d8d7579L,
42184         0x004bf35a7d69620L,0x005cb5aeda8404eL,0x1910d0b5cb1f449L,
42185         0x0b292797b836027L,0x069ac990bb3d483L,0x06a46c4e934442aL,
42186         0x037fcbf1e7b2ad2L,0x19707b9505f5f2bL,0x1353dd7f3898ecaL,
42187         0x1988da638868100L,0x1b5a39634adb0e9L,0x1fc45c5900ad1abL,
42188         0x00bc63fbca2ca16L,0x0a794f8f273be0cL,0x03a43d81b5441a2L },
42189       { 0x060e5759c3e2370L,0x0c0c9fc02438cd4L,0x1cf29b8be6a8675L,
42190         0x12c288e336741b7L,0x1effec21b6c7e95L,0x08675fd4824e3a6L,
42191         0x178562e8192c8fdL,0x1e5625045809343L,0x0b654b7d9b1d527L,
42192         0x03842ce87fe8218L,0x1d299d3c1511af1L,0x0a37475bb32a6f8L,
42193         0x0be33533b5e5532L,0x13f20ce7251f6b6L,0x146e5e4bcbd1340L,
42194         0x14d3e5b09dd054bL,0x1ddcc76b123db6fL,0x041a7c2e290fd1dL } },
42195     /* 226 */
42196     { { 0x09347c12ce9b31aL,0x029157f1fd9db99L,0x0d354bfe43f4762L,
42197         0x0c5634103a979dfL,0x0a411f0853b1738L,0x0db01d29c608dd1L,
42198         0x15d05e256e4f050L,0x10c532773556217L,0x1ccbbd046099129L,
42199         0x14fd7d8775055d2L,0x111888d598625d9L,0x11386cfff4a9a90L,
42200         0x1d1c3478da4a63bL,0x15301a7be5d6ae8L,0x06c4e4714ce489eL,
42201         0x1ea2a1cdae0bfccL,0x14cdd14b660f74fL,0x031cec58529995aL },
42202       { 0x0423162162217cdL,0x12515408e14737dL,0x186085d9b700b83L,
42203         0x1208d40dded1b39L,0x1de921015126373L,0x014c69a2775118eL,
42204         0x15fa4181f23c845L,0x1c24fe4e574c7b2L,0x1e7ce80cca5e8caL,
42205         0x00b75f1127bd31fL,0x13969e259cf8d16L,0x1444a6d757a89bdL,
42206         0x0ee3bf77af13756L,0x15e7cc5e3226b0dL,0x1ea58b182cafdb8L,
42207         0x000467616b3e653L,0x02cb0769a1aabb5L,0x02048189b063aa0L } },
42208     /* 227 */
42209     { { 0x0d2873a1670433fL,0x0a6fb12a49efe42L,0x066a03f3e27b24eL,
42210         0x01b652ec2dd60b4L,0x19e63046e39e431L,0x14e54f283a16e4eL,
42211         0x07437cc6b632077L,0x1a30d557f29f6f6L,0x036cda27a1b3c82L,
42212         0x18d177a1cb816c2L,0x0ff77118204a67eL,0x091ba472c470501L,
42213         0x137b3c9353e4b2bL,0x097dc53496d9617L,0x06011d356d6cc5cL,
42214         0x04af1f370f47610L,0x1c8d85909861e95L,0x040334776f9bd15L },
42215       { 0x0edcd35b39a0249L,0x1866a597c575771L,0x1791c88f7c16bc8L,
42216         0x15c1d26fe852b62L,0x0cbc9162bb66982L,0x04ee5080ce95b94L,
42217         0x01ed17144aba73dL,0x1d22369234ec61eL,0x148d4f34ca03874L,
42218         0x0fe87532265ba19L,0x1e6b87e56cc30f0L,0x1a9bdb16c15827eL,
42219         0x1f61ead81c40362L,0x04c61e944f418a7L,0x1485c0bb5803751L,
42220         0x03e66bf96383384L,0x0e9592329fc3a9cL,0x00233baa40def36L } },
42221     /* 228 */
42222     { { 0x03de56e39233c96L,0x0204e4039bf57f7L,0x06f4806af1a21a3L,
42223         0x165690c40b595c2L,0x0f19056c0f2cea9L,0x0e1520f191c3f0bL,
42224         0x0fa1ba9d4d96a97L,0x09aed8535982569L,0x0a01fcab78d6329L,
42225         0x0edf4458655cf92L,0x11b96fd05301520L,0x1127972d6f54eccL,
42226         0x117664e097fe111L,0x09fe7ad4db24fadL,0x1ffd8d2865908b9L,
42227         0x1312ab2f1937a16L,0x056b5feb38e3c22L,0x001c524fd8419e2L },
42228       { 0x1e3818c13e93257L,0x15e4ed3093a0d9aL,0x0925f2ab01ac533L,
42229         0x067b54222c9edd2L,0x0de2034a82278e3L,0x0dd31873e62b2f2L,
42230         0x1bef6edf7257c28L,0x1ad03bb3e46cd2aL,0x1c63e6319bb132dL,
42231         0x11158117e12099bL,0x12064dfa2fac71bL,0x129bb1927158470L,
42232         0x0aa6bb564483b19L,0x037c8c03daa67d6L,0x1e367cc69f35138L,
42233         0x151cc3ba8737751L,0x060660c2a787f74L,0x025dbb711090dabL } },
42234     /* 229 */
42235     { { 0x0151e8ae6354817L,0x04a75781c5a1c3dL,0x1a2216562618cf5L,
42236         0x0e3b975824990d8L,0x00edad067215382L,0x0072eb7a43d7c66L,
42237         0x1fd56b4cc147f94L,0x1aa14e23637adc8L,0x0a68709a78c746aL,
42238         0x1f8b931320179afL,0x023bebecc304c09L,0x008380d8e92f8daL,
42239         0x0edcc3e2da9ef1cL,0x04970839e863a76L,0x084add0c317e5b8L,
42240         0x1d6041e27279e55L,0x18b245840162107L,0x04421e92fbdbb7cL },
42241       { 0x01501dcedb2a83eL,0x147d815dc6b9227L,0x196764977d8af3fL,
42242         0x1e8556df8612040L,0x00f09dfd3c715dcL,0x0c857539e0282adL,
42243         0x1d278499d17638dL,0x0c6a705e9b0edfeL,0x0fc69feefa920c6L,
42244         0x10b0108cfeb88e5L,0x070ef641d713577L,0x17a27bdad7e4843L,
42245         0x0b6263a1163800cL,0x1e93261bc63f507L,0x1672630d6f5e561L,
42246         0x0e76aadc45c8ae2L,0x14971bf2a2dfa73L,0x00281fc9cc49ae4L } },
42247     /* 230 */
42248     { { 0x1addc6671dad4f6L,0x124448125f50db2L,0x038bd8174f748e3L,
42249         0x1d61b2d713f6ed9L,0x0601b2cb13d5f5dL,0x11e92a705add1abL,
42250         0x03a9f8df524760fL,0x175d10c08464819L,0x1374182f3e91c99L,
42251         0x161657cd43d6c8cL,0x0c102bd5d3ca549L,0x1da328800146962L,
42252         0x1e06df42e75b9bcL,0x05e8844ea6662bdL,0x16ed4008ba3b141L,
42253         0x1d5b618a62ef5bbL,0x0f9690d31d29ecfL,0x039abbc7f0bb334L },
42254       { 0x186ee3e843c1137L,0x0217d1f85b9e687L,0x1e762ac838e8f07L,
42255         0x082c485f5c1ceacL,0x19b092e46f95f1fL,0x11b5603dc4708e1L,
42256         0x00b9858a500f930L,0x064cc20be825b58L,0x174dc28a7862e06L,
42257         0x08c7fd979d91e46L,0x0905f01d17fefc8L,0x1408980ae23c230L,
42258         0x14cefbe4de49b55L,0x0bdfb88396332dbL,0x13c19d873130076L,
42259         0x1a1f165940db58aL,0x0a1fc599daa7450L,0x029731bd30d18c1L } },
42260     /* 231 */
42261     { { 0x01700f16bebc6dbL,0x1a2edfca81ec924L,0x14f17454e46529aL,
42262         0x0bcb5a55798e2b9L,0x0b7b466f942a1c0L,0x09c8c59b541219dL,
42263         0x19b3ae904efb6e8L,0x194d314ac4921e9L,0x1bb720da6f3f1f3L,
42264         0x08b6a0eb1a38d59L,0x14889cc0f4d8248L,0x18008c774d3dc01L,
42265         0x0d62845fd17fd4cL,0x0056e4e3d6304f2L,0x1ebef298d80ecb2L,
42266         0x129577e2df9348bL,0x09841007f7fc4bcL,0x03e48b5a7d3a58bL },
42267       { 0x1026f9178bac2d4L,0x1404c1300d43ae0L,0x1db801cf590228bL,
42268         0x09f983f7115a5e4L,0x0a6b291f443610cL,0x16307e2b93dc116L,
42269         0x1522c19154cb223L,0x006a3c91133db35L,0x1841b48b5f543f1L,
42270         0x16658df6ac8e775L,0x0b7c3e773d6a2e9L,0x0041668fbb69f89L,
42271         0x02cb44c5213a7caL,0x0293e062550d666L,0x08f3d41dceda0a0L,
42272         0x1924d546e9820e0L,0x07c733d10006b74L,0x00ff9c8b7bbd468L } },
42273     /* 232 */
42274     { { 0x0218fe4f997939dL,0x0fdddbc8ac1d9d5L,0x176a1fdd582cf53L,
42275         0x02bb525931674f6L,0x06666f4aa9c0280L,0x074eebf0f5a556aL,
42276         0x0c1d8bac5e94453L,0x0dde8d4cd49df1eL,0x1900b45c6810e54L,
42277         0x1d7912c25d7826eL,0x0721c9721350bfdL,0x044b1c9907bc798L,
42278         0x01170d88b23093fL,0x1603b722317d6f2L,0x174506f86584b92L,
42279         0x069b5e91ae68c65L,0x0c9c1b1f759925eL,0x00cf68d2b0395c8L },
42280       { 0x0f7fcde6c735473L,0x04733b001de1f4eL,0x12f3ec666ee2aaeL,
42281         0x033599997a2430fL,0x10f65459bb73044L,0x09314110a57f9e5L,
42282         0x082e1abb2068dbeL,0x121550596653f3aL,0x182f3f90f5773ccL,
42283         0x17b0735fb112bf0L,0x0d12fef51d8b7d2L,0x0253b72e0ea7e31L,
42284         0x097c22c18e3948bL,0x0bdf4bd6e374907L,0x0d8dfe4e4f58821L,
42285         0x1a3abd1ae70588dL,0x199f6625ccbf1feL,0x03798f07cb4340aL } },
42286     /* 233 */
42287     { { 0x05afe5582b8f204L,0x020db69ac5aa562L,0x1efeb357d7b6b01L,
42288         0x1627379b26e427cL,0x16dbcbb01914c70L,0x09ae90b8a5a2c0cL,
42289         0x07c83a4a5f4d47bL,0x00b1ec8106ed47cL,0x1150a8a9d2f3cd7L,
42290         0x19b7400ee6ecfb6L,0x13ad9573d5b60beL,0x00192554b442b4aL,
42291         0x023b089f0376105L,0x0215b3746886857L,0x1ba3521246c81e7L,
42292         0x0de8a95e35c7a1dL,0x1e6137e4c284155L,0x043af198431ec53L },
42293       { 0x080fddcaf6c0accL,0x08f335d8f3e046eL,0x0b860a1616b756bL,
42294         0x004eb8fb4db8e2fL,0x126b9e15bdc5434L,0x02fd287a5a64296L,
42295         0x12cc97c287efda8L,0x03b8df03c8f02f7L,0x02cbd432870ff2eL,
42296         0x112480b33e3fbfeL,0x16b2ded6169b122L,0x15a88ccd80afa08L,
42297         0x0fe6d7d63d2e972L,0x0713a0a263a6c3eL,0x09612bbdc19f61cL,
42298         0x1fbd765942af516L,0x009495c5bfb75f0L,0x02d5d82c0f9c370L } },
42299     /* 234 */
42300     { { 0x1e62d2bf0c97f57L,0x02438cb179463c5L,0x119d1ed42aec3f8L,
42301         0x0689f413db8a914L,0x0b05a96ef6b26e0L,0x1357417ea26371dL,
42302         0x02677b6c00cb1c3L,0x184517a8057afc9L,0x043f2e9639b7c11L,
42303         0x161fe0767489b8bL,0x0e2f240bf43e303L,0x0754f9578758ed3L,
42304         0x1206924cc99d9cbL,0x0130480a7445444L,0x0b9e782945186a9L,
42305         0x07d018fe955172cL,0x0bc4ef0210a8b1bL,0x0382a23400dff72L },
42306       { 0x0b3d713121901c1L,0x11313ff56aa557dL,0x0a16f022e88fa42L,
42307         0x0a6dd844fcc9edaL,0x06c191ab8d99301L,0x04e7164cd0b55c8L,
42308         0x0ea021ac73d6fd9L,0x1e0b240ceb2cd7cL,0x018836279ccba2cL,
42309         0x00abdc3f7fa9a43L,0x1262592c88ebc8bL,0x09e0155cf4af7f5L,
42310         0x0063218a80cd0fdL,0x0fc478a76d6edcaL,0x07b67f4e112ede7L,
42311         0x0a06d8367c7a96eL,0x06b6c634a13d620L,0x037ab5767dc3405L } },
42312     /* 235 */
42313     { { 0x01dc803d9205c5dL,0x0afbeb3891c94d8L,0x1ff6766d9595a25L,
42314         0x1da76359fc7bd77L,0x0094eeffb844395L,0x0c8ff582194590bL,
42315         0x141d598c7fea08aL,0x00a1bbccdcc321bL,0x175b03c55e8577cL,
42316         0x048e72fc8b91203L,0x0229023aece8fdbL,0x1f140b14272d345L,
42317         0x179a6e06761d376L,0x1db8e94479d2ca2L,0x130c30040c0a715L,
42318         0x017381087e85168L,0x0add8e6aff8730eL,0x03db5f408a76b22L },
42319       { 0x0c38e4a3d3aa54eL,0x19ca1ec1ea84d1fL,0x188490e55788408L,
42320         0x0fea3a7a89f0954L,0x1eca4e372910471L,0x1d2aef316922163L,
42321         0x086d6316948f617L,0x0d18deb99b50a3bL,0x0044bcaa8200014L,
42322         0x1a80f34700b8170L,0x064d679a82b3b3dL,0x0d5b581de165e10L,
42323         0x08fd964f0133ddaL,0x0985c86c4bd776eL,0x1048bad236b3439L,
42324         0x143bc98bf5adf70L,0x0742284ec1ed700L,0x0437cd41aede52aL } },
42325     /* 236 */
42326     { { 0x01d9055450cc69fL,0x18a5e64f6fcc787L,0x19dfb9fae80543aL,
42327         0x0f331f1ca637729L,0x1b16eef05f7a673L,0x0e2f0aac41c2718L,
42328         0x14aaaee4a1c8f61L,0x0e9fca3c68b97b2L,0x0c5d0ee287e2416L,
42329         0x0e0a3778800c178L,0x0e7a4b9fd6f8b3fL,0x075f6cad7a7c1eeL,
42330         0x1e5168e289501abL,0x1c77082558aa96eL,0x0c111d65037f8c6L,
42331         0x1522685246c0788L,0x1869306f114c460L,0x02dfd4fd781da8fL },
42332       { 0x023f52c107b258eL,0x1415deb31a0ee15L,0x1b6208f3fc6a627L,
42333         0x08e336923ea9479L,0x0433dfb8f45b779L,0x09287744c6110c1L,
42334         0x1d9543e77647312L,0x08aa185455c9f42L,0x1f7aa1ce42c327fL,
42335         0x1d0ad6b2c1d8f20L,0x03569686feb6784L,0x14511c3f7b9b354L,
42336         0x16915f7f879b1caL,0x03f40d0f57c941dL,0x0034a5b04393832L,
42337         0x0b7b009fb94ac21L,0x0da6acc96161275L,0x00d8933554147f7L } },
42338     /* 237 */
42339     { { 0x0bc0a00774ee49cL,0x1b42965b11beba7L,0x12b177e4e28dddbL,
42340         0x116df7f77bf80a8L,0x145f2eaec3388ecL,0x16749bc25645e6bL,
42341         0x1e84ea7159826c7L,0x0e2cadf6d58fbd1L,0x15f8ded74a532b8L,
42342         0x186a145d5444f84L,0x09fca042debb0aaL,0x1c3dfdd96698876L,
42343         0x0b9e89c2db26426L,0x1c90884822218dbL,0x1604162ab12f174L,
42344         0x1ec1d24dee6d09fL,0x023452fa691471eL,0x019a8bfed90c6bdL },
42345       { 0x1c33f46593c4a36L,0x0eb8c1b58d4f754L,0x107509defbb2b1aL,
42346         0x1cfc9e2f38ab441L,0x146d88a23e8ca24L,0x03817c2b9b99b4eL,
42347         0x155d1c73ac731ccL,0x18516309b2e6bddL,0x17f4517a20704ceL,
42348         0x1894e8c6b831529L,0x115c6ec75df871fL,0x061306a1b1640f4L,
42349         0x1f61fab8ef774acL,0x1aeec00d93d948cL,0x0d1647e9f13304eL,
42350         0x12567cfcc4ab628L,0x149349937b85a35L,0x018fd631e9863baL } },
42351     /* 238 */
42352     { { 0x0e8cf1b04913fb6L,0x009a80bb4d35997L,0x0dc5e0f987c1f90L,
42353         0x13c4fe5ffcf21d7L,0x0daf89bf1e5107fL,0x06f3468925d33ffL,
42354         0x0afb86248038796L,0x1552c4e6546dbebL,0x072cc37cfacbeb4L,
42355         0x062fd4b749e2d3bL,0x08c5f3798ce4eecL,0x1ccf06165ad8985L,
42356         0x041be5b96a97f65L,0x19867336a57e1a8L,0x103613c2fd02981L,
42357         0x0d6112d4374f326L,0x1f53ee182540762L,0x000ed9aedbd5865L },
42358       { 0x00fbc2dac0efee2L,0x175e6eb8edda2b7L,0x18f866da6afa101L,
42359         0x026fc03045ce57bL,0x11458b4c49cb7e6L,0x1e2eb1e5dc600e0L,
42360         0x19dd9082d211da1L,0x030308fbf428a98L,0x0bede911dd1839dL,
42361         0x1cee4e493c6f823L,0x0f58ae2068cdb06L,0x10f327cef5b8529L,
42362         0x0543ce3ba77f096L,0x1bb2777e3d64833L,0x111973c521a57f5L,
42363         0x19b63c1841e1735L,0x01d636e8d28a6e2L,0x03db5d4c66baa9aL } },
42364     /* 239 */
42365     { { 0x11d9e03c1881ab4L,0x12eaad98b464465L,0x151ca08d9338670L,
42366         0x01e2c35449505a7L,0x01ebb2c99599439L,0x163d3abc1c5e007L,
42367         0x0882a3f577f32f7L,0x0909ba407849feeL,0x15ec173b30efeffL,
42368         0x0f8e9598b21459aL,0x0f679415ba04fe6L,0x0575816633e380dL,
42369         0x04fd223b1592917L,0x0c6848f6b57071cL,0x151923af404167aL,
42370         0x1cf30d662d1c94cL,0x1082211447f3375L,0x023f4080cb8f5a2L },
42371       { 0x045d45abc8c290dL,0x089aac087d99d38L,0x02491beefcbe8cfL,
42372         0x1670b8f9b2575e0L,0x0161985cacff3f1L,0x0443a462d8a8767L,
42373         0x173231bb829fcaaL,0x0873b11191cbd11L,0x04dd735f2ccb864L,
42374         0x00f09db9e207b79L,0x0897ffcffb5a473L,0x162e4afdcb8ff87L,
42375         0x13f32db1354cb43L,0x016ff969d532a7cL,0x1298e5113d63428L,
42376         0x0cd2ef1c7e31151L,0x07b39646ccef3e8L,0x03c2d8c81706e74L } },
42377     /* 240 */
42378     { { 0x0ce2361a92f9a20L,0x0e543ceb22a077eL,0x0a1474035f16defL,
42379         0x185d2f924da8e73L,0x18da6a8b067ac8dL,0x028db495751fff3L,
42380         0x05069a0a2fd518fL,0x020ede388f2e2aaL,0x0f4bcbef63977d8L,
42381         0x0de24a4aa0de73dL,0x1d019b45c10695dL,0x0b7b0eeabd5fc03L,
42382         0x1d59e7ae80d282dL,0x1c1559b7b71083eL,0x14758d2a95b8598L,
42383         0x1b088cbdd1ded73L,0x02799a2160ace4eL,0x032abe1b3dbb896L },
42384       { 0x01b0268d75b6e52L,0x09b2008c68744abL,0x0cc1a8bac6bac20L,
42385         0x0cda1211299fea6L,0x15fc1d484e46222L,0x118316dd9a8913dL,
42386         0x0b7164d97a81d5eL,0x10e995946f7acdcL,0x1220d7d23b90958L,
42387         0x007e9c9c62239dfL,0x1cdc299e1f693e7L,0x1799a0afe9715bfL,
42388         0x0c1173f33aef0aeL,0x092d135a102f3a2L,0x0beeff6e347c296L,
42389         0x1a509526c9e92e4L,0x0b4c891ae778227L,0x00ae20682507045L } },
42390     /* 241 */
42391     { { 0x1af169a2a0e18d1L,0x0e00ba60193e14dL,0x08fdef098b3a65cL,
42392         0x1b031fe6f3b0346L,0x0cd3c3302099db8L,0x0d02a9b31fb31eaL,
42393         0x091c3bd4c970c04L,0x0e139ae17b9f301L,0x1e64452d11c9ed0L,
42394         0x1dfa1fa5633b709L,0x1b029aba170a96bL,0x0aa08e0921892f7L,
42395         0x07491e6ba92faaeL,0x157d4c8a055cbd4L,0x1c9955d0157d4deL,
42396         0x1ad7ff92b5b766cL,0x037646343b9d119L,0x03c474a504e9a0fL },
42397       { 0x13a6fe59c53461aL,0x044bf0471db7682L,0x0bcc1da364e5d7bL,
42398         0x0d98427a9f51ebaL,0x05b0147c9bd6bffL,0x1dc0b4ac863da08L,
42399         0x1e3a4828d8a2df1L,0x11f8cd410dcb79cL,0x13dd4d2824dec1dL,
42400         0x08567a260cee674L,0x0b61d7610d69fa2L,0x0f83d4c70364cc6L,
42401         0x17f0dcc12859016L,0x037c6a31d912cbcL,0x17be8e646984ad1L,
42402         0x0cf108430baf182L,0x093df55ec37119fL,0x048d8ce633c06f5L } },
42403     /* 242 */
42404     { { 0x1f2709dcb5d8b80L,0x0b0c17e1ab30775L,0x0644157be5a40eeL,
42405         0x1bc8f8868570e7bL,0x154f8867d1ea4b4L,0x06bbf7e625c9226L,
42406         0x1d58e4ec68b2bf6L,0x0ac0d1a49cfd183L,0x15f5fabb6499730L,
42407         0x192462802a11ba7L,0x178ad4fce3a44e0L,0x11d6f76d017d86dL,
42408         0x17d8f313b5ed07eL,0x17e969c94b2409eL,0x1228c69eeda81a6L,
42409         0x1864b80db091c10L,0x1af6867fb2fe4f0L,0x01e15d41a0339a1L },
42410       { 0x162d7759d3ad63bL,0x055cbacf0758fd5L,0x098ce217845cfe7L,
42411         0x1dc4165f3ce0665L,0x09eca947f22cafcL,0x146c46da94dd3f2L,
42412         0x055849255085988L,0x08901d447d87247L,0x01b8907e7d43706L,
42413         0x1bfd22aab1f2722L,0x060a7aca92c3e92L,0x0148900c0f25995L,
42414         0x0c246991ced0a72L,0x1a468435c666ed0L,0x02bb84cde88c96cL,
42415         0x04a7eacddaa13ecL,0x1d83d30e091147fL,0x00fd313d2e0839dL } },
42416     /* 243 */
42417     { { 0x11222a242478fd4L,0x06378b385900050L,0x013e0d671b7ab3dL,
42418         0x12f7279b79ee376L,0x030db60b618e282L,0x0d9d94cb70dd719L,
42419         0x15777c5ff4ed259L,0x0ff4b0c738d78e0L,0x0c3ea92ed4b817dL,
42420         0x0415953691d8452L,0x048a2b705c043a4L,0x1c8c41d13b2f08eL,
42421         0x1703ff77c9753b9L,0x15df3072e7bf27cL,0x03805f5b0fe0914L,
42422         0x0bdb73c86597970L,0x03e150a5acdc0a4L,0x033dc5e82a3cc3aL },
42423       { 0x06079b4f4797cf7L,0x04cc5681fef0173L,0x18e9532abbc78c7L,
42424         0x1deec92e22b546eL,0x0f29b1a764d9a1fL,0x136549be706e39dL,
42425         0x1a9e19986c20fedL,0x0c37e9ae9fc65f6L,0x125f6ef09df00a5L,
42426         0x1e21c1fc18e88acL,0x1304314daf78dcaL,0x1f3f10598cb6dabL,
42427         0x13451a99b8d4945L,0x15d608d240fa478L,0x029282850058735L,
42428         0x150493b29a9dbe3L,0x0df65363165a467L,0x03a14bd54d264d7L } },
42429     /* 244 */
42430     { { 0x09758a4e21124baL,0x0c0cc543ffde962L,0x1744f598e2a266fL,
42431         0x102bef7eec8bf79L,0x04e6d57e94645ffL,0x130edcafd339b7eL,
42432         0x051287ab991d64bL,0x0e8f2aeb81997bfL,0x0a3d1304725b31dL,
42433         0x040ef912655ad73L,0x1f4a6468a21fc9eL,0x0b2144d588b31b7L,
42434         0x12d8661d4a23d07L,0x0500a07b972c4c2L,0x0cde0a8ded704eeL,
42435         0x09d201f28333c7fL,0x112722aa0591bc1L,0x044d55bdd6aadddL },
42436       { 0x1345a96d656bdc7L,0x0e457f0bb669dc5L,0x02d8cb59310d0efL,
42437         0x0ef3705683ad2a3L,0x1fb0cf82fcf364aL,0x00943dc83d9a277L,
42438         0x043bfcf4320f144L,0x0b9d3e4d4b2699bL,0x1e5f5aaf207082bL,
42439         0x15b963af673e0b2L,0x042a06fa61b3593L,0x131ffe2a6d55d2bL,
42440         0x03a8263d5efeef4L,0x0a574395822b012L,0x081da1a502f853dL,
42441         0x09af57dcf7993c6L,0x146d496a27dc1bcL,0x00016e14baca055L } },
42442     /* 245 */
42443     { { 0x0533937b69d60c3L,0x1f2a97f4b93aaf7L,0x1e37031c9698982L,
42444         0x1d9565cf85623f6L,0x0e2322cb6982c27L,0x13827ba5e776ecfL,
42445         0x1859654ac67b448L,0x10a5be9850b0a94L,0x0ba40b5bf7b1924L,
42446         0x05e54a8008cfa95L,0x1f472f96b761bffL,0x0df7b3a1e582e8cL,
42447         0x14b8d4ebc99bf53L,0x02d4098b9e14b71L,0x0cd7dd81257e3d0L,
42448         0x0424518b3d1ace6L,0x0730b53d324e054L,0x026ab229a9e1dedL },
42449       { 0x122f8007e5c0877L,0x1a1f30654d3b239L,0x1d2e8b049c59206L,
42450         0x0fda626d84463e9L,0x18db30de0959685L,0x08475e574131911L,
42451         0x08c7994beb50266L,0x092171a30295e1aL,0x02680c54b09cbc3L,
42452         0x0a2b179a5f9dfc7L,0x14242c24ad657ffL,0x1948bc2bf868530L,
42453         0x11bc378168e6f39L,0x022d2543b80ba8cL,0x085506a41a512ceL,
42454         0x19169598dae9505L,0x062adc9bab3b155L,0x00f97c4e73b9836L } },
42455     /* 246 */
42456     { { 0x053ef419affefdfL,0x1f672a67c92b5c1L,0x0bcad113920c175L,
42457         0x1f974a8e3e6ee00L,0x15cbe015b189755L,0x05c214e44241e5eL,
42458         0x1d874953df1a5a8L,0x0ae310a17a8c3e7L,0x17ba210890a2471L,
42459         0x0d5de176c977586L,0x1b2afa5977b224dL,0x0e4978aad095f6aL,
42460         0x0f6a7a74929da23L,0x177a5d236c5d1cbL,0x026c9ebf2e436dcL,
42461         0x06cddba469fc132L,0x147bdf3c16476f4L,0x004e404bf8bf286L },
42462       { 0x004b14060050c07L,0x1418c21d471bf35L,0x06caed57907f0a7L,
42463         0x1459cc1c7597285L,0x1b9d82f4ed2fea5L,0x1e9bfd6e3d8ff9eL,
42464         0x1d4e523afb30da1L,0x124f22a7c65d960L,0x06a60054f570756L,
42465         0x038e6864003acddL,0x1ce1bcc248b7c4eL,0x0b3d066af6f82f4L,
42466         0x09394151864e9fcL,0x09a6dc448e9359dL,0x1f36dc644a8088bL,
42467         0x0606ccce5f9e8b3L,0x16c5a3f268d44ffL,0x037889f69b488f0L } },
42468     /* 247 */
42469     { { 0x0a9df591836f1c9L,0x08cfaa119183ea9L,0x1c0577b4a16be99L,
42470         0x155ec4feeb080d8L,0x0ce0417d0a1545cL,0x089a21d70888f75L,
42471         0x12f2feca2f7da98L,0x0b1bd3de156a5b7L,0x1e9dc181b7813e6L,
42472         0x18ed5edcc893912L,0x16638c8a0531642L,0x0cddb269dcfcbe0L,
42473         0x1ab99ba4bf5c3b9L,0x1e0daaf3a75c276L,0x0aa183eca4668d0L,
42474         0x03fed535bb69329L,0x1e21b7220dff681L,0x0331b511de8d0c1L },
42475       { 0x15d5a2d20587283L,0x01164f783fe2eefL,0x15543bdb78e02ceL,
42476         0x0e4ba2ce3a2f0d7L,0x1cdb1def163cf90L,0x017e253a5fcb8f8L,
42477         0x153dd5d27a0c021L,0x1961c5db78e4ff0L,0x1bb27bbdabce24aL,
42478         0x0d8ce7602df6846L,0x0848fbdf2412f30L,0x1e37b13305b755bL,
42479         0x0e65f6e63202429L,0x172cfe9924e9b0bL,0x07ca7d68de27ea3L,
42480         0x0f1402c174775fdL,0x0f80f2d3b61af53L,0x03d77663b39e153L } },
42481     /* 248 */
42482     { { 0x1a4757cdc43b0dbL,0x12742cc08ce56f9L,0x0fd9185b0558f62L,
42483         0x189ea67d2ff012bL,0x19cfc5ad3e2a07bL,0x14029654c121b39L,
42484         0x1b198629ae8eb35L,0x12b7ac1cb211439L,0x1ae3841a502b1b6L,
42485         0x036ff890c850cadL,0x0afab2b4c7f66e6L,0x044998e51ef65beL,
42486         0x180cf0a9927d893L,0x0c35227561c7539L,0x057c0f2a10e6a01L,
42487         0x1f10bdbcfefe02cL,0x0454824990827a1L,0x0147620035bc53bL },
42488       { 0x1820c2ea2fe0009L,0x1d2e9789c3a74f0L,0x115314936d4b846L,
42489         0x0cffdbca532ea44L,0x1b2500d44d47742L,0x14922580e9a0cd4L,
42490         0x186e73822924861L,0x1c1742d2047ba37L,0x0242c3e5432a301L,
42491         0x1ab7bdd384833c4L,0x14a8271d2a33126L,0x1083aedf2873e15L,
42492         0x0b621fb60e99cd1L,0x1e1cbb1a76ed7f0L,0x1fc2a1015afb952L,
42493         0x1815e8ca7f0c1feL,0x1c36bd4876f2011L,0x009a7a663864a92L } },
42494     /* 249 */
42495     { { 0x021a3ece938dff4L,0x00d3da4353cd1cbL,0x1e5f7a5414ddf44L,
42496         0x13ccbb0fb7e589dL,0x173b8cfaf318409L,0x0148b75c4e3ffd9L,
42497         0x09d91a2ea9417a1L,0x0574f21fa129d7dL,0x1679df6d4e59289L,
42498         0x011998e7e7f6ba0L,0x13bf4a6203fc848L,0x1bbba0688a0217eL,
42499         0x0b342858c87ca78L,0x12baa43d16584f6L,0x12c1246797adb70L,
42500         0x1a8e2a0ceb42bd7L,0x0f409d2e74f7381L,0x03751bc14c1e9ebL },
42501       { 0x05c094b4e5cc40aL,0x11fb50d79befde3L,0x1a77e409b911e8bL,
42502         0x0b27101ea7decefL,0x1f644aa9b7878c9L,0x10461e25518583bL,
42503         0x198ee83145a0cbcL,0x060f804ef5ccb1aL,0x0ef0b3c38ae1d91L,
42504         0x0179bd3b4ae1f52L,0x130715a8317834cL,0x0b8841979f3fc00L,
42505         0x1d568a0e7c9fd49L,0x0c94322a3836adcL,0x069c2722c8977fdL,
42506         0x11ad0a4fa88cb1bL,0x07d47c558da87c0L,0x0303773735da778L } },
42507     /* 250 */
42508     { { 0x0d99fc757c621f6L,0x12060bff41ea401L,0x1e867bc666c0a4bL,
42509         0x05cc58eccc37bf8L,0x0673875378a0410L,0x1d32d78b66d1b87L,
42510         0x18826f2065d3478L,0x18c32e84091ef1fL,0x1c83a058abf5981L,
42511         0x135921a4e44b816L,0x0cbc7a74699e2bcL,0x1361fe535c53311L,
42512         0x181d7cf5ec472bfL,0x19346eec50a1f1cL,0x113fdda7275f916L,
42513         0x0ece62cd9b4aabfL,0x1076044cdf0a4aaL,0x024edd37bf48a43L },
42514       { 0x0e47fb2a758e37aL,0x198eb96c757b310L,0x17e5be708842bdaL,
42515         0x0f21df86566a55aL,0x01e4b2640093f72L,0x18abcaa1ae4cee2L,
42516         0x0d5d6fea1e38016L,0x0b3338a41481cceL,0x1ca68259487eea7L,
42517         0x14fbdc0f8951a45L,0x1f3060aa8b38d40L,0x0e97d5abc58b4a8L,
42518         0x1b55682cdfa11d8L,0x05df47334d781a4L,0x14e52afe1baffaaL,
42519         0x1d71e7b570f05eaL,0x18c458bf797ebc8L,0x0244853d24dbef3L } },
42520     /* 251 */
42521     { { 0x12996898da995f6L,0x15573f630ab77ebL,0x1030d5aa0b574e7L,
42522         0x03826b79fcd2b20L,0x0f595c78b2046b2L,0x02fda0753905b20L,
42523         0x0eff00a093beb9fL,0x17d2fb1fa981db6L,0x112f0290579f24eL,
42524         0x17e23e78c3f535cL,0x07f49de275708c5L,0x16d9124c7d99843L,
42525         0x128b6d30a6233a6L,0x04d99b40411b1a5L,0x11dd15b28d4b897L,
42526         0x00cb72711ad9481L,0x076f8e55b0b3c92L,0x02e0ba3a58121cdL },
42527       { 0x088e7c28aaccab5L,0x13c1b5567682decL,0x1df733b03d94600L,
42528         0x1824b8510430b70L,0x07fdc54c93cadc1L,0x1c4519a2efaa053L,
42529         0x1e8b13cf21b8b09L,0x19e7d0e88d3c741L,0x1c59daa47273983L,
42530         0x031e245a54b6c52L,0x14af3f0b962454cL,0x170f09c85187871L,
42531         0x0cf0c4fd5390e78L,0x0a0f3002c805149L,0x094e872dfe4b6deL,
42532         0x01f4f2acf2482d9L,0x08c35f6f31db1abL,0x02eb3af5a3dac20L } },
42533     /* 252 */
42534     { { 0x0ee1a77870c6025L,0x111dbc8d16fe557L,0x0310e1ad9313f12L,
42535         0x1bcb5ce562f61ccL,0x1eefa212d5d5b17L,0x01c5cb36fe44564L,
42536         0x0bb313fabbefb50L,0x00e133586ad1c5aL,0x0548ea612012af2L,
42537         0x1ff6cedc4e1890cL,0x1a47138399ccc53L,0x0c9f5f0601c0383L,
42538         0x1c6773c3be009bbL,0x00410cfd43c0280L,0x06c1bff8335bb7bL,
42539         0x166def80abc0ff0L,0x0a382b63f9ce080L,0x0017e65d7854ff6L },
42540       { 0x191d4d1b47cac61L,0x08b43d5c370964cL,0x17b0ae53c108ba7L,
42541         0x1291cc91cb18d0aL,0x0f89ac57ca40051L,0x13c966cdd48fd97L,
42542         0x078553d0648186fL,0x03305a443977a1eL,0x0062eb13bfc4440L,
42543         0x1d4be194cbc87eeL,0x05b651819e992fcL,0x0600da46eeb49cfL,
42544         0x15ed7f0f23c46ddL,0x1da7b1ebc339626L,0x189cfca08614770L,
42545         0x01edea1475c19a4L,0x145800e58fceac6L,0x02b78f22b09c22aL } },
42546     /* 253 */
42547     { { 0x1ccb3f632c24f3bL,0x18e3f836c0bf300L,0x02edaa899dda67aL,
42548         0x1c108babc11b8c8L,0x181a79a87838affL,0x140cd879a7f658fL,
42549         0x092e1a8b8a0b4f9L,0x0738972ef9d046fL,0x10f46b3db876364L,
42550         0x032faa04bcb824bL,0x021d8a1e46f90e9L,0x16d868331d8dafcL,
42551         0x17093d94bb00220L,0x14eb48592bd9c31L,0x0ab46921004b858L,
42552         0x069c605d93b6a41L,0x0f8afee2fc685dcL,0x0488e8c9b12a806L },
42553       { 0x1b1bd58f5e5af5bL,0x1131dbdb5115389L,0x1137cebcab729f2L,
42554         0x134088417b56d7dL,0x0ba36c1116651e5L,0x0121881da2459daL,
42555         0x1b2ecf18aff37fdL,0x101bc2b894be352L,0x0be0ad8a1e4d1f9L,
42556         0x095e8a71b339d1dL,0x00ebda484ab3760L,0x1738aec12b9c806L,
42557         0x0a107f5ca58f6daL,0x044b51d83ef8c41L,0x18ecfc2e40f98f2L,
42558         0x10fbdea090a89b0L,0x0655e5019b9c098L,0x015f3a27f507a9cL } },
42559     /* 254 */
42560     { { 0x14cd05f5b50f324L,0x0f5920f51e3d102L,0x0971ffe39adee6cL,
42561         0x1dd8081104950b1L,0x10cba9bdd83902fL,0x0e4f0f3959324a6L,
42562         0x16e07405dbe42caL,0x1f80ba9d6059d75L,0x0874405b1372b8bL,
42563         0x0209440bcf568c8L,0x08f74fb0ad23357L,0x14ee7e9aa067a89L,
42564         0x0d564c3a0984499L,0x1a17401dd9bd9c6L,0x1d462ca03a6525fL,
42565         0x1fbc980f68f4171L,0x07ac710e3c53568L,0x039afaa17e75687L },
42566       { 0x0a9a17138380039L,0x17f0bfba68ce465L,0x04fb32f06a2eb7eL,
42567         0x13fc052e0b25a87L,0x130e9b363c5dbf3L,0x1ea4a522a95ad5cL,
42568         0x0b10dfb98c0c8abL,0x13104d535ae7e05L,0x198c53562993562L,
42569         0x0434fc3b9a15d9cL,0x04008393e6de683L,0x0349a68f1353aeaL,
42570         0x1acfa856376361dL,0x045603f2786f6adL,0x1bc72f501fb9cfeL,
42571         0x0b75bf58fa07e13L,0x19e25d697cb4d47L,0x00f4c264e8a5e9cL } },
42572     /* 255 */
42573     { { 0x16d05614850c817L,0x12d8c9a44c096e3L,0x055179632efac22L,
42574         0x1497cc3cb4e4e7aL,0x17aeb8e18900b5fL,0x0d1ea5d5044348eL,
42575         0x1f4f799999abf4dL,0x0b871458332afd8L,0x0a0648e8f668d6fL,
42576         0x1cfe4963d6e0ba3L,0x045b0210c1970c7L,0x1440c3cd5cd2474L,
42577         0x162aa47e7336370L,0x0f7fb6c231361b9L,0x0fb4b51503097cbL,
42578         0x12925300904999bL,0x0014b5bfce0039aL,0x03623a52b3b4a17L },
42579       { 0x0eb9a417d88e3a1L,0x09e4462423a151dL,0x0344ff9844c4417L,
42580         0x16350d3d17cb3bdL,0x0a75d90a148f5b6L,0x0a3009bd455e2cdL,
42581         0x13364bc326f1d88L,0x12487f54e8f8704L,0x081763a186a5d0bL,
42582         0x1e1a0de4de5d75eL,0x04c583dd174776eL,0x0a5b6eb9cbe9c30L,
42583         0x0cd50de4c2a53ceL,0x1aebb2b68af5733L,0x12954a97b6265b1L,
42584         0x00b69c9feae2389L,0x0ce215e985a3c53L,0x03592c4aa7d0dd1L } },
42585 };
42586 
42587 /* Multiply the base point of P1024 by the scalar and return the result.
42588  * If map is true then convert result to affine coordinates.
42589  *
42590  * Stripe implementation.
42591  * Pre-generated: 2^0, 2^128, ...
42592  * Pre-generated: products of all combinations of above.
42593  * 8 doubles and adds (with qz=1)
42594  *
42595  * r     Resulting point.
42596  * k     Scalar to multiply by.
42597  * map   Indicates whether to convert result to affine.
42598  * ct    Constant time required.
42599  * heap  Heap to use for allocation.
42600  * returns MEMORY_E when memory allocation fails and MP_OKAY on success.
42601  */
sp_1024_ecc_mulmod_base_18(sp_point_1024 * r,const sp_digit * k,int map,int ct,void * heap)42602 static int sp_1024_ecc_mulmod_base_18(sp_point_1024* r, const sp_digit* k,
42603         int map, int ct, void* heap)
42604 {
42605     return sp_1024_ecc_mulmod_stripe_18(r, &p1024_base, p1024_table,
42606                                       k, map, ct, heap);
42607 }
42608 
42609 #endif
42610 
42611 /* Multiply the base point of P1024 by the scalar and return the result.
42612  * If map is true then convert result to affine coordinates.
42613  *
42614  * km    Scalar to multiply by.
42615  * r     Resulting point.
42616  * map   Indicates whether to convert result to affine.
42617  * heap  Heap to use for allocation.
42618  * returns MEMORY_E when memory allocation fails and MP_OKAY on success.
42619  */
sp_ecc_mulmod_base_1024(const mp_int * km,ecc_point * r,int map,void * heap)42620 int sp_ecc_mulmod_base_1024(const mp_int* km, ecc_point* r, int map, void* heap)
42621 {
42622 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
42623     sp_point_1024* point = NULL;
42624     sp_digit* k = NULL;
42625 #else
42626     sp_point_1024  point[1];
42627     sp_digit k[18];
42628 #endif
42629     int err = MP_OKAY;
42630 
42631 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
42632     point = (sp_point_1024*)XMALLOC(sizeof(sp_point_1024), heap,
42633                                          DYNAMIC_TYPE_ECC);
42634     if (point == NULL)
42635         err = MEMORY_E;
42636     if (err == MP_OKAY) {
42637         k = (sp_digit*)XMALLOC(sizeof(sp_digit) * 18, heap,
42638                                DYNAMIC_TYPE_ECC);
42639         if (k == NULL)
42640             err = MEMORY_E;
42641     }
42642 #endif
42643 
42644     if (err == MP_OKAY) {
42645         sp_1024_from_mp(k, 18, km);
42646 
42647             err = sp_1024_ecc_mulmod_base_18(point, k, map, 1, heap);
42648     }
42649     if (err == MP_OKAY) {
42650         err = sp_1024_point_to_ecc_point_18(point, r);
42651     }
42652 
42653 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
42654     if (k != NULL)
42655         XFREE(k, heap, DYNAMIC_TYPE_ECC);
42656     if (point != NULL)
42657         XFREE(point, heap, DYNAMIC_TYPE_ECC);
42658 #endif
42659 
42660     return err;
42661 }
42662 
42663 /* Multiply the base point of P1024 by the scalar, add point a and return
42664  * the result. If map is true then convert result to affine coordinates.
42665  *
42666  * km      Scalar to multiply by.
42667  * am      Point to add to scalar mulitply result.
42668  * inMont  Point to add is in montgomery form.
42669  * r       Resulting point.
42670  * map     Indicates whether to convert result to affine.
42671  * heap    Heap to use for allocation.
42672  * returns MEMORY_E when memory allocation fails and MP_OKAY on success.
42673  */
sp_ecc_mulmod_base_add_1024(const mp_int * km,const ecc_point * am,int inMont,ecc_point * r,int map,void * heap)42674 int sp_ecc_mulmod_base_add_1024(const mp_int* km, const ecc_point* am,
42675         int inMont, ecc_point* r, int map, void* heap)
42676 {
42677 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
42678     sp_point_1024* point = NULL;
42679     sp_digit* k = NULL;
42680 #else
42681     sp_point_1024 point[2];
42682     sp_digit k[18 + 18 * 2 * 5];
42683 #endif
42684     sp_point_1024* addP = NULL;
42685     sp_digit* tmp = NULL;
42686     int err = MP_OKAY;
42687 
42688 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
42689     point = (sp_point_1024*)XMALLOC(sizeof(sp_point_1024) * 2, heap,
42690                                          DYNAMIC_TYPE_ECC);
42691     if (point == NULL)
42692         err = MEMORY_E;
42693     if (err == MP_OKAY) {
42694         k = (sp_digit*)XMALLOC(
42695             sizeof(sp_digit) * (18 + 18 * 2 * 5),
42696             heap, DYNAMIC_TYPE_ECC);
42697         if (k == NULL)
42698             err = MEMORY_E;
42699     }
42700 #endif
42701 
42702     if (err == MP_OKAY) {
42703         addP = point + 1;
42704         tmp = k + 18;
42705 
42706         sp_1024_from_mp(k, 18, km);
42707         sp_1024_point_from_ecc_point_18(addP, am);
42708     }
42709     if ((err == MP_OKAY) && (!inMont)) {
42710         err = sp_1024_mod_mul_norm_18(addP->x, addP->x, p1024_mod);
42711     }
42712     if ((err == MP_OKAY) && (!inMont)) {
42713         err = sp_1024_mod_mul_norm_18(addP->y, addP->y, p1024_mod);
42714     }
42715     if ((err == MP_OKAY) && (!inMont)) {
42716         err = sp_1024_mod_mul_norm_18(addP->z, addP->z, p1024_mod);
42717     }
42718     if (err == MP_OKAY) {
42719             err = sp_1024_ecc_mulmod_base_18(point, k, 0, 0, heap);
42720     }
42721     if (err == MP_OKAY) {
42722             sp_1024_proj_point_add_18(point, point, addP, tmp);
42723 
42724         if (map) {
42725                 sp_1024_map_18(point, point, tmp);
42726         }
42727 
42728         err = sp_1024_point_to_ecc_point_18(point, r);
42729     }
42730 
42731 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
42732     if (k != NULL)
42733         XFREE(k, heap, DYNAMIC_TYPE_ECC);
42734     if (point)
42735         XFREE(point, heap, DYNAMIC_TYPE_ECC);
42736 #endif
42737 
42738     return err;
42739 }
42740 
42741 #ifndef WOLFSSL_SP_SMALL
42742 /* Generate a pre-computation table for the point.
42743  *
42744  * gm     Point to generate table for.
42745  * table  Buffer to hold pre-computed points table.
42746  * len    Length of table.
42747  * heap   Heap to use for allocation.
42748  * returns BAD_FUNC_ARG when gm or len is NULL, LENGTH_ONLY_E when table is
42749  * NULL and length is returned, BUFFER_E if length is too small and 0 otherwise.
42750  */
sp_ecc_gen_table_1024(const ecc_point * gm,byte * table,word32 * len,void * heap)42751 int sp_ecc_gen_table_1024(const ecc_point* gm, byte* table, word32* len,
42752     void* heap)
42753 {
42754 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
42755     sp_point_1024* point = NULL;
42756     sp_digit* t = NULL;
42757 #else
42758     sp_point_1024 point[1];
42759     sp_digit t[5 * 2 * 18];
42760 #endif
42761     int err = MP_OKAY;
42762 
42763     if ((gm == NULL) || (len == NULL)) {
42764         err = BAD_FUNC_ARG;
42765     }
42766 
42767     if ((err == MP_OKAY) && (table == NULL)) {
42768         *len = sizeof(sp_table_entry_1024) * 256;
42769         err = LENGTH_ONLY_E;
42770     }
42771     if ((err == MP_OKAY) && (*len < (int)(sizeof(sp_table_entry_1024) * 256))) {
42772         err = BUFFER_E;
42773     }
42774 
42775 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
42776     if (err == MP_OKAY) {
42777         point = (sp_point_1024*)XMALLOC(sizeof(sp_point_1024), heap,
42778             DYNAMIC_TYPE_ECC);
42779         if (point == NULL)
42780             err = MEMORY_E;
42781     }
42782     if (err == MP_OKAY) {
42783         t = (sp_digit*)XMALLOC(sizeof(sp_digit) * 5 * 2 * 18, heap,
42784             DYNAMIC_TYPE_ECC);
42785         if (t == NULL)
42786             err = MEMORY_E;
42787     }
42788 #endif
42789 
42790     if (err == MP_OKAY) {
42791         sp_1024_point_from_ecc_point_18(point, gm);
42792             err = sp_1024_gen_stripe_table_18(point,
42793                 (sp_table_entry_1024*)table, t, heap);
42794     }
42795     if (err == 0) {
42796         *len = sizeof(sp_table_entry_1024) * 256;
42797     }
42798 
42799 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
42800     if (t != NULL)
42801         XFREE(t, heap, DYNAMIC_TYPE_ECC);
42802     if (point != NULL)
42803         XFREE(point, heap, DYNAMIC_TYPE_ECC);
42804 #endif
42805 
42806     return err;
42807 }
42808 #else
42809 /* Generate a pre-computation table for the point.
42810  *
42811  * gm     Point to generate table for.
42812  * table  Buffer to hold pre-computed points table.
42813  * len    Length of table.
42814  * heap   Heap to use for allocation.
42815  * returns BAD_FUNC_ARG when gm or len is NULL, LENGTH_ONLY_E when table is
42816  * NULL and length is returned, BUFFER_E if length is too small and 0 otherwise.
42817  */
sp_ecc_gen_table_1024(const ecc_point * gm,byte * table,word32 * len,void * heap)42818 int sp_ecc_gen_table_1024(const ecc_point* gm, byte* table, word32* len,
42819     void* heap)
42820 {
42821     int err = 0;
42822 
42823     if ((gm == NULL) || (len == NULL)) {
42824         err = BAD_FUNC_ARG;
42825     }
42826 
42827     if ((err == 0) && (table == NULL)) {
42828         *len = 0;
42829         err = LENGTH_ONLY_E;
42830     }
42831     if ((err == 0) && (*len != 0)) {
42832         err = BUFFER_E;
42833     }
42834     if (err == 0) {
42835         *len = 0;
42836     }
42837 
42838     (void)heap;
42839 
42840     return err;
42841 }
42842 #endif
42843 /* Multiply the point by the scalar and return the result.
42844  * If map is true then convert result to affine coordinates.
42845  *
42846  * km     Scalar to multiply by.
42847  * gm     Point to multiply.
42848  * table  Pre-computed points.
42849  * r      Resulting point.
42850  * map    Indicates whether to convert result to affine.
42851  * heap   Heap to use for allocation.
42852  * returns MEMORY_E when memory allocation fails and MP_OKAY on success.
42853  */
sp_ecc_mulmod_table_1024(const mp_int * km,const ecc_point * gm,byte * table,ecc_point * r,int map,void * heap)42854 int sp_ecc_mulmod_table_1024(const mp_int* km, const ecc_point* gm, byte* table,
42855         ecc_point* r, int map, void* heap)
42856 {
42857 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
42858     sp_point_1024* point = NULL;
42859     sp_digit* k = NULL;
42860 #else
42861     sp_point_1024 point[1];
42862     sp_digit k[18];
42863 #endif
42864     int err = MP_OKAY;
42865 
42866 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
42867     point = (sp_point_1024*)XMALLOC(sizeof(sp_point_1024), heap,
42868         DYNAMIC_TYPE_ECC);
42869     if (point == NULL) {
42870         err = MEMORY_E;
42871     }
42872     if (err == MP_OKAY) {
42873         k = (sp_digit*)XMALLOC(sizeof(sp_digit) * 18, heap, DYNAMIC_TYPE_ECC);
42874         if (k == NULL)
42875             err = MEMORY_E;
42876     }
42877 #endif
42878 
42879     if (err == MP_OKAY) {
42880         sp_1024_from_mp(k, 18, km);
42881         sp_1024_point_from_ecc_point_18(point, gm);
42882 
42883 #ifndef WOLFSSL_SP_SMALL
42884             err = sp_1024_ecc_mulmod_stripe_18(point, point,
42885                 (const sp_table_entry_1024*)table, k, map, 0, heap);
42886 #else
42887         (void)table;
42888         err = sp_1024_ecc_mulmod_18(point, point, k, map, 0, heap);
42889 #endif
42890     }
42891     if (err == MP_OKAY) {
42892         err = sp_1024_point_to_ecc_point_18(point, r);
42893     }
42894 
42895 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
42896     if (k != NULL)
42897         XFREE(k, heap, DYNAMIC_TYPE_ECC);
42898     if (point != NULL)
42899         XFREE(point, heap, DYNAMIC_TYPE_ECC);
42900 #endif
42901 
42902     return err;
42903 }
42904 
42905 /* Multiply p* in projective co-ordinates by q*.
42906  *
42907  * r.x = p.x - (p.y * q.y)
42908  * r.y = (p.x * q.y) + p.y
42909  *
42910  * px  [in,out]  A single precision integer - X ordinate of number to multiply.
42911  * py  [in,out]  A single precision integer - Y ordinate of number to multiply.
42912  * q   [in]      A single precision integer - multiplier.
42913  * t   [in]      Two single precision integers - temps.
42914  */
sp_1024_proj_mul_qx1_18(sp_digit * px,sp_digit * py,const sp_digit * q,sp_digit * t)42915 static void sp_1024_proj_mul_qx1_18(sp_digit* px, sp_digit* py,
42916         const sp_digit* q, sp_digit* t)
42917 {
42918     sp_digit* t1 = t;
42919     sp_digit* t2 = t + 2 * 18;
42920 
42921     /* t1 = p.x * q.y */
42922     sp_1024_mont_mul_18(t1, px, q, p1024_mod, p1024_mp_mod);
42923     /* t2 = p.y * q.y */
42924     sp_1024_mont_mul_18(t2, py, q, p1024_mod, p1024_mp_mod);
42925     /* r.x = p.x - (p.y * q.y) */
42926     sp_1024_mont_sub_18(px, px, t2, p1024_mod);
42927     /* r.y = (p.x * q.y) + p.y */
42928     sp_1024_mont_add_18(py, t1, py, p1024_mod);
42929 }
42930 
42931 /* Square p* in projective co-ordinates.
42932  *
42933  *   px' = (p.x + p.y) * (p.x - p.y) = p.x^2 - p.y^2
42934  *   py' = 2 * p.x * p.y
42935  *
42936  * px  [in,out]  A single precision integer - X ordinate of number to square.
42937  * py  [in,out]  A single precision integer - Y ordinate of number to square.
42938  * t   [in]      Two single precision integers - temps.
42939  */
sp_1024_proj_sqr_18(sp_digit * px,sp_digit * py,sp_digit * t)42940 static void sp_1024_proj_sqr_18(sp_digit* px, sp_digit* py, sp_digit* t)
42941 {
42942     sp_digit* t1 = t;
42943     sp_digit* t2 = t + 2 * 18;
42944 
42945     /* t1 = p.x + p.y */
42946     sp_1024_mont_add_18(t1, px, py, p1024_mod);
42947     /* t2 = p.x - p.y */
42948     sp_1024_mont_sub_18(t2, px, py, p1024_mod);
42949     /* r.y = p.x * p.y */
42950     sp_1024_mont_mul_18(py, px, py, p1024_mod, p1024_mp_mod);
42951     /* r.x = (p.x + p.y) * (p.x - p.y) */
42952     sp_1024_mont_mul_18(px, t1, t2, p1024_mod, p1024_mp_mod);
42953     /* r.y = (p.x * p.y) * 2 */
42954     sp_1024_mont_dbl_18(py, py, p1024_mod);
42955 }
42956 
42957 #ifdef WOLFSSL_SP_SMALL
42958 /* Perform the modular exponentiation in Fp* for SAKKE.
42959  *
42960  * Simple square and multiply when expontent bit is one algorithm.
42961  * Square and multiply performed in Fp*.
42962  *
42963  * base  [in]   Base. MP integer.
42964  * exp   [in]   Exponent. MP integer.
42965  * res   [out]  Result. MP integer.
42966  * returns 0 on success and MEMORY_E if memory allocation fails.
42967  */
sp_ModExp_Fp_star_1024(const mp_int * base,mp_int * exp,mp_int * res)42968 int sp_ModExp_Fp_star_1024(const mp_int* base, mp_int* exp, mp_int* res)
42969 {
42970 #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && \
42971     !defined(WOLFSSL_SP_NO_MALLOC)
42972     sp_digit* td;
42973     sp_digit* t;
42974     sp_digit* tx;
42975     sp_digit* ty;
42976     sp_digit* b;
42977     sp_digit* e;
42978 #else
42979     sp_digit t[4 * 2 * 18];
42980     sp_digit tx[2 * 18];
42981     sp_digit ty[2 * 18];
42982     sp_digit b[2 * 18];
42983     sp_digit e[2 * 18];
42984 #endif
42985     sp_digit* r;
42986     int err = MP_OKAY;
42987     int bits;
42988     int i;
42989 
42990 #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && \
42991     !defined(WOLFSSL_SP_NO_MALLOC)
42992     td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 8 * 18 * 2, NULL,
42993                             DYNAMIC_TYPE_TMP_BUFFER);
42994     if (td == NULL) {
42995         err = MEMORY_E;
42996     }
42997 #endif
42998 
42999     if (err == MP_OKAY) {
43000 #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && \
43001     !defined(WOLFSSL_SP_NO_MALLOC)
43002         t  = td;
43003         tx = td + 4 * 18 * 2;
43004         ty = td + 5 * 18 * 2;
43005         b  = td + 6 * 18 * 2;
43006         e  = td + 7 * 18 * 2;
43007 #endif
43008         r = ty;
43009 
43010         bits = mp_count_bits(exp);
43011         sp_1024_from_mp(b, 18, base);
43012         sp_1024_from_mp(e, 18, exp);
43013 
43014         XMEMCPY(tx, p1024_norm_mod, sizeof(sp_digit) * 18);
43015         sp_1024_mul_18(b, b, p1024_norm_mod);
43016         err = sp_1024_mod_18(b, b, p1024_mod);
43017     }
43018     if (err == MP_OKAY) {
43019         XMEMCPY(ty, b, sizeof(sp_digit) * 18);
43020 
43021         for (i = bits - 2; i >= 0; i--) {
43022             sp_1024_proj_sqr_18(tx, ty, t);
43023             if ((e[i / 57] >> (i % 57)) & 1) {
43024                 sp_1024_proj_mul_qx1_18(tx, ty, b, t);
43025             }
43026         }
43027     }
43028 
43029     if (err == MP_OKAY) {
43030         sp_1024_mont_inv_18(tx, tx, t);
43031 
43032         XMEMSET(tx + 18, 0, sizeof(sp_digit) * 18);
43033         sp_1024_mont_reduce_18(tx, p1024_mod, p1024_mp_mod);
43034         XMEMSET(ty + 18, 0, sizeof(sp_digit) * 18);
43035         sp_1024_mont_reduce_18(ty, p1024_mod, p1024_mp_mod);
43036 
43037         sp_1024_mul_18(r, tx, ty);
43038         err = sp_1024_mod_18(r, r, p1024_mod);
43039     }
43040     if (err == MP_OKAY) {
43041         err = sp_1024_to_mp(r, res);
43042     }
43043 
43044 #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && \
43045     !defined(WOLFSSL_SP_NO_MALLOC)
43046     if (td != NULL) {
43047         XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);
43048     }
43049 #endif
43050     return err;
43051 }
43052 
43053 #else
43054 /* Pre-computed table for exponentiating g.
43055  * Striping: 8 points at a distance of (128 combined for
43056  * a total of 256 points.
43057  */
43058 static const sp_digit sp_1024_g_table[256][18] = {
43059     { 0x000000000000000L, 0x000000000000000L, 0x000000000000000L,
43060       0x000000000000000L, 0x000000000000000L, 0x000000000000000L,
43061       0x000000000000000L, 0x000000000000000L, 0x000000000000000L,
43062       0x000000000000000L, 0x000000000000000L, 0x000000000000000L,
43063       0x000000000000000L, 0x000000000000000L, 0x000000000000000L,
43064       0x000000000000000L, 0x000000000000000L, 0x000000000000000L },
43065     { 0x10a46d2335c1685L, 0x0f4b8f0803d2c0bL, 0x0f7d0f2929cfab2L,
43066       0x0b04c848ea81d1eL, 0x136576d12646f81L, 0x1f8d7d9d7a4dda5L,
43067       0x1479b6278b451caL, 0x0f84f7d10585fa2L, 0x1addedc858f8871L,
43068       0x16c2cdf8b563637L, 0x10686cb63ab9635L, 0x1400c383e61a1ceL,
43069       0x1a9b67e0966faf7L, 0x1e9da7beb36de84L, 0x09f263887c47019L,
43070       0x16442c2a574058eL, 0x0f4afd58891e86cL, 0x02cf49e3535e9ddL },
43071     { 0x14dd36f71dd4594L, 0x0e64f805778f372L, 0x113a867d94c2ef2L,
43072       0x127ea412513d4b4L, 0x0f5c14188588aa9L, 0x09ccfd4ba9bca64L,
43073       0x1aad4462f5e4b04L, 0x0a5737a75fbeb96L, 0x1813d1cb22ecb96L,
43074       0x0a2b133a01c4c09L, 0x1c466d2b210c73fL, 0x152214301d6ca3eL,
43075       0x179f7bfa2edd9f6L, 0x0854e86c89ca368L, 0x00dcf4c5bc618c5L,
43076       0x0a572be33841adfL, 0x003be85ac6a9b6aL, 0x031f78c3dba7b17L },
43077     { 0x0376b7f016f45e7L, 0x1edab95f6417c3eL, 0x1d07390a6d80706L,
43078       0x058f5fb03ae725eL, 0x1241098b6fdbf0aL, 0x107c67ded20d8fbL,
43079       0x0f1356d01d1d2edL, 0x17d267c1a836661L, 0x1ae182830733fa3L,
43080       0x07694cd87ae3668L, 0x0cd538fe6183228L, 0x130c2aab3882ffeL,
43081       0x1c129f85cbb1360L, 0x03b42fdf55865b1L, 0x06658cda0bb3125L,
43082       0x059b4a0bd1d85d6L, 0x02390dcc794ddacL, 0x027f33c8e78c96dL },
43083     { 0x0a423d505e8733cL, 0x02f328eab8be0caL, 0x1a23a586cc8b321L,
43084       0x0db683039846f8fL, 0x113bd7210c4471cL, 0x00bd8480643af13L,
43085       0x1abda77f7a7b6cbL, 0x14c8614dbcbd119L, 0x1aaa7a61a7b81ceL,
43086       0x1296813119fcc6aL, 0x1bf74181a26a6baL, 0x0f9cb95895576abL,
43087       0x148e95076130cfaL, 0x074d0f297d26d88L, 0x01005c0c255c311L,
43088       0x1b3a431843ec234L, 0x097555d1ffebe78L, 0x00224150c2b0ed9L },
43089     { 0x1758ac273d486d8L, 0x0fca330e6e0f3f3L, 0x07f08622ad3e05aL,
43090       0x05e66e6c60e4793L, 0x1d8c2260a0e54f0L, 0x18de302b05f712dL,
43091       0x1fad4a3f0c1f114L, 0x06fade43e34fc89L, 0x1c8e4499c57128dL,
43092       0x11d829f6bd97522L, 0x09e810ca8f488a5L, 0x0a9a6a8b2cd0818L,
43093       0x1fd73557e95b518L, 0x034903bd3370d24L, 0x0d09c083499ff66L,
43094       0x1b689f426a1a7ceL, 0x09f1a9c3f2568ccL, 0x0419d07fc6f6dfcL },
43095     { 0x0c419c7ab376b76L, 0x14a7993e8786654L, 0x078aa4314534edcL,
43096       0x1d4c4aeb4dcad77L, 0x098c0a88931ba51L, 0x00b5152b7f703d8L,
43097       0x0982c12f96bbad3L, 0x0e1ca266a17cdd6L, 0x1339edad6a1d5c2L,
43098       0x1b376acf4edd6e8L, 0x0efa20b741bb03cL, 0x139196230fb6842L,
43099       0x01d8a1058a22d63L, 0x115ba2788ff64afL, 0x1c170300fdcfa9aL,
43100       0x02340e83faa35e9L, 0x05f2e2df95a85f8L, 0x034959e71f5924bL },
43101     { 0x0e6cb72d2a127b4L, 0x03752c7c940b786L, 0x118d1e8dd8599a9L,
43102       0x03c1572ddc87d9eL, 0x12edbe8c163d9a0L, 0x127332e40a2e36dL,
43103       0x14be4bd09b2b937L, 0x0622e9a1680e9c4L, 0x054c240d77d2af8L,
43104       0x00fd1cb9eb2949bL, 0x05247282751a556L, 0x0a66a8a4c8780b7L,
43105       0x11d41283278c4e8L, 0x181b0f92996b219L, 0x1bc27c9911e40e1L,
43106       0x0bfc0ee83236313L, 0x0d6c0cf0aaf81deL, 0x0199f21857a0021L },
43107     { 0x1f04de4cf26d3b7L, 0x1b9835a9fbcdf2eL, 0x117c6022d9915e9L,
43108       0x090a06e6c148027L, 0x0b061037ef291eaL, 0x0489dd8ffe4ebe8L,
43109       0x0161f6741376597L, 0x0ab29146f5fe277L, 0x0b5443483fe3ee7L,
43110       0x1e10f3a023189c3L, 0x041397377ad630fL, 0x10c4cae59aa5674L,
43111       0x0115aaa40894fe1L, 0x02cf523175cd38dL, 0x1ac0a8e2b71bf95L,
43112       0x123a37631a2ea95L, 0x108ae1276362f77L, 0x00874598eeb5debL },
43113     { 0x07f03e53ed9f1afL, 0x0923bab33b0b35cL, 0x18c1d33856e00ebL,
43114       0x004d63d0b671b9aL, 0x1af99c151877e2bL, 0x012a3d58b2a68b8L,
43115       0x17bd65e0ba7924eL, 0x098db8ff8f84daaL, 0x19038f95d2fbeb5L,
43116       0x12c86ff01b601abL, 0x0dbab93f70fdfffL, 0x18a9e6bc35119f9L,
43117       0x12da0a5568cb1fbL, 0x0db7aaab9e470edL, 0x0b0281a6a1ce4fdL,
43118       0x12b5670c8d665cfL, 0x0bcfd261c832a84L, 0x03242a926066e62L },
43119     { 0x0bfb3e2c4a6ff2aL, 0x01fdd1ad321450dL, 0x1fc226bfdd08aa8L,
43120       0x1574bb7b2710844L, 0x12a182cb2337883L, 0x100f829c0c3574eL,
43121       0x079eae7c1d93526L, 0x0b724823fd722f6L, 0x0700b1903570cbbL,
43122       0x0a8c0eadc8a5f3eL, 0x1110dc660460b57L, 0x1a48ae97332e26bL,
43123       0x15632d28b232758L, 0x1d1c1f84d328547L, 0x08cf600901e2eb3L,
43124       0x16892ca8d4c1801L, 0x03ca4061c7a2df8L, 0x00fbb79f9791a2bL },
43125     { 0x0a2c14344c436b0L, 0x182ab0fb4e43d4dL, 0x05ed7db6cb7de41L,
43126       0x03daad75046be62L, 0x1d0afa4885761f4L, 0x0e738f7c18a327bL,
43127       0x1d222a67ca454ebL, 0x07564f7ed2622d6L, 0x0a98a5a8c9bb944L,
43128       0x1c3c0131772fef4L, 0x1e4f74604ab2ddfL, 0x0999b909792474dL,
43129       0x0ff1d4995aaf92aL, 0x0276c4ce9e12b15L, 0x14a94e3f67f0cf0L,
43130       0x14e4d805195289dL, 0x005d0f367bb049eL, 0x0024927fd9e8847L },
43131     { 0x0548e3dc673562fL, 0x19812f175724603L, 0x0cad7871a5df4ecL,
43132       0x08dd7caaf7cc3faL, 0x01d6e18e424e206L, 0x0bf4adbb39c8e02L,
43133       0x06e312e3aee3853L, 0x1a695d16fa84132L, 0x0f8a0df66e01290L,
43134       0x0bf1251c92f2fa7L, 0x1ecb2c54209cab2L, 0x0e5c4a0e4cc2f34L,
43135       0x029062fa49b40b0L, 0x19e29de76d6cf0cL, 0x0509e661e029e13L,
43136       0x1084cb15056ed3eL, 0x03508cd849cc146L, 0x026fe7404e1c057L },
43137     { 0x1069cb2d527b780L, 0x0d00acbbc986ea2L, 0x002f89f4098f54bL,
43138       0x0d765a36562198cL, 0x154adf3c34102c2L, 0x187fa3a6329311aL,
43139       0x1b9f35a244e0917L, 0x11507f5198b9522L, 0x11e10f139d15c8dL,
43140       0x0b9ee1740ee2b59L, 0x1b2c11713b66ebcL, 0x0fb08fa02450ff9L,
43141       0x139f3a532f307fdL, 0x110a9e111252b8aL, 0x0a2902167a7a077L,
43142       0x17a478ac4b2bbc8L, 0x002dc7daff89339L, 0x00683ac845c5034L },
43143     { 0x10af2a7de085f2aL, 0x06927df4cd972c3L, 0x0985672904ee23fL,
43144       0x090ab3f0a31181aL, 0x1622da0d1f02a2eL, 0x051b0ac1dcb010fL,
43145       0x11a0970170bd5b7L, 0x17c02919e38f221L, 0x0392f2896272695L,
43146       0x01e85dad46b277bL, 0x14891073f2f14a2L, 0x19d8a4c22fcbde1L,
43147       0x19f04928e9f5dafL, 0x1c9f97155b43095L, 0x0304544a0fdd134L,
43148       0x01bfdf7ddafdae0L, 0x15af2cde215a436L, 0x0127d4b0e178429L },
43149     { 0x167db3f616df7f6L, 0x02bec7dec819303L, 0x0a41ba0b551190cL,
43150       0x0ad12c87b62e9b5L, 0x0c89a0602284f34L, 0x013e890c58c8efeL,
43151       0x14516ead1abd35bL, 0x13cb4afe90d9312L, 0x0c03214e9cc942fL,
43152       0x19f0e47a0ca80acL, 0x0dd67ce6b50eac9L, 0x16ffca1dc2e719dL,
43153       0x1c8f4d7d4e5e1b8L, 0x1aab01f9fb1ad8fL, 0x14be9823bfddf8dL,
43154       0x16dc2403ec3a2eeL, 0x11494d7a03d4a6fL, 0x01b8e611efe2780L },
43155     { 0x09b115dda90c351L, 0x0b75f9b26ce0314L, 0x080bd942cc6db46L,
43156       0x08deaec85eef512L, 0x08100127cc28c16L, 0x06403dee27bf1b0L,
43157       0x103ca20db342371L, 0x0a62501e2adc004L, 0x03f9a6d7899cb39L,
43158       0x0524a699d40101cL, 0x05fa47a1f4d1d10L, 0x1a0e4dbbc4948adL,
43159       0x0d7640c30e70d97L, 0x0dd37363037b52cL, 0x0f04fa00f0b03a1L,
43160       0x1af1e661ed4f5e3L, 0x17f3e602e4fc9f4L, 0x0495b5e5006407dL },
43161     { 0x03d5c835f00822eL, 0x12b895c58b78917L, 0x07124ac28cc03a0L,
43162       0x1b4f9832a903865L, 0x1bb1413f6b4e32aL, 0x09651385f74e770L,
43163       0x0454fb7edeea92aL, 0x1f39a8e55f5d477L, 0x0e8f09e7e00f0c0L,
43164       0x070ec392e6f5db8L, 0x0eb8212a6d8eda9L, 0x03707fab1ecbfc5L,
43165       0x1aa3b62759f4014L, 0x1c8718446bf62f6L, 0x09df8c66abdb99dL,
43166       0x10e3842b5b0603eL, 0x09de7db4b98cf33L, 0x038ffb164a7817cL },
43167     { 0x04c71022a4a84d9L, 0x12566af5e38f355L, 0x0297c73595e38bbL,
43168       0x1fffe2414a76235L, 0x09e6503383f5ef9L, 0x0220c05262cc708L,
43169       0x0a30787a7e64328L, 0x0d717065a8deb30L, 0x0753f28a033af53L,
43170       0x176e258db6a7b45L, 0x19a4a9cb3347c24L, 0x1efba444c865dbbL,
43171       0x1ea3d2661cd3aa0L, 0x1ee1beed1c6ddb1L, 0x1bdad33c7867f1bL,
43172       0x174d2d83166a109L, 0x073e6a83fe9df1bL, 0x0207ea3f3afcac1L },
43173     { 0x188b746267140a4L, 0x1fe0f755b797dadL, 0x0239a6189521b6eL,
43174       0x025d6ddf85bb3d9L, 0x0ac8ff8869beebaL, 0x110ca867e110a54L,
43175       0x1eda6575725bad6L, 0x06f2671380a82e3L, 0x02d85d4521b4683L,
43176       0x06b45042089a12eL, 0x1004e7b1b085d05L, 0x172fee60109bca5L,
43177       0x061f578aa320cf0L, 0x1cdb57218d60b51L, 0x1529a5462e7eacfL,
43178       0x1c50cd1b04223b0L, 0x18c0b334d98dffbL, 0x02d8e08abf31c99L },
43179     { 0x0edaab172b6bb8fL, 0x12769017e496148L, 0x0f17f9a531ce371L,
43180       0x1f96a9b9c9e8574L, 0x032420dc316dc65L, 0x16e7ca6596b351bL,
43181       0x0b2745b9c1b9c15L, 0x15050138ec949e6L, 0x1ab18d830ea6edcL,
43182       0x1e8d67340e32fabL, 0x059471f684b0413L, 0x1acd8ef234903f2L,
43183       0x14785e67a30ac3bL, 0x0d07eac8db568e7L, 0x0718d13934ff113L,
43184       0x015679c2c9002dcL, 0x0f484de9cb833e5L, 0x04b1d5c1d53ab77L },
43185     { 0x04b47d8df4ea5a3L, 0x1440aae7f22ff4aL, 0x156228f0d592595L,
43186       0x1dcf933c2ba2dcfL, 0x155071bc84e55b3L, 0x02bee71ff71026fL,
43187       0x155c1c401bca410L, 0x159fd18721b774eL, 0x03645bcb63319adL,
43188       0x0c4f4583e105fecL, 0x1425a5f5f655e20L, 0x0643733e9c771caL,
43189       0x01a60cfb6a037d1L, 0x01b9c16d008d929L, 0x107701d99652aaaL,
43190       0x13109913723fb07L, 0x1586b82b899076bL, 0x0221a407e5f22e2L },
43191     { 0x0ffffb49114221aL, 0x027971f42bd3d7cL, 0x03903e951e1d2bbL,
43192       0x03adf2c2a485c5aL, 0x1bfe9b77ef3e6b3L, 0x01d4355914b29bfL,
43193       0x0ab1b0aa743cbedL, 0x0f6482509da48aeL, 0x1a3868917e721baL,
43194       0x1f7be00608bd3c6L, 0x1241c74c5816b36L, 0x153c0cb51dd2702L,
43195       0x18c442be82c2dadL, 0x1b6b95ac6ad89c6L, 0x0c0f9b66db0892fL,
43196       0x006e373a6ab9f1dL, 0x1ebab6d1eb0a170L, 0x04b88c54467fd53L },
43197     { 0x19c59a2cdecb5d8L, 0x1e40dd49d34335fL, 0x160411dd3efe020L,
43198       0x154040e16849c1bL, 0x0fbfb781e779a3cL, 0x1950e24e9a97dd8L,
43199       0x19406a2c36080fbL, 0x1e570b0c6f62967L, 0x15ba70a498a882fL,
43200       0x13980419d8377d2L, 0x100bd040bfb8aa8L, 0x05331404474b485L,
43201       0x0685c3fc72e4e76L, 0x1f297573edd15d1L, 0x03d17d9553f9d8fL,
43202       0x070f8616a80b44eL, 0x082d56a177aa573L, 0x00be03bc6a5b8fdL },
43203     { 0x06dff1d2735e37bL, 0x0272b32b762b907L, 0x12767aeea5e3262L,
43204       0x117413e78945eb5L, 0x15b0437740fa451L, 0x1d1765461fd0bbfL,
43205       0x0f50286877b3659L, 0x094ed1794e00a51L, 0x1f224952b18691cL,
43206       0x1709622f436afeaL, 0x16455cde1669a85L, 0x061341ff9c1cf41L,
43207       0x1ba96cc9a3723f4L, 0x0d691d1c2d46dbcL, 0x0fd7611b744ab80L,
43208       0x1dacd3ffd8743c5L, 0x0c6d6ce84e1a452L, 0x0090ceae42b8ff2L },
43209     { 0x1eaa67f262969ebL, 0x159ce9781f3b9a1L, 0x19455eec2424e8eL,
43210       0x1b1a2a04e9cc24fL, 0x0580bdbd0f82b0eL, 0x1a1f35ffffe56c7L,
43211       0x04759474f41d6a5L, 0x11029097b631758L, 0x095cd9990eb24c3L,
43212       0x0b530e83fd633e3L, 0x03dd8a8139ae1c8L, 0x1ac3974af990861L,
43213       0x0dd234a07a2865dL, 0x1d03c9fc9e14b58L, 0x18a7b39dbe4a0e4L,
43214       0x0de84e16afc3e17L, 0x0301314a82f7e62L, 0x01646bd596b2bf9L },
43215     { 0x1cf58920825e4d6L, 0x0f552b77c1da233L, 0x17604c4042377d4L,
43216       0x0b1ba12c7ec7cccL, 0x1df6436a229f89fL, 0x0f5dd3c6258a6ecL,
43217       0x1ce06676b91a751L, 0x1d6231556eeb49bL, 0x1da8978bd29e37fL,
43218       0x0e76ad556516bf7L, 0x03417719f5aa29aL, 0x1e1aeff09468d93L,
43219       0x0eed8cd59a7474bL, 0x08e9cc7dea21459L, 0x0882c46c3f47357L,
43220       0x09888b2c027b729L, 0x15896eb705a1b40L, 0x0114ce93ba584ecL },
43221     { 0x19cd58dc64397e6L, 0x0c78f5fb6e98f2dL, 0x0384fa7c76cab06L,
43222       0x0f1f9b8d18b0cdbL, 0x053c01fd405ae28L, 0x0edafb52594066fL,
43223       0x1e2837258fcb504L, 0x117dabaa3137d89L, 0x0336fd13d916ee9L,
43224       0x092d8d98216fa47L, 0x158a46b3801d39aL, 0x16904a62fd2a19eL,
43225       0x0b821c446be8d38L, 0x185b2c9a63d68e9L, 0x1283541c71104d7L,
43226       0x0d84d2e36e6dea5L, 0x18eaf9ffa5727b4L, 0x010d633bc8c9b30L },
43227     { 0x1420e3f2d7fbcd2L, 0x11239cbdefe0c55L, 0x0fe137d752d049cL,
43228       0x0c700f6fa692406L, 0x133c36256fcd423L, 0x19140a6fe0cd84dL,
43229       0x066e04f5bcdd683L, 0x138e12f14b206f8L, 0x14f3989970ff27bL,
43230       0x0070d22b0ad21c4L, 0x0d25a8f980bdd3fL, 0x086364c39439ff4L,
43231       0x1bee0164cdc3f1cL, 0x13fbdf4fb09108eL, 0x10b86ecc118fb93L,
43232       0x074ac02befcf125L, 0x1d8663d88d62448L, 0x0074760f387316cL },
43233     { 0x08ccc298a0878ddL, 0x00baeb320038d54L, 0x0082945cd85e66bL,
43234       0x1dbab1462b20689L, 0x08d221a1316d023L, 0x0e2471983c2dea4L,
43235       0x09dc6dd2cf79e56L, 0x0a685dc070498cfL, 0x159ef6cdde0b914L,
43236       0x01857144d91bf48L, 0x11e93125760c95eL, 0x02fda0ee6ccdc30L,
43237       0x06a294a32567b12L, 0x0326c1932c0c964L, 0x0c4f96ddaa83d5aL,
43238       0x0e7fbc5457a25e9L, 0x035d850c1c01b6bL, 0x0329d3cafae881bL },
43239     { 0x1e2898550dcb199L, 0x1c72f3fd015b067L, 0x1f0f25d80f42cd6L,
43240       0x1a4fe2636b794faL, 0x02b12d52b0e5288L, 0x1b92e39d53826f7L,
43241       0x0c44f881ac76076L, 0x0c6162507358ba3L, 0x014f970cbdb45d7L,
43242       0x0cbfc9f59092f47L, 0x15ce73b9f6a89b2L, 0x1a7e3fde41d37aeL,
43243       0x147c6a42b146ecbL, 0x13fd87e8fcca508L, 0x103692f4a27ad3cL,
43244       0x0f2ec2230da6334L, 0x15e083f65a5fb9dL, 0x0186fe23dea2233L },
43245     { 0x0fc5ae29eaadfe8L, 0x13f2a5a6a74095eL, 0x0b7e2d4cd584940L,
43246       0x08ad4d4429560e0L, 0x1059068ea2b9c20L, 0x018887d8d1efbd1L,
43247       0x038728d452c8662L, 0x1096f7c466d896fL, 0x017073ce63e2f69L,
43248       0x1708a5316efbd63L, 0x064afc1f5f0f221L, 0x1c17d635c5124ecL,
43249       0x15251849395da69L, 0x003d1d504c1d78bL, 0x03f88626b14a935L,
43250       0x04a022a6b8fb55cL, 0x0cfe16fe872397fL, 0x02b952c8faa6109L },
43251     { 0x166841909a5553aL, 0x0a18c193b99de24L, 0x12c8fbbf5a40fc1L,
43252       0x17e4424da9f39d6L, 0x0fed9578bd3cbf9L, 0x01836c36cb38e01L,
43253       0x13f96ee965f3b28L, 0x0ed6e0bdac27aceL, 0x1f1d3622b67f33fL,
43254       0x0de79e308e5c618L, 0x119f7394f46aa45L, 0x1253f2115687470L,
43255       0x1d8d15767a902feL, 0x0857e83db71f24cL, 0x02c643a050b6d72L,
43256       0x1349c2418df78d9L, 0x03c80c865532491L, 0x032e165f0ec6416L },
43257     { 0x04cda20a660bb63L, 0x01d8543743122b4L, 0x13d9ae83bb5c9f7L,
43258       0x0acf3ba2b0ec8e5L, 0x08452d4479c162eL, 0x1fabcf5b44213b8L,
43259       0x05dc20a6f1acd04L, 0x10725d42bd92a02L, 0x15e34e300477381L,
43260       0x01e51a4b9f0e978L, 0x13c7708a6f4f7a3L, 0x1e3729defda74b8L,
43261       0x0ddfae7a1a783efL, 0x0d04cc29236db9cL, 0x173d2ad0d4f5cb8L,
43262       0x111724a675ab141L, 0x166d80550160e78L, 0x0418a206a9dd3bfL },
43263     { 0x03e2e32f611b2daL, 0x13714e87d23567aL, 0x0fa2082cf035741L,
43264       0x0c3a7c89e1d12feL, 0x1fd27a66c45c28eL, 0x0f428bc94ebfb36L,
43265       0x1e375cd6e182840L, 0x035d47f9d307bc0L, 0x1c9977db5638ce1L,
43266       0x0441c17a429b59dL, 0x11e8f1932b7f181L, 0x1eff0428f6e2fc1L,
43267       0x0c1b411e3e3cd17L, 0x0c2fda36f4ab31eL, 0x1c467295ce6b23eL,
43268       0x0502a70a7339b79L, 0x1664a985a70e15aL, 0x028261d4536afa2L },
43269     { 0x0b55283b8fa53c7L, 0x07f9c284a3a7180L, 0x10710df3897e617L,
43270       0x01cb4253da469a4L, 0x0abcc6742983243L, 0x140f70b569c4ab5L,
43271       0x09c0a8b700075fbL, 0x17698478d6cce16L, 0x0b35e567ea6e8a3L,
43272       0x03859e7534b39f5L, 0x1ea70f9b8a3ab2fL, 0x09bcaa6f6fb50b4L,
43273       0x056de937dc2ae68L, 0x1c2182112f6561fL, 0x1f71482fcba9b27L,
43274       0x0d5ba7195efa0efL, 0x1d2c27af0b169f5L, 0x024b7234ce38e90L },
43275     { 0x014fc829fa93467L, 0x1bb420759530a5dL, 0x1ebd20cf826f0b8L,
43276       0x046d0d7b98cb379L, 0x01f3216abc85975L, 0x0040dc205fe8404L,
43277       0x1e4ef118ef6985fL, 0x18b7a03f50d7608L, 0x05a21ece62cd640L,
43278       0x1dfb52a1101eae2L, 0x103b7254459ede5L, 0x195eecb744d19d6L,
43279       0x09aeab51f9d67aaL, 0x186b431d45d06cfL, 0x1c1a54b052c857aL,
43280       0x0896a6a99b9b7cbL, 0x1e84f2b5ccfcb37L, 0x0099c48b98981bfL },
43281     { 0x068064045003cd1L, 0x00bde2257156377L, 0x067f7a394c53f6bL,
43282       0x138f9d52b8979a8L, 0x18f37e0181e34ebL, 0x04c8645dabbb169L,
43283       0x129efb3133ec098L, 0x1de178927f2a146L, 0x068074172543304L,
43284       0x1607e5935e45515L, 0x0a6d18ed17fa96bL, 0x0a5cabf7b7593cfL,
43285       0x060485dff44bb29L, 0x06f523cb2878605L, 0x178e8080b144135L,
43286       0x1e68ba59df412d2L, 0x1bd4c8102b46da1L, 0x021175ab9f9c19fL },
43287     { 0x0592eb6a6ad3f47L, 0x10fb6cb8a5d0756L, 0x04641ca05166c21L,
43288       0x04c9d4b006af83dL, 0x14b12723cf7c94eL, 0x1db9b53929bb562L,
43289       0x0f373ca9ae9076bL, 0x15b913d12419740L, 0x0f2e20cb45b0fd3L,
43290       0x1752d2a6b302cffL, 0x0fea2e2277e2f09L, 0x0fc2cd47e57fdccL,
43291       0x1c747312e140f1cL, 0x193cccff84ff5e4L, 0x1f4ac15f466e709L,
43292       0x05b8d53f776996fL, 0x182cfba27d7a0daL, 0x01b42a0e7961292L },
43293     { 0x10d3c9e22799d37L, 0x1bef2d67d199d28L, 0x063c203de56c6d9L,
43294       0x155f91bf849cd5cL, 0x0e842dc269b53c2L, 0x033ff43cbaa0db0L,
43295       0x161df569bcabeb0L, 0x1e5a04114077a0fL, 0x034b473f0654be2L,
43296       0x13e08157a8af11fL, 0x16fe74ab06bd239L, 0x14836d427a01601L,
43297       0x0a97e94c11e264fL, 0x0352c37a0b34bc3L, 0x1e49fa427633cb6L,
43298       0x14acc0e77f0d38fL, 0x134b89778802241L, 0x02cd2dfac911309L },
43299     { 0x1d1c91e81347191L, 0x00d5e75cb4cb974L, 0x1d9ea751a9fc61bL,
43300       0x19b54fa72e0f110L, 0x191b9aa0da93cfcL, 0x0e9e36045f74f8eL,
43301       0x00402099ff5e3e3L, 0x1f7f270c1a12845L, 0x06a6a71aadadb47L,
43302       0x055035bd30ab7c5L, 0x0c1780e6122f267L, 0x046e5555226b543L,
43303       0x19b13f3bd136ddcL, 0x05662fa6bbf3f03L, 0x133f4da342d72f9L,
43304       0x1c1f009b48bf130L, 0x19cf14ef618d3d3L, 0x0233ab260a1f5bcL },
43305     { 0x1725904b6fff5d7L, 0x199d7c96e23a946L, 0x15d5b482e2a80dfL,
43306       0x028775d873212baL, 0x08a2b9b032235fcL, 0x09ae30d17f5a57bL,
43307       0x1d21987140c6253L, 0x1e759256d45d50eL, 0x08eb48b15011bc6L,
43308       0x147f09463cf6e59L, 0x06f032974a801a8L, 0x0e645e2b70a13eeL,
43309       0x0c7a036218f3167L, 0x07c0f04f7f46b94L, 0x1f143641a3ce72dL,
43310       0x03c062ee7e02cf6L, 0x0d50d0f7adbed6aL, 0x04506f70b2774c2L },
43311     { 0x04991bf47366e6fL, 0x026cff4361802a8L, 0x1d46903338dae02L,
43312       0x0c7e32c3c429898L, 0x00445e43bbb46aaL, 0x0f10afab53c2fcaL,
43313       0x002376e346d5f24L, 0x118d51c8a7d8fddL, 0x1c0367ef8bbaa1eL,
43314       0x086c8f8f1f0c084L, 0x13f439f8828b0ccL, 0x1908aa9984eff2fL,
43315       0x1d7b628403f1e80L, 0x1ff050be744dde0L, 0x1c001cddde2a598L,
43316       0x17da53d3b633f83L, 0x0232ce7fe7db6f6L, 0x03d825ae9774be7L },
43317     { 0x1546bc782c5faf8L, 0x1a62f475c084badL, 0x01879de1478069cL,
43318       0x07d2adaa3e7aacdL, 0x03c3c37c833a101L, 0x00a476639a8b98eL,
43319       0x1bd0581dce3ef83L, 0x0ae5d8de177c377L, 0x00aa2ac6ecfa518L,
43320       0x194816bb371d6f8L, 0x154227188b5b8c1L, 0x16474dbb005f9a9L,
43321       0x15338863723ae21L, 0x146c0c1172a32d2L, 0x01a5deb61446682L,
43322       0x04e589e29a0646fL, 0x11c515b081c9c7bL, 0x00e354ad264cdf1L },
43323     { 0x0b14ad5c2821363L, 0x00c11a68bef0e53L, 0x0b1332b7a1220a7L,
43324       0x1304913c4f5debaL, 0x1081d927f412ab3L, 0x05d68fc964e04c7L,
43325       0x07ec5be1ef7d1d7L, 0x0ede955b570343bL, 0x0475a7923b75f3bL,
43326       0x0ee856b6dddd47fL, 0x1d85912dc2ad166L, 0x1102697b35e306dL,
43327       0x0eba9abda32a464L, 0x132b12fdae48913L, 0x06392f933b21c27L,
43328       0x10f39a967233c10L, 0x0c9a5c09c8414f6L, 0x039384501185432L },
43329     { 0x133c0b1f34a466cL, 0x1704e3fcea2dd27L, 0x1fb838a1e17286eL,
43330       0x0d21101103ae1e1L, 0x1b043da3824c714L, 0x037a197120b6155L,
43331       0x0f871ccf69c4f3bL, 0x0ca56b20c9392f2L, 0x0db62d5b0b35c93L,
43332       0x0af5b711f2e0d95L, 0x02d73aec5ad454dL, 0x10d3ee12d2399fdL,
43333       0x1b61a85bd59e081L, 0x1d7081fbe432fcfL, 0x119fa77c5a74f33L,
43334       0x0a2272a4b88e6e6L, 0x1217db55c0b4369L, 0x03a48e3a639932eL },
43335     { 0x12ed5bf80d2b94dL, 0x16319dd25930598L, 0x1633588866846e2L,
43336       0x175d70591d590d8L, 0x19ef9ced317ccf6L, 0x15e6ad16fd94f72L,
43337       0x0c8076a9f626390L, 0x1b927c52b90b2e9L, 0x069e75784d9fc5aL,
43338       0x162384f809551ddL, 0x0a7cdf2174f2e75L, 0x1c4ba7ba957a3fbL,
43339       0x010b3ba22ee5487L, 0x03746e5d807ea58L, 0x19a19932d64524fL,
43340       0x0d6ed6e653f5779L, 0x0416829d1c26890L, 0x045e7e9f2ba0bb4L },
43341     { 0x0882734d3c8c314L, 0x0597888c3841983L, 0x1f0f01a2e85a57cL,
43342       0x10ef248f0f726feL, 0x1f9922275365e0dL, 0x0ffea78aa93f2f0L,
43343       0x18e24281a59209fL, 0x15bab167be45eb0L, 0x183446b896af20eL,
43344       0x0ebcb85a83a312bL, 0x034819008a9a442L, 0x115ece3d86f3b3dL,
43345       0x09057fe91ed1e5fL, 0x0944820c37aa128L, 0x0e4cab7c5376a05L,
43346       0x126f17af0021c3bL, 0x1493e18d1e4905aL, 0x029e56e7bde9bd5L },
43347     { 0x1b5edf75e53d0ffL, 0x1303644455fb38dL, 0x03e04881b457621L,
43348       0x0bc456d466c9236L, 0x1173b317b301834L, 0x04f2cad5d33ca5dL,
43349       0x093463079619df7L, 0x0a69c20c904472cL, 0x061752e59da55ddL,
43350       0x0c5a755cf2143ceL, 0x19e12d247cafb40L, 0x13a43cf2853d95eL,
43351       0x0510f262243dcdbL, 0x1328762e1b4a0a4L, 0x06a5d8041bc642aL,
43352       0x0208cea854b5d6dL, 0x0b169bd75e9c32dL, 0x048424cb25fc631L },
43353     { 0x1390cf65a93c661L, 0x031324edaf82b58L, 0x0a7694685e20612L,
43354       0x1ecee5bd3525527L, 0x1c71487c1b0cbb8L, 0x11211f3733ff5ebL,
43355       0x10be3e6d0e0b539L, 0x1e52dfb4a1d76b4L, 0x0c921b3376089a4L,
43356       0x0e996bdc3af628bL, 0x1b4b2b1040492d2L, 0x04138843f6f57b0L,
43357       0x0bf6b7de33f6862L, 0x149e49341f0ca4dL, 0x171330337b863c3L,
43358       0x01a45a9db7abc11L, 0x1e8c2b75be47358L, 0x01ebfb7fd23466bL },
43359     { 0x07b290cdffbd5d1L, 0x0ced34b819c6ff5L, 0x0c2243fbb72675dL,
43360       0x0a85b9cd1cacd01L, 0x12ae4d82bc690afL, 0x0cadb0428cef95dL,
43361       0x087d1584919fdfcL, 0x066cb346859b078L, 0x055771bf5556516L,
43362       0x1e3449aaa45d2b1L, 0x06480e524bc8e97L, 0x11c73938c02f6a8L,
43363       0x14511e601956752L, 0x0e8b52aa9f83276L, 0x152afb8c0fe7ae4L,
43364       0x09cf87c3189fa44L, 0x0e640994d6ffd43L, 0x047d8969fb6ef3aL },
43365     { 0x06381a2293cb7a4L, 0x104f85c3dbf26b6L, 0x008c1e2b0fbd14fL,
43366       0x00af195d229e425L, 0x116ba4dde89ffadL, 0x1ac0502515b4b53L,
43367       0x04c1c51a06853dbL, 0x11226b1f2f6985eL, 0x1878969962932fbL,
43368       0x0eec28513452d7bL, 0x1c7db7f88e7e0caL, 0x1a5c9e8e933b5eeL,
43369       0x17867ca0e95f20fL, 0x1bacc0f64db21f3L, 0x0ac725f9e163b34L,
43370       0x068a77d28d4b233L, 0x1b14f9303a206ffL, 0x01fe63398bae91bL },
43371     { 0x09debd5df21f920L, 0x1870fe0a00dc828L, 0x0ff656992abfebdL,
43372       0x0a586f424448539L, 0x1deb926bf212085L, 0x19f8ee0ea649fa3L,
43373       0x0f1184bcf93027eL, 0x1a4ac10b4b2b6a3L, 0x02a2f5d62f10fdbL,
43374       0x06eb167ef8659e1L, 0x10928dac3c952d8L, 0x00baac8c256e2a8L,
43375       0x0fa1f5249cc3a5aL, 0x1f3150c45f5f186L, 0x10a64e493b1a40dL,
43376       0x10d0aebe1f7595eL, 0x034d41345dcb3faL, 0x03228a37ee38a8eL },
43377     { 0x0ec633aba1924f9L, 0x1789b00319370f6L, 0x1eb1f943f05eee9L,
43378       0x13de7b1c00406eaL, 0x11dc5a74ca53191L, 0x0a095c4aa2d3552L,
43379       0x14001b887563f4cL, 0x1860378600af763L, 0x0f1789c696ed1a9L,
43380       0x17969afcc2c7d24L, 0x1426e6065efa15eL, 0x0eaa53544cba869L,
43381       0x07c058fa801dc07L, 0x0a5d0a6765681dfL, 0x01429d24b5c2a7dL,
43382       0x0bbb4db8f0a0ad8L, 0x12e2a7ca4a94d00L, 0x022469eb955fdcfL },
43383     { 0x056f14529b33989L, 0x1a8de54d740ad6eL, 0x184d2c1d10521a0L,
43384       0x1479b3e67767e8aL, 0x1ff6e4a3955ce42L, 0x07554889d6f2762L,
43385       0x1bf7f4eab1c5694L, 0x01418c3d932accdL, 0x1108a28b8f6a447L,
43386       0x0177ac272a42264L, 0x16c58b438bccdd0L, 0x063f68def979704L,
43387       0x0c96f2fd893dcd1L, 0x12c9463c1040bc7L, 0x18f11653631759cL,
43388       0x0613e50b467bf32L, 0x1a572497175d92aL, 0x03b440a3ce5b80cL },
43389     { 0x043a11491767eedL, 0x0dcd6c95fb2edddL, 0x13800e978869784L,
43390       0x025466a82bd1445L, 0x0a9ead626360442L, 0x195772e162b1da2L,
43391       0x1875d2f01899282L, 0x0baeb71aaeb17e5L, 0x11cff0ee7d08a26L,
43392       0x1c8a70ed85b8953L, 0x0497412c61a4b45L, 0x1e98ad99d02b86bL,
43393       0x1c9fff0e3ade253L, 0x0ed5f68cd23c920L, 0x1eb941942e741bbL,
43394       0x1c300ce26a4c0b3L, 0x026f37600fb532cL, 0x03387580e2f2d43L },
43395     { 0x173c0af73cdbb43L, 0x07662bf9218d6efL, 0x1504a868e1173c2L,
43396       0x052449bbe322f00L, 0x1eac7eff69a104fL, 0x16899121a979c6dL,
43397       0x0d1dbf0eced39f0L, 0x1e14d3d28616bc9L, 0x07d932340975a46L,
43398       0x049c4cf2eb27767L, 0x0849436c8d17a60L, 0x1264fe96f2d6f70L,
43399       0x154bb90b1f23552L, 0x08897beb1774e60L, 0x0eab8c87ea723d6L,
43400       0x02cd45a1e5f3039L, 0x127b77f03660075L, 0x028242973b1aeffL },
43401     { 0x10f3ce5a2f392faL, 0x003b57636483c17L, 0x1a4a12eaabd8c9bL,
43402       0x0797d1d3275a03bL, 0x0d950908b01b16dL, 0x09d79c38982e121L,
43403       0x0a68319bf585ce1L, 0x04eee6a281da788L, 0x18a31b12a1fabf0L,
43404       0x029800102c598bbL, 0x1f67f2a71f7ae68L, 0x0d37d0ccfa6157fL,
43405       0x08e9a9e13fd05efL, 0x1c8f574e179d398L, 0x0339b10fd326866L,
43406       0x1f160a1a19dcec3L, 0x0c4fb24dc405240L, 0x04c97f0a8fbf486L },
43407     { 0x054db3138f197aaL, 0x16b4ec3c397cc22L, 0x1ec113c2a0a2937L,
43408       0x1d463c918d2f684L, 0x1d98efec9821e1aL, 0x0659d771c6584feL,
43409       0x155cc82e13ea120L, 0x0d774b769508e8eL, 0x0a9be080acd50e9L,
43410       0x0228f4e77881aa8L, 0x1b9d7f1104c9731L, 0x1d30714bc67ac4dL,
43411       0x19a2b0abd26eea5L, 0x0db04154b990df5L, 0x0af30ab2a4b9212L,
43412       0x173f63b902d1532L, 0x1e0134ecf4b9c8eL, 0x02d345fd4262db8L },
43413     { 0x0ff3b45ff0a2bfbL, 0x0fffcaa817c585aL, 0x02156c70309b441L,
43414       0x161a773a0829bcbL, 0x026d3917ed16865L, 0x0d9e0717ad12298L,
43415       0x03cb9a88bd24fd3L, 0x0c290e2a915c483L, 0x06ab363a8509befL,
43416       0x0e50f1d5c65ddf6L, 0x03726100468e5a4L, 0x1c141ab94aeee3cL,
43417       0x0581897bc1ff982L, 0x042d6af3f5a0582L, 0x0cdedf12f092918L,
43418       0x0c51fa2b91f414cL, 0x03956ce6ef7bef1L, 0x03c567efccfaf7aL },
43419     { 0x1bf7f15f8520189L, 0x1015063bfb0e222L, 0x1ae77e88b86e550L,
43420       0x0e3e94690e73db8L, 0x0814cc52d2d6026L, 0x14f891e6c99c94aL,
43421       0x0dbdf79da849017L, 0x1c1c460dd415c6dL, 0x053815218b83a58L,
43422       0x0315dbb5020918dL, 0x0894f2fcc6f9c66L, 0x06646fbd0c3fd1bL,
43423       0x1690ae48902dfc5L, 0x05d53769792e49fL, 0x02d28a59af2e3c2L,
43424       0x19292de215c1f21L, 0x1668cb4b48cb061L, 0x0056c96b9e83ad1L },
43425     { 0x1b95fedc2ca548aL, 0x063104066c4d5dfL, 0x152cd19b0a011deL,
43426       0x07a97d12057d322L, 0x13e681edea3be09L, 0x1a00b0c23dbcca8L,
43427       0x1ffa3c8aa3d2c0bL, 0x1ec7de5969a95d6L, 0x19adc5151b3aed5L,
43428       0x00e67e8cc6188b1L, 0x0b05ee8f5f623fbL, 0x09a68c84212fb85L,
43429       0x1794b90bcf08fa6L, 0x05a854f5af5fc05L, 0x06a99ac6de2d2e8L,
43430       0x079da349fd2684fL, 0x1ae8ef4dcaf075bL, 0x04addec50385374L },
43431     { 0x1f92495e614bbd0L, 0x1d443dc11f1b1acL, 0x07b3f06f5a9dd59L,
43432       0x0f1d06b885c48f9L, 0x0ade066a2bfaaf4L, 0x0b699b18a77a705L,
43433       0x18e241caea98d70L, 0x01ff48538e3c5e1L, 0x0cac1e5d0bd07d9L,
43434       0x0ff9af528a7ae02L, 0x014ff301553b05aL, 0x0d6e546b28ff126L,
43435       0x002aebe487ab1d8L, 0x0fdce790f14fd83L, 0x037f3d6828435b7L,
43436       0x0f4555a28e0b3e4L, 0x119480dc66fb886L, 0x01bad4427e092d4L },
43437     { 0x18cbe2e1217f7eaL, 0x10f1543ae36d58bL, 0x1b006f6c6950685L,
43438       0x01c9fae795eee0fL, 0x113a0d86678864aL, 0x0983345d75e3326L,
43439       0x1654100c97e6723L, 0x0cf727db3925e38L, 0x1fdf36763541e06L,
43440       0x0cbfdd85c8d33b1L, 0x09a7a981e72683fL, 0x19003d55188e4d5L,
43441       0x01afa63c55c7303L, 0x07e8956def63ae4L, 0x1a20e2807373789L,
43442       0x0a6f33fc1bb4e32L, 0x0ec66bb093b3841L, 0x01346c0c58465c2L },
43443     { 0x1dae35841580555L, 0x19733a39e881db9L, 0x004efb3306ad3f0L,
43444       0x05649dd3bc48182L, 0x1fa8e066da4099fL, 0x1c6bf71bd865adcL,
43445       0x00502d6b8139190L, 0x0f0fefa62c856e4L, 0x186ef4edb339e4aL,
43446       0x0f3bf769d3ec1baL, 0x1eb4def5c1f0ba9L, 0x06741f2f2313107L,
43447       0x0a2e7a208e816b6L, 0x021aa8b57126014L, 0x17cafd445c7f8f1L,
43448       0x074ac7d7276669eL, 0x04b8419ed4b01b5L, 0x0458139ae02b652L },
43449     { 0x09bb464e1019195L, 0x0601379fe1460dcL, 0x19b8aff0ec84779L,
43450       0x15237bf25f58241L, 0x0d995bc9ec71bc5L, 0x048fff242ebd5a0L,
43451       0x189965f19da3b99L, 0x185b2aa5a335f79L, 0x1bae6c7fe8e1b76L,
43452       0x13ec140ebf1d68dL, 0x126be57a625cd05L, 0x0499141903047c2L,
43453       0x1bc3006c0dd1f00L, 0x0c3b9ea67ab8ffeL, 0x0d50362ccbb3df9L,
43454       0x0a084b0454f05faL, 0x1fe5ab45c3f0436L, 0x020071d5025a6c2L },
43455     { 0x13216495e46e4a2L, 0x176b21209b03a23L, 0x0ec7183b1df4de8L,
43456       0x07cbc1585ccb244L, 0x05107ab75e13aacL, 0x0129eded0be20deL,
43457       0x08a5996c8bb25cfL, 0x137fe70cf714a02L, 0x1fed660d50621a9L,
43458       0x1e14283644fe1faL, 0x0d42e7c591469e8L, 0x0064cf96b0de7daL,
43459       0x19967185b127c3eL, 0x0509804de403e3bL, 0x0bc7d3427055f51L,
43460       0x143306c5eec8f5bL, 0x0394a42b9acf3a6L, 0x0098e1ed146d370L },
43461     { 0x0785ff1a7da83baL, 0x0da12e827a21b25L, 0x06f7b00fe04bd05L,
43462       0x1501ebe944f8113L, 0x1da251b9c58d411L, 0x1d97991e996b087L,
43463       0x020f266ed141334L, 0x1fa33188897e984L, 0x060c261af730e83L,
43464       0x106526fe5816dc8L, 0x1e0e2e77c79f201L, 0x1f2f898d21921feL,
43465       0x175d75f1546b79cL, 0x0e58747f898a8a6L, 0x105d8569f01d3c4L,
43466       0x01fe17241558365L, 0x0e9de8098ad44aaL, 0x038e8d2351a2a2eL },
43467     { 0x0178f76fa1b382eL, 0x07661bb96ed06bbL, 0x0cab175344c2836L,
43468       0x091ae4c45954b55L, 0x0a3bed0627d38baL, 0x1e7667e2a086db6L,
43469       0x18f5fd8de9621e4L, 0x0823ecbb5fadccbL, 0x1c3b44a8560a456L,
43470       0x1a3d9d427bc2a05L, 0x1f6b75793583d83L, 0x12182fa76dab049L,
43471       0x1f325fc13ad8ccfL, 0x1b247d5c804755eL, 0x114b52cfa435c58L,
43472       0x0159672c9fe7449L, 0x121b95cc416533dL, 0x0366934cf88b3faL },
43473     { 0x18c0b3b12f4f3acL, 0x0e7f14ce8defd96L, 0x13e0c3cdcc9ac0fL,
43474       0x06f8b51904a8006L, 0x0d8f144222dd689L, 0x0ba17975b849e86L,
43475       0x16b76249e569d61L, 0x0bdc2be505810f5L, 0x07bbdc74916ab7bL,
43476       0x187f205d2c565daL, 0x105faf8aeb0e6f4L, 0x134d8c3409781bcL,
43477       0x0df27355694b4b1L, 0x18558cb7c99c61aL, 0x0232597a3c0dd08L,
43478       0x1704df45df970d9L, 0x1c219eee274c7eeL, 0x0193e031fed1a2eL },
43479     { 0x1399eff5b47cd53L, 0x0c34e8ca1d77f55L, 0x11ec500aa19aefaL,
43480       0x156384b42dcc9d9L, 0x022de271c3e7c2aL, 0x16b52fe210b5bc8L,
43481       0x0ccdb9637f320d9L, 0x0f9a2b2a13db502L, 0x0370400f2130bfbL,
43482       0x1f2702cc9da43c0L, 0x0e87f8e7cf34886L, 0x0565dd969f0e0c4L,
43483       0x166c27b83b72aa2L, 0x0d2fd2df8d7a624L, 0x0c06bc9e90aa52fL,
43484       0x0225935f7504491L, 0x056eb6b9d2a3670L, 0x001078ce8e06fb4L },
43485     { 0x1051a86a4dbba20L, 0x075e36d8ef2e29bL, 0x086799496102d86L,
43486       0x1ba579989b34f01L, 0x10285a249440302L, 0x04313474ff811e8L,
43487       0x0451cee4dfb8ce9L, 0x19fc6fdc5e499acL, 0x079fbbfd3a3d057L,
43488       0x1dd0b69e66ef7e7L, 0x0163b16c8c5c9d7L, 0x1d7ce41875b722cL,
43489       0x068b4f6bba47699L, 0x18c503b81313a1cL, 0x128458152c024abL,
43490       0x11ec133a121d759L, 0x144f757e1ff0c88L, 0x03cf39390580282L },
43491     { 0x12acf252820a239L, 0x1cba75573598831L, 0x1ae92302877ec68L,
43492       0x12b47dcf55ac3faL, 0x1980446dd2453c3L, 0x0b33b7aa422ad05L,
43493       0x1d6867ca765ef78L, 0x10be4a59418f126L, 0x1e961af3e7743a9L,
43494       0x063ce2b3366dec6L, 0x0e153b2f14e3e5cL, 0x0e75424d0a38294L,
43495       0x052a9f558c58daaL, 0x1de8af02f4daddaL, 0x0864e74debdfe0fL,
43496       0x140ad4890f24e71L, 0x06de428b2b59511L, 0x0000e9e71b80ac2L },
43497     { 0x0be36b9e145b1d7L, 0x1c9c5004e2b326bL, 0x19f79f03db6fcf8L,
43498       0x0d8687ea725cac5L, 0x190897b1951044eL, 0x17bcbe52d5b15c6L,
43499       0x0a392c687dc2d44L, 0x0bb239baea8ea1eL, 0x1b4c80e2fffb816L,
43500       0x0f69ce3aca68159L, 0x0a92755a0cfb719L, 0x0979e6d27431982L,
43501       0x0afcd2c404e7369L, 0x08ea00ca1a6609aL, 0x16179181c6f57f0L,
43502       0x0f4080aeb208ff8L, 0x084b3280360790bL, 0x025dc637e2057e3L },
43503     { 0x120e2ddfd0f8796L, 0x05206d899e4ef18L, 0x1b02a4da71b9a5aL,
43504       0x0cc00e4e77fd46cL, 0x0cb8143937e5b6dL, 0x15e0029cf276784L,
43505       0x0d4f121ffa7367fL, 0x1d7d715e8880333L, 0x02f124e3b293519L,
43506       0x10610c564164e0bL, 0x075bc9c27716421L, 0x0a8a6daa0a5359aL,
43507       0x1959120bfc5696dL, 0x087fd348601faefL, 0x10ca09e668fa234L,
43508       0x0bb13a9f39f4ad8L, 0x0782e8fea9e9a13L, 0x01b4cd440db53bfL },
43509     { 0x1ca33721eb1c64dL, 0x19d16f8e940aa2dL, 0x06cd94dc41bfa73L,
43510       0x029ef97e9b6fc5dL, 0x0058b37f06c1715L, 0x1a74e2e5ef20b71L,
43511       0x0e9d60b14e9fa20L, 0x00529b7bfc5d358L, 0x1795ec6cbc5e67cL,
43512       0x011e12f8a135406L, 0x134835aa353e7e3L, 0x14a9a76f846bdc5L,
43513       0x003d7a4d52838daL, 0x1c0e5a39dcf0476L, 0x10c72ab2a51d7a5L,
43514       0x0a30ee4e3e73cbdL, 0x18b1df08e9f8253L, 0x0279d258190457fL },
43515     { 0x17b81071ed095f8L, 0x1bfd36d1136a707L, 0x014abecdb4748f8L,
43516       0x1c0fb1c623161f3L, 0x03e0f16eb114634L, 0x0f761bdcb1a54bfL,
43517       0x087049152ee7108L, 0x0f969d9abb7ae56L, 0x0f96038686df20dL,
43518       0x1a9acfeefc37051L, 0x1553e96b1222aa7L, 0x0957a2093be9887L,
43519       0x1eb020607a56d71L, 0x1d01192f098a959L, 0x0ba136d26f87061L,
43520       0x0f70089e49e94a5L, 0x1fd9e525c030b5aL, 0x036c3a2235368bcL },
43521     { 0x09d07aabe9a42f5L, 0x098b61bc0e66469L, 0x09b6771a7a847f5L,
43522       0x1f11fdd234e34ebL, 0x18d44f124e19e0dL, 0x174a724ce15a6e7L,
43523       0x1330817db7e48c6L, 0x1d64ff750ed9e51L, 0x06e1a0f01f57f7cL,
43524       0x01f8f9a79fe9dbaL, 0x17129d0b07484f8L, 0x04e0fbd70b0141dL,
43525       0x1faf0848bc5caacL, 0x03d63ace87aebc8L, 0x13f14c45fd452b4L,
43526       0x01e7b2b472e6920L, 0x00995a4aca97bb7L, 0x01e79c264ffce2bL },
43527     { 0x00506bace1fc9e3L, 0x10ba133b581ccb8L, 0x0e379cafdecd25cL,
43528       0x10f36413ee56943L, 0x0e26a8e1ca8602aL, 0x1279cd482c05c86L,
43529       0x18b847bcce6dff8L, 0x1e96d8bb322c526L, 0x151174e1a577b24L,
43530       0x1c07e5a82f228f4L, 0x05ebec520c86f7cL, 0x0d76e8fcba55e9bL,
43531       0x05be99a60809980L, 0x0a2af41042a92ebL, 0x15829949920a367L,
43532       0x00ee11918a80bb0L, 0x1263c67e73c7103L, 0x0159244287739efL },
43533     { 0x173cde68541159fL, 0x1260c27da085910L, 0x18647cb2871de08L,
43534       0x0d51647c800f450L, 0x06b2344a52c207dL, 0x1694a2838d01085L,
43535       0x131b36c3961f2d7L, 0x172d8ad71df021fL, 0x11248c58f62d843L,
43536       0x1c81b1eba6334baL, 0x03dfcb99b19bd92L, 0x0883824d797cc69L,
43537       0x0373ce49e8b2f9dL, 0x140d86f85603f95L, 0x118874549219d63L,
43538       0x0943942116a9a3aL, 0x01517261ece7441L, 0x049c59de6351d61L },
43539     { 0x1e4a16be4ded340L, 0x0fd954074401b54L, 0x181b735ceb2e399L,
43540       0x09554caf532e112L, 0x09101b061c3a043L, 0x05db2679827e2c2L,
43541       0x0b7d7983ed86b68L, 0x0bf031855d9eaa8L, 0x17402057656f76dL,
43542       0x0b35bc849299ecbL, 0x195795d35bad7edL, 0x036b4ab6896f5c8L,
43543       0x1b93747ea560f7aL, 0x196d672b3cb80bcL, 0x1a0f01a2b9f83a3L,
43544       0x0e683308e8c0f09L, 0x16b24e8c9ed1530L, 0x0367fac52ecf44eL },
43545     { 0x08c01b003e51f68L, 0x0f9128e97f3eb28L, 0x142c26f62017874L,
43546       0x1407c82b6fef331L, 0x007d9798255e907L, 0x029c4b68a4233ebL,
43547       0x143d01570ec7a6dL, 0x1b86a002027013eL, 0x0fbbb2fa6d0233fL,
43548       0x1b405857f8c105cL, 0x101370e34c5f802L, 0x088999918fbf63aL,
43549       0x066ec13f84133d5L, 0x023717243fd423fL, 0x18eceb30cfe0f60L,
43550       0x0d5ee78c4ff8a90L, 0x1275f67f8aaeb93L, 0x02ff2564798dbc9L },
43551     { 0x01aa4bf8b6f401eL, 0x18951d6ae3f6a2cL, 0x1c99bec1ed28176L,
43552       0x09384579a8f6030L, 0x09371c95fdd11f0L, 0x123757aa2a53ea3L,
43553       0x05b4019b157ee66L, 0x0b830c6f8f8ffdfL, 0x0bafc1d346b83e9L,
43554       0x0e1c2c9805da16eL, 0x17b0acd39f9c495L, 0x1f6163099dd1bb1L,
43555       0x0249a2786469c9cL, 0x10087973c6e6062L, 0x1de9080a43657c8L,
43556       0x17b5b0dc4a992d2L, 0x14820931c89eb2aL, 0x0409bb8b2090e02L },
43557     { 0x066b25e9c5a8edfL, 0x1c461083c53d6b1L, 0x0df521dbbb7db84L,
43558       0x12c4e88c2ebe04eL, 0x1385382a242fa7fL, 0x1b8df79f167decdL,
43559       0x02a4aeb6b5ec40bL, 0x068ac5579f4cefaL, 0x0573ebd1751fdffL,
43560       0x1fb2c293e12863cL, 0x1c5bbb11f2a25b5L, 0x1360cec4593dc19L,
43561       0x02f8f2c0758ccd7L, 0x1300428a98fe2c4L, 0x1a316ea48cacdfaL,
43562       0x08dfc9af766c305L, 0x198bf24735cd2f1L, 0x03ce140774e696dL },
43563     { 0x1cc8203f2b48122L, 0x0248b582562475eL, 0x13727f12217aa30L,
43564       0x0f0582003959e0cL, 0x076de250ab83899L, 0x0d5c10399cf390bL,
43565       0x12cb85ea96baa38L, 0x06049a51940d782L, 0x0570c5bb7816b62L,
43566       0x02891ae67735b03L, 0x0fe27c60fab909bL, 0x078d38cc4e96365L,
43567       0x06b51e38bc3e3afL, 0x19f2071df058221L, 0x0f96f909b6f1639L,
43568       0x1e8107f3baaf16bL, 0x14f9fd9f79152c8L, 0x03ac039d254f1ffL },
43569     { 0x127b0578691ca22L, 0x15feb09d150db3eL, 0x0e16b1e5504fc81L,
43570       0x14eaa6cc0fd097aL, 0x08a0e24cc5d18a2L, 0x03a6de970b36f3eL,
43571       0x010e95b55d430f1L, 0x065bde8898226cdL, 0x114646e53cf4b84L,
43572       0x1e0681854fecbc1L, 0x132090a5fb880d2L, 0x017ffaf7cd8f7b4L,
43573       0x1608c7f3ff3d0b1L, 0x1a7ea6229690b23L, 0x1a784101b949666L,
43574       0x1a65bf7573f4293L, 0x0a89342a7fa8661L, 0x01f9f1a2c7d7b35L },
43575     { 0x1ec35af951597aaL, 0x1ea5624efb275a8L, 0x16726fd3bfd6d9dL,
43576       0x12a2b4526a04ed9L, 0x1d9bb9c3423eca4L, 0x10f84e4534b2a9fL,
43577       0x17e63e67ba77fb7L, 0x06571f452ac333cL, 0x1b763875835292cL,
43578       0x19a76ee7e20740dL, 0x157a7d9515f6561L, 0x047c618f1a57b05L,
43579       0x0cc1433d67c8ee3L, 0x1e418a5773bd972L, 0x038bd8d5b67e01cL,
43580       0x052bc883ddbc454L, 0x0ef1e9e17ed6c48L, 0x0320690621a614aL },
43581     { 0x09a0b8e3284d513L, 0x01aa2f98a829d27L, 0x101d16b354a81d3L,
43582       0x183bca1b6f66dceL, 0x0549fc46d80bdcfL, 0x1f83d446cea3ee1L,
43583       0x15308a6dbbc4cc0L, 0x0e69c8c3594da95L, 0x1ca8e351dfc9f1bL,
43584       0x1e204a6aba30732L, 0x00accc3ccb4d9e2L, 0x096c50ae85d16c6L,
43585       0x11876c29c369a07L, 0x0895e8bd6ff2958L, 0x06a98e7ce791826L,
43586       0x00b831dc81acc69L, 0x016b968902ac72eL, 0x007ce0e54606c94L },
43587     { 0x0bbaab367433df3L, 0x129a38ae9b1460fL, 0x03625fc31732daaL,
43588       0x16cbc811f227464L, 0x1537345172c918cL, 0x06e504a5b1c42a6L,
43589       0x04c99cc4e668c2dL, 0x1119e4ace601476L, 0x15ea60dfa6608b3L,
43590       0x056ba583d9486feL, 0x009e275da53e6d6L, 0x1b716cc61f63064L,
43591       0x10c65e3eaf48593L, 0x1f3931fc1eda3fbL, 0x19bfccd8e527244L,
43592       0x1048137359d8dcdL, 0x0c534bd9ba7098aL, 0x03f18e097a2e9b7L },
43593     { 0x0281d680dfd2dd7L, 0x165801255b0ec5fL, 0x017e510c7e5c7beL,
43594       0x152b39677973860L, 0x0ffbb406660c8dfL, 0x14d086feeafe186L,
43595       0x1f46de918c6f9e5L, 0x0ec66dc613dbc27L, 0x176b3bfadfc9470L,
43596       0x148c92eee639111L, 0x1c35cc55b13b87eL, 0x1c821c566e8ee83L,
43597       0x13efc4d93c4f64eL, 0x1e27dd97435f496L, 0x1f286ef14edf80fL,
43598       0x174c15832d9ea66L, 0x1574de41a307e23L, 0x00d10ce229936a9L },
43599     { 0x1cf7ef8aa4db0bcL, 0x18c033db64cb1feL, 0x019cf62864bcb88L,
43600       0x05ffb8eee384c72L, 0x02fc0edbc0cec2eL, 0x063021ccbe471adL,
43601       0x00481e3843b060bL, 0x11dfa1bc5965619L, 0x14d6c457f69e57fL,
43602       0x09f34d92da9f8e1L, 0x08cc2b13e272e25L, 0x06532aacd7cc845L,
43603       0x0d437442d192ff2L, 0x1f534a01b9e6a81L, 0x00c198bc1339642L,
43604       0x17f26d582a6fdf0L, 0x12fe02bcf77b6d0L, 0x00bd554ccde480cL },
43605     { 0x13d56438e55db2eL, 0x0f7219dca342886L, 0x03956e2118be0d7L,
43606       0x0bd42fc4f834288L, 0x1d95f7a9a6ff3b3L, 0x0b396791fcce1b6L,
43607       0x11701c85ff766f7L, 0x04be801583dba40L, 0x094b55c874ff06bL,
43608       0x1225072872524dfL, 0x097a46d0eda04c2L, 0x1bc2429f2d8bd12L,
43609       0x0c0f97fa9778bedL, 0x12dfe93387a2b52L, 0x1d823be8a3f61aeL,
43610       0x0e97876965b1f7cL, 0x04afbd5ff8c2264L, 0x03594157852f9d9L },
43611     { 0x0fc025f6341a595L, 0x01c6b5222f1463cL, 0x18f7ad11a109647L,
43612       0x06eaa8f066e57adL, 0x083e16c43f9466dL, 0x13d65a488a0a698L,
43613       0x1ed905176519a56L, 0x162205bbe131fa5L, 0x02a2b2d2d0bfd87L,
43614       0x0f4df2e2ca2a844L, 0x1e2fd2a0091779aL, 0x1ad16460d61ddc6L,
43615       0x06c2be9f3d80b0bL, 0x04016122bb52a2eL, 0x104b7ed0a7459edL,
43616       0x12ec427cc884e56L, 0x0bfb664f529ee8dL, 0x036a7ae91aa3837L },
43617     { 0x1c8f2b600ba9f88L, 0x003f03ddb685f9aL, 0x150acee0796ff72L,
43618       0x1d4f58f03c1424dL, 0x137dcba6335ce6cL, 0x04b2439f184737fL,
43619       0x10d340a3729898fL, 0x04ce5d74afd1030L, 0x1a9e3d59f79b78aL,
43620       0x17853ee9783d751L, 0x1919e093417dd34L, 0x02e0022dbd6dc1fL,
43621       0x1258f37580b2085L, 0x1a0385d9ce152f4L, 0x05df6439e2f5e95L,
43622       0x10368aa3f90e573L, 0x0ad6eda93c440dbL, 0x0255785a7eb2e9aL },
43623     { 0x1ef25063514c7afL, 0x13ed6de0c0f56cdL, 0x1a1e3e8fb162c27L,
43624       0x0a2e770d0bde795L, 0x121d32ddd8dbfabL, 0x0ce233592487e04L,
43625       0x16f6d3bbce1ae2fL, 0x1b7839baa5f40c3L, 0x064de989a25bc04L,
43626       0x17cc1b5c2b9431bL, 0x16a0122f912a801L, 0x1c9c12e0318e234L,
43627       0x17b2c11fb116dedL, 0x1390f66cb95762bL, 0x1afcea45136b786L,
43628       0x029aff338a4d7adL, 0x137a1d4165b1c2eL, 0x045965e9cc15e31L },
43629     { 0x0ec1bf28a52e991L, 0x1017b67cea17614L, 0x04c318d3a9142e8L,
43630       0x078aec5739060faL, 0x087c2a2d3fc257bL, 0x0ca4455e994c68aL,
43631       0x01b4b2853c69e8cL, 0x1138e1952760d74L, 0x19aa3f4b3ee405eL,
43632       0x03277599aef7573L, 0x17d5e00efc75333L, 0x016a8ac2d7fba2aL,
43633       0x06086e33f6041ecL, 0x18121e7a91efc07L, 0x1333560e669e723L,
43634       0x190630d85049d0eL, 0x070220eeaec8fc5L, 0x02bf141823edf1bL },
43635     { 0x060b698fbcdf666L, 0x0354cc5f5d8e937L, 0x16ea012610daf74L,
43636       0x1ca457911a80895L, 0x08423b20d76bf75L, 0x1cc53932ae25cd9L,
43637       0x1d8059703d2494cL, 0x0b4eda9e56e1946L, 0x1469899252030faL,
43638       0x159bf43db02a382L, 0x1bdcc54f786cbe5L, 0x19195aa9de0bdf2L,
43639       0x0aa93617b05ecbbL, 0x1e5d10bef5944e8L, 0x1528b5ceb03ef55L,
43640       0x0c0c7a1a796ac33L, 0x1a6e8bee9d4c91dL, 0x02789701bb4b7feL },
43641     { 0x0cfa42215f1a610L, 0x12e2a9bc328cd26L, 0x1151ce0e04d2012L,
43642       0x0896509c54248d4L, 0x146d1320fa15b48L, 0x14507d1b2326328L,
43643       0x0013bedaea231c2L, 0x0d4e9cf9dcf2789L, 0x18c34d22cb95ae1L,
43644       0x0cf6c4ffce0ea6eL, 0x0219b4c8094dc67L, 0x056537ac8894c34L,
43645       0x0cf277bab145b23L, 0x14a245817c44749L, 0x1487b2dcf9a71baL,
43646       0x15f643492dd52b6L, 0x191a8f78ea75858L, 0x041e9199f589337L },
43647     { 0x063328867b478d7L, 0x10d70a8517e4e0eL, 0x0cc06348906e87bL,
43648       0x111279ad2c0b6d5L, 0x08117a8769f1f28L, 0x139ebb8aceb3305L,
43649       0x17c2ba0480465c3L, 0x164a51fde0127eaL, 0x1b3978db8d854dfL,
43650       0x15a1f7b7a2ecfddL, 0x192ffb56fb8e5f5L, 0x1eb2d7eedb5a2fbL,
43651       0x0e3d40754ca01e0L, 0x1c7437799459140L, 0x147961a3b6d848bL,
43652       0x14ab7044d6d5f6fL, 0x021463532152f40L, 0x039b1789f62d18bL },
43653     { 0x12eb27c73c0c430L, 0x0532fd28e1b2bbcL, 0x1b3b48653c6e330L,
43654       0x110296928ea14b9L, 0x0b6fbbf41894568L, 0x1543045df8540d2L,
43655       0x1e578ddbd3d63c2L, 0x1abb26c3ad0730eL, 0x1b6510cd8e3a8d0L,
43656       0x1f17edfdb60d22aL, 0x04553abb2247e58L, 0x0e2bfead1ec8592L,
43657       0x172f2b399e0eb1eL, 0x04f85f85f3d7ce6L, 0x060da547f0e6eb2L,
43658       0x04151e10c3b2521L, 0x0add9b16f02da0aL, 0x01788349fd1c607L },
43659     { 0x1a6ce910c06ded2L, 0x0421797ec843d83L, 0x1f5aa7d8d69be5dL,
43660       0x023dac0c4dc8d17L, 0x169ee54804b6189L, 0x0b51008fd97c4f9L,
43661       0x0ceb272f4444f72L, 0x13cceb359fc21acL, 0x164ba66fc8faa62L,
43662       0x1435724a3f9c141L, 0x10e81756736a669L, 0x162811d45edd051L,
43663       0x04af3953c87c7afL, 0x0ed54f2792a8e47L, 0x1bc65016d4f49e6L,
43664       0x0f9b63dfed1a95aL, 0x0432775dbdd9643L, 0x04c2fc1f227f3d0L },
43665     { 0x1603c16eaf45294L, 0x188b06125aba8c4L, 0x0060e75ad4b5c04L,
43666       0x05db28668098224L, 0x14f41b687079cf0L, 0x0560f0862d8145bL,
43667       0x13c38f70fc1da72L, 0x044b58bdd47f164L, 0x0ee6684bae34c5cL,
43668       0x092cf31cd5e2295L, 0x14b347a77d17329L, 0x1926348879f560fL,
43669       0x0992c003b307019L, 0x06c65e17347eed5L, 0x1e0729cb67c5e70L,
43670       0x18f3377e2b4de3cL, 0x0f154d779d550dcL, 0x0064472a007f4b1L },
43671     { 0x0f71a6ae8f44357L, 0x1a5fb1d1e55b542L, 0x16796baf1a03dd6L,
43672       0x0914ea7de466993L, 0x075e3c8ececaf08L, 0x07c69d71400a608L,
43673       0x0cabaee7568e3ddL, 0x124eb3108c9701cL, 0x17b328e6ff2bc37L,
43674       0x1dd8fd7f76870cbL, 0x1ab25568cc196baL, 0x1b1f245b79d0ce9L,
43675       0x05987b907a8c19fL, 0x1d9d166bc60bd74L, 0x01ddcbe27ccd89cL,
43676       0x19dadd75d4033f5L, 0x1154e5de4993a25L, 0x04712b05c578883L },
43677     { 0x0d3746c3141aba6L, 0x083cfdd5967cf2bL, 0x00c673749f1d168L,
43678       0x053bfb2a1d6c705L, 0x1a9408ff2223763L, 0x0b008c0f058ae69L,
43679       0x0ee9d26a00802c4L, 0x1aa4e33b6bb4707L, 0x16078340a651046L,
43680       0x094ea6f4ba91d8fL, 0x00d1723828a2ae2L, 0x158415be138e808L,
43681       0x052331d61161275L, 0x09c8e5285a0d593L, 0x0488c548c331df1L,
43682       0x13453117c19251fL, 0x0e5fef3d92b92fdL, 0x02c802f91419279L },
43683     { 0x1b1750c3c4c1c74L, 0x1d56074b37dbcb5L, 0x16499b165cfef9cL,
43684       0x04750cad6d0b4ebL, 0x10446cde8c97f93L, 0x19c4bf95b821d8aL,
43685       0x1cac952245bdcffL, 0x1cd227ba0396316L, 0x0d0a751f1488c0dL,
43686       0x08bab8a42ac652cL, 0x050c0512998f686L, 0x015961c10c312eeL,
43687       0x0cf39ead9c2df19L, 0x0b9c16d080407e0L, 0x18a8ce00216b1b8L,
43688       0x15d1bd2f230a264L, 0x16ee4495936b43bL, 0x02bd3c7136bc1efL },
43689     { 0x01b346f40dbddd8L, 0x0d493ca0861d60bL, 0x1e0c621b3cecad2L,
43690       0x0467727bd718a84L, 0x00df579d72df323L, 0x077a804e46acfaaL,
43691       0x0190f975e99f708L, 0x18788d67230cfe1L, 0x0ecfa2445ad96adL,
43692       0x0c7ac4d8622a268L, 0x124c0782105f5d9L, 0x1ed588a9c511cddL,
43693       0x0fac0f462d6ca5eL, 0x046c501b20c8824L, 0x14d6dfa14901f60L,
43694       0x1b50f698a674fedL, 0x0e83251e4128f6aL, 0x00e51b862c0e239L },
43695     { 0x0bd5171a801b68aL, 0x143ce7e8ccc59caL, 0x0afd0458c809cc4L,
43696       0x09eb603fb6920b5L, 0x1cda128bb5fe87fL, 0x1e98fbbc6f291d4L,
43697       0x130d42fc586871eL, 0x05b6bbd9fa04720L, 0x0224b2882e188f1L,
43698       0x0e9400efcced73aL, 0x119ed4233473483L, 0x187b810cfc7395aL,
43699       0x002b4250726c311L, 0x177ec801b8d08b9L, 0x0f4ec0e0efd1938L,
43700       0x0b754a7a089143bL, 0x07932db52f4e626L, 0x012c259a62619d6L },
43701     { 0x0b863892aeec688L, 0x1a05d22fdf2919eL, 0x07dff582d7e2979L,
43702       0x1890e9227a845ceL, 0x1a17d80d455d185L, 0x02a29202615d9b7L,
43703       0x0995cfc9c6152b0L, 0x190edba608b5173L, 0x02e42c3e162ee7cL,
43704       0x013338326fb63e8L, 0x1f754771f2d2200L, 0x157c30f12fc0b24L,
43705       0x0ef2d5737c6b3faL, 0x1fa8d4ffff35691L, 0x001eeaabed809a7L,
43706       0x14935c3906a8ad3L, 0x085acddb6ff951cL, 0x03f4089ba1fcd58L },
43707     { 0x1722a8b830a88b1L, 0x0c75467088bf0d6L, 0x02e01026d1f6464L,
43708       0x06d88da3a67c05aL, 0x0589669cb53812dL, 0x1866af17e84ed87L,
43709       0x1114e6117341856L, 0x19618382ab4470dL, 0x1da774de5f5ff43L,
43710       0x183b5cc71c8e066L, 0x1c7bfd4013ca1aeL, 0x08d95dd817fd2faL,
43711       0x0732a1ad9423e0bL, 0x1cb6d2117229c33L, 0x16caffbf8327e04L,
43712       0x1f522c6ed8344c7L, 0x1a6001c7918ba56L, 0x021b5c6326fc242L },
43713     { 0x0117e9d8ab764bcL, 0x10f4a503befc244L, 0x174c3063baf77e9L,
43714       0x1ff928a3b8b4eecL, 0x071a347a548916aL, 0x1da0ef80d297198L,
43715       0x10a198cee577ac8L, 0x0d1bafad1928791L, 0x1e4f9d41e18d970L,
43716       0x0c845c846493cceL, 0x10523b51ce528deL, 0x0a2f9aa3ca7fcc2L,
43717       0x1e0243dcb6e5018L, 0x0bcaa202a83003aL, 0x1f697ff97737988L,
43718       0x196ccdef921c2a6L, 0x1e11df7aae40768L, 0x02933654f36df4aL },
43719     { 0x0ddee6d1386b3dbL, 0x057ad3e1c72a042L, 0x1103ac13d277e79L,
43720       0x11fbcb49fb66830L, 0x10257cfc2138a1eL, 0x1eb8609f3734921L,
43721       0x07fc0d4671b8c67L, 0x1d11e69c2e90d86L, 0x0f1e298fd940ce1L,
43722       0x1dc658e8a4b06beL, 0x104d1cacbceffdbL, 0x016828ddf1fe40fL,
43723       0x0b7bd3e220899a2L, 0x1135f513bef61b1L, 0x0d32d9ea5d41139L,
43724       0x0e0741e6568929fL, 0x02bc17a09201fc6L, 0x020f992dcce6c25L },
43725     { 0x12ed513ce2843a4L, 0x024c70039457e18L, 0x0089361933979d2L,
43726       0x094c40107751de5L, 0x0bed338d3406470L, 0x1f3d9c2c82f0ecaL,
43727       0x1eee4a95e32d418L, 0x083304edb2c513cL, 0x0dfe2dc47f17b73L,
43728       0x091a90f8ed644a2L, 0x1b4a348d002a9d6L, 0x00bd4ec374867b6L,
43729       0x0d9bfd07ddc6477L, 0x1216547ec4a3dd3L, 0x030d1a003cb8eb0L,
43730       0x031fa93de8ce1d7L, 0x09e7db3d37bd9aaL, 0x02b5987db72c675L },
43731     { 0x1ecdcaacd80a428L, 0x0916e4399644883L, 0x1e60eb69107debeL,
43732       0x092496011441b10L, 0x12e81c3a3bed9a4L, 0x1c03e99091a99e5L,
43733       0x0bb2f0d3901d597L, 0x11a17f5df4a3e5fL, 0x178b634a5ade8a8L,
43734       0x0705bfc4a1c9548L, 0x088dde42ec73631L, 0x09f5f0e4095c612L,
43735       0x1585d3cd83dea9bL, 0x03291d3c9f6fc0fL, 0x10365a563e23147L,
43736       0x0fe0fc8e5f7162fL, 0x146899081e5dccfL, 0x009a9e62bac5ee8L },
43737     { 0x0a5649739bf6e18L, 0x05ad1324dc4e394L, 0x128373a2e39d67aL,
43738       0x02408e08191b286L, 0x0a7b8e82d935bf5L, 0x1c094a1559d0b23L,
43739       0x1ca5fc560fb589fL, 0x057082d4fc0e5acL, 0x149685d86cd39e4L,
43740       0x13cbfe3cac6edd6L, 0x03e4a055739b7a2L, 0x0ae1f146c46b4abL,
43741       0x0052877ae575f4eL, 0x1358b75ede34e7eL, 0x07307c63d064ea6L,
43742       0x1cf131a3be87976L, 0x158723a830e5a21L, 0x01f610c2efa28efL },
43743     { 0x1d4c7d71f0bc2d7L, 0x163663728ea095cL, 0x164e827e03d9a60L,
43744       0x0a08f5c13925c05L, 0x17f351f9b7dd2d2L, 0x1c285f1a818a4f9L,
43745       0x14b21a75273871dL, 0x13ac048559625e1L, 0x0ba188c567bc28bL,
43746       0x1203090835e02a8L, 0x012c7e35f50ca63L, 0x15cfa712a3c161bL,
43747       0x1b8bc97607b4a67L, 0x0a4bd5395a93e2bL, 0x0f7599af24f17cdL,
43748       0x08f46be3bd19873L, 0x1e53087dc5ce9d4L, 0x044d9ab5b5108d5L },
43749     { 0x16db0afdfdcc837L, 0x005d55438dbd4f6L, 0x1f2470752dc83eeL,
43750       0x0f5b593cb882757L, 0x0b8657a3f5b56bfL, 0x00eca72b32516d4L,
43751       0x0d96046c13dc839L, 0x1d4c7c23a4c6e86L, 0x0ee628ecef426daL,
43752       0x08b0ce4e58b16e1L, 0x1605fe1d92190c0L, 0x0e04ab09790d39eL,
43753       0x0f00bf7928e1bb9L, 0x0e30777296613e7L, 0x0b70be53bcea03bL,
43754       0x09ea4fc24057d0fL, 0x126656f18e08a0dL, 0x01ce27886abe2e8L },
43755     { 0x1a9b68ce88aecd3L, 0x1848c528c554ed9L, 0x16b52f53b951556L,
43756       0x0e040d1b09db839L, 0x011ac72d79b68b6L, 0x0d053c3ed640684L,
43757       0x18a0db479b4d6a0L, 0x0899083d3d477a2L, 0x0a7bc1775894c44L,
43758       0x15b1b92f8d50901L, 0x1dd9fb1f53155bcL, 0x1767a8dfea377d8L,
43759       0x0d73f7e3392817eL, 0x0d7692627ef2df4L, 0x195e73d131b25ddL,
43760       0x1f79817342e0f6dL, 0x100cff164789069L, 0x020a5aa16a48a95L },
43761     { 0x1c31e58606e173bL, 0x1a70dc873389d19L, 0x144b7aec82bd6dfL,
43762       0x0e0a241ce084bf6L, 0x1013e4ecc788c61L, 0x03736b9f782b014L,
43763       0x1a42a7e74d6b207L, 0x05dc263d11f28a0L, 0x1708f9b3244af08L,
43764       0x1726b360dd15754L, 0x1d29b9d036ca72cL, 0x0491a308600f5e3L,
43765       0x18ed556a6c74ab9L, 0x13868bd30999c77L, 0x023d6ffd23988f8L,
43766       0x10a2a78e6c5f52cL, 0x12a43977874444eL, 0x02933c6b57005c5L },
43767     { 0x1ff1c59df36aeb4L, 0x1329e5495e055aeL, 0x125a49e97e054b5L,
43768       0x085bfa923e1c07eL, 0x0571f89b8509d41L, 0x19a24292c616295L,
43769       0x07824af5860124cL, 0x00c3467d29e7efbL, 0x0fab418d32c1bf9L,
43770       0x1ce24872d52b4aeL, 0x0465bbdb4b5fffcL, 0x00ea1ef291521c8L,
43771       0x12d3053b4f3ecd4L, 0x0eccba64a5ac7cdL, 0x08bda0ae3ba10a9L,
43772       0x19d4c474b383b7eL, 0x0dd045ac614c8efL, 0x038205d2de08677L },
43773     { 0x0364f81515a1a96L, 0x11a818c2193f016L, 0x19406b64f53cc69L,
43774       0x024e76c2e61412cL, 0x12cda9d29d7694fL, 0x0a60bbc4436c3b6L,
43775       0x1a5ac78069d08a0L, 0x00c69244ed70cceL, 0x02fd4f0c65b25f0L,
43776       0x0939a4ffd94a625L, 0x18362b7874cdbd9L, 0x07d1cfc70c1d83fL,
43777       0x01b774c31eaf9a2L, 0x01b2bc254be95b9L, 0x1d3aa8feb0f9609L,
43778       0x06491fe5bfe9ce1L, 0x1c13d281e1afe87L, 0x04821d36b05e8e4L },
43779     { 0x111a0fe766c7937L, 0x0f6ae55de1df18aL, 0x0333802222b06cbL,
43780       0x1ac2c401e65582cL, 0x14a2ea06928754bL, 0x1f0837dc00e41e9L,
43781       0x136522b5e80ea72L, 0x10132d610459dbfL, 0x1c3c3463ae40698L,
43782       0x1897526facbfb31L, 0x14e0d10324abe7eL, 0x0b8c9d1b42a8591L,
43783       0x02db4e801a79bc8L, 0x0f1abcd94abb8fdL, 0x0ab41e1ef4b04e0L,
43784       0x1588dc8b8ebbfffL, 0x135b0760a3cb73eL, 0x0131b15a41d092fL },
43785     { 0x1c68d28eefc3e89L, 0x1743bb4f4f73892L, 0x0e1abd792dd4b43L,
43786       0x05970d6667160f7L, 0x1f552bacdb70907L, 0x06d0f4fe9e90757L,
43787       0x1c51697bacac530L, 0x10a723ed11489f2L, 0x121fbd3101e06d4L,
43788       0x0f27952df54e6a4L, 0x0351929efc87691L, 0x11900a9aa8e2f6cL,
43789       0x11bee0f2e9193f8L, 0x00a1c939ad6729eL, 0x11ad7ba4b09958fL,
43790       0x0b375390dc1652dL, 0x15e452fe23109ffL, 0x0174a95902aae49L },
43791     { 0x0846bcad75f886eL, 0x12edf6a1efe2c15L, 0x16d801ec6e1b9a2L,
43792       0x126abfe56a207c8L, 0x0263ecc9580e2ecL, 0x0f2f19de3817935L,
43793       0x081d8a0d6ce1860L, 0x0da04a227d8d824L, 0x1a5c26e3a7fbd85L,
43794       0x17c1fd9ceb75e58L, 0x094fca9134bea23L, 0x1e66a763f52ef55L,
43795       0x1117559a307c14eL, 0x1849bbf07fb0250L, 0x0bc09ccaf365ac2L,
43796       0x1de0d4b82912db6L, 0x04b1c0a84c9eb53L, 0x0091b680b981bc7L },
43797     { 0x1481c8fc084373bL, 0x123b432304bd76bL, 0x1e8184ef0d2ca6bL,
43798       0x19269785602601bL, 0x0e2be7e23712714L, 0x008400432923148L,
43799       0x115d9553eee7fb4L, 0x105e1d816708462L, 0x165baf594330a32L,
43800       0x1eef0d438377c0bL, 0x11c9f6e9d4c3a4eL, 0x1acce9992b96fa5L,
43801       0x052438906dbb0c5L, 0x08a32c79d9fe69bL, 0x05fc3a466206507L,
43802       0x18fd5cc2deaaad9L, 0x16e353c2d854b9eL, 0x00152400a31065aL },
43803     { 0x1d6d23d506ccd38L, 0x10e2a482cdd5308L, 0x109da74047148a6L,
43804       0x0db05126fae2f93L, 0x03835083e87e1b4L, 0x0d612c7aeb1dddcL,
43805       0x1347fc29ed09eabL, 0x1fb33564d7b3e2aL, 0x0dec0ffbf8ec955L,
43806       0x14abe33a4fe5c40L, 0x0577b87804537bbL, 0x096e6d3e8d8e647L,
43807       0x0091eb2599192a6L, 0x117461ed2182233L, 0x155b462f8b6a21eL,
43808       0x0ebe7489c584b86L, 0x1e031390414b55fL, 0x00ec5ef37c790bfL },
43809     { 0x1cd39f8a2028924L, 0x078ce583765cf81L, 0x12df5bc16119b95L,
43810       0x0cb40c0eed0c577L, 0x110fec10dbe0671L, 0x0ddb2e49cbe4bd5L,
43811       0x0e8e3d084e099bcL, 0x1cc829bd9974ce5L, 0x1594d4d43f88b05L,
43812       0x0c9fabd564a6a68L, 0x10a9aafec5d8e1eL, 0x16b76df8cab4e9fL,
43813       0x04ee8d2139d8196L, 0x1b069d136e1bae4L, 0x0e4ee1ee6c02808L,
43814       0x0413d66dda6b9bdL, 0x1c1f565b28bcc83L, 0x01a4e34a1e30809L },
43815     { 0x1b394444de6c88aL, 0x16238a380103f68L, 0x0288870ade03570L,
43816       0x0810a1327d6de8bL, 0x1aef0c18749f756L, 0x1e38782005d2bcdL,
43817       0x1fafcb5d0a4e1cdL, 0x0a78b51c5d8428cL, 0x0243a666e5337f4L,
43818       0x0c8f8e3f685ea85L, 0x1cfa43d2f47e472L, 0x1d14be1c253674fL,
43819       0x170738963596089L, 0x138c1564e869d0bL, 0x05f170a73e10b54L,
43820       0x0aed24232a53210L, 0x0faa32f327e8725L, 0x002b2c3d5c4e16cL },
43821     { 0x08562ed1ce4733dL, 0x1fbe5cc728a2200L, 0x087ea6ad1ae57ebL,
43822       0x1d6c351826be060L, 0x16b3597689494c5L, 0x01697b2be4a81b1L,
43823       0x1c0f9afa1323cabL, 0x1761cb669b137a4L, 0x1c4ad918f7e872aL,
43824       0x1544f4fe2029770L, 0x0bb8fcc642d47b0L, 0x086edffe4a9f859L,
43825       0x08883e097258fd1L, 0x07d8aa1c379e06bL, 0x12ab8018f4283a4L,
43826       0x01ed98870ec97edL, 0x1de815f15653f1dL, 0x00dc3f976dc366dL },
43827     { 0x1792bbb2b0b15b1L, 0x05ad3e735d3bc9aL, 0x1f67763cdde68f9L,
43828       0x1b8531a3dff759fL, 0x047031c6005450bL, 0x0b4033071faaab6L,
43829       0x14b081dc3c1ea57L, 0x0a99c7d09c05a20L, 0x1b050791e7aa8ccL,
43830       0x0b10f39dd1911d1L, 0x06e534e58ca6413L, 0x168efd700adb0f7L,
43831       0x08edfca0cc8df9cL, 0x0b895065712186fL, 0x0122a64dd2fd05aL,
43832       0x1cb3d7c7e78ef11L, 0x023b22b87b1c4a3L, 0x0470113e21f4adeL },
43833     { 0x00e22a83210964dL, 0x0aefaff82b77580L, 0x087f6bc7ab5f733L,
43834       0x00cf9b95c6042e7L, 0x0bdcc90cd02833eL, 0x125a7a8e62ba65cL,
43835       0x00a621bb29c50c8L, 0x1d7a01cc075767fL, 0x1b98ece1b0c1a8dL,
43836       0x14523721bc6130eL, 0x077436985979748L, 0x113296fde1c58dfL,
43837       0x13bda9f306b3ae3L, 0x1c50426d9d1e0b5L, 0x053a5417a689b4cL,
43838       0x00d78a51cb326a7L, 0x16e848ecb114ea2L, 0x00a58ad5aa02a2eL },
43839     { 0x16d86c9664c59a2L, 0x115f0b07ebd5287L, 0x15a641cb2e38f7fL,
43840       0x1302ed4fc067f36L, 0x0587080b5f2325dL, 0x0ea702bcd06a73aL,
43841       0x0a38693b837bc35L, 0x1dd815b3ff590f6L, 0x1d6f18d2f3f09b4L,
43842       0x044b57394974ec3L, 0x0254f58251d8f33L, 0x0f5031f7f3f5951L,
43843       0x094b63d701dbee9L, 0x03f53917ef90707L, 0x0ad5c7f2ee9b8c1L,
43844       0x0abeb9cafc394c2L, 0x02e1e16ac76009aL, 0x03a15df6c621c4fL },
43845     { 0x1ea86dcc1dc2c73L, 0x1feade0b21d5f91L, 0x087c9363287d2eeL,
43846       0x01196b958e0ff1fL, 0x14e66a7dde68a6eL, 0x1bd6bc3eaa6325aL,
43847       0x0ae51e276e88aa6L, 0x0229b11aa81c6c9L, 0x0c8c2e02d1f72e0L,
43848       0x041302ba371513cL, 0x0d6ecd2c61f1f53L, 0x1bfdd71fc193cd8L,
43849       0x087d11e415ed8b3L, 0x1c32e3fcdb5e1a7L, 0x1b305f2ce422efeL,
43850       0x1ad36e2fa39cdc3L, 0x124151e3308f7cdL, 0x04bdead0a5ae4a0L },
43851     { 0x01c62fe81e82861L, 0x0a5b6eea1620770L, 0x156f997a4795c0fL,
43852       0x08b5777fbafca5cL, 0x072a45f4b8b4937L, 0x0794ec5a78afa96L,
43853       0x19d7f3a10d6a154L, 0x12d3beed736b05bL, 0x052e84c5fa20c8bL,
43854       0x1bbe9688545057aL, 0x06ef6329804f0ebL, 0x13744df060be071L,
43855       0x080cec8b9ab0d9bL, 0x1fd5ed0c7829f42L, 0x10930a9358cd9ebL,
43856       0x1745ca1ea77c94cL, 0x069f892c58c864fL, 0x018be3698a4662aL },
43857     { 0x03525b02cb7d42bL, 0x005e49887d65706L, 0x008bfc81023d549L,
43858       0x1fc1821d411aba4L, 0x118eb23d6b01402L, 0x12950cbfdf7b453L,
43859       0x035ba8051ad6904L, 0x102b35f9c90221cL, 0x0e9a1d27f022de1L,
43860       0x0dcb68b6e1fa4edL, 0x0b8fd7bef90021bL, 0x0c83d9978239f83L,
43861       0x19525f8636f9d70L, 0x013b1e182481113L, 0x0418c2cdda5e5abL,
43862       0x07e2f398690783bL, 0x0fd451651f0ee3dL, 0x03572cb9cced05cL },
43863     { 0x1b13bc7bff4d2eeL, 0x0a1149858b9ec2bL, 0x0f541e524db081dL,
43864       0x14bdfaab7d6c4a9L, 0x0e0c33891d5f232L, 0x10fca26037a542aL,
43865       0x01edf3cb16d6639L, 0x0998ac90c3ffabfL, 0x0ee261fb15a2afaL,
43866       0x07fb91316cbd3baL, 0x06b88b5b3c01eacL, 0x0a69a68de428351L,
43867       0x1f97b6497e28880L, 0x1d157ffe47f39dfL, 0x1469c9a2a1656cbL,
43868       0x170573df39e7de2L, 0x072a84ee5f1e744L, 0x033248246de31ffL },
43869     { 0x1b7bb781e8b760dL, 0x185ec12d56d5048L, 0x167fead489bf51eL,
43870       0x0d7ff8291d02927L, 0x029be3db4a6dd22L, 0x185585ad0197c55L,
43871       0x121a0c636f1c0d2L, 0x08db9997f6afacaL, 0x08506ab379c581eL,
43872       0x089b53714187671L, 0x1e4d5b3db2031c2L, 0x06efded63d0c916L,
43873       0x0183f0f1c9fa176L, 0x0b55f6ee964e0e6L, 0x0ec37925bc149b4L,
43874       0x10e747c1d31c552L, 0x1ec6f2d7ada0f13L, 0x0275c9dae79fd24L },
43875     { 0x189f7e5e11fae32L, 0x0ba7ae2011fa8deL, 0x137d2470fdbf44fL,
43876       0x0eaaa4f36e36002L, 0x05ba00681d849a5L, 0x1e51655dcf444b8L,
43877       0x19dbe0888906704L, 0x0555f776d0bfa66L, 0x1931c3f5275878aL,
43878       0x15777f7f79ea8b9L, 0x097322f629a1e04L, 0x1b67b33e182c313L,
43879       0x06a19d48b682cffL, 0x14e362705fab2a0L, 0x00105c95817888fL,
43880       0x03990a7cf03bd0dL, 0x168cdf5c90bc700L, 0x015ac16c9be021fL },
43881     { 0x1165c8281abc2aeL, 0x1c07af15b4f6550L, 0x0f481fffd9be9ccL,
43882       0x0ca8eeca0d812f6L, 0x157fa21c5d60382L, 0x06deeaee5d64f9dL,
43883       0x1cca9e1d436d326L, 0x0390bc42207b3dfL, 0x1ceed172c2f11c4L,
43884       0x071c9324f1a4604L, 0x0e4dae0c7b77eeaL, 0x1a0dea10c946e39L,
43885       0x0de93acfcd915c3L, 0x19f97bd57f4719eL, 0x1f3ba692fb8435eL,
43886       0x095fb83b1d691d6L, 0x0c04fa49ce3fa57L, 0x03c30a884c316daL },
43887     { 0x1e3f4807ae72c21L, 0x150a27e8786d29fL, 0x07a3e30e91518c6L,
43888       0x08a369e3578eddcL, 0x17cdbb24379ae09L, 0x1eafe6951d21cbeL,
43889       0x1bd69e8533ffa0aL, 0x19f77c9da25e84fL, 0x09b0a43ee284d3cL,
43890       0x1dbc5c9c776370fL, 0x1013919ee3a1ed5L, 0x180a686e984031aL,
43891       0x055428deb50c8adL, 0x01d7d167b21b9b0L, 0x0a55be6d3603b03L,
43892       0x038d0daa3f27875L, 0x0259f9a28ab8416L, 0x02a05b5dbb5e4e0L },
43893     { 0x0e1734c321d315dL, 0x0b3096c3702e802L, 0x0516eea336053bdL,
43894       0x1359b8f135d5f5cL, 0x1877570f1fb07a4L, 0x1e29ef3510f4d6aL,
43895       0x063acb92a0dfae6L, 0x08a86db65263ac5L, 0x143afbc78ea362fL,
43896       0x14b9ecbd55fb2c2L, 0x1f6af832493580aL, 0x11e0f95be1d3b9cL,
43897       0x0175020538f69d9L, 0x0230e694f05a82dL, 0x083a060f6df468dL,
43898       0x0a1edc3850eecbcL, 0x08c2ca2586752ddL, 0x044be558a49701cL },
43899     { 0x1ed38130d8bab8aL, 0x09b26521c10052cL, 0x1cb101605057047L,
43900       0x14f5912ce80d0f7L, 0x197411a086ad0d3L, 0x019b8e22494082dL,
43901       0x00c79d2612c47ceL, 0x1c0e1a5db081a35L, 0x0d883628b6c912fL,
43902       0x07c7bfd8a7d4469L, 0x1ca9373c2b24f91L, 0x13554d849f4cac9L,
43903       0x03bf6cd94982f62L, 0x10528c16d5c835dL, 0x1ae4e94b208b99cL,
43904       0x0e7545fe8fb5861L, 0x0c5dc62c4a4fff6L, 0x0325803b1a3b587L },
43905     { 0x03f533eb3c9a404L, 0x1bfb9dbf7cca90fL, 0x18a5b094da4ec76L,
43906       0x080e71dda98fe27L, 0x0e26cad07ce7f4cL, 0x162e78e67e9d99eL,
43907       0x1380761e124d407L, 0x19e7f1f813bb810L, 0x0217cab32c39b5aL,
43908       0x16d785dcf7aaa8eL, 0x1dbd5b8485ea550L, 0x1625846e0055f78L,
43909       0x1fb070a29380178L, 0x0bb654b205a961cL, 0x15a38db8e49454dL,
43910       0x01d084aab284833L, 0x18c291fb82c09e5L, 0x03ee91753330c76L },
43911     { 0x1fe844b49cbb3bfL, 0x063822ab17d92bfL, 0x14de7d6a116b783L,
43912       0x0dca24eff83cddcL, 0x10635718956d7f2L, 0x0abf9a163aea5c9L,
43913       0x1d0ace685224a5aL, 0x0e519e9d66505caL, 0x16b0d3ddd83247bL,
43914       0x1d4fb19900d211bL, 0x100f04505292159L, 0x088f6ded522c82cL,
43915       0x10dac6f79060afdL, 0x1e9dcec14afca49L, 0x12b7c3da17fe52eL,
43916       0x0e912b91f31f8a3L, 0x0c89559c88ab13bL, 0x0189bbe332f8c7eL },
43917     { 0x1c5de097dcfb35fL, 0x0654f80e61b7c1aL, 0x0175d5db2d8cb73L,
43918       0x15ef6966eafd27dL, 0x109a19b50c2dd48L, 0x1ff303cecae6a7dL,
43919       0x16b49d4bb4565c6L, 0x0de8731019e4b2dL, 0x0e52efb5369e90aL,
43920       0x004bb3181e9f305L, 0x0d93eaa541c3811L, 0x076c0ac49ba5f9eL,
43921       0x0400d5e467d8f99L, 0x0647a29259ad4c1L, 0x02805e78a274090L,
43922       0x1b57bde8a8478c9L, 0x0713a5fd695587eL, 0x01ed66286508f29L },
43923     { 0x13e4f946499ae4cL, 0x0e5f0b829e293e5L, 0x13a6f9e0ba2a91bL,
43924       0x11b0903c8b00febL, 0x0a286fd0b6c64d2L, 0x0e6da4f9af228c5L,
43925       0x0fabfdedee6eb7cL, 0x1f7e7f6c4215d84L, 0x00a9ba385b9bfd2L,
43926       0x08d06a9c403f9d0L, 0x091012c5eca10b9L, 0x0d0ff3bb3e14f56L,
43927       0x14f3e9df646fd57L, 0x106f8ca6e68f7edL, 0x1a77c15774b7de9L,
43928       0x114637da7e587c0L, 0x0f7469b75612324L, 0x04334a4f0b4a3a2L },
43929     { 0x09a0da53f4ab07aL, 0x17999faa537df9dL, 0x0486c8f3ca40b35L,
43930       0x1d091c7ab01925dL, 0x13b218abc9581c3L, 0x165a6bc9d78fdeeL,
43931       0x00e80e1663a8419L, 0x16aa002729d3218L, 0x13b664b1e7d0877L,
43932       0x1ced8ddeba63848L, 0x1510d538b577435L, 0x08366653b7050a5L,
43933       0x107b96d4800d2b8L, 0x014aee237d42275L, 0x1dfb138de9415a7L,
43934       0x062ef85a706e729L, 0x198dc3884ff5b08L, 0x02ba1a95c458fd2L },
43935     { 0x12193f70d5d7ce9L, 0x0fe9305a43f57f6L, 0x0d65ef997f40f06L,
43936       0x00f04e1aacf8895L, 0x1aa70198dd9da86L, 0x0cc2efc54276005L,
43937       0x0a360bb09f924a1L, 0x03b32d995e1bc40L, 0x14e7648c761c220L,
43938       0x0b19ade048e0cf5L, 0x08e9a7c359e0aeaL, 0x0681a528c9264a7L,
43939       0x01099f68733f204L, 0x14cb008d222290dL, 0x14ea5397f2f3025L,
43940       0x147427109abb1f0L, 0x04f2418c624d3b6L, 0x01f218d7903571eL },
43941     { 0x167d93983d381f1L, 0x00d57686019e1fcL, 0x134151041da0d94L,
43942       0x10a1274da77e75eL, 0x192f2900a86d159L, 0x185baaa1d703a0eL,
43943       0x1b5bffacabe98dbL, 0x08da1214d47548aL, 0x1336a4fdaaefdb6L,
43944       0x08dff220d4a17beL, 0x0a8fb6147b907bfL, 0x0d0c23d26b8aff8L,
43945       0x0653bbb3434f1c9L, 0x16c4b61566abbb3L, 0x0efe907c9a4c6eaL,
43946       0x19de3141f77a30dL, 0x1351c3d7d82a203L, 0x036d69f8af13326L },
43947     { 0x1940b7d12ec35a1L, 0x0e2db73efd89468L, 0x031bc4cc8755886L,
43948       0x14678b1d6c5984fL, 0x19903c435e76904L, 0x0cb50c8a8487aaeL,
43949       0x12e9c186f249b0fL, 0x0372e953e071815L, 0x17a4140217198b2L,
43950       0x034accefc4ac637L, 0x1cbc76faf404a6cL, 0x0c27be751b86a2fL,
43951       0x08672375c51109aL, 0x09c1e9698472c22L, 0x1fe0df159642e92L,
43952       0x1aabff87dcf8c17L, 0x03fc87a539027d2L, 0x0121c74ea2fa8bdL },
43953     { 0x0a453088815af3cL, 0x18d1979e4df6ae2L, 0x17265ed9777f957L,
43954       0x0825ca3d6b5de39L, 0x063f249061c61d9L, 0x19f118de86d62a7L,
43955       0x18041bc510a7342L, 0x163ee6f8785e3b4L, 0x17150e04b6bbc4fL,
43956       0x02da6448df140e5L, 0x118cf35dc07d6c8L, 0x1e8c54a26921e36L,
43957       0x1368f1f7f28b33eL, 0x1ea0b5b3eeda3e3L, 0x1e56ecfd2b69446L,
43958       0x01ccf3a552f9bfeL, 0x00100a8b7b29620L, 0x009f9c808d7f187L },
43959     { 0x1d296ef7bd0c827L, 0x08879a514ffa31eL, 0x01a072694569418L,
43960       0x0a4d1794eff0f26L, 0x198045dfde8d804L, 0x0072c265dc18124L,
43961       0x18188fe435c41a3L, 0x016550719504c76L, 0x0293bb5e7535c5dL,
43962       0x1754ceaab20a888L, 0x046b406ef680173L, 0x017f49b1a031fc6L,
43963       0x001cf2b8662497eL, 0x0c625d4599eebbdL, 0x0adef26f01d6dcfL,
43964       0x036165308cda8e4L, 0x1b617a7ce24cbdaL, 0x022c6a5b5b40381L },
43965     { 0x026a20e4d54d8b2L, 0x0b4b726990506c5L, 0x0163e653dc00169L,
43966       0x185eca9350d316bL, 0x1694d00d7a4adc3L, 0x02015e8c09740c9L,
43967       0x190411ae6c001ccL, 0x041c21428934366L, 0x1eae95ea5992302L,
43968       0x17e174d8da41061L, 0x0d72d61727ae28fL, 0x06332f08e0c9fcbL,
43969       0x108f27d49f21ae0L, 0x17b92ab5b47785bL, 0x136c068c967bc60L,
43970       0x1f2b8015c08aec4L, 0x191628e3b065668L, 0x02f89fafd5b7ddfL },
43971     { 0x06ed9ae3a9b0dc6L, 0x0def4b7c41f643eL, 0x1e23aa2cd9deba8L,
43972       0x1934cdc757d4cd7L, 0x08217ffddefa6abL, 0x06f82e626998bdbL,
43973       0x19d3bdd0723c8a4L, 0x1943e1fbe2efa22L, 0x1fdf0ece7c35989L,
43974       0x176c96fb5ce2416L, 0x04f99956fc729c3L, 0x05204b9d9338e6eL,
43975       0x02e803e69c90acbL, 0x0bb89d0d1be4f1dL, 0x1685d35f028f14cL,
43976       0x005ec6a1b8acadeL, 0x0a211625a4405f8L, 0x010cb24aed1bdd2L },
43977     { 0x0cb2fd313142680L, 0x148ebb2e8a67a00L, 0x1aaf7f899a7aae7L,
43978       0x1015c4578b8d419L, 0x0b6ec250beefce5L, 0x1c78ff9e15bcc36L,
43979       0x123b212b6c68b5cL, 0x16b2e137850a2ddL, 0x1f36931298e8f7dL,
43980       0x0477e35cad8cbfcL, 0x04254a6aaa90131L, 0x197a2882a9613feL,
43981       0x03427f34352c3c8L, 0x090c4be099f7bdeL, 0x19522801285e503L,
43982       0x1f4c4b54188fad9L, 0x1082971cea73d56L, 0x049d687580223afL },
43983     { 0x00b6967988a9963L, 0x03bfbb28af46ebdL, 0x0e18edad43c9879L,
43984       0x0ba67245bcc4e9cL, 0x087a5b3d63a9b8dL, 0x0171919e1c69fdbL,
43985       0x1333c63dbc2704cL, 0x1ee4a980b87c05fL, 0x1c04ed0b726e662L,
43986       0x0ab235c0a1ff03cL, 0x0a51232405b2307L, 0x1897f047af2fdf1L,
43987       0x0fbccde451e5674L, 0x020bf56f02c37b9L, 0x1b9623717f22355L,
43988       0x1a3f2572a4412aeL, 0x0344408dd425844L, 0x039fc61f87520e0L },
43989     { 0x1534fc85df763ddL, 0x013f99d638c1b44L, 0x185dba3c5680ec5L,
43990       0x099641111c1b6b7L, 0x057caea61d39094L, 0x0fbdf9bc0264d6cL,
43991       0x0a33ea96110a146L, 0x02ac4ddd9e25275L, 0x1749e0d98ea36a0L,
43992       0x1ffb6d71990f6e6L, 0x17ba98a2de4733bL, 0x0aa45a2dc6c32c7L,
43993       0x1cb15ae206a14e0L, 0x1e5192f251702c7L, 0x0d06a283c9a1d17L,
43994       0x0a370f9f3a80e42L, 0x175dfed25d97caaL, 0x00084571cd6df6eL },
43995     { 0x0d178f3a9e88f63L, 0x0d88f55863992aaL, 0x0f9b8987629aa81L,
43996       0x1d1a172390ee74aL, 0x09bb004d24db7daL, 0x118485ef085839fL,
43997       0x07227f22fbf9d53L, 0x0342d5e0b32198dL, 0x0ddc838039d5951L,
43998       0x1fb2dcca362ed7eL, 0x192fa07b8296670L, 0x1c6df675362ff77L,
43999       0x15445dad0088891L, 0x0a84bf0f864d56bL, 0x01693877ff11aafL,
44000       0x0a4671090113759L, 0x1df348bb42fa0c4L, 0x0403e036c7589e0L },
44001     { 0x0a969ec98ee0ef6L, 0x0aa41c5dbdbd780L, 0x124a80be3f6eea7L,
44002       0x1516e0aaf848909L, 0x00ad1af27bdb201L, 0x064afdf2c9a1f23L,
44003       0x074ed4ea6a50a66L, 0x01d2e9b67bdb50cL, 0x1ce1525c9ed399cL,
44004       0x0dab440fb9084deL, 0x1df456660846922L, 0x1675de1e4eb411fL,
44005       0x17fa2f358b5df76L, 0x01cd831a49f8c07L, 0x160ed4eab13ff3fL,
44006       0x133f84d258c4c2eL, 0x061b2fdfa36b553L, 0x00b2126364cb03dL },
44007     { 0x1d65c55dd2744a9L, 0x060e17f1d7a0c2eL, 0x1a67bfa2c224951L,
44008       0x0b53bed23465905L, 0x1be9967430b7ab2L, 0x1968914c1c22a84L,
44009       0x1c9caf3b349632bL, 0x019115c8131798eL, 0x0d43961414b8efaL,
44010       0x07fb3dcf6b26896L, 0x195790b9fcd0111L, 0x188a8b61d3d753cL,
44011       0x14f03ded283d16fL, 0x16665c2e23a51f0L, 0x14e946e8f26b7feL,
44012       0x063627bfcd782e4L, 0x18adddaf4b9fb58L, 0x02aa27301527a23L },
44013     { 0x17c5313baa80b4fL, 0x138b7b1dee477c4L, 0x0b6ded0b16a0048L,
44014       0x12110661195c4e8L, 0x0d341ab1e9d9e1eL, 0x0a2c381a96461f9L,
44015       0x1676058f41403b6L, 0x0530693bae78521L, 0x02053c5e01f6c7dL,
44016       0x1883a2365a1019eL, 0x022f4827426bc60L, 0x1cdd64f28d02ed9L,
44017       0x1e19b1b540d0f70L, 0x114ca5a1b905aceL, 0x1b14f3e02dfb370L,
44018       0x01e8583499b9c5bL, 0x061dd7d3edd1ed6L, 0x02b9accae7120e9L },
44019     { 0x04ba3fba0237056L, 0x160b219d599c46eL, 0x0ef49c7b1849a15L,
44020       0x07c60637d9803ddL, 0x0118a1f5abdeb03L, 0x100799a777220cbL,
44021       0x01dcfb125d0856dL, 0x1fa36e30b9e110dL, 0x17b0c46cd7c1b7dL,
44022       0x0a1d96d25262f44L, 0x096612ec7fe5374L, 0x09c9939e68cbb73L,
44023       0x00eace64c9ac390L, 0x1b456ccd7c394deL, 0x05503097308a085L,
44024       0x0d22f77a7610315L, 0x0f0e468ed5f049aL, 0x0442a436f9f622fL },
44025     { 0x0942c934bdff464L, 0x138cf92d3da28b5L, 0x1c2cc96f8c90f6cL,
44026       0x1633fc667399600L, 0x041ee8ff2055a31L, 0x17c6f7d6534d741L,
44027       0x1cf19d81f742157L, 0x0213c492c1e3436L, 0x1bcb0e8a271d368L,
44028       0x0f08d513442f35cL, 0x1742ac617ab864aL, 0x0dc81f03f239316L,
44029       0x0f994fc5031a0b9L, 0x188ceb70268745eL, 0x0933830cf605a5fL,
44030       0x1f3ae5210650f55L, 0x02dc5dd4d3ec91fL, 0x018e767f46a55cbL },
44031     { 0x17bfd9afc8b21e8L, 0x09959d8ca1b6fa1L, 0x0b524870da83977L,
44032       0x1b47a1f521fcb20L, 0x1bb523bd8e9de84L, 0x06b4bacb31f356aL,
44033       0x0d672600288febbL, 0x1e2201381b369f7L, 0x1839aa7bdc9d20fL,
44034       0x0817b36f66b7d1eL, 0x1b53ef1545b2a7dL, 0x0becd8e85588901L,
44035       0x05ff3252f865ffaL, 0x1aece59e95be3caL, 0x15bc749cbfbf015L,
44036       0x09d8623610c77adL, 0x1b35d8f3cf09a6aL, 0x034b0da356d12a3L },
44037     { 0x07b587ecb35e2acL, 0x0aa35abd78a6ce8L, 0x096f6ca281307b5L,
44038       0x08e13aa9e1d942fL, 0x1c6f400ea1f91d4L, 0x0670c853738cfecL,
44039       0x0ff49392e23b7eeL, 0x0bbf2f03dba48dcL, 0x1d67120e6b655afL,
44040       0x13c168ec9a09e53L, 0x18828a5c1fe8876L, 0x1e64a9d08246d2fL,
44041       0x1e36051f9f1eb51L, 0x19e72df49712a6cL, 0x0fde53f76bb10adL,
44042       0x155b31353465d9aL, 0x0121964e22f0781L, 0x03531d48629baa9L },
44043     { 0x0554e003d7acbbbL, 0x0b3455ba7b0843bL, 0x19c8e231466cb00L,
44044       0x087d729a9fc9452L, 0x0cd6d2f60166771L, 0x1b87bf84351e6f8L,
44045       0x0f9f3e1960085ecL, 0x142cb110182b49aL, 0x1d6ed58165ba3f4L,
44046       0x1e63c09ae5238eeL, 0x0fc1d3a11295daaL, 0x0366dd4a05d5013L,
44047       0x070e021ed3a53a8L, 0x030bf8b2e105c98L, 0x0d7342e309fe24aL,
44048       0x052c34a8ec88d04L, 0x10effc89ffd8255L, 0x028f6a51168a8ecL },
44049     { 0x1d6963a449701b4L, 0x0c8d1dd93e5791bL, 0x1856d5ca597faa3L,
44050       0x0bb6a17efa7df37L, 0x0e643b9b75a7a05L, 0x15aeaf7eb3a4076L,
44051       0x1225fca9834b5b3L, 0x0bed1f86418bdafL, 0x041c53cf628ce68L,
44052       0x114b88fb88330afL, 0x1c84e08d403b303L, 0x04c0d853fc90f50L,
44053       0x0ae1ef9712af0a9L, 0x0968b4dfc9ef9f9L, 0x0a5e4f0357dbec7L,
44054       0x124add6f5fc4ce9L, 0x0e54173d94ae9f4L, 0x016b4a8de15c5aeL },
44055     { 0x1007d9f904e222eL, 0x19247c37a7084eeL, 0x1a2e3d0a7bb8ccfL,
44056       0x0b9f8eea31a9329L, 0x0b0f42f12957341L, 0x1a1a8cb73ff51d0L,
44057       0x1c6831e572df709L, 0x0ab04151ecce23cL, 0x183d95d9c2b874fL,
44058       0x05b26bc73870b13L, 0x0d4fd62e4a9d0b5L, 0x116288f6bcdb248L,
44059       0x0cbcf931a032204L, 0x13d7913405d6b98L, 0x0ee4fe5d7134226L,
44060       0x075dc8c92098370L, 0x1f0a24eba02165bL, 0x032e2473c704662L },
44061     { 0x01c73cede222c22L, 0x1ec66fe7511da0dL, 0x0c52c850ec195a0L,
44062       0x1eb3f9d8ee06039L, 0x11204cef284adf8L, 0x19a883fd8e2c0e1L,
44063       0x02303d534fbba51L, 0x025b7ecfe169a63L, 0x176a3f2d110f18dL,
44064       0x004fd1403e9f009L, 0x1c2918979fb380eL, 0x0fdb6512ba5de0dL,
44065       0x0908b0553ad8286L, 0x17922a22f0837a4L, 0x1668f2f88a03e9bL,
44066       0x1745a805aaf0b51L, 0x06ff63dd9ffd438L, 0x01b5ae6963d3591L },
44067     { 0x1ff4e20545679a7L, 0x005a0a29063a843L, 0x1fea6d167361936L,
44068       0x1390b5e3472146aL, 0x0d935a5ea19eaf3L, 0x0d33c506a3aebccL,
44069       0x1a041d140660de0L, 0x088e9072ef21985L, 0x1c6a21d112f4122L,
44070       0x08742fc9b528d1bL, 0x00547baa9d37e23L, 0x054f279f3389feaL,
44071       0x11376a9ab614e18L, 0x0911c4ffa2ac9efL, 0x1117a2863dcf2bdL,
44072       0x03b91a4f992c1eeL, 0x1d80692f4c539a5L, 0x0046be0a26d9cdfL },
44073     { 0x09c0d963ecca773L, 0x148c96a4610ab40L, 0x15d36daf59061faL,
44074       0x0854cf19bfe1d99L, 0x11587b7e7731237L, 0x1852633d4b36c5eL,
44075       0x05ef7cf06840584L, 0x148f98dd070bf9cL, 0x195e95bb8a8de7aL,
44076       0x1f0f45ac4c18471L, 0x1c90fb8d1da528fL, 0x18857619a57e032L,
44077       0x040f9b2b49f3fe9L, 0x039b3e8fdac8293L, 0x1b851ed30e17a2fL,
44078       0x095b23a60a15d6bL, 0x0028e2c38790400L, 0x02f9554775d5b81L },
44079     { 0x008d4641266524bL, 0x19c406850cfb371L, 0x017b6841bafedefL,
44080       0x07cc85ba8d4b54dL, 0x0682e4d60a69e8dL, 0x05a9a6779a4e30eL,
44081       0x19ee09bdbb8ec3fL, 0x1ecfb57424e0bd6L, 0x12babb27e18be05L,
44082       0x0cd7e5d4716c2e8L, 0x1cb46b8b674e1a5L, 0x05cc3d4de0dddb9L,
44083       0x14866e5ae859dc5L, 0x015e69e3e1413c5L, 0x12fa0bf67fc0d00L,
44084       0x1e449d10958ecf0L, 0x149a316498083c9L, 0x031280d4c5a37fcL },
44085     { 0x03f7d9aad264086L, 0x119edd2f0725eabL, 0x000a3234f59f29aL,
44086       0x108dcc9633d04a6L, 0x00aa4536a288dacL, 0x0a9f567d1e48cb9L,
44087       0x0af4e04c326c3b5L, 0x0eec4500dc05d51L, 0x052fbf54dceccfeL,
44088       0x0cd4718a7868db8L, 0x1484cf566c5d06fL, 0x003934dfd514a33L,
44089       0x00b5c4eb10fd741L, 0x08fced2f68d67bdL, 0x17a9619e1266dceL,
44090       0x0a6355754989381L, 0x065cc9c5f73a1f3L, 0x024bd8aff7e9fe3L },
44091     { 0x056cbaaf45568e9L, 0x0d07f638c9537c5L, 0x174e6ac94e6bd24L,
44092       0x109586fb53b7607L, 0x02a0f5b4c86522fL, 0x0e29cfc6466dd10L,
44093       0x1c0ba0427f1d68aL, 0x17f39a0da639521L, 0x18f31f0443e216dL,
44094       0x0d534565d1f5ec8L, 0x0343490b001fd26L, 0x1f7f0d536f9c550L,
44095       0x04d6308edcdd8dfL, 0x03400965202e9f4L, 0x1a841c76be8cff8L,
44096       0x06fcd85dd7a27dbL, 0x0b7b7ae7e5c2ff6L, 0x00c6a35364f28a6L },
44097     { 0x08cbb22a78b7802L, 0x0eed924be5d7a43L, 0x1cf90aba2b741d1L,
44098       0x15699d69c989d65L, 0x0325fd40ac0abcdL, 0x1639a29706c192dL,
44099       0x1c6e5b3f815c44eL, 0x056e80f4f116282L, 0x070eb06036da7a5L,
44100       0x1859b7cec28bb56L, 0x0274a5f0a553ceaL, 0x1391b9ae0b5a282L,
44101       0x0d7bb5e751370deL, 0x103738461f86daeL, 0x04c143517e4f506L,
44102       0x1fdf221aa9f14fdL, 0x04069e6f8e45a38L, 0x02a822300e9fb17L },
44103     { 0x1c5c91006cb9cc9L, 0x03a6ba0e8000a68L, 0x18f8448dbee1508L,
44104       0x1c535abf04f9b0cL, 0x0951fc8339721ffL, 0x068a278e90fdfd1L,
44105       0x0b9ac73781b9d00L, 0x0cd2084b2d722f2L, 0x03365c8e529ad51L,
44106       0x1110742cd777f4cL, 0x14c625c30abb8f8L, 0x07b73fe20179796L,
44107       0x16f532973f477caL, 0x0d15e80d9383a0bL, 0x15e7e4e848462b2L,
44108       0x1afb7e684a4127bL, 0x04f563a8ff7c6f5L, 0x006d189fe6bd876L },
44109     { 0x1125a8c15aa2557L, 0x0eb8600449f4e1bL, 0x06519ee2a08f288L,
44110       0x08f960085490e27L, 0x09e2ce180d3e9a7L, 0x0d75611695fa7feL,
44111       0x01983554c683412L, 0x0009a534c2de07aL, 0x0473d50d61f1b7fL,
44112       0x178765de51ef286L, 0x166fa8270a3c9ceL, 0x1d41f0e08cc9c52L,
44113       0x01731083ef6d7c2L, 0x0a0e12aa56fd727L, 0x058b40d4250309aL,
44114       0x0521c882ce82142L, 0x0cc620230d81e82L, 0x031b185f46da0a5L },
44115     { 0x18d52228a7d2e41L, 0x1ac11f5b17c3cdfL, 0x0f75b100b625279L,
44116       0x0dbc58b35a369a6L, 0x09b9dc38883e04dL, 0x1b86265f9f9c7a2L,
44117       0x081167665f462d2L, 0x0da3ed36418279dL, 0x1ca3d702558e260L,
44118       0x0a7ecbb930e8dbcL, 0x1abea16850dbe8fL, 0x1d317688780ead5L,
44119       0x0ce558f6be369b3L, 0x1c5647c4fe728c3L, 0x196a9cbac3351e3L,
44120       0x09d60d00e9e6fabL, 0x0ed295845c06854L, 0x018354c38f8b344L },
44121     { 0x0451e9d634ec136L, 0x193e50737b2c7deL, 0x054b036d04807b7L,
44122       0x018b7fdccf537c0L, 0x1a2d602387b6ef2L, 0x17dc4c9a94191c4L,
44123       0x10b79839593631eL, 0x05695e457801593L, 0x128e6f63182a9d2L,
44124       0x03ae380fa99380dL, 0x1063e2081d7e470L, 0x051a37d54a23edaL,
44125       0x176e72a13df9fa6L, 0x1bfa600e2a8f3d0L, 0x12756224c18856dL,
44126       0x0f9a8e3574e6327L, 0x0376443ebe058e5L, 0x01419d620f4081fL },
44127     { 0x0564b868da5ec5cL, 0x0ced40e046d923fL, 0x1c2e315e9ca2b0fL,
44128       0x0f3a687b853af83L, 0x1dc603393512afeL, 0x1d0ca0da1c7267fL,
44129       0x01125f5689c0373L, 0x1cdabe647f04e64L, 0x11b87a58e1393c6L,
44130       0x05b45e8825d5218L, 0x1071691c8ad35fbL, 0x152e40d6bf55813L,
44131       0x169976327ef42faL, 0x043bc3ecf0ee5e6L, 0x1700645956ea790L,
44132       0x06a717ab38eafbcL, 0x103673020ed0bcfL, 0x009066a2a524eb1L },
44133     { 0x1fdb8f4cab0f9eeL, 0x01f7816672c7775L, 0x01056a341996f00L,
44134       0x0d372aeee936d4dL, 0x0721ab5c642ed3aL, 0x1278699ef243f82L,
44135       0x17737bcbfce0086L, 0x1e57a2deab053b7L, 0x12ef05b4b0e93dfL,
44136       0x10fd50905e4d760L, 0x0b8b0b519fea4b7L, 0x1ec8bd667c68cdbL,
44137       0x168f0103cb758daL, 0x0df01218533d6cfL, 0x10152f0547da4eaL,
44138       0x066ddaad3092dd6L, 0x03e8ef1677e7019L, 0x0010e7e8b3fef75L },
44139     { 0x073715fdf5c36f3L, 0x1ef1beb25692a2eL, 0x1443cb3ddc4dc0eL,
44140       0x0e1e732790aa6d1L, 0x104ae4ca1e5ec7bL, 0x1dd8c5fed8b3bb1L,
44141       0x0f568363dc5f8f4L, 0x16aa4ce0e7ecc68L, 0x1faeb52ef156008L,
44142       0x0bd6afc91252387L, 0x1b8e47b4aad46aeL, 0x1caf32e860595f0L,
44143       0x17fd0ae28adc0c7L, 0x1fc76ace6447d40L, 0x04a2eda01f08b7eL,
44144       0x12b46bbdb8463d6L, 0x18e71edcd9ca205L, 0x003932da3639e7bL },
44145     { 0x1dd99f0bd66232fL, 0x157c4e2013b8b39L, 0x17e96e183f13166L,
44146       0x14f5287e775f04dL, 0x123c428d239ea8aL, 0x19dcad07070d8d2L,
44147       0x1d4ed57a838e9a5L, 0x03fd47339544aaeL, 0x0f8adf72f06957bL,
44148       0x1c4f9a09de9a181L, 0x1c9f43e290ea5c0L, 0x18115b5ef2de667L,
44149       0x1b49c12aa2cd9c0L, 0x1d056374b6e6524L, 0x110203b76237bb9L,
44150       0x1e97b1e8eaeba0cL, 0x16c6e9d667d0cc2L, 0x01b62baa598e8a4L },
44151     { 0x120046ef323d84bL, 0x088913f3c4e27c8L, 0x1d3a486e01569a6L,
44152       0x1500f32e9c961d5L, 0x140f8c796339844L, 0x16f7a4e482a3353L,
44153       0x192e8706343df35L, 0x18aa52fb4d69647L, 0x11c09dff3c41800L,
44154       0x02483ad9bf7b3bbL, 0x10e9014144f7b5bL, 0x05d2d6162e0b529L,
44155       0x14c48af5ae3d674L, 0x04ac116f603c224L, 0x193653d030054cbL,
44156       0x0bd6b45bb5bcb82L, 0x04efc8a8ac9a297L, 0x0037dfc308ca34aL },
44157     { 0x165338e3f45aa97L, 0x1ac640e8207f596L, 0x166c3f7be2e760eL,
44158       0x15c9ae82f80bfdeL, 0x130a1a237beb071L, 0x12de81cc15b0fadL,
44159       0x1afcd317ca8abedL, 0x14bc815793ab97eL, 0x0422c326df06612L,
44160       0x090f34ecab8d714L, 0x02c42c8f4d0d3b2L, 0x12af3b40f266f91L,
44161       0x013619cf4d96d2eL, 0x0caf77d0c19ea35L, 0x0fa3c3b6746594fL,
44162       0x0b56254fb082340L, 0x1ea5e64295304bbL, 0x02f4e507e8f87d4L },
44163     { 0x1d54571197c5dc4L, 0x1205ff3c54ad12dL, 0x1bf3ff6c3acb8b6L,
44164       0x181a2e8cf8cbf73L, 0x0758c6a3e952dc2L, 0x01a54d60fe4e3deL,
44165       0x12d5bf1e558b350L, 0x1164dc6df7cc3ecL, 0x06adc4b9e1e8472L,
44166       0x18b2fe9d47cd645L, 0x04e9140f8f804dfL, 0x0a26cac8f1c6f79L,
44167       0x17064ddc77eacc5L, 0x1b49b48a699c8b8L, 0x0909299d6cc6371L,
44168       0x0be68d363e38e6cL, 0x0f88cc2045b4995L, 0x04a031159e341b5L },
44169     { 0x110ccb70d997973L, 0x0b12ee9fc788aa3L, 0x13556e5eaf54ecaL,
44170       0x14ce7c294b19e18L, 0x1d262246c6321e0L, 0x041d8882a0d7ce9L,
44171       0x14a9379b61d51bfL, 0x16c8fd2fb51e02cL, 0x00f82b3a6ad9802L,
44172       0x0d5203ad74e2259L, 0x1d778b3b4afdddaL, 0x151492f481b55e7L,
44173       0x083c23ba9c1ef1eL, 0x18c851641707c30L, 0x178cda362a66293L,
44174       0x17ae3c56939199fL, 0x1b6b9f49824bde6L, 0x0405d8b323c2df6L },
44175     { 0x1e575fefd145cb5L, 0x172b0d62f344182L, 0x033e1e4ec9cc557L,
44176       0x1c267646708c3ceL, 0x02a7ba079f1553dL, 0x18437d17dcf061dL,
44177       0x12e4f0eff5aa0f9L, 0x17b6d750a011769L, 0x10b66d78976f82dL,
44178       0x0ad37fb2a75a4ffL, 0x1748dc7c82cc89fL, 0x1384a9c539b99acL,
44179       0x03cb118ff979ea4L, 0x062c0005b24bacbL, 0x031de725a566377L,
44180       0x0b46b2a20f23022L, 0x150edfc154863b8L, 0x003bdd2f5209091L },
44181     { 0x13a38d3cdd86f61L, 0x10a228281505585L, 0x171601b409c90c4L,
44182       0x111465e21e3225dL, 0x0e80c76001dc1f9L, 0x127459dd8e98e88L,
44183       0x127bb51bb1f97d1L, 0x0efaad35e6d357eL, 0x09d286ea72cdadeL,
44184       0x1f38106a2d6ac90L, 0x148db98a66b9fcaL, 0x137ba7eab80f57cL,
44185       0x1a52350e80c9317L, 0x17f83ac3409c4caL, 0x1ce594c24049972L,
44186       0x0fa42b6790365e8L, 0x0e2baf7581d9bc7L, 0x03590036fa2c8d1L },
44187     { 0x0fe50a8965b1bc1L, 0x1a9b54b15da7ed9L, 0x14cc0039fe664c7L,
44188       0x0aa7aa24bdaae31L, 0x12125caf84728f2L, 0x1fb3cf27c530c26L,
44189       0x1016953c69c04d5L, 0x0eae153e8182a63L, 0x110d0cb976fa8b7L,
44190       0x03b7a0f4ee09674L, 0x15e9d49d57e252dL, 0x1c20c4ae8348b91L,
44191       0x18c917b16cd6c12L, 0x1c6b5850131537dL, 0x10e3a0c93445b98L,
44192       0x115f9092a818065L, 0x150855b911c6686L, 0x02990bf535e935aL },
44193     { 0x0840473259f52b4L, 0x0d4e5f3108a367eL, 0x017b2b2f49ba5a3L,
44194       0x1bc94a86892c9d7L, 0x181a4ff7ab7daa2L, 0x040af7b6e1dc241L,
44195       0x0c78681ea5acd07L, 0x15189f5d3d187a9L, 0x10f938d1e42ce9eL,
44196       0x193ed661ae60297L, 0x180727a681bc1e9L, 0x1b9694dacb43903L,
44197       0x136044a9a6a9e08L, 0x195e94adfc7168bL, 0x1e06c4a6624f743L,
44198       0x01585411a66f3f2L, 0x0ef64bd60016183L, 0x001c3498f6cd6dfL },
44199     { 0x0d7abb3d09885a5L, 0x095b3f1aadd83e8L, 0x033d4dbaebb7b67L,
44200       0x10d339c9ac77847L, 0x111594cd61ca2e7L, 0x18b5691aa7fa238L,
44201       0x1d711572f9c240cL, 0x080830cf3fa93ffL, 0x075bacd750f9c6cL,
44202       0x1bf6e4414b9390dL, 0x05a21f97bd40bd9L, 0x06cf7e641c1d04bL,
44203       0x0f8bbdccb2459e9L, 0x1bb3431ec0e71b7L, 0x031b6e06e825ff2L,
44204       0x0e9179a7443adabL, 0x0200e4967cdb4a8L, 0x016557ba48a820eL },
44205     { 0x0f980066ed20424L, 0x0751191238aa2a2L, 0x0695e06a321acf9L,
44206       0x0af5cb6e164d1daL, 0x156d398248d0ab7L, 0x198fd2365459901L,
44207       0x173ca73a39a04b7L, 0x1bd7213a465b24bL, 0x1302c8f78f56723L,
44208       0x0b92eb4d5d64b7cL, 0x091f295f4685c04L, 0x0a23831457cecadL,
44209       0x11ad50d9d96bb5dL, 0x18582a8c5ab722fL, 0x163fe44dba21b89L,
44210       0x06c3d8f8e3e7a13L, 0x1d865a1bbe29350L, 0x0436bfa9922ff1dL },
44211     { 0x1f16eb6b0bf719aL, 0x1a84c45e1ec89ccL, 0x19489b3406d2da5L,
44212       0x0921131a39f5ca1L, 0x087ec666d3e3ac5L, 0x1522dc26d1dcedcL,
44213       0x0c16160c01913efL, 0x0266d3e77b306abL, 0x10fb239a8579bccL,
44214       0x1ada29cb715ec08L, 0x1ceebc90663f493L, 0x0db7106faa3a00fL,
44215       0x02eae75b1668a67L, 0x1edb041e3477753L, 0x00db1697ff97e50L,
44216       0x1ff0aa5929a1efbL, 0x0dd5a4c3c6fcbc1L, 0x034152af1c3605aL },
44217     { 0x0f235a4587495aaL, 0x101361a63922ee4L, 0x1316dd691b8c89dL,
44218       0x0bd987cbcfad5c1L, 0x14296629890d396L, 0x03b9138d899a178L,
44219       0x09a2f22649f9a2aL, 0x0342a87e4fc4649L, 0x06c44768449cdc2L,
44220       0x1e3fea78a296856L, 0x0c28c7fd2c11726L, 0x0d410a5eec22598L,
44221       0x12c6fdd7a6415d4L, 0x1da63e48d6b9b82L, 0x0235c3373b30eadL,
44222       0x0720ba59be036edL, 0x1cd054f2542e40dL, 0x001113fd37f7f26L },
44223     { 0x005efd9b751948bL, 0x176a37efe912e8cL, 0x18253cb22c8a3bfL,
44224       0x1f2def8bcb96251L, 0x14cbeca09d1090bL, 0x04658204ace8225L,
44225       0x13f38872557e638L, 0x135783e4f3ad1f4L, 0x0b021e14e0710aeL,
44226       0x068b74fc408b3faL, 0x1708baef27c6959L, 0x0dbfc6841dd5eb4L,
44227       0x15d5c4e8435f371L, 0x147fdd40cb8f5c8L, 0x14dd5e193f157f0L,
44228       0x18fa0684fca9afbL, 0x178446e6a6215ebL, 0x02a3f124d14934bL },
44229     { 0x106868aa1ffda27L, 0x166e63caae7a823L, 0x0784298fcf62d39L,
44230       0x153bcbce15eca2aL, 0x193428235b4127eL, 0x17bea89e9604dd7L,
44231       0x100946326760ea8L, 0x19d418b763bbbddL, 0x07ffddf8403dcf1L,
44232       0x0bf2694b0b7ef6dL, 0x1595a5e4ca87c39L, 0x01d06323a9c7a48L,
44233       0x01c220218b7475eL, 0x05e592829a3cdf5L, 0x184cb9bf3ad7242L,
44234       0x183d638d0b9d478L, 0x0eac42dc745bfe6L, 0x022d20e60695847L },
44235     { 0x0a9b2c74dbbf0e1L, 0x1cb17d0be7b871fL, 0x1d617bad319907fL,
44236       0x05537d62fdb83d4L, 0x0285741a4f5412dL, 0x07e88f964f27a95L,
44237       0x0613a4f7df69261L, 0x0eb655f7bb81be6L, 0x096323d252421e3L,
44238       0x03df0f224efbc0fL, 0x1807b4f5626fab2L, 0x137a51ffedba28aL,
44239       0x148a0f298c0f0bdL, 0x0c4734a216992ceL, 0x0b0abd8d8b5e9dfL,
44240       0x1b40550980d6d6dL, 0x0c8ba850ac9d087L, 0x00943b1e4a17720L },
44241     { 0x1a80f07acbac178L, 0x100221a5847b714L, 0x1451c3fb7b49f30L,
44242       0x070cc2aecfd2c63L, 0x0b088548b2115daL, 0x174701be3afae26L,
44243       0x05d496ca7484e68L, 0x179fd3fb4cd1710L, 0x13f1d8d88c1de7eL,
44244       0x03b2b2f0190c091L, 0x195586c72657cedL, 0x1631627d6e360e6L,
44245       0x1399b3a0eb2160cL, 0x1907e6ba3f46d28L, 0x049b5c97a3287e6L,
44246       0x0c6fed4fc00cf68L, 0x0d21e8204b768bbL, 0x03af4b5e67e27baL },
44247     { 0x09d1fdc0d19716eL, 0x0282c3e1c22928cL, 0x1b47aa61f4ab7d6L,
44248       0x06d80e2a1ec9508L, 0x0d6fd5b712b6bf8L, 0x09faafc8ec2ea32L,
44249       0x044a6a5e220d93dL, 0x090c01077b102a1L, 0x1a7672683ea876fL,
44250       0x005973d60ad9244L, 0x1be3490b47664baL, 0x00539e7bc92530bL,
44251       0x1cb14876279c57bL, 0x0572db43ff017c1L, 0x1ae065abae93f92L,
44252       0x0a47b150de136baL, 0x149d88f566ba16eL, 0x0184d374d5d1344L },
44253     { 0x127ee50bdfbe97aL, 0x1f387dc628626f7L, 0x0c05ff827d70697L,
44254       0x0b7da6d98b98f7dL, 0x1550ed3a8fa15a8L, 0x084340e061d66dbL,
44255       0x1732f1607be1faeL, 0x1d142b666c5893aL, 0x00fbb17141fa264L,
44256       0x13fc6c7c70f7744L, 0x133f58870ad8f49L, 0x1cfaa77cfdfba63L,
44257       0x1fdb2a358a924dbL, 0x1aeb4560ea1743bL, 0x13fa9573e59cf1dL,
44258       0x16405c6b2f1fae2L, 0x189eeb366535769L, 0x0022c12c56bac9bL },
44259     { 0x1f71a74a042dbdfL, 0x02c2babbcefd12eL, 0x0e9c34b9995cb50L,
44260       0x0b945d125c1ccd9L, 0x0f0e6b5f285d674L, 0x03b3e1fab546f78L,
44261       0x1ae7383ba14768cL, 0x0853180acb08668L, 0x0b35fce26d6b3c7L,
44262       0x044adff9cbbbf00L, 0x03da9b9edb621b0L, 0x10869e052097079L,
44263       0x1b2e84ec34bee14L, 0x0b6884c8bfba48aL, 0x07eb302eabd98f2L,
44264       0x1805200970eafc8L, 0x158a2b880e56f86L, 0x029fa51f04adbb9L },
44265     { 0x1bb08ce89fc48e7L, 0x062bbd7d5ad7588L, 0x0fe283072d6ae98L,
44266       0x14f2eaf96de0d79L, 0x163191607d2efaeL, 0x1bdbd4f136c858bL,
44267       0x1cafd0aa86ad8adL, 0x1e071dd819a50bbL, 0x1d35947f5f3a8f7L,
44268       0x1e46e077e0e5adaL, 0x0332831161173e5L, 0x1312493c4de5fd7L,
44269       0x0d483ed89a16e8dL, 0x08ec8839be13273L, 0x17a67c04e8fc515L,
44270       0x1aac70a02ac5c60L, 0x036aaf98d746908L, 0x0054cf329eb91e9L },
44271     { 0x1536f46abbc0559L, 0x1833dcd50d0b011L, 0x08a4305a06d7058L,
44272       0x0226f1d20e453faL, 0x0b793a2d61254beL, 0x12a96de307fabd5L,
44273       0x028da9bcb7e2d19L, 0x13535a63127182eL, 0x1c5cd9abe29b74dL,
44274       0x1ba3939fbc24291L, 0x1aa4e83438c18f3L, 0x03c68491c7b1824L,
44275       0x0e8323ddfafe202L, 0x19931cf3ecb9a1fL, 0x0c955227dda1dd4L,
44276       0x1efd52ca1f862eaL, 0x1c0b595dbd13eebL, 0x01d4ae5a28087e5L },
44277     { 0x14e68cb39d7ff2eL, 0x0e5a5e0eae247caL, 0x11ddc5a50e2a374L,
44278       0x012395b19c05525L, 0x12cd08d27965c0bL, 0x0815ed062bcc559L,
44279       0x14860696f0f0e9aL, 0x1b6a8ba124aa30dL, 0x0f0077cdbd27e64L,
44280       0x0abe5524668496dL, 0x1e8e80914caacc0L, 0x073683995746545L,
44281       0x014744aee6a5fb6L, 0x06dd49ed00b816eL, 0x05e13c5216ed0dbL,
44282       0x0e58726b2fecc65L, 0x0455d713c1ddad6L, 0x01b3691170185b9L },
44283     { 0x10b4875573ea5b2L, 0x1200dd486d226eaL, 0x0995e8680c403f3L,
44284       0x0b9e2288c0f6a7fL, 0x0538bf49722a80aL, 0x15669085c75f82dL,
44285       0x141f6b850451f4cL, 0x00ecd24e258f6b5L, 0x06dc5fee73f48caL,
44286       0x0768a4c95c53c6cL, 0x0cc51774bc5d666L, 0x1bc2bf2e371c9d1L,
44287       0x1dadf1b36843408L, 0x12c995bf02af536L, 0x0224ff52eddb9cfL,
44288       0x17fb48850e2a7a6L, 0x125173dccd20661L, 0x048395d4cbcef7eL },
44289     { 0x14de4dd9620ea39L, 0x0b24fe418e77423L, 0x0ec734ea710fefcL,
44290       0x1e7e7be3aa161d1L, 0x0f0ec9b36a38286L, 0x0e04f1a7683959cL,
44291       0x0890a9b93261dcaL, 0x175d47d158d15a2L, 0x06ae0e22bfbdfa5L,
44292       0x10b8f67d8507ac9L, 0x0a21b5ae1c7e355L, 0x1d526bc237b4676L,
44293       0x007f0f153f6b19bL, 0x1eb6017726c0ad2L, 0x0a23d19f982365dL,
44294       0x02ca8fd1e47b36dL, 0x02926ac9652439dL, 0x046c9635e9aaa36L },
44295     { 0x1e0d7ceabeb0ff7L, 0x1a92a1f07217c59L, 0x089b7a021267ef8L,
44296       0x1e39a89786afa36L, 0x035cfee19ece2e1L, 0x1fac0e0922d6de2L,
44297       0x0e51e1d3ba103e4L, 0x01522d4ef397b41L, 0x0abcc815afa57aeL,
44298       0x1d6f616f85310d8L, 0x0940ae07e42f725L, 0x1bc2a77bcc7b7cdL,
44299       0x1f78884c2554bf9L, 0x05ddaa385447ed5L, 0x014fbd4c2a94ac7L,
44300       0x04fd5f00a72d852L, 0x1c08d43d8988dd8L, 0x02725f60bae0d72L },
44301     { 0x18483a2fcc09676L, 0x0251f8cf54d4a5fL, 0x1bcf5c0a977515fL,
44302       0x05087fcfb14d0a5L, 0x16e35158e7915fdL, 0x0ba3783225dd4c0L,
44303       0x1c2d6346e57427bL, 0x0bc8ee08b037215L, 0x10bd4bc6bd4fd13L,
44304       0x16e7033da7419d2L, 0x1a3cc3fd5aa6869L, 0x1001d858c7fc581L,
44305       0x0598f508a8a9c80L, 0x1949409d224e105L, 0x1fa06880ae532ccL,
44306       0x0eceec8fc7a51d8L, 0x12472e67d1ab487L, 0x03d2551fab7cef6L },
44307     { 0x19ef1bae27a0045L, 0x096a7d92165a82aL, 0x0390e73e3493720L,
44308       0x0b367f38a84748fL, 0x0ffa1fcf97544fcL, 0x11641dad6340995L,
44309       0x12eddd3e3fb80d2L, 0x14d2d98c81f9a7eL, 0x0775dce9db0512eL,
44310       0x1ee50cee6e71c0fL, 0x1acfcea74ff9559L, 0x1e8434324e9f83dL,
44311       0x1428d69b1238e0bL, 0x0fe84efc0acc97dL, 0x06ad77d23f3af7aL,
44312       0x0d38bb93bf49f68L, 0x1e10cbd7dc8c0a2L, 0x03014153dfbf856L },
44313     { 0x007e538dceea2e7L, 0x191641e21030ebeL, 0x03e53c7d9458e28L,
44314       0x178eeed420ced05L, 0x15e6b405f21b69fL, 0x13db21631d1a0bdL,
44315       0x051013267c96246L, 0x19a70d25950595aL, 0x0f1e82ffe00869bL,
44316       0x185b8a70b7f2335L, 0x1d0be4640644e30L, 0x0da01f4a2d5cbf6L,
44317       0x0cd8c73a43e9016L, 0x1de2e1b92aa87bdL, 0x130e7b4b5a901f7L,
44318       0x17ce1c8f4ea72d1L, 0x1423fd286d94a5fL, 0x02fa574e391e35cL },
44319     { 0x16a2dda53f4d561L, 0x0a2e80b6d0cc96cL, 0x07eff752c144a1bL,
44320       0x1b3e432bd489340L, 0x037661b325488a0L, 0x12f701620a8d855L,
44321       0x0205ee6311c7be7L, 0x015497950dd50cbL, 0x1bbcadb877a68fcL,
44322       0x059a324b5b9b354L, 0x1a6350559870b62L, 0x098d9202841865dL,
44323       0x152f2752aff5b3bL, 0x088726ce511a939L, 0x092aa00bd9339cdL,
44324       0x14a072734fe4d59L, 0x1d29cd3e291401aL, 0x049500a11ee2357L },
44325     { 0x1f24be11c2f7dbdL, 0x04807dbea93fd74L, 0x16ee1923c4a36a3L,
44326       0x04902832832c7c4L, 0x1a6756fb9ab713eL, 0x06c85ef43fbe80bL,
44327       0x1aaf49d37617816L, 0x12b047fdcf504acL, 0x09f6230d7742401L,
44328       0x02bcf96565af237L, 0x09898c5a9321f81L, 0x1487b33610ae544L,
44329       0x03e488789e9ca19L, 0x0a0361dec36e15dL, 0x18255fbe582d6e6L,
44330       0x0a2b6de58851712L, 0x19b90748706161cL, 0x007e47f0f554465L },
44331     { 0x0ae1bedfeb90f2dL, 0x1dd9e52458aacb4L, 0x1e73d93a58d7ce4L,
44332       0x01f17ceb8457cc5L, 0x1e6f7529354c241L, 0x165598debf5381aL,
44333       0x1cfff09921a3858L, 0x0fd62723ce190c1L, 0x1df367c751d8983L,
44334       0x0a85b5a15f994a0L, 0x03d1b9e304c63f8L, 0x1b57458962c12bdL,
44335       0x0e701afbf32b3f1L, 0x0f443a62e3667aeL, 0x11b72f8eb49d4c1L,
44336       0x125ba7250bca2bbL, 0x09f3c954d86d998L, 0x01685d4316fe9bcL },
44337     { 0x0cd8ee8b472e1afL, 0x0a7575bb55de675L, 0x0fe34364fef7acdL,
44338       0x0ffcdf8e0d36a41L, 0x04ee2f39fccd60dL, 0x00f28f549a9eef5L,
44339       0x19ddd7ac2497a6aL, 0x0d3dc669b43a26cL, 0x0c1d28c9fd5354dL,
44340       0x0bb8baac952f6aaL, 0x18d9fedfdc3606eL, 0x1d9552675cf4ba7L,
44341       0x19e23cfbb77be7eL, 0x04a4bb40932678fL, 0x0d88d6c344a7d2aL,
44342       0x0edb4e0a6eb4813L, 0x1fcccf64c7548a3L, 0x04b1e438926a0edL },
44343     { 0x0e290cbde36a814L, 0x180cab99d895addL, 0x019fddff83866f6L,
44344       0x1a52e419d41d75bL, 0x1029ec720a7d19fL, 0x08c88f21a6bb28cL,
44345       0x1fd8215abfc5eedL, 0x00da144bb35b014L, 0x0ffca86aff848c1L,
44346       0x1f45efca1d6ba4eL, 0x180a138f9a5aed4L, 0x0615dddc842bf73L,
44347       0x1e2ecf3c633eb66L, 0x070060604ec7ddcL, 0x15efab1c7693fe9L,
44348       0x18fdf652d7cb2baL, 0x1bd1751fbada8ceL, 0x01681f59e7faaebL },
44349     { 0x116925f04f2ec1dL, 0x0793b068a3f7175L, 0x1812ab676782a1eL,
44350       0x167ee206b6885beL, 0x0cb95d5b891df44L, 0x147691e1413959cL,
44351       0x1cf8dbc53bed57bL, 0x0bde7888c1e2761L, 0x0889f9bd76bd733L,
44352       0x04f73b8fbaadd37L, 0x0613fbb4866db22L, 0x0e6fd85dc822c4dL,
44353       0x0263efcd372d44cL, 0x131bc135dca1c2dL, 0x19ade9f6424c86dL,
44354       0x0c36f849f14f27dL, 0x0d9a3ca8d24a7cfL, 0x042172060e2a5d6L },
44355     { 0x0268ed6a661d843L, 0x1466527ad9866adL, 0x1b444c4785dc08cL,
44356       0x098cd2b2ce2dcdfL, 0x17b2e280690decbL, 0x1f21685ed62dfb2L,
44357       0x128be09fe0b287bL, 0x00d8aa9d81594bfL, 0x1ac5276c1dde455L,
44358       0x1fa65847183ba89L, 0x1db66b321e5f32dL, 0x10281b2665a5195L,
44359       0x17285a409fd5964L, 0x1111e849e635714L, 0x0a3f025ddcf0a95L,
44360       0x1fcd85aa4cd58a2L, 0x128a596b7cbbc31L, 0x0073198cd656489L },
44361     { 0x1cd2fadf0360ac2L, 0x1306f142f302d5aL, 0x1c43896e6c521adL,
44362       0x1b55358aa9058d9L, 0x126c070e9d5fa38L, 0x0662969efe78dc2L,
44363       0x11fd40de6a5acffL, 0x143c6cb385217f9L, 0x15b1a3db569d3e6L,
44364       0x00a945acdbda16aL, 0x17be92708a801adL, 0x00313699c76d269L,
44365       0x04b3abaf3290f38L, 0x1fc1c4f15839de0L, 0x0968d6c9e96888bL,
44366       0x14f8416f53aa3ffL, 0x05a4939ecef28e1L, 0x04441ced10c3938L },
44367     { 0x0b66c30701ce29aL, 0x178932c4c0ea82bL, 0x1030417e7c84eb2L,
44368       0x0c6e7c7a27a9b5fL, 0x1a2ee3cafee571eL, 0x101c2d73934e437L,
44369       0x1a6b3d732992b74L, 0x1de42fe4eae6001L, 0x0c934db470e7273L,
44370       0x14a7a7b9aadb3bbL, 0x08dae5bf0146010L, 0x03b760a432163f5L,
44371       0x10e9eaef528f88bL, 0x0db40dc81abc8dcL, 0x0570da7cdfecbafL,
44372       0x0439273a14a3a88L, 0x026fc59cca71d2eL, 0x03209467f50fa86L },
44373     { 0x03678a2e8f5b0b5L, 0x1124e69a0782cf8L, 0x11064f29f3b171fL,
44374       0x0d79075f3082880L, 0x1aa8bbb0075ca34L, 0x01187bf9cf8019fL,
44375       0x1cd14f463c3b7ceL, 0x0eaf1bfe019a891L, 0x1849228c0d51aa4L,
44376       0x0a7138418649468L, 0x0e9a1a3c4b3f4f7L, 0x13b71167440d8cdL,
44377       0x19016dae0109104L, 0x1129f1beec32e82L, 0x1a61c6d1667a417L,
44378       0x0265c6459e184f9L, 0x1da014f54da174aL, 0x049b1a504ded5e5L },
44379     { 0x0826b27a9a2e304L, 0x10c3360d2609231L, 0x00c888e05c4315fL,
44380       0x0b5308f9fd22757L, 0x0b5f46fd7e9b6b8L, 0x1c733694b2ae789L,
44381       0x17aadca555cae00L, 0x103c9974c02df52L, 0x0bbc11071b9dedaL,
44382       0x1f8004d1f8e7b0fL, 0x09ddecdcf833ee5L, 0x0139a273ac76a6eL,
44383       0x1a4f87d78e302f9L, 0x1a0243b18f6b396L, 0x1308ac8d881de8eL,
44384       0x1ddcf8811865b3bL, 0x17e4b4c5bf226deL, 0x013365a33de031aL },
44385     { 0x1aa4154b56363e8L, 0x1e83c1e0d526db7L, 0x1778ae79965d2d3L,
44386       0x1df4009708286b1L, 0x119911a65b34ae3L, 0x1b5fbc67a259767L,
44387       0x17255572aa0ce94L, 0x03ac0dc3d7310e1L, 0x0e3c3287d09f351L,
44388       0x0597a75ceae79b2L, 0x13a2498eae3279aL, 0x051d86d56c2382aL,
44389       0x0ba1b7d12015488L, 0x098adc6b84995feL, 0x11ceb05fb9ed6f1L,
44390       0x055e6f05fa1a3eeL, 0x0e1bcb029a83c8fL, 0x0258ead0da922a7L },
44391     { 0x0fe517463d52c0cL, 0x0a92f0c4604ce89L, 0x158cd838e558dcdL,
44392       0x1559f4b486b8c42L, 0x197e810788b3f1cL, 0x0f040548091d053L,
44393       0x16b6ae8c7dad6c5L, 0x191afbcbc25f947L, 0x03287361b0df511L,
44394       0x064006a32babea7L, 0x043cf5481fb245fL, 0x0de261dd41c6210L,
44395       0x133ea5a2ec0d4e5L, 0x1f355de85dfbf70L, 0x02fd865bf01dd8aL,
44396       0x1a8559063fb9c24L, 0x127e07439fab622L, 0x040c35c9fa84725L },
44397     { 0x019d15409312867L, 0x01602dfd7beda63L, 0x19a07d7d7769f81L,
44398       0x0f49f87b05839e2L, 0x0e68b8fe50aa505L, 0x1a6b22769876b2eL,
44399       0x0125fb2c0702efaL, 0x038f6bb88890638L, 0x1351e6a009b7d9bL,
44400       0x1dc31dceca3be48L, 0x196244175044292L, 0x19e886b016f5574L,
44401       0x1690be357e30086L, 0x13da90a7589ce03L, 0x10ead5c4afffc68L,
44402       0x137f4f39f8dae45L, 0x12a4743de57f34aL, 0x005fcbf4be4f715L },
44403     { 0x0ec4ec8dda19e96L, 0x10c7536183745cbL, 0x04ad97da4629533L,
44404       0x161b341b32fd06cL, 0x02fdcc091ac6f68L, 0x1e1f09cc534bd23L,
44405       0x05cc1973897c656L, 0x00c312dd9b56727L, 0x19eb81a0f32f128L,
44406       0x1eba0b70e96e3efL, 0x11e5dab51cd6674L, 0x15353ebde873c45L,
44407       0x0b9e69d94e3de37L, 0x054e85e435bd605L, 0x1dbc4839afea780L,
44408       0x1847eaed50e1aacL, 0x0bb3bd91bb4feaaL, 0x047f2a4161f2055L },
44409     { 0x1ae67c2ce9a4d1eL, 0x15c01a78e901c42L, 0x1ce89741864930fL,
44410       0x1a611f6838b8d91L, 0x071c294e803de0aL, 0x17586d4cb0fade7L,
44411       0x1a2db71881e37c0L, 0x11f90fdea2b6c95L, 0x169679f1e50b4d1L,
44412       0x0e004d0a90ccfa1L, 0x1212f83d90297f1L, 0x176247b56acd4faL,
44413       0x0c64275d2c4c918L, 0x05696f6b533e08aL, 0x12d723656a44ee7L,
44414       0x077ec313da316d6L, 0x03f4aeb6206b42dL, 0x01c946334dde45eL },
44415     { 0x04bea4adacb4b64L, 0x115227930bcd0efL, 0x0539ea444a900fdL,
44416       0x1ba6de663de7559L, 0x007b85c490448fbL, 0x10dbbda130215e2L,
44417       0x1a6116b62965884L, 0x01a62ce949ecf9dL, 0x17fae8bbe4e3b2fL,
44418       0x00efb6ed3e49875L, 0x1bea6309674351aL, 0x13cd7d4383fb5bdL,
44419       0x0b21d405d11b14dL, 0x19c493aa1dd56e4L, 0x1c73793c077fe4dL,
44420       0x1a1b30386b67de0L, 0x0f61704d2e19150L, 0x0366644479aa89aL },
44421     { 0x0d36f0e7ad7504cL, 0x1932ffbcaceeefcL, 0x1b7bfb799eaaf28L,
44422       0x1d75d7e65e1b9a3L, 0x014edcfc1276f4cL, 0x16c75bb412d3730L,
44423       0x138782e306a0a66L, 0x034624049521371L, 0x0cb8fd98b9cbd35L,
44424       0x04209bc7d58f45fL, 0x143d74e5cf2b3e9L, 0x09084b3aa4a82fdL,
44425       0x0374b91393a17e1L, 0x0d651e74a9eadc2L, 0x103e0563de4ac84L,
44426       0x1af7a06bfe22191L, 0x0f96afa6357ad4eL, 0x0178a8cc05937d7L },
44427     { 0x08631da29d2d439L, 0x1dde15e01ccaa86L, 0x1e49b016dd6c487L,
44428       0x016d9c8fd87cb52L, 0x1d88c6586d6cf4cL, 0x1aad0bdd550bb3cL,
44429       0x16a140c76e79fccL, 0x1bf0703c7b015deL, 0x1c71db29015a31bL,
44430       0x1c7b5ba4a4c7ebeL, 0x17cfe44efbbbd98L, 0x04e3e956cf6689dL,
44431       0x10fd22df11e6173L, 0x102e27491d10163L, 0x1ae6483def80e24L,
44432       0x095543843210b51L, 0x1656c805ce8beb5L, 0x01aa582db8562c6L },
44433     { 0x171e2367a9170e9L, 0x16216a656a866b8L, 0x093cf37733ec07bL,
44434       0x074cd95c35ff7d0L, 0x165c7d01a73e8ceL, 0x1ecb8f5b89c53fcL,
44435       0x09cac001638fd70L, 0x0dea4b235865fe1L, 0x0a32fb5bcbbbce7L,
44436       0x1920d5c54fc0d0cL, 0x14cccbb29a18c3cL, 0x13f88905e277e63L,
44437       0x17a4681be2847afL, 0x12af7e7cb0cb710L, 0x0b31c1664e3e4cbL,
44438       0x1f5847cfb5970e1L, 0x1a1d41be893cf09L, 0x0246e2ae2571a91L },
44439     { 0x0623826a5092193L, 0x161b1344c4b8647L, 0x1abc9727ad0791bL,
44440       0x01078fa48a5e26aL, 0x17d00e384178064L, 0x090a8e4c16f7b3cL,
44441       0x021a4e0badb9e94L, 0x0042a9c20ef15ebL, 0x0187070758a51cfL,
44442       0x0f5d4fbb8989e2cL, 0x1ee5cee85564133L, 0x1e963a1af674bacL,
44443       0x118b8af2cd851c9L, 0x0c35c6b10cf94ebL, 0x0ee70cf2e5333feL,
44444       0x118d10e4bc49772L, 0x021405ce4c566e3L, 0x02fb5476e85b6e0L },
44445     { 0x1704ca58f9a8690L, 0x14bb317bb5203c1L, 0x1631a48040a0fcdL,
44446       0x0d79c7499ff7825L, 0x04aab26d4cd58f1L, 0x122bd43c0233250L,
44447       0x05e500173eee93aL, 0x072a6f2a367714bL, 0x14ca2b9e44fe1f7L,
44448       0x0214566ef992bcbL, 0x168d083a890f6f9L, 0x0c57e879c03cc91L,
44449       0x01f27db490cce65L, 0x05fdbe784207821L, 0x01e5f4c55b32dc2L,
44450       0x029773666901ab5L, 0x1ac2e12e07a9eb8L, 0x00e532839653fc3L },
44451     { 0x1b321cf2b9d25a0L, 0x1fee52053a36dfdL, 0x0c39678da2d59abL,
44452       0x08fb000d1f8382aL, 0x1647dd6856ed1eaL, 0x1bc6d44dba6c7f2L,
44453       0x0ce44765ad41e26L, 0x0be736ea487177cL, 0x0ef8d443e0d858cL,
44454       0x0e96da4cb23551aL, 0x14ef47999d50f13L, 0x0180d130130aff5L,
44455       0x1249facabad0d71L, 0x0a7cd0c94fbd7f9L, 0x0cc1e841577b070L,
44456       0x1fec9594cc7323fL, 0x0eeac44fd9135ffL, 0x0231657db65d69eL },
44457     { 0x060a647de3237ddL, 0x19ae6415c3a020bL, 0x1d6777e957e257dL,
44458       0x1ce4d72295ef0f3L, 0x1c93e29815ef043L, 0x18c1988c3a9c9e8L,
44459       0x084ae868af9d1bbL, 0x0fe9cfd1bf84b53L, 0x1dfefc97da9c391L,
44460       0x043ae8185175f20L, 0x1748d69ccb4732fL, 0x0ffdb3754da61eeL,
44461       0x0b65f4857606feeL, 0x089fc1e0553c27dL, 0x03e744c8c557889L,
44462       0x1d5fba5f6ee307dL, 0x0082a291503b546L, 0x00949e4c6366c9bL },
44463     { 0x078125149d53b77L, 0x1a01ecb757d63b9L, 0x1f6d28dadc469aaL,
44464       0x110fcee3836faf8L, 0x13b375228238c70L, 0x03a986a4afb55f9L,
44465       0x0446ac2c0a27232L, 0x13d9507970dcef6L, 0x1be1c0fb8a1bd18L,
44466       0x067d97d8d74ebe3L, 0x108f1525030fa16L, 0x1c82e95b220fa0bL,
44467       0x05064e714216e79L, 0x1efeb0a7d0523f8L, 0x11a622f1a4a7353L,
44468       0x11f63db64b09872L, 0x0ba73e4b5f3e46fL, 0x029dbcd50b4754aL },
44469     { 0x16fafce44bbb6a1L, 0x0ddd033c10b9410L, 0x0cc2a7764e6b4e9L,
44470       0x1be33df5fdde3c9L, 0x1b4ec014022eaf3L, 0x16339c7f6ad5e73L,
44471       0x02689925a3b9944L, 0x00a462330d253fdL, 0x00d539d8d47397cL,
44472       0x0005e2a11a2cb62L, 0x01fd614d1984759L, 0x120793abb41f725L,
44473       0x17c83af2a804099L, 0x1940a8f0f2f7a4cL, 0x10044132277006cL,
44474       0x0593a2a1f6952b0L, 0x03340a6f7d5f387L, 0x041486b68ab6174L },
44475     { 0x04637c6d8546946L, 0x1a51cb4f62bfd7cL, 0x06935e2401fb684L,
44476       0x1c1b8f7013a846bL, 0x0d6784a9b42557fL, 0x056daff31572969L,
44477       0x1f29689c532982fL, 0x02398411bcc6755L, 0x02380ed5ced9678L,
44478       0x135aaf4ed990b30L, 0x0b40b299d48d69bL, 0x1df3667f41c237dL,
44479       0x06f06a2a0851cc6L, 0x1623d9e7fe911f1L, 0x0aa613803cccb87L,
44480       0x05c288b3e52f741L, 0x1b06fa1d969ee95L, 0x0283778d59827d5L },
44481     { 0x1b4eb2735bff163L, 0x05cb7f54fd4c208L, 0x0cfe77ac9f39c4cL,
44482       0x0b3ba387aacd59dL, 0x073075aaa2daf1aL, 0x038dac7a84853f5L,
44483       0x0b670da9abce78cL, 0x02d451ac67bbee7L, 0x0dd354cacbdc89aL,
44484       0x1f51a11ea6e5e1eL, 0x11d348de764b477L, 0x0adf1ddacecadddL,
44485       0x03fa8feb1fe14a4L, 0x1cc7e5e3fd5f3baL, 0x069c1b8501333e2L,
44486       0x18cf0d99a5f7feeL, 0x144daaf3fdb4d85L, 0x020adbedf8a9001L },
44487     { 0x10105867d8377a7L, 0x11eb465c019394bL, 0x0a27c0e930c81a2L,
44488       0x1b2791e521facfaL, 0x09e5a2b84bc7095L, 0x15cf9db897d09e7L,
44489       0x1530bf1ab1b183fL, 0x00219b46db2dc1cL, 0x14549975186320aL,
44490       0x098c648cbf80788L, 0x1130ff9a4d9423eL, 0x1df30be0d15403bL,
44491       0x10a2b5511c769a2L, 0x1a0917029a91677L, 0x1d750fc01a597b6L,
44492       0x03ab3f9c1f5f982L, 0x19d525dc9bdec83L, 0x00f618a78d7ac43L },
44493     { 0x063feef2c8310c2L, 0x10a6d22bf1fba03L, 0x03f394d1a21ea9fL,
44494       0x1ec6fd858a72562L, 0x1542f8dfcde4a38L, 0x0f0b88a83b99905L,
44495       0x06f18d04c0be7dfL, 0x0de031638c75c97L, 0x0f001c46edd2f9eL,
44496       0x1dd854b937667d0L, 0x06e675dd1b831f4L, 0x0defeb0eb5d9526L,
44497       0x1c96939c82e0c8bL, 0x1ef2d3325d9978bL, 0x0afe9add944d748L,
44498       0x00bbce326d968a5L, 0x188ad5cc08f2dc1L, 0x00bf48e893fffabL },
44499     { 0x092ced3b7e051caL, 0x06a7e8ce3bb6a5fL, 0x0d480219e12f191L,
44500       0x0f9d3ad66391569L, 0x1289e9c73ea6622L, 0x150cf71ca924d1eL,
44501       0x16bb15142799744L, 0x01d4f7a8d25186cL, 0x1354997e477963eL,
44502       0x0bb2cabdaccb996L, 0x012bae47528ed83L, 0x1d483bd67c5132bL,
44503       0x0d572571df6e653L, 0x18c570fce53e4c7L, 0x1dee5fbcc068e3eL,
44504       0x141aa2c53ef84c7L, 0x001df242282afc4L, 0x008c79da59eee86L },
44505     { 0x0a0a0a87ad4762bL, 0x1c26d462c68babaL, 0x058133ddb6186bbL,
44506       0x0cfcc1b3162dfe9L, 0x1ecc1dbac0be878L, 0x0b0a3d41b1bffd9L,
44507       0x11b970912982577L, 0x00b47c2f068b610L, 0x1735eb686e77a4cL,
44508       0x1e0c5a7efbac34aL, 0x06342c6f7f94bd6L, 0x181a00e2b7422acL,
44509       0x1ac2dd617f878ecL, 0x10db0b880edede8L, 0x1d64f08874ad8c4L,
44510       0x0e048459d14f289L, 0x1273b9b536a44f1L, 0x000e8533e4681f3L },
44511     { 0x19642361e46533cL, 0x1bcc87dc461573dL, 0x145a90b12863a51L,
44512       0x1bb078f48a0336bL, 0x0cb663e37135e81L, 0x1606b1ba534deeaL,
44513       0x03699ed9fb36f9dL, 0x01407aa8a4223cdL, 0x1596cceb5d2e865L,
44514       0x0ab96fe95781d9bL, 0x192e87eaf5654b3L, 0x08ad69db0ad2a46L,
44515       0x12c950d5d47f47dL, 0x043717c22d6c5abL, 0x1aec1132b74b7e9L,
44516       0x011cdbaa4f6878aL, 0x00fc9adba24997cL, 0x00db12d833ed319L },
44517     { 0x0dfaa7b4fd8446dL, 0x19780d7b7f5f5a2L, 0x0e23fa20e2d7006L,
44518       0x1f7752eb177e888L, 0x07156bc9f33c434L, 0x0484c595cb8e5d4L,
44519       0x11775ac9179707dL, 0x1af0fb96a685683L, 0x0db1f80c634d852L,
44520       0x0b7192c1219ed1aL, 0x008194fdf7c309bL, 0x0cf86c1966cbecdL,
44521       0x029826656ac4ca5L, 0x1f834bb4190fd56L, 0x01d98e44fd729beL,
44522       0x0e6dc2a72f2434eL, 0x08dbdf143288400L, 0x0199f654b0cfe4aL },
44523     { 0x1337948ac775d81L, 0x128c7ea0edde511L, 0x093ef3f3a520e30L,
44524       0x0ca8e07fcec478fL, 0x13fb3b5baad3623L, 0x0e00f8159d09d20L,
44525       0x0598576cd5969fdL, 0x123ae4811b8a46bL, 0x15a17f8e51d616eL,
44526       0x060b775e592dcccL, 0x1a33c4ce4dd0fa4L, 0x0e95ca96c94fe6bL,
44527       0x0a65cd449d987daL, 0x1bf3d8aeaabd991L, 0x1344d3dd9420a94L,
44528       0x00e8c9a4b8e85e5L, 0x135ae9d9c074ccfL, 0x0397e1088439468L },
44529     { 0x106b203f96004c8L, 0x1cae7a2c02affd4L, 0x019d57cd642760fL,
44530       0x17caa191ddaefabL, 0x15a060814a9ea6fL, 0x14103148e46654aL,
44531       0x1e179287fb9e2f3L, 0x0cdd735bc0d347bL, 0x1fbbdcf0c7d3de6L,
44532       0x1451c8dae99b6a8L, 0x1e34a170bff0f08L, 0x1bc65ef62cb6ec1L,
44533       0x04561770401ee48L, 0x0ef7fcd001c01ecL, 0x1f8d69395cfd922L,
44534       0x14d8dc344e71d42L, 0x12d238ef17c8840L, 0x02404a37c588f6cL },
44535     { 0x0c747a8fd71f119L, 0x12e2f29f59b4ac2L, 0x1e198a6161e8679L,
44536       0x135631ade81c5ecL, 0x0630b8c048a4889L, 0x157c4950d4c8126L,
44537       0x15892125d4258b2L, 0x1a9910d3575c41fL, 0x03b72b04d6c2b7dL,
44538       0x13baf5b04c97be8L, 0x0701b9f41b9a138L, 0x06c3c977a00e011L,
44539       0x0b4ba846e4cb3b4L, 0x032326cf50d7333L, 0x1e14e7f0070bac9L,
44540       0x15f8ff0de57cd83L, 0x10216e8e8aecf68L, 0x046d5b0fee39c34L },
44541     { 0x0a5c903d54d1d45L, 0x014bf7fa7cdd121L, 0x1480d351e2d2b35L,
44542       0x161188c4345b116L, 0x1486540235b2ba2L, 0x0f997369e91cdd9L,
44543       0x1f708779dabb644L, 0x0050eff179e7e0dL, 0x1802714c19ec515L,
44544       0x0822275d2c83806L, 0x108a7cc773255e8L, 0x0f57702d3fdb0d2L,
44545       0x152caf080e5ece7L, 0x05ebe778aadf450L, 0x0e5fb84fac86c53L,
44546       0x0d2193bdef5a2cfL, 0x1e7e03ca879118fL, 0x037bbf316fccd94L },
44547     { 0x071bdede40bbf59L, 0x1d229b200d56b51L, 0x00d5cd5073445deL,
44548       0x0c96e3605e2eabcL, 0x0813359f3465b46L, 0x1c75639175b889dL,
44549       0x1ced65e4aa3f5bcL, 0x17e2354025ffe77L, 0x099aafabff85c3fL,
44550       0x0f0517783606621L, 0x15755ddcedecea4L, 0x1cedacd30814629L,
44551       0x132e5a8be6ae5e2L, 0x00e7aac04309b03L, 0x0fb440bb9b5d5e3L,
44552       0x1e1d64689c01ed1L, 0x180799d78868184L, 0x031c0ce48e1e967L },
44553     { 0x05392e17884b073L, 0x1d0fe758933f565L, 0x17c241c0e29e7b0L,
44554       0x19c988f6e07a0feL, 0x1bf96b91cb2ac07L, 0x1527dffcb332770L,
44555       0x19403afd5d624abL, 0x008b557e723f5bcL, 0x0c5b3376f171d12L,
44556       0x1fb0628d069ec0dL, 0x0b3f9e5daa112c7L, 0x19357b4c24b4216L,
44557       0x134ebd453ee131cL, 0x0825b5e0f07e0b6L, 0x0be32af0340c669L,
44558       0x1368fc87417ce14L, 0x1eec80afeec55e4L, 0x033ea46894132ebL },
44559     { 0x08d59a7ea2d56d6L, 0x15e8713a4053183L, 0x16c2b9cd9b375c6L,
44560       0x140e409d78d7a23L, 0x177e6293fbb639cL, 0x1d461ec4d12173fL,
44561       0x1e6a37b9f28add6L, 0x0208e5bb87ac945L, 0x084229df47561a0L,
44562       0x0fb1642e2db24eaL, 0x15ac6d37249f365L, 0x0240bdcc0b2dfbaL,
44563       0x10abf29401fe8bbL, 0x0868e0c21f7e552L, 0x0c077d75240343cL,
44564       0x087ea59e2275251L, 0x1c7a3d7ebc31f0eL, 0x013ca871c741c26L },
44565     { 0x0b21ff0e1d0fa79L, 0x1e8198245aef4f5L, 0x1a24bf8dd32d2e7L,
44566       0x149d643ed699268L, 0x0925e7e7bb4827fL, 0x0a6298a338b7bcdL,
44567       0x1b77c510afcd9f7L, 0x11240e72a99a5d2L, 0x14e0141ae8502aaL,
44568       0x170070d4777b664L, 0x1a1245620336be3L, 0x14b8d2c5008cab9L,
44569       0x185d15dfbfff3abL, 0x0fb4279299ae627L, 0x0796f629fc11032L,
44570       0x04b575d008a7f76L, 0x171a1c99813ff22L, 0x02a7fbc423cd92eL },
44571     { 0x1c6ee30de40b068L, 0x1232df379d28f13L, 0x1813e8ec87da489L,
44572       0x1b8083022bc4948L, 0x0df90d2b50a5a5aL, 0x186007f1942a20cL,
44573       0x0238eedd3963f72L, 0x1938d1e36769458L, 0x1339df0810ccd9eL,
44574       0x0a9b16e5bc3754fL, 0x1178c72556bab64L, 0x003b16d4d8d6512L,
44575       0x1c3678a427d6a2cL, 0x14649816034f416L, 0x08407985e1d5400L,
44576       0x1650d159b52cb3fL, 0x0fe4e4e4573ee30L, 0x0456dd6c29f8c18L },
44577     { 0x00ae11f0969d524L, 0x1ed7bf9cde63c83L, 0x1d99f307f30bd0bL,
44578       0x05c466da9e79d8cL, 0x0e1c0f7f456b9cfL, 0x027d873550faef4L,
44579       0x12ca336f0ab4826L, 0x1de81219f4c368cL, 0x140d86f301243f3L,
44580       0x0d8b66666af43f3L, 0x1c5a30c09b35065L, 0x0d9702d80e60807L,
44581       0x1358407a1ddbe38L, 0x0b8bf0d78a75c37L, 0x12f25b3d622d3e0L,
44582       0x0e3836eb8834ccdL, 0x05ff342c1aa027eL, 0x039c9801b604a2fL },
44583     { 0x14f757d22cdaf42L, 0x1ac8efa0c0d55caL, 0x0067d5453c95e22L,
44584       0x11e31fab791730dL, 0x022ceb9169642e0L, 0x07b4c2c95982e88L,
44585       0x072b85c5640f9a9L, 0x15497afad3ac22fL, 0x0dacdfd5dd29c01L,
44586       0x02eeead6c888466L, 0x0b1ec592b23c55cL, 0x09c36a48c65e869L,
44587       0x1b731fc44761a51L, 0x104b0d98a2dcf30L, 0x1abc88f3d584d23L,
44588       0x133a7385152cee7L, 0x1e25bd10182aa7cL, 0x045e376257214b2L },
44589     { 0x096e5c0e7f2a32bL, 0x04006049c451868L, 0x0df10078d833fd5L,
44590       0x1976c0a94c0dfc8L, 0x0457aa6e6655fc9L, 0x14d95ba8870c304L,
44591       0x1698682b3f288acL, 0x194e64907c6a36fL, 0x1e31471ee6be6c8L,
44592       0x0b2a18e45b2e4d0L, 0x0b0ee5235972ef9L, 0x18435d365551f93L,
44593       0x0daa60aa6ad308fL, 0x0c17e06a6b53ef8L, 0x11e935ca11365aaL,
44594       0x112ab56025858b0L, 0x0152b3c8f71dcebL, 0x04742a1bedf4e3fL },
44595 };
44596 
44597 /* Perform the modular exponentiation in Fp* for SAKKE.
44598  *
44599  * Base is fixed to be the g parameter - a precomputed table is used.
44600  *
44601  * Striping: 128 points at a distance of 8 combined.
44602  * Total of 256 points in table.
44603  * Square and multiply performed in Fp*.
44604  *
44605  * base  [in]   Base. MP integer.
44606  * exp   [in]   Exponent. MP integer.
44607  * res   [out]  Result. MP integer.
44608  * returns 0 on success, MP_READ_E if there are too many bytes in an array
44609  * and MEMORY_E if memory allocation fails.
44610  */
sp_ModExp_Fp_star_1024(const mp_int * base,mp_int * exp,mp_int * res)44611 int sp_ModExp_Fp_star_1024(const mp_int* base, mp_int* exp, mp_int* res)
44612 {
44613 #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && \
44614     !defined(WOLFSSL_SP_NO_MALLOC)
44615     sp_digit* td;
44616     sp_digit* t;
44617     sp_digit* tx;
44618     sp_digit* ty;
44619 #else
44620     sp_digit t[4 * 2 * 18];
44621     sp_digit tx[2 * 18];
44622     sp_digit ty[2 * 18];
44623 #endif
44624     sp_digit* r = NULL;
44625     unsigned char e[128];
44626     int err = MP_OKAY;
44627     int i;
44628     int y;
44629 
44630     (void)base;
44631 
44632 #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && \
44633     !defined(WOLFSSL_SP_NO_MALLOC)
44634     td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 6 * 18 * 2, NULL,
44635                             DYNAMIC_TYPE_TMP_BUFFER);
44636     if (td == NULL) {
44637         err = MEMORY_E;
44638     }
44639 #endif
44640 
44641     if (err == MP_OKAY) {
44642 #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && \
44643     !defined(WOLFSSL_SP_NO_MALLOC)
44644         t  = td;
44645         tx = td + 4 * 18 * 2;
44646         ty = td + 5 * 18 * 2;
44647 #endif
44648         r = ty;
44649 
44650         (void)mp_to_unsigned_bin_len(exp, e, 128);
44651 
44652         XMEMCPY(tx, p1024_norm_mod, sizeof(sp_digit) * 18);
44653         y  =  e[112] >> 7;
44654         y |= (e[96] >> 7) << 1;
44655         y |= (e[80] >> 7) << 2;
44656         y |= (e[64] >> 7) << 3;
44657         y |= (e[48] >> 7) << 4;
44658         y |= (e[32] >> 7) << 5;
44659         y |= (e[16] >> 7) << 6;
44660         y |= (e[0] >> 7) << 7;
44661         XMEMCPY(ty, sp_1024_g_table[y], sizeof(sp_digit) * 18);
44662         for (i = 126; i >= 0; i--) {
44663             y  =  (e[127 - (i / 8)] >> (i & 0x7)) & 1;
44664             y |= ((e[111 - (i / 8)] >> (i & 0x7)) & 1) << 1;
44665             y |= ((e[95 - (i / 8)] >> (i & 0x7)) & 1) << 2;
44666             y |= ((e[79 - (i / 8)] >> (i & 0x7)) & 1) << 3;
44667             y |= ((e[63 - (i / 8)] >> (i & 0x7)) & 1) << 4;
44668             y |= ((e[47 - (i / 8)] >> (i & 0x7)) & 1) << 5;
44669             y |= ((e[31 - (i / 8)] >> (i & 0x7)) & 1) << 6;
44670             y |= ((e[15 - (i / 8)] >> (i & 0x7)) & 1) << 7;
44671 
44672             sp_1024_proj_sqr_18(tx, ty, t);
44673             sp_1024_proj_mul_qx1_18(tx, ty, sp_1024_g_table[y], t);
44674         }
44675     }
44676 
44677     if (err == MP_OKAY) {
44678         sp_1024_mont_inv_18(tx, tx, t);
44679         sp_1024_mont_mul_18(r, tx, ty, p1024_mod, p1024_mp_mod);
44680         XMEMSET(r + 18, 0, sizeof(sp_digit) * 18);
44681         sp_1024_mont_reduce_18(r, p1024_mod, p1024_mp_mod);
44682 
44683         err = sp_1024_to_mp(r, res);
44684     }
44685 
44686 #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && \
44687     !defined(WOLFSSL_SP_NO_MALLOC)
44688     if (td != NULL) {
44689         XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);
44690     }
44691 #endif
44692     return err;
44693 }
44694 
44695 #endif /* WOLFSSL_SP_SMALL */
44696 /* Multiply p* by q* in projective co-ordinates.
44697  *
44698  *   p.x' = (p.x * q.x) - (p.y * q.y)
44699  *   p.y' = (p.x * q.y) + (p.y * q.x)
44700  * But applying Karatsuba:
44701  *   v0 = p.x * q.x
44702  *   v1 = p.y * q.y
44703  *   p.x' = v0 - v1
44704  *   p.y' = (px + py) * (qx + qy) - v0 - v1
44705  *
44706  * px  [in,out]  A single precision integer - X ordinate of number to multiply.
44707  * py  [in,out]  A single precision integer - Y ordinate of number to multiply.
44708  * qx  [in]      A single precision integer - X ordinate of number of
44709  *               multiplier.
44710  * qy  [in]      A single precision integer - Y ordinate of number of
44711  *               multiplier.
44712  * t   [in]      Two single precision integers - temps.
44713  */
sp_1024_proj_mul_18(sp_digit * px,sp_digit * py,const sp_digit * qx,const sp_digit * qy,sp_digit * t)44714 static void sp_1024_proj_mul_18(sp_digit* px, sp_digit* py,
44715         const sp_digit* qx, const sp_digit* qy, sp_digit* t)
44716 {
44717     sp_digit* t1 = t;
44718     sp_digit* t2 = t + 2 * 18;
44719 
44720     /* t1 = px + py */
44721     sp_1024_mont_add_18(t1, px, py, p1024_mod);
44722     /* t2 = qx + qy */
44723     sp_1024_mont_add_18(t2, qx, qy, p1024_mod);
44724     /* t2 = (px + py) * (qx + qy) */
44725     sp_1024_mont_mul_18(t2, t1, t2, p1024_mod, p1024_mp_mod);
44726     /* t1 = py * qy */
44727     sp_1024_mont_mul_18(t1, py, qy, p1024_mod, p1024_mp_mod);
44728     /* t2 = (px + py) * (qx + qy) - (py * qy) */
44729     sp_1024_mont_sub_18(t2, t2, t1, p1024_mod);
44730     /* px = px * qx */
44731     sp_1024_mont_mul_18(px, px, qx, p1024_mod, p1024_mp_mod);
44732     /* py = (px + py) * (qx + qy) - (py * qy) - (px * qx) */
44733     sp_1024_mont_sub_18(py, t2, px, p1024_mod);
44734     /* px = (px * qx) - (py * qy)*/
44735     sp_1024_mont_sub_18(px, px, t1, p1024_mod);
44736 }
44737 
44738 #ifndef WOLFSSL_SP_SMALL
44739 /*
44740  * Convert point from projective to affine but keep in Montgomery form.
44741  *
44742  * p  [in,out]  Point to convert.
44743  * t  [in]      Temporary numbers: 2.
44744  */
sp_1024_mont_map_18(sp_point_1024 * p,sp_digit * t)44745 static void sp_1024_mont_map_18(sp_point_1024* p, sp_digit* t)
44746 {
44747     sp_digit* t1 = t;
44748     sp_digit* t2 = t + 2 * 18;
44749 
44750     sp_1024_mont_inv_18(t1, p->z, t2);
44751     sp_1024_mont_sqr_18(t2, t1, p1024_mod, p1024_mp_mod);
44752     sp_1024_mont_mul_18(t1, t2, t1, p1024_mod, p1024_mp_mod);
44753     sp_1024_mont_mul_18(p->x, p->x, t2, p1024_mod, p1024_mp_mod);
44754     sp_1024_mont_mul_18(p->y, p->y, t1, p1024_mod, p1024_mp_mod);
44755     XMEMCPY(p->z, p1024_norm_mod, sizeof(sp_digit) * 18);
44756 }
44757 
44758 #endif /* WOLFSSL_SP_SMALL */
44759 /*
44760  * Calculate gradient of line through P, P and [-2]P, accumulate line and
44761  * double P.
44762  *
44763  * Calculations:
44764  *   l = 3 * (p.x^2 - p.z^4) = 3 * (p.x - p.z^2) * (p.x + p.z^2)
44765  *   r.x = l * (p.x + q.x * p.z^2) - 2 * p.y^2
44766  *   r.y = 2 * p.y * p.z^3 * q.y (= p'.z * p.z^2 * q.y)
44767  *   v* = v*^2 * r*
44768  *   p'.x = l^2 - 8 * p.y^2 * p.x
44769  *   p'.y = (4 * p.y^2 * p.x - p'.x) * l - 8 * p.y^4
44770  *   p'.z = 2 * p.y * p.z
44771  *
44772  * @param  [in,out]  vx  X-ordinate of projective value in F*.
44773  * @param  [in,out]  vy  Y-ordinate of projective value in F*.
44774  * @param  [in,out]  p   ECC point - point on E(F_p^2) to double.
44775  * @param  [in]      q   ECC point - second point on E(F_P^2).
44776  * @param  [in]      t   SP temporaries (6 used).
44777  */
sp_1024_accumulate_line_dbl_18(sp_digit * vx,sp_digit * vy,sp_point_1024 * p,const sp_point_1024 * q,sp_digit * t)44778 static void sp_1024_accumulate_line_dbl_18(sp_digit* vx, sp_digit* vy,
44779         sp_point_1024* p, const sp_point_1024* q, sp_digit* t)
44780 {
44781     sp_digit* t1  = t +  0 * 18;
44782     sp_digit* pz2 = t +  2 * 18;
44783     sp_digit* rx  = t +  4 * 18;
44784     sp_digit* ry  = t +  6 * 18;
44785     sp_digit* l   = t +  8 * 18;
44786     sp_digit* ty  = t + 10 * 18;
44787 
44788     /* v = v^2 */
44789     sp_1024_proj_sqr_18(vx, vy, t);
44790     /* pz2 = p.z^2 */
44791     sp_1024_mont_sqr_18(pz2, p->z, p1024_mod, p1024_mp_mod);
44792     /* t1 = p.x + p.z^2 */
44793     sp_1024_mont_add_18(ty, p->x, pz2, p1024_mod);
44794     /* l = p.x - p.z^2 */
44795     sp_1024_mont_sub_18(l, p->x, pz2, p1024_mod);
44796     /* t1 = (p.x + p.z^2) * (p.x - p.z^2) = p.x^2 - p.z^4 */
44797     sp_1024_mont_mul_18(t1, l, ty, p1024_mod, p1024_mp_mod);
44798     /* l = 3 * (p.x^2 - p.z^4) */
44799     sp_1024_mont_tpl_18(l, t1, p1024_mod);
44800     /* t1 = q.x * p.z^2 */
44801     sp_1024_mont_mul_18(t1, q->x, pz2, p1024_mod, p1024_mp_mod);
44802     /* t1 = p.x + q.x * p.z^2 */
44803     sp_1024_mont_add_18(t1, p->x, t1, p1024_mod);
44804     /* r.x = l * (p.x + q.x * p.z^2) */
44805     sp_1024_mont_mul_18(rx, l, t1, p1024_mod, p1024_mp_mod);
44806     /* r.y = 2 * p.y */
44807     sp_1024_mont_dbl_18(ry, p->y, p1024_mod);
44808     /* ty = 4 * p.y ^ 2 */
44809     sp_1024_mont_sqr_18(ty, ry, p1024_mod, p1024_mp_mod);
44810     /* t1 = 2 * p.y ^ 2 */
44811     sp_1024_div2_18(t1, ty, p1024_mod);
44812     /* r.x -= 2 * (p.y ^ 2) */
44813     sp_1024_mont_sub_18(rx, rx, t1, p1024_mod);
44814     /* p'.z = p.y * 2 * p.z */
44815     sp_1024_mont_mul_18(p->z, p->z, ry, p1024_mod, p1024_mp_mod);
44816     /* r.y = p'.z * p.z^2 */
44817     sp_1024_mont_mul_18(t1, p->z, pz2, p1024_mod, p1024_mp_mod);
44818     /* r.y = p'.z * p.z^2 * q.y */
44819     sp_1024_mont_mul_18(ry, t1, q->y, p1024_mod, p1024_mp_mod);
44820     /* v = v^2 * r */
44821     sp_1024_proj_mul_18(vx, vy, rx, ry, t);
44822 
44823     /* Double point using previously calculated values
44824      *   l = 3 * (p.x - p.z^2).(p.x + p.z^2)
44825      *   ty = 4 * p.y^2
44826      *   p'.z = 2 * p.y * p.z
44827      */
44828     /* t1 = (4 * p.y^2) ^ 2 = 16 * p.y^4 */
44829     sp_1024_mont_sqr_18(t1, ty, p1024_mod, p1024_mp_mod);
44830     /* t1 = 16 * p.y^4 / 2 = 8 * p.y^4 */
44831     sp_1024_div2_18(t1, t1, p1024_mod);
44832     /* p'.y = 4 * p.y^2 * p.x */
44833     sp_1024_mont_mul_18(p->y, ty, p->x, p1024_mod, p1024_mp_mod);
44834     /* p'.x = l^2 */
44835     sp_1024_mont_sqr_18(p->x, l, p1024_mod, p1024_mp_mod);
44836     /* p'.x = l^2 - 4 * p.y^2 * p.x */
44837     sp_1024_mont_sub_18(p->x, p->x, p->y, p1024_mod);
44838     /* p'.x = l^2 - 8 * p.y^2 * p.x */
44839     sp_1024_mont_sub_18(p->x, p->x, p->y, p1024_mod);
44840     /* p'.y = 4 * p.y^2 * p.x - p.x' */
44841     sp_1024_mont_sub_18(ty, p->y, p->x, p1024_mod);
44842     /* p'.y = (4 * p.y^2 * p.x - p'.x) * l */
44843     sp_1024_mont_mul_18(p->y, ty, l, p1024_mod, p1024_mp_mod);
44844     /* p'.y = (4 * p.y^2 * p.x - p'.x) * l - 8 * p.y^4 */
44845     sp_1024_mont_sub_18(p->y, p->y, t1, p1024_mod);
44846 }
44847 
44848 #ifdef WOLFSSL_SP_SMALL
44849 /*
44850  * Calculate gradient of line through C, P and -C-P, accumulate line and
44851  * add P to C.
44852  *
44853  * Calculations:
44854  *   r.x = (q.x + p.x) * c.y - (q.x * c.z^2 + c.x) * p.y * c.z
44855  *   r.y = (c.x - p.x * c.z^2) * q.y * c.z
44856  *   v* = v* * r*
44857  *   r = p.y * c.z^3 - c.y
44858  *   c'.x = r^2 + h^3 - 2 * c.x * h^2
44859  *   c'.y = r * (c'.x - c.x * h^2) - c.y * h^3
44860  *   c'.z = (c.x - p.x * c.z^2) * c.z
44861  *
44862  * @param  [in,out]  vx     X-ordinate of projective value in F*.
44863  * @param  [in,out]  vy     Y-ordinate of projective value in F*.
44864  * @param  [in,out]  c      ECC point - current point on E(F_p^2) to be added
44865  *                          to.
44866  * @param  [in]      p      ECC point - point on E(F_p^2) to add.
44867  * @param  [in]      q      ECC point - second point on E(F_P^2).
44868  * @param  [in]      qx_px  SP that is a constant value across adds.
44869  * @param  [in]      t      SP temporaries (6 used).
44870  */
sp_1024_accumulate_line_add_one_18(sp_digit * vx,sp_digit * vy,sp_point_1024 * c,sp_point_1024 * p,sp_point_1024 * q,sp_digit * qx_px,sp_digit * t)44871 static void sp_1024_accumulate_line_add_one_18(sp_digit* vx, sp_digit* vy,
44872         sp_point_1024* c, sp_point_1024* p, sp_point_1024* q, sp_digit* qx_px,
44873         sp_digit* t)
44874 {
44875     sp_digit* t1  = t;
44876     sp_digit* t2  = t +  2 * 18;
44877     sp_digit* rx  = t +  4 * 18;
44878     sp_digit* ry  = t +  6 * 18;
44879     sp_digit* h   = t +  8 * 18;
44880     sp_digit* r   = t + 10 * 18;
44881 
44882     /* r.x = (q.x + p.x) * c.y */
44883     sp_1024_mont_mul_18(rx, qx_px, c->y, p1024_mod, p1024_mp_mod);
44884     /* t2 = c.z^2 */
44885     sp_1024_mont_sqr_18(t2, c->z, p1024_mod, p1024_mp_mod);
44886     /* t1 = q.x * c.z^2 */
44887     sp_1024_mont_mul_18(t1, q->x, t2, p1024_mod, p1024_mp_mod);
44888     /* t1 = q.x * c.z^2 + c.x */
44889     sp_1024_mont_add_18(h, t1, c->x, p1024_mod);
44890     /* r = p.y * c.z */
44891     sp_1024_mont_mul_18(ry, p->y, c->z, p1024_mod, p1024_mp_mod);
44892     /* t1 = (q.x * c.z^2 + c.x) * p.y * c.z */
44893     sp_1024_mont_mul_18(t1, h, ry, p1024_mod, p1024_mp_mod);
44894     /* r = p.y * c.z * c.z^2 = p.y * c.z^3  */
44895     sp_1024_mont_mul_18(r, ry, t2, p1024_mod, p1024_mp_mod);
44896     /* r.x -= (q.x * c.z^2 + c.x) * p.y * c.z */
44897     sp_1024_mont_sub_18(rx, rx, t1, p1024_mod);
44898     /* t1 = p.x * c.z^2 */
44899     sp_1024_mont_mul_18(t1, p->x, t2, p1024_mod, p1024_mp_mod);
44900     /* h = c.x - p.x * c.z^2 */
44901     sp_1024_mont_sub_18(h, c->x, t1, p1024_mod);
44902     /* c'.z = (c.x - p.x * c.z^2) * c.z */
44903     sp_1024_mont_mul_18(c->z, h, c->z, p1024_mod, p1024_mp_mod);
44904     /* r.y = (c.x - p.x * c.z^2) * c.z * q.y */
44905     sp_1024_mont_mul_18(ry, c->z, q->y, p1024_mod, p1024_mp_mod);
44906     /* v = v * r */
44907     sp_1024_proj_mul_18(vx, vy, rx, ry, t);
44908 
44909     /* Add p to c using previously calculated values.
44910      *   h = c.x - p.x * c.z^2
44911      *   r = p.y * c.z^3
44912      *   c'.z = (c.x - p.x * c.z^2) * c.z
44913      */
44914 
44915     /* r = p.y * c.z^3 - c.y */
44916     sp_1024_mont_sub_18(r, r, c->y, p1024_mod);
44917     /* t1 = r^2 */
44918     sp_1024_mont_sqr_18(t1, r, p1024_mod, p1024_mp_mod);
44919     /* t2 = h^2 */
44920     sp_1024_mont_sqr_18(rx, h, p1024_mod, p1024_mp_mod);
44921     /* ry = c.x * h^2 */
44922     sp_1024_mont_mul_18(ry, c->x, rx, p1024_mod, p1024_mp_mod);
44923     /* t2 = h^3 */
44924     sp_1024_mont_mul_18(t2, rx, h, p1024_mod, p1024_mp_mod);
44925     /* c->x = r^2 + h^3 */
44926     sp_1024_mont_add_18(c->x, t1, t2, p1024_mod);
44927     /* t1 = 2 * c.x * h^2 */
44928     sp_1024_mont_dbl_18(t1, ry, p1024_mod);
44929     /* c'.x = r^2 + h^3 - 2 * c.x * h^2 */
44930     sp_1024_mont_sub_18(c->x, c->x, t1, p1024_mod);
44931     /* ry = c'.x - c.x * h^2 */
44932     sp_1024_mont_sub_18(t1, c->x, ry, p1024_mod);
44933     /* ry = r * (c'.x - c.x * h^2) */
44934     sp_1024_mont_mul_18(ry, t1, r, p1024_mod, p1024_mp_mod);
44935     /* t2 = c.y * h^3 */
44936     sp_1024_mont_mul_18(t1, t2, c->y, p1024_mod, p1024_mp_mod);
44937     /* c'.y = r * (c'.x - c.x * h^2) - c.y * h^3 */
44938     sp_1024_mont_sub_18(c->y, ry, t1, p1024_mod);
44939 }
44940 
44941 /*
44942  * Calculate r = pairing <P, Q>.
44943  *
44944  * That is, multiply base in PF_p[q] by the scalar s, such that s.P = Q.
44945  *
44946  * @param  [in]  key  SAKKE key.
44947  * @param  [in]  p    First point on E(F_p)[q].
44948  * @param  [in]  q    Second point on E(F_p)[q].
44949  * @param  [in]  r    Result of calculation.
44950  * @return  0 on success.
44951  * @return  MEMORY_E when dynamic memory allocation fails.
44952  * @return  Other -ve value on internal failure.
44953  */
sp_Pairing_1024(const ecc_point * pm,const ecc_point * qm,mp_int * res)44954 int sp_Pairing_1024(const ecc_point* pm, const ecc_point* qm, mp_int* res)
44955 {
44956     int err = MP_OKAY;
44957 #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && \
44958     !defined(WOLFSSL_SP_NO_MALLOC)
44959     sp_digit* td = NULL;
44960     sp_digit* t;
44961     sp_digit* vx;
44962     sp_digit* vy;
44963     sp_digit* qx_px;
44964 #else
44965     sp_digit t[6 * 2 * 18];
44966     sp_digit vx[2 * 18];
44967     sp_digit vy[2 * 18];
44968     sp_digit qx_px[2 * 18];
44969     sp_point_1024 pd;
44970     sp_point_1024 qd;
44971     sp_point_1024 cd;
44972 #endif
44973     sp_point_1024* p = NULL;
44974     sp_point_1024* q = NULL;
44975     sp_point_1024* c = NULL;
44976     sp_digit* r = NULL;
44977     int i;
44978 
44979     err = sp_1024_point_new_18(NULL, pd, p);
44980     if (err == MP_OKAY) {
44981         err = sp_1024_point_new_18(NULL, qd, q);
44982     }
44983     if (err == MP_OKAY) {
44984         err = sp_1024_point_new_18(NULL, cd, c);
44985     }
44986 
44987 #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && \
44988     !defined(WOLFSSL_SP_NO_MALLOC)
44989     if (err == MP_OKAY) {
44990         td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 9 * 18 * 2, NULL,
44991                                 DYNAMIC_TYPE_TMP_BUFFER);
44992         if (td == NULL) {
44993             err = MEMORY_E;
44994         }
44995     }
44996 #endif
44997 
44998     if (err == MP_OKAY) {
44999 #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && \
45000     !defined(WOLFSSL_SP_NO_MALLOC)
45001         t     = td;
45002         vx    = td + 6 * 18 * 2;
45003         vy    = td + 7 * 18 * 2;
45004         qx_px = td + 8 * 18 * 2;
45005 #endif
45006         r = vy;
45007 
45008         sp_1024_point_from_ecc_point_18(p, pm);
45009         sp_1024_point_from_ecc_point_18(q, qm);
45010 
45011         err = sp_1024_mod_mul_norm_18(p->x, p->x, p1024_mod);
45012     }
45013     if (err == MP_OKAY) {
45014         err = sp_1024_mod_mul_norm_18(p->y, p->y, p1024_mod);
45015     }
45016     if (err == MP_OKAY) {
45017         err = sp_1024_mod_mul_norm_18(p->z, p->z, p1024_mod);
45018     }
45019     if (err == MP_OKAY) {
45020         err = sp_1024_mod_mul_norm_18(q->x, q->x, p1024_mod);
45021     }
45022     if (err == MP_OKAY) {
45023         err = sp_1024_mod_mul_norm_18(q->y, q->y, p1024_mod);
45024     }
45025     if (err == MP_OKAY) {
45026         XMEMCPY(c, p, sizeof(sp_point_1024));
45027         XMEMSET(vx, 0, sizeof(sp_digit) * 2 * 18);
45028         vx[0] = 1;
45029         XMEMSET(vy, 0, sizeof(sp_digit) * 2 * 18);
45030 
45031         sp_1024_mont_add_18(qx_px, q->x, p->x, p1024_mod);
45032 
45033         for (i = 1020; i >= 0; i--) {
45034             /* Accumulate line into v and double point. */
45035             sp_1024_accumulate_line_dbl_18(vx, vy, c, q, t);
45036 
45037             if ((i > 0) && ((p1024_order[i / 57] >> (i % 57)) & 1)) {
45038                 /* Accumulate line into v and add P into C. */
45039                 sp_1024_accumulate_line_add_one_18(vx, vy, c, p, q, qx_px, t);
45040             }
45041         }
45042 
45043         /* Final exponentiation */
45044         sp_1024_proj_sqr_18(vx, vy, t);
45045         sp_1024_proj_sqr_18(vx, vy, t);
45046 
45047         /* Convert from PF_p[q] to F_p */
45048         sp_1024_mont_inv_18(vx, vx, t);
45049         sp_1024_mont_mul_18(r, vx, vy, p1024_mod, p1024_mp_mod);
45050         XMEMSET(r + 18, 0, sizeof(sp_digit) * 18);
45051         sp_1024_mont_reduce_18(r, p1024_mod, p1024_mp_mod);
45052 
45053         err = sp_1024_to_mp(r, res);
45054     }
45055 
45056 #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && \
45057     !defined(WOLFSSL_SP_NO_MALLOC)
45058     if (td != NULL) {
45059         XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);
45060     }
45061 #endif
45062     sp_1024_point_free_18(c, 1, NULL);
45063     sp_1024_point_free_18(q, 1, NULL);
45064     sp_1024_point_free_18(p, 1, NULL);
45065     return err;
45066 }
45067 
45068 #else
45069 /*
45070  * Calculate gradient of line through C, P and -C-P, accumulate line and
45071  * add P to C.
45072  *
45073  * Both C and P have z ordinates to use in the calculation.
45074  *
45075  * Calculations:
45076  *   r.x  = (q.x * c.z^2 + c.x) * p.y * c.z - (q.x * p.z^2 + p.x) * c.y * p.z
45077  *   r.y  = (p.x * c.z^2 - c.x * p.z^2) * q.y * p.z * c.z
45078  *   v*   = v* * r*
45079  *   h    = p.x * c.z^2 - c.x * p.z^2
45080  *   r    = p.y * c.z^3 - c.y * p.z^3
45081  *   c'.x = r^2 - h^3 - 2 * c.x * p.z^2 * h^2
45082  *   c'.y = r * (c.x * p.z^2 * h^2 - c'.x) - c.y * p.z^3 * h^3
45083  *   c'.z = (p.x * c.z^2 - c.x * p.z^2) * c.z
45084  *
45085  * @param  [in,out]  vx     X-ordinate of projective value in F*.
45086  * @param  [in,out]  vy     Y-ordinate of projective value in F*.
45087  * @param  [in,out]  c      ECC point - current point on E(F_p^2) to be added
45088  *                          to.
45089  * @param  [in,out]  p      ECC point - point on E(F_p^2) to add.
45090  * @param  [in,out]  q      ECC point - second point on E(F_P^2).
45091  * @param  [in,out]  t      SP temporaries (6 used).
45092  * @param  [in,out]  neg    Indicates to use negative P.
45093  * @return  0 on success.
45094  * @return  MEMORY_E when dynamic memory allocation fails.
45095  * @return  Other -ve value on internal failure.
45096  */
sp_1024_accumulate_line_add_n_18(sp_digit * vx,sp_digit * vy,const sp_point_1024 * p,const sp_point_1024 * q,sp_point_1024 * c,sp_digit * t,int neg)45097 static void sp_1024_accumulate_line_add_n_18(sp_digit* vx, sp_digit* vy,
45098         const sp_point_1024* p, const sp_point_1024* q,
45099         sp_point_1024* c, sp_digit* t, int neg)
45100 {
45101     sp_digit* t1 = t;
45102     sp_digit* t2 = t +  2 * 18;
45103     sp_digit* rx = t +  4 * 18;
45104     sp_digit* ry = t +  6 * 18;
45105     sp_digit* h  = t +  8 * 18;
45106     sp_digit* r  = t + 10 * 18;
45107 
45108     /* h = p.z^2 */
45109     sp_1024_mont_sqr_18(h, p->z, p1024_mod, p1024_mp_mod);
45110     /* rx = q.x * p.z^2 */
45111     sp_1024_mont_mul_18(rx, q->x, h, p1024_mod, p1024_mp_mod);
45112     /* rx = q.x * p.z^2 + p.x */
45113     sp_1024_mont_add_18(t2, rx, p->x, p1024_mod);
45114     /* c.y = c.y * p.z */
45115     sp_1024_mont_mul_18(t1, c->y, p->z, p1024_mod, p1024_mp_mod);
45116     /* r.x = (q.x * p.z^2 + p.x) * c.y * p.z */
45117     sp_1024_mont_mul_18(rx, t2, t1, p1024_mod, p1024_mp_mod);
45118     /* c.y = c.y * p.z^3 */
45119     sp_1024_mont_mul_18(c->y, t1, h, p1024_mod, p1024_mp_mod);
45120     /* t2 = c.z^2 */
45121     sp_1024_mont_sqr_18(t2, c->z, p1024_mod, p1024_mp_mod);
45122     /* t1 = q.x * c.z^2 */
45123     sp_1024_mont_mul_18(t1, q->x, t2, p1024_mod, p1024_mp_mod);
45124     /* t1 = q.x * c.z^2 + c.x */
45125     sp_1024_mont_add_18(t1, t1, c->x, p1024_mod);
45126     /* c.x = c.x * p.z^2 */
45127     sp_1024_mont_mul_18(c->x, c->x, h, p1024_mod, p1024_mp_mod);
45128     /* r = p.y * c.z */
45129     sp_1024_mont_mul_18(r, p->y, c->z, p1024_mod, p1024_mp_mod);
45130     if (neg) {
45131         /* r = -p.y * c.z */
45132         sp_1024_mont_sub_18(r, p1024_mod, r, p1024_mod);
45133     }
45134     /* t1 = (q.x * c.z^2 + c.x) * p.y * c.z */
45135     sp_1024_mont_mul_18(ry, t1, r, p1024_mod, p1024_mp_mod);
45136     /* r.x -= (q.x * c.z^2 + c.x) * p.y * c.z */
45137     sp_1024_mont_sub_18(rx, ry, rx, p1024_mod);
45138     /* t1 = p.x * c.z^2 */
45139     sp_1024_mont_mul_18(t1, p->x, t2, p1024_mod, p1024_mp_mod);
45140     /* h = p.x * c.z^2 - c.x * p.z^2 */
45141     sp_1024_mont_sub_18(h, t1, c->x, p1024_mod);
45142     /* c'.z = (p.x * c.z^2 - c.x * p.z^2) * c.z */
45143     sp_1024_mont_mul_18(t1, h, c->z, p1024_mod, p1024_mp_mod);
45144     /* c'.z = (p.x * c.z^2 - c.x * p.z^2) * c.z * p.z */
45145     sp_1024_mont_mul_18(c->z, t1, p->z, p1024_mod, p1024_mp_mod);
45146     /* r.y = (p.x * c.z^2 - c.x * p.z^2) * c.z * p.z * q.y */
45147     sp_1024_mont_mul_18(ry, c->z, q->y, p1024_mod, p1024_mp_mod);
45148     /* r = p.y * c.z^3 */
45149     sp_1024_mont_mul_18(t1, r, t2, p1024_mod, p1024_mp_mod);
45150     /* r = p.y * c.z^3 - c.y * p.z^3 */
45151     sp_1024_mont_sub_18(r, t1, c->y, p1024_mod);
45152     /* v = v * r */
45153     sp_1024_proj_mul_18(vx, vy, rx, ry, t);
45154 
45155     /* Add p to c using previously calculated values.
45156      *   h = p.x * c.z^2 - c.x * p.z^2
45157      *   r = p.y * c.z^3 - c.y * p.z^3
45158      *   c'.z = (p.x * c.z^2 - c.x * p.z^2) * c.z
45159      */
45160 
45161     /* t1 = r^2 */
45162     sp_1024_mont_sqr_18(t1, r, p1024_mod, p1024_mp_mod);
45163     /* t2 = h^2 */
45164     sp_1024_mont_sqr_18(rx, h, p1024_mod, p1024_mp_mod);
45165     /* ry = c.x * p.z^2 * h^2 */
45166     sp_1024_mont_mul_18(ry, rx, c->x, p1024_mod, p1024_mp_mod);
45167     /* t2 = h^3 */
45168     sp_1024_mont_mul_18(t2, rx, h, p1024_mod, p1024_mp_mod);
45169     /* c'.x = r^2 - h^3 */
45170     sp_1024_mont_sub_18(c->x, t1, t2, p1024_mod);
45171     /* t1 = 2 * c.x * p.z^2 * h^2 */
45172     sp_1024_mont_dbl_18(t1, ry, p1024_mod);
45173     /* c'.x = r^2 - h^3 - 2 * c.x * p.z^2 * h^2 */
45174     sp_1024_mont_sub_18(c->x, c->x, t1, p1024_mod);
45175     /* ry = c.x * p.z^2 * h^2 - c'.x */
45176     sp_1024_mont_sub_18(t1, ry, c->x, p1024_mod);
45177     /* ry = r * (c.x * p.z^2 * h^2 - c'.x) */
45178     sp_1024_mont_mul_18(ry, t1, r, p1024_mod, p1024_mp_mod);
45179     /* t2 = c.y * p.z^3 * h^3 */
45180     sp_1024_mont_mul_18(t1, t2, c->y, p1024_mod, p1024_mp_mod);
45181     /* c'.y = r * (c.x * p.z^2 * h^2 - c'.x) - c.y * p.z^3 * h^3 */
45182     sp_1024_mont_sub_18(c->y, ry, t1, p1024_mod);
45183 }
45184 
45185 /*
45186  * Perform n accumulate doubles and doubles of P.
45187  *
45188  * py = 2 * p.y
45189  *
45190  * For each double:
45191  * Calculate gradient of line through P, P and [-2]P, accumulate line and
45192  * double P.
45193  *
45194  * Calculations:
45195  *   l = 3 * (p.x^2 - p.z^4) = 3 * (p.x - p.z^2) * (p.x + p.z^2)
45196  *   r.x = l * (p.x + q.x * p.z^2) - py^2 / 2
45197  *   r.y = py * p.z^3 * q.y (= p'.z * p.z^2 * q.y)
45198  *   v* = v*^2 * r*
45199  *   p'.x = l^2 - 2 * py^2 * p.x
45200  *   py' = (py^2 * p.x - p'.x) * l - py^4 (= 2 * p'.y)
45201  *   p'.z = py * p.z
45202  *
45203  * Finally:
45204  *   p'.y = py' / 2
45205  *
45206  * @param  [in,out]  vx  X-ordinate of projective value in F*.
45207  * @param  [in,out]  vy  Y-ordinate of projective value in F*.
45208  * @param  [in,out]  p   ECC point - point on E(F_p^2) to double.
45209  * @param  [in]      q   ECC point - second point on E(F_P^2).
45210  * @param  [in]      n   Number of times to double.
45211  * @param  [in]      t   SP temporaries (6 used).
45212  */
sp_1024_accumulate_line_dbl_n_18(sp_digit * vx,sp_digit * vy,sp_point_1024 * p,const sp_point_1024 * q,int n,sp_digit * t)45213 static void sp_1024_accumulate_line_dbl_n_18(sp_digit* vx, sp_digit* vy,
45214         sp_point_1024* p, const sp_point_1024* q, int n, sp_digit* t)
45215 {
45216     sp_digit* t1  = t +  0 * 18;
45217     sp_digit* pz2 = t +  2 * 18;
45218     sp_digit* rx  = t +  4 * 18;
45219     sp_digit* ry  = t +  6 * 18;
45220     sp_digit* l   = t +  8 * 18;
45221     sp_digit* ty  = t + 10 * 18;
45222     int i;
45223 
45224     /* py = 2 * p.y */
45225     sp_1024_mont_dbl_18(p->y, p->y, p1024_mod);
45226 
45227     for (i = 0; i < n; i++) {
45228         /* v = v^2 */
45229         sp_1024_proj_sqr_18(vx, vy, t);
45230         /* pz2 = p.z^2 */
45231         sp_1024_mont_sqr_18(pz2, p->z, p1024_mod, p1024_mp_mod);
45232         /* t1 = p.x + p.z^2 */
45233         sp_1024_mont_add_18(t1, p->x, pz2, p1024_mod);
45234         /* l = p.x - p.z^2 */
45235         sp_1024_mont_sub_18(l, p->x, pz2, p1024_mod);
45236         /* t1 = (p.x + p.z^2) * (p.x - p.z^2) = p.x^2 - p.z^4 */
45237         sp_1024_mont_mul_18(ty, l, t1, p1024_mod, p1024_mp_mod);
45238         /* l = 3 * (p.x^2 - p.z^4) */
45239         sp_1024_mont_tpl_18(l, ty, p1024_mod);
45240         /* t1 = q.x * p.z^2 */
45241         sp_1024_mont_mul_18(t1, q->x, pz2, p1024_mod, p1024_mp_mod);
45242         /* t1 = p.x + q.x * p.z^2 */
45243         sp_1024_mont_add_18(t1, p->x, t1, p1024_mod);
45244         /* r.x = l * (p.x + q.x * p.z^2) */
45245         sp_1024_mont_mul_18(rx, l, t1, p1024_mod, p1024_mp_mod);
45246         /* ty = py ^ 2 */
45247         sp_1024_mont_sqr_18(ty, p->y, p1024_mod, p1024_mp_mod);
45248         /* t1 = py ^ 2 / 2 */
45249         sp_1024_div2_18(t1, ty, p1024_mod);
45250         /* r.x -= py ^ 2 / 2 */
45251         sp_1024_mont_sub_18(rx, rx, t1, p1024_mod);
45252         /* p'.z = py * pz */
45253         sp_1024_mont_mul_18(p->z, p->z, p->y, p1024_mod, p1024_mp_mod);
45254         /* r.y = p'.z * p.z^2 */
45255         sp_1024_mont_mul_18(t1, p->z, pz2, p1024_mod, p1024_mp_mod);
45256         /* r.y = p'.z * p.z^2 * q.y */
45257         sp_1024_mont_mul_18(ry, t1, q->y, p1024_mod, p1024_mp_mod);
45258         /* v = v^2 * r */
45259         sp_1024_proj_mul_18(vx, vy, rx, ry, t);
45260 
45261         /* Double point using previously calculated values
45262          *   l = 3 * (p.x - p.z^2).(p.x + p.z^2)
45263          *   ty = py^2
45264          *   p'.z = py * p.z
45265          */
45266         /* t1 = py^2 ^ 2 = py^4 */
45267         sp_1024_mont_sqr_18(t1, ty, p1024_mod, p1024_mp_mod);
45268         /* py' = py^2 * p. x */
45269         sp_1024_mont_mul_18(p->y, ty, p->x, p1024_mod, p1024_mp_mod);
45270         /* p'.x = l^2 */
45271         sp_1024_mont_sqr_18(p->x, l, p1024_mod, p1024_mp_mod);
45272         /* p'.x = l^2 - py^2 * p.x */
45273         sp_1024_mont_sub_18(p->x, p->x, p->y, p1024_mod);
45274         /* p'.x = l^2 - 2 * p.y^2 * p.x */
45275         sp_1024_mont_sub_18(p->x, p->x, p->y, p1024_mod);
45276         /* py' = py^2 * p.x - p.x' */
45277         sp_1024_mont_sub_18(ty, p->y, p->x, p1024_mod);
45278         /* py' = (p.y^2 * p.x - p'.x) * l */
45279         sp_1024_mont_mul_18(p->y, ty, l, p1024_mod, p1024_mp_mod);
45280         /* py' = (p.y^2 * p.x - p'.x) * l * 2 */
45281         sp_1024_mont_dbl_18(p->y, p->y, p1024_mod);
45282         /* py' = (p.y^2 * p.x - p'.x) * l * 2 - p.y^4 */
45283         sp_1024_mont_sub_18(p->y, p->y, t1, p1024_mod);
45284     }
45285 
45286     /* p'.y = py' / 2 */
45287     sp_1024_div2_18(p->y, p->y, p1024_mod);
45288 }
45289 
45290 /* Operations to perform based on order - 1.
45291  * Sliding window. Start at bottom and stop when bottom bit is one.
45292  * Subtract if top bit in window is one.
45293  * Width of 6 bits.
45294  * Pairs: #dbls, add/subtract window value
45295  */
45296 static const signed char sp_1024_order_op[] = {
45297    5,   6, -13,   9, -21,   6,  -5,   8,  31,   6,   3,   6, -27,   6,  25,   9,
45298   -1,   6, -11,   6, -13,   6,  -7,   6, -15,   6, -29,   7,  25,   6,  -9,   6,
45299  -19,   7,   3,   6,  11,   9, -23,   6,   1,   6,  27,   6,   1,   7, -25,   8,
45300   13,   7, -13,   7, -23,  10,  19,   7,   7,   7,  -3,   7,  27,   6,  -7,   7,
45301  -21,   7,  11,   7,  31,   8,   1,   7, -23,   6, -17,   6,  -3,  10,  11,   6,
45302  -21,   7, -27,  11, -29,   6,  -1,  10,  15,   8,  27,   7,  17,   6,  17,   7,
45303  -13,   8,  13,   6,  21,   7, -29,   6,  19,   7, -25,   6,  11,   9,  29,   7,
45304   -7,   8,  27,   7,  29,  10,  -1,   8,  -7,   8,  17,   6,  17,   7, -27,   7,
45305  -21,   6,  -9,   6, -27,  12, -23,   6,  19,   6,  13,   6, -11,   7,  27,   6,
45306   17,   6,  -7,   6, -25,   7, -29,   6,   9,   7,   7,   6,  13,   6, -25,   6,
45307  -19,   6,  13,   6, -11,   6,   5,   8,  19,   6, -21,   8,  23,   7,  27,   6,
45308  -13,   6, -19,  11,  29,   7, -15,   6,  -9,   7, -21,  10,  -3,   7,  21,  10,
45309   25,   6, -15,   6, -23,   6,  21,   6,   1,   6,  21,   7,  -3,   6,  -3,   7,
45310   -7,   6, -23,   7,   7,   8,  15,   9,   5,   6, -11,   6,  21,  11, -27,   7,
45311   27,   6, -11,   6,  31,   6, -21,   6,  19,   6,  -7,   8,  -7,  13,  -3,   6,
45312   -7,   7,  -3,   6,   1,   6,   7,   8,  19,   8,  11,   9,  -9,   7, -31,  12,
45313   25,   6, -17,   9, -15,   7,   5,   6,  25,   7,  -5,   7, -25,   6,  17,   8,
45314  -19,   6, -13,   6,  27,   8,   1,   7,  -5,   7,  -1,   6,  21,   6,   3,  10,
45315   -3,   1,
45316 };
45317 /*
45318  * Calculate r = pairing <P, Q>.
45319  *
45320  * That is, multiply base in PF_p[q] by the scalar s, such that s.P = Q.
45321  *
45322  * Sliding window. Start at bottom and stop when bottom bit is one.
45323  * Subtract if top bit in window is one.
45324  * Width of 6 bits.
45325  *
45326  * @param  [in]  pm   First point on E(F_p)[q].
45327  * @param  [in]  qm   Second point on E(F_p)[q].
45328  * @param  [in]  res  Result of calculation.
45329  * @return  0 on success.
45330  * @return  MEMORY_E when dynamic memory allocation fails.
45331  */
sp_Pairing_1024(const ecc_point * pm,const ecc_point * qm,mp_int * res)45332 int sp_Pairing_1024(const ecc_point* pm, const ecc_point* qm, mp_int* res)
45333 {
45334     int err;
45335 #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && \
45336     !defined(WOLFSSL_SP_NO_MALLOC)
45337     sp_digit* td = NULL;
45338     sp_digit* t;
45339     sp_digit* vx;
45340     sp_digit* vy;
45341     sp_digit (*pre_vx)[36];
45342     sp_digit (*pre_vy)[36];
45343     sp_digit (*pre_nvy)[36];
45344     sp_point_1024* pre_p;
45345 #else
45346     sp_digit t[6 * 2 * 18];
45347     sp_digit vx[2 * 18];
45348     sp_digit vy[2 * 18];
45349     sp_digit pre_vx[16][36];
45350     sp_digit pre_vy[16][36];
45351     sp_digit pre_nvy[16][36];
45352     sp_point_1024 pre_p[16];
45353     sp_point_1024 pd;
45354     sp_point_1024 qd;
45355     sp_point_1024 cd;
45356 #endif
45357     sp_point_1024* p = NULL;
45358     sp_point_1024* q = NULL;
45359     sp_point_1024* c = NULL;
45360     sp_digit* r = NULL;
45361     int i;
45362     int j;
45363 
45364     err = sp_1024_point_new_18(NULL, pd, p);
45365     if (err == MP_OKAY) {
45366         err = sp_1024_point_new_18(NULL, qd, q);
45367     }
45368     if (err == MP_OKAY) {
45369         err = sp_1024_point_new_18(NULL, cd, c);
45370     }
45371 
45372 #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && \
45373     !defined(WOLFSSL_SP_NO_MALLOC)
45374     if (err == MP_OKAY) {
45375         td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 56 * 18 * 2 + 16 * sizeof(sp_point_1024), NULL,
45376                                 DYNAMIC_TYPE_TMP_BUFFER);
45377         if (td == NULL) {
45378             err = MEMORY_E;
45379         }
45380     }
45381 #endif
45382 
45383     if (err == MP_OKAY) {
45384 #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && \
45385     !defined(WOLFSSL_SP_NO_MALLOC)
45386         t       = td;
45387         vx      = td + 6 * 18 * 2;
45388         vy      = td + 7 * 18 * 2;
45389         pre_vx  = (sp_digit(*)[36])(td + 8 * 18 * 2);
45390         pre_vy  = (sp_digit(*)[36])(td + 24 * 18 * 2);
45391         pre_nvy = (sp_digit(*)[36])(td + 40 * 18 * 2);
45392         pre_p   = (sp_point_1024*)(td + 56 * 18 * 2);
45393 #endif
45394         r = vy;
45395 
45396         sp_1024_point_from_ecc_point_18(p, pm);
45397         sp_1024_point_from_ecc_point_18(q, qm);
45398 
45399         err = sp_1024_mod_mul_norm_18(p->x, p->x, p1024_mod);
45400     }
45401     if (err == MP_OKAY) {
45402         err = sp_1024_mod_mul_norm_18(p->y, p->y, p1024_mod);
45403     }
45404     if (err == MP_OKAY) {
45405         err = sp_1024_mod_mul_norm_18(p->z, p->z, p1024_mod);
45406     }
45407     if (err == MP_OKAY) {
45408         err = sp_1024_mod_mul_norm_18(q->x, q->x, p1024_mod);
45409     }
45410     if (err == MP_OKAY) {
45411         err = sp_1024_mod_mul_norm_18(q->y, q->y, p1024_mod);
45412     }
45413     if (err == MP_OKAY) {
45414         /* Generate pre-computation table: 1, 3, ... , 31 */
45415         XMEMCPY(&pre_p[0], p, sizeof(sp_point_1024));
45416         XMEMSET(pre_vx[0], 0, sizeof(sp_digit) * 2 * 18);
45417         pre_vx[0][0] = 1;
45418         XMEMSET(pre_vy[0], 0, sizeof(sp_digit) * 2 * 18);
45419         sp_1024_mont_sub_18(pre_nvy[0], p1024_mod, pre_vy[0], p1024_mod);
45420 
45421         /* [2]P for adding */
45422         XMEMCPY(c, p, sizeof(sp_point_1024));
45423         XMEMSET(vx, 0, sizeof(sp_digit) * 2 * 18);
45424         vx[0] = 1;
45425         XMEMSET(vy, 0, sizeof(sp_digit) * 2 * 18);
45426         sp_1024_accumulate_line_dbl_18(vx, vy, c, q, t);
45427 
45428         /* 3, 5, ... */
45429         for (i = 1; i < 16; i++) {
45430             XMEMCPY(&pre_p[i], &pre_p[i-1], sizeof(sp_point_1024));
45431             XMEMCPY(pre_vx[i], pre_vx[i-1], sizeof(sp_digit) * 2 * 18);
45432             XMEMCPY(pre_vy[i], pre_vy[i-1], sizeof(sp_digit) * 2 * 18);
45433             sp_1024_proj_mul_18(pre_vx[i], pre_vy[i], vx, vy, t);
45434             sp_1024_accumulate_line_add_n_18(pre_vx[i], pre_vy[i], c,
45435                     q, &pre_p[i], t, 0);
45436             sp_1024_mont_sub_18(pre_nvy[i], p1024_mod, pre_vy[i], p1024_mod);
45437         }
45438 
45439         j = sp_1024_order_op[0] / 2;
45440         XMEMCPY(c, &pre_p[j], sizeof(sp_point_1024));
45441         XMEMCPY(vx, pre_vx[j], sizeof(sp_digit) * 2 * 18);
45442         XMEMCPY(vy, pre_vy[j], sizeof(sp_digit) * 2 * 18);
45443 
45444         /* Accumulate line into v and double point n times. */
45445         sp_1024_accumulate_line_dbl_n_18(vx, vy, c, q,
45446                 sp_1024_order_op[1], t);
45447 
45448         for (i = 2; i < 290; i += 2) {
45449             j = sp_1024_order_op[i];
45450             if (j > 0) {
45451                 j /= 2;
45452                 /* Accumulate line into v and add P into C. */
45453                 sp_1024_proj_mul_18(vx, vy, pre_vx[j], pre_vy[j], t);
45454                 sp_1024_accumulate_line_add_n_18(vx, vy, &pre_p[j], q, c,
45455                     t, 0);
45456             }
45457             else {
45458                 j = -j / 2;
45459                 /* Accumulate line into v and add P into C. */
45460                 sp_1024_proj_mul_18(vx, vy, pre_vx[j], pre_nvy[j], t);
45461                 sp_1024_accumulate_line_add_n_18(vx, vy, &pre_p[j], q, c,
45462                     t, 1);
45463             }
45464 
45465             /* Accumulate line into v and double point n times. */
45466             sp_1024_accumulate_line_dbl_n_18(vx, vy, c, q,
45467                     sp_1024_order_op[i + 1], t);
45468         }
45469 
45470         /* Final exponentiation */
45471         sp_1024_proj_sqr_18(vx, vy, t);
45472         sp_1024_proj_sqr_18(vx, vy, t);
45473 
45474         /* Convert from PF_p[q] to F_p */
45475         sp_1024_mont_inv_18(vx, vx, t);
45476         sp_1024_mont_mul_18(r, vx, vy, p1024_mod, p1024_mp_mod);
45477         XMEMSET(r + 18, 0, sizeof(sp_digit) * 18);
45478         sp_1024_mont_reduce_18(r, p1024_mod, p1024_mp_mod);
45479 
45480         err = sp_1024_to_mp(r, res);
45481     }
45482 
45483 #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && \
45484     !defined(WOLFSSL_SP_NO_MALLOC)
45485     if (td != NULL) {
45486         XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);
45487     }
45488 #endif
45489     sp_1024_point_free_18(c, 1, NULL);
45490     sp_1024_point_free_18(q, 1, NULL);
45491     sp_1024_point_free_18(p, 1, NULL);
45492     return err;
45493 }
45494 
45495 #endif /* WOLFSSL_SP_SMALL */
45496 #ifdef WOLFSSL_SP_SMALL
45497 /*
45498  * Generate table for pairing.
45499  *
45500  * Small implementation does not use a table - returns 0 length.
45501  *
45502  * pm     [in]      Point to generate table for.
45503  * table  [in]      Generated table.
45504  * len    [in,out]  On in, the size of the buffer.
45505  *                  On out, length of table generated.
45506  * @return  0 on success.
45507  *          LENGTH_ONLY_E when table is NULL and only length returned.
45508  *          BUFFER_E when len is too small.
45509  */
sp_Pairing_gen_precomp_1024(const ecc_point * pm,byte * table,word32 * len)45510 int sp_Pairing_gen_precomp_1024(const ecc_point* pm, byte* table,
45511         word32* len)
45512 {
45513     int err = 0;
45514 
45515     if (table == NULL) {
45516         *len = 0;
45517         err = LENGTH_ONLY_E;
45518     }
45519     else if (*len != 0) {
45520         err = BUFFER_E;
45521     }
45522 
45523     (void)*pm;
45524 
45525     return err;
45526 }
45527 
45528 /*
45529  * Calculate r = pairing <P, Q>.
45530  *
45531  * That is, multiply base in PF_p[q] by the scalar s, such that s.P = Q.
45532  *
45533  * Small implementation does not use a table - use the normal implementation.
45534  *
45535  * @param  [in]  pm     First point on E(F_p)[q].
45536  * @param  [in]  qm     Second point on E(F_p)[q].
45537  * @param  [in]  res    Result of calculation.
45538  * @param  [in]  table  Precomputed table of values.
45539  * @param  [in]  len    Length of precomputed table of values in bytes.
45540  * @return  0 on success.
45541  * @return  MEMORY_E when dynamic memory allocation fails.
45542  */
sp_Pairing_precomp_1024(const ecc_point * pm,const ecc_point * qm,mp_int * res,const byte * table,word32 len)45543 int sp_Pairing_precomp_1024(const ecc_point* pm, const ecc_point* qm,
45544     mp_int* res, const byte* table, word32 len)
45545 {
45546     (void)table;
45547     (void)len;
45548     return sp_Pairing_1024(pm, qm, res);
45549 }
45550 
45551 #else
45552 /*
45553  * Calc l and c for the point when doubling p.
45554  *
45555  * l = 3 * (p.x^2 - 1) / (2 * p.y)
45556  * c = l * p.x - p.y
45557  *
45558  * @param  [out]  lr  Gradient result - table entry.
45559  * @param  [out]  cr  Constant result - table entry.
45560  * @param  [in]   px  X-ordinate of point to double.
45561  * @param  [in]   py  Y-ordinate of point to double.
45562  * @param  [in]   t   SP temporaries (3 used).
45563  */
sp_1024_accum_dbl_calc_lc_18(sp_digit * lr,sp_digit * cr,const sp_digit * px,const sp_digit * py,sp_digit * t)45564 static void sp_1024_accum_dbl_calc_lc_18(sp_digit* lr, sp_digit* cr,
45565         const sp_digit* px, const sp_digit* py, sp_digit* t)
45566 {
45567     sp_digit* t1 = t + 0 * 2 * 18;
45568     sp_digit* t2 = t + 2 * 2 * 18;
45569     sp_digit* l  = t + 4 * 2 * 18;
45570 
45571 
45572     /* l = 1 / 2 * p.y */
45573     sp_1024_mont_dbl_18(l, py, p1024_mod);
45574     sp_1024_mont_inv_18(l, l, t);
45575 
45576     /* t1 = p.x^2 */
45577     sp_1024_mont_sqr_18(t1, px, p1024_mod, p1024_mp_mod);
45578     /* t1 = p.x - 1 */
45579     sp_1024_mont_sub_18(t1, t1, p1024_norm_mod, p1024_mod);
45580     /* t1 = 3 * (p.x^2 - 1) */
45581     sp_1024_mont_dbl_18(t2, t1, p1024_mod);
45582     sp_1024_mont_add_18(t1, t1, t2, p1024_mod);
45583     /* t1 = 3 * (p.x^2 - 1) / (2 * p.y) */
45584     sp_1024_mont_mul_18(l, l, t1, p1024_mod, p1024_mp_mod);
45585     /* t2 = l * p.x */
45586     sp_1024_mont_mul_18(t2, l, px, p1024_mod, p1024_mp_mod);
45587     /* c = t2 = l * p.x - p.y */
45588     sp_1024_mont_sub_18(t2, t2, py, p1024_mod);
45589 
45590     XMEMCPY(lr, l, sizeof(sp_digit) * 18);
45591     XMEMCPY(cr, t2, sizeof(sp_digit) * 18);
45592 }
45593 
45594 /*
45595  * Calc l and c when adding p and c.
45596  *
45597  * l = (c.y - p.y) / (c.x - p.x)
45598  * c = (p.x * c.y - cx * p.y) / (cx - p.x)
45599  *
45600  * @param  [out]  lr  Gradient result - table entry.
45601  * @param  [out]  cr  Constant result - table entry.
45602  * @param  [in]   px  X-ordinate of point to add.
45603  * @param  [in]   py  Y-ordinate of point to add.
45604  * @param  [in]   cx  X-ordinate of current point.
45605  * @param  [in]   cy  Y-ordinate of current point.
45606  * @param  [in]   t   SP temporaries (3 used).
45607  */
sp_1024_accum_add_calc_lc_18(sp_digit * lr,sp_digit * cr,const sp_digit * px,const sp_digit * py,const sp_digit * cx,const sp_digit * cy,sp_digit * t)45608 static void sp_1024_accum_add_calc_lc_18(sp_digit* lr, sp_digit* cr,
45609         const sp_digit* px, const sp_digit* py, const sp_digit* cx,
45610         const sp_digit* cy, sp_digit* t)
45611 {
45612     sp_digit* t1 = t + 0 * 2 * 18;
45613     sp_digit* c  = t + 2 * 2 * 18;
45614     sp_digit* l  = t + 4 * 2 * 18;
45615 
45616 
45617     /* l = 1 / (c.x - p.x) */
45618     sp_1024_mont_sub_18(l, cx, px, p1024_mod);
45619     sp_1024_mont_inv_18(l, l, t);
45620 
45621     /* c = p.x * c.y */
45622     sp_1024_mont_mul_18(c, px, cy, p1024_mod, p1024_mp_mod);
45623     /* t1 = c.x * p.y */
45624     sp_1024_mont_mul_18(t1, cx, py, p1024_mod, p1024_mp_mod);
45625     /* c = (p.x * c.y) - (c.x * p.y) */
45626     sp_1024_mont_sub_18(c, c, t1, p1024_mod);
45627     /* c = ((p.x * c.y) - (c.x * p.y)) / (c.x - p.x) */
45628     sp_1024_mont_mul_18(c, c, l, p1024_mod, p1024_mp_mod);
45629     /* t1 = c.y - p.y */
45630     sp_1024_mont_sub_18(t1, cy, py, p1024_mod);
45631     /* l = (c.y - p.y) / (c.x - p.x) */
45632     sp_1024_mont_mul_18(l, t1, l, p1024_mod, p1024_mp_mod);
45633 
45634     XMEMCPY(lr, l, sizeof(sp_digit) * 18);
45635     XMEMCPY(cr, c, sizeof(sp_digit) * 18);
45636 }
45637 
45638 /*
45639  * Calculate vx and vy given gradient l and constant c and point q.
45640  *
45641  * l is a the gradient and is multiplied by q->x.
45642  * c is a the constant that is added to the multiplicative result.
45643  * q->y is the y-ordinate in result to multiply.
45644  *
45645  * if dbl
45646  *   v*  = v*^2
45647  * r.x = l * q.x + c
45648  * r.y = q->y
45649  * v*  = v* * r*
45650  *
45651  * @param  [in,out]  vx     X-ordinate of projective value in F*.
45652  * @param  [in,out]  vy     Y-ordinate of projective value in F*.
45653  * @param  [in]      l      Gradient to multiply with.
45654  * @param  [in]      c      Constant to add with.
45655  * @param  [in]      q      ECC point - second point on E(F_P^2).
45656  * @param  [in]      t      SP temporaries (3 used).
45657  * @param  [in]      dbl    Indicates whether this is for doubling. Otherwise
45658  *                          adding.
45659  */
sp_1024_accumulate_line_lc_18(sp_digit * vx,sp_digit * vy,const sp_digit * l,const sp_digit * c,const sp_point_1024 * q,sp_digit * t,int dbl)45660 static void sp_1024_accumulate_line_lc_18(sp_digit* vx, sp_digit* vy,
45661         const sp_digit* l, const sp_digit* c, const sp_point_1024* q,
45662         sp_digit* t, int dbl)
45663 {
45664     sp_digit* rx = t + 4 * 2 * 18;
45665 
45666     /* v = v^2 */
45667     if (dbl) {
45668         sp_1024_proj_sqr_18(vx, vy, t);
45669     }
45670     /* rx = l * q.x + c */
45671     sp_1024_mont_mul_18(rx, l, q->x, p1024_mod, p1024_mp_mod);
45672     sp_1024_mont_add_18(rx, rx, c, p1024_mod);
45673     /* v = v^2 * r */
45674     sp_1024_proj_mul_18(vx, vy, rx, q->y, t);
45675 }
45676 
45677 /* Operations to perform based on order - 1.
45678  * Sliding window. Start at bottom and stop when bottom bit is one.
45679  * Subtract if top bit in window is one.
45680  * Width of 6 bits.
45681  * Pairs: #dbls, add/subtract window value
45682  */
45683 static const signed char sp_1024_order_op_pre[] = {
45684    5,   6, -13,   9, -21,   6,  -5,   8,  31,   6,   3,   6, -27,   6,  25,   9,
45685   -1,   6, -11,   6, -13,   6,  -7,   6, -15,   6, -29,   7,  25,   6,  -9,   6,
45686  -19,   7,   3,   6,  11,   9, -23,   6,   1,   6,  27,   6,   1,   7, -25,   8,
45687   13,   7, -13,   7, -23,  10,  19,   7,   7,   7,  -3,   7,  27,   6,  -7,   7,
45688  -21,   7,  11,   7,  31,   8,   1,   7, -23,   6, -17,   6,  -3,  10,  11,   6,
45689  -21,   7, -27,  11, -29,   6,  -1,  10,  15,   8,  27,   7,  17,   6,  17,   7,
45690  -13,   8,  13,   6,  21,   7, -29,   6,  19,   7, -25,   6,  11,   9,  29,   7,
45691   -7,   8,  27,   7,  29,  10,  -1,   8,  -7,   8,  17,   6,  17,   7, -27,   7,
45692  -21,   6,  -9,   6, -27,  12, -23,   6,  19,   6,  13,   6, -11,   7,  27,   6,
45693   17,   6,  -7,   6, -25,   7, -29,   6,   9,   7,   7,   6,  13,   6, -25,   6,
45694  -19,   6,  13,   6, -11,   6,   5,   8,  19,   6, -21,   8,  23,   7,  27,   6,
45695  -13,   6, -19,  11,  29,   7, -15,   6,  -9,   7, -21,  10,  -3,   7,  21,  10,
45696   25,   6, -15,   6, -23,   6,  21,   6,   1,   6,  21,   7,  -3,   6,  -3,   7,
45697   -7,   6, -23,   7,   7,   8,  15,   9,   5,   6, -11,   6,  21,  11, -27,   7,
45698   27,   6, -11,   6,  31,   6, -21,   6,  19,   6,  -7,   8,  -7,  13,  -3,   6,
45699   -7,   7,  -3,   6,   1,   6,   7,   8,  19,   8,  11,   9,  -9,   7, -31,  12,
45700   25,   6, -17,   9, -15,   7,   5,   6,  25,   7,  -5,   7, -25,   6,  17,   8,
45701  -19,   6, -13,   6,  27,   8,   1,   7,  -5,   7,  -1,   6,  21,   6,   3,  10,
45702   -3,   1,
45703 };
45704 
45705 /*
45706  * Generate table for pairing.
45707  *
45708  * Calculate the graident (l) and constant (c) at each step of the way.
45709  * Sliding window. Start at bottom and stop when bottom bit is one.
45710  * Subtract if top bit in window is one.
45711  * Width of 6 bits.
45712  *
45713  * pm     [in]      Point to generate table for.
45714  * table  [in]      Generated table.
45715  * len    [in,out]  On in, the size of the buffer.
45716  *                  On out, length of table generated.
45717  * @return  0 on success.
45718  *          LENGTH_ONLY_E when table is NULL and only length returned.
45719  *          BUFFER_E when len is too small.
45720  *          MEMORY_E when dynamic memory allocation fauls.
45721  */
sp_Pairing_gen_precomp_1024(const ecc_point * pm,byte * table,word32 * len)45722 int sp_Pairing_gen_precomp_1024(const ecc_point* pm, byte* table,
45723         word32* len)
45724 {
45725     int err = 0;
45726 #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && \
45727     !defined(WOLFSSL_SP_NO_MALLOC)
45728     sp_digit* td = NULL;
45729     sp_digit* t;
45730     sp_point_1024* pre_p;
45731 #else
45732     sp_digit t[6 * 2 * 18];
45733     sp_point_1024 pre_p[16];
45734     sp_point_1024 pd;
45735     sp_point_1024 cd;
45736     sp_point_1024 negd;
45737 #endif
45738     sp_point_1024* p = NULL;
45739     sp_point_1024* c = NULL;
45740     sp_point_1024* neg = NULL;
45741     int i;
45742     int j;
45743     int k;
45744     sp_table_entry_1024* precomp = (sp_table_entry_1024*)table;
45745 
45746     if (table == NULL) {
45747         *len = sizeof(sp_table_entry_1024) * 1167;
45748         err = LENGTH_ONLY_E;
45749     }
45750 
45751     if ((err == MP_OKAY) &&
45752             (*len < (int)(sizeof(sp_table_entry_1024) * 1167))) {
45753         err = BUFFER_E;
45754     }
45755 
45756     if (err == MP_OKAY) {
45757         err = sp_1024_point_new_18(NULL, pd, p);
45758     }
45759     if (err == MP_OKAY) {
45760         err = sp_1024_point_new_18(NULL, cd, c);
45761     }
45762     if (err == MP_OKAY) {
45763         err = sp_1024_point_new_18(NULL, negd, neg);
45764     }
45765 
45766 #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && \
45767     !defined(WOLFSSL_SP_NO_MALLOC)
45768     if (err == MP_OKAY) {
45769         td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 6 * 18 * 2 + 16 * sizeof(sp_point_1024), NULL,
45770                                 DYNAMIC_TYPE_TMP_BUFFER);
45771         if (td == NULL) {
45772             err = MEMORY_E;
45773         }
45774     }
45775 #endif
45776 
45777     if (err == MP_OKAY) {
45778 #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && \
45779     !defined(WOLFSSL_SP_NO_MALLOC)
45780         t     = td;
45781         pre_p = (sp_point_1024*)(td + 6 * 18 * 2);
45782 #endif
45783 
45784         sp_1024_point_from_ecc_point_18(p, pm);
45785 
45786         err = sp_1024_mod_mul_norm_18(p->x, p->x, p1024_mod);
45787     }
45788     if (err == MP_OKAY) {
45789         err = sp_1024_mod_mul_norm_18(p->y, p->y, p1024_mod);
45790     }
45791     if (err == MP_OKAY) {
45792         XMEMCPY(p->z, p1024_norm_mod, sizeof(p1024_norm_mod));
45793         neg->infinity = 0;
45794         c->infinity = 0;
45795 
45796         /* Generate pre-computation table: 1, 3, ... , 31 */
45797         XMEMCPY(&pre_p[0], p, sizeof(sp_point_1024));
45798         /* [2]P for adding */
45799         sp_1024_proj_point_dbl_18(c, p, t);
45800 
45801         /* 1, 3, ... */
45802         for (i = 1; i < 16; i++) {
45803             sp_1024_proj_point_add_18(&pre_p[i], &pre_p[i-1], c, t);
45804             sp_1024_mont_map_18(&pre_p[i], t);
45805         }
45806 
45807         k = 0;
45808         j = sp_1024_order_op_pre[0] / 2;
45809         XMEMCPY(c, &pre_p[j], sizeof(sp_point_1024));
45810 
45811         for (j = 0; j < sp_1024_order_op_pre[1]; j++) {
45812             sp_1024_accum_dbl_calc_lc_18(precomp[k].x, precomp[k].y, c->x, c->y, t);
45813             k++;
45814             sp_1024_proj_point_dbl_18(c, c, t);
45815             sp_1024_mont_map_18(c, t);
45816         }
45817 
45818         for (i = 2; i < 290; i += 2) {
45819             j = sp_1024_order_op_pre[i];
45820             if (j > 0) {
45821                 sp_1024_accum_add_calc_lc_18(precomp[k].x, precomp[k].y,
45822                     pre_p[j/2].x, pre_p[j/2].y, c->x, c->y, t);
45823                 k++;
45824                 sp_1024_proj_point_add_18(c, c, &pre_p[j/2], t);
45825                 sp_1024_mont_map_18(c, t);
45826             }
45827             else {
45828                 XMEMCPY(neg->x, pre_p[-j / 2].x, sizeof(pre_p->x));
45829                 sp_1024_mont_sub_18(neg->y, p1024_mod, pre_p[-j / 2].y,
45830                         p1024_mod);
45831                 XMEMCPY(neg->z, pre_p[-j / 2].z, sizeof(pre_p->z));
45832 
45833                 sp_1024_accum_add_calc_lc_18(precomp[k].x, precomp[k].y,
45834                     neg->x, neg->y, c->x, c->y, t);
45835                 k++;
45836                 sp_1024_proj_point_add_18(c, c, neg, t);
45837                 sp_1024_mont_map_18(c, t);
45838             }
45839 
45840             for (j = 0; j < sp_1024_order_op_pre[i + 1]; j++) {
45841                 sp_1024_accum_dbl_calc_lc_18(precomp[k].x, precomp[k].y, c->x, c->y, t);
45842                 k++;
45843                 sp_1024_proj_point_dbl_18(c, c, t);
45844                 sp_1024_mont_map_18(c, t);
45845             }
45846         }
45847 
45848         *len = sizeof(sp_table_entry_1024) * 1167;
45849     }
45850 
45851 #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && \
45852     !defined(WOLFSSL_SP_NO_MALLOC)
45853     if (td != NULL) {
45854         XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);
45855     }
45856 #endif
45857     sp_1024_point_free_18(neg, 1, NULL);
45858     sp_1024_point_free_18(c, 1, NULL);
45859     sp_1024_point_free_18(p, 1, NULL);
45860     return err;
45861 }
45862 
45863 /*
45864  * Calculate r = pairing <P, Q>.
45865  *
45866  * That is, multiply base in PF_p[q] by the scalar s, such that s.P = Q.
45867  *
45868  * Sliding window. Start at bottom and stop when bottom bit is one.
45869  * Subtract if top bit in window is one.
45870  * Width of 6 bits.
45871  * Pre-generate values in window (1, 3, ...) - only V.
45872  * Table contains all gradient l and a constant for each point on the path.
45873  *
45874  * @param  [in]  pm     First point on E(F_p)[q].
45875  * @param  [in]  qm     Second point on E(F_p)[q].
45876  * @param  [in]  res    Result of calculation.
45877  * @param  [in]  table  Precomputed table of values.
45878  * @param  [in]  len    Length of precomputed table of values in bytes.
45879  * @return  0 on success.
45880  * @return  MEMORY_E when dynamic memory allocation fails.
45881  */
sp_Pairing_precomp_1024(const ecc_point * pm,const ecc_point * qm,mp_int * res,const byte * table,word32 len)45882 int sp_Pairing_precomp_1024(const ecc_point* pm, const ecc_point* qm,
45883     mp_int* res, const byte* table, word32 len)
45884 {
45885     int err = 0;
45886 #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && \
45887     !defined(WOLFSSL_SP_NO_MALLOC)
45888     sp_digit* td = NULL;
45889     sp_digit* t;
45890     sp_digit* vx;
45891     sp_digit* vy;
45892     sp_digit (*pre_vx)[36];
45893     sp_digit (*pre_vy)[36];
45894     sp_digit (*pre_nvy)[36];
45895 #else
45896     sp_digit t[6 * 2 * 18];
45897     sp_digit vx[2 * 18];
45898     sp_digit vy[2 * 18];
45899     sp_digit pre_vx[16][36];
45900     sp_digit pre_vy[16][36];
45901     sp_digit pre_nvy[16][36];
45902     sp_point_1024 pd;
45903     sp_point_1024 qd;
45904     sp_point_1024 cd;
45905 #endif
45906     sp_point_1024* p = NULL;
45907     sp_point_1024* q = NULL;
45908     sp_point_1024* c = NULL;
45909     sp_digit* r = NULL;
45910     int i;
45911     int j;
45912     int k;
45913     const sp_table_entry_1024* precomp = (const sp_table_entry_1024*)table;
45914 
45915     if (len < (int)(sizeof(sp_table_entry_1024) * 1167)) {
45916         err = BUFFER_E;
45917     }
45918 
45919     if (err == MP_OKAY) {
45920         err = sp_1024_point_new_18(NULL, pd, p);
45921     }
45922     if (err == MP_OKAY) {
45923         err = sp_1024_point_new_18(NULL, qd, q);
45924     }
45925     if (err == MP_OKAY) {
45926         err = sp_1024_point_new_18(NULL, cd, c);
45927     }
45928 
45929 #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && \
45930     !defined(WOLFSSL_SP_NO_MALLOC)
45931     if (err == MP_OKAY) {
45932         td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 56 * 18 * 2, NULL,
45933                                 DYNAMIC_TYPE_TMP_BUFFER);
45934         if (td == NULL) {
45935             err = MEMORY_E;
45936         }
45937     }
45938 #endif
45939 
45940     if (err == MP_OKAY) {
45941 #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && \
45942     !defined(WOLFSSL_SP_NO_MALLOC)
45943         t       = td;
45944         vx      = td + 6 * 18 * 2;
45945         vy      = td + 7 * 18 * 2;
45946         pre_vx  = (sp_digit(*)[36])(td + 8 * 18 * 2);
45947         pre_vy  = (sp_digit(*)[36])(td + 24 * 18 * 2);
45948         pre_nvy = (sp_digit(*)[36])(td + 40 * 18 * 2);
45949 #endif
45950         r = vy;
45951 
45952         sp_1024_point_from_ecc_point_18(p, pm);
45953         sp_1024_point_from_ecc_point_18(q, qm);
45954 
45955         err = sp_1024_mod_mul_norm_18(p->x, p->x, p1024_mod);
45956     }
45957     if (err == MP_OKAY) {
45958         err = sp_1024_mod_mul_norm_18(p->y, p->y, p1024_mod);
45959     }
45960     if (err == MP_OKAY) {
45961         err = sp_1024_mod_mul_norm_18(p->z, p->z, p1024_mod);
45962     }
45963     if (err == MP_OKAY) {
45964         err = sp_1024_mod_mul_norm_18(q->x, q->x, p1024_mod);
45965     }
45966     if (err == MP_OKAY) {
45967         err = sp_1024_mod_mul_norm_18(q->y, q->y, p1024_mod);
45968     }
45969     if (err == MP_OKAY) {
45970         /* Generate pre-computation table: 1, 3, ... , 31 */
45971         XMEMSET(pre_vx[0], 0, sizeof(sp_digit) * 2 * 18);
45972         pre_vx[0][0] = 1;
45973         XMEMSET(pre_vy[0], 0, sizeof(sp_digit) * 2 * 18);
45974         sp_1024_mont_sub_18(pre_nvy[0], p1024_mod, pre_vy[0], p1024_mod);
45975 
45976         /* [2]P for adding */
45977         XMEMCPY(c, p, sizeof(sp_point_1024));
45978         XMEMSET(vx, 0, sizeof(sp_digit) * 2 * 18);
45979         vx[0] = 1;
45980         XMEMSET(vy, 0, sizeof(sp_digit) * 2 * 18);
45981         sp_1024_accumulate_line_dbl_18(vx, vy, c, q, t);
45982 
45983         /* 3, 5, ... */
45984         for (i = 1; i < 16; i++) {
45985             XMEMCPY(pre_vx[i], pre_vx[i-1], sizeof(sp_digit) * 2 * 18);
45986             XMEMCPY(pre_vy[i], pre_vy[i-1], sizeof(sp_digit) * 2 * 18);
45987             sp_1024_proj_mul_18(pre_vx[i], pre_vy[i], vx, vy, t);
45988             sp_1024_accumulate_line_add_n_18(pre_vx[i], pre_vy[i], c,
45989                 q, p, t, 0);
45990             sp_1024_mont_sub_18(pre_nvy[i], p1024_mod, pre_vy[i],
45991                 p1024_mod);
45992         }
45993 
45994         XMEMCPY(c->z, p1024_norm_mod, sizeof(sp_digit) * 18);
45995         c->infinity = 0;
45996         j = sp_1024_order_op_pre[0] / 2;
45997         XMEMCPY(vx, pre_vx[j], sizeof(sp_digit) * 2 * 18);
45998         XMEMCPY(vy, pre_vy[j], sizeof(sp_digit) * 2 * 18);
45999 
46000         k = 0;
46001         for (j = 0; j < sp_1024_order_op_pre[1]; j++) {
46002             /* Accumulate line into v and double point. */
46003             sp_1024_accumulate_line_lc_18(vx, vy, precomp[k].x,
46004                 precomp[k].y, q, t, 1);
46005             k++;
46006         }
46007 
46008         for (i = 2; i < 290; i += 2) {
46009             sp_1024_accumulate_line_lc_18(vx, vy, precomp[k].x,
46010                 precomp[k].y, q, t, 0);
46011             k++;
46012 
46013             j = sp_1024_order_op_pre[i];
46014             if (j > 0) {
46015                 j /= 2;
46016                 /* Accumulate line into v. */
46017                 sp_1024_proj_mul_18(vx, vy, pre_vx[j], pre_vy[j], t);
46018             }
46019             else {
46020                 j = -j / 2;
46021                 /* Accumulate line into v. */
46022                 sp_1024_proj_mul_18(vx, vy, pre_vx[j], pre_nvy[j], t);
46023             }
46024 
46025             for (j = 0; j < sp_1024_order_op_pre[i + 1]; j++) {
46026                 /* Accumulate line into v and double point. */
46027                 sp_1024_accumulate_line_lc_18(vx, vy, precomp[k].x,
46028                     precomp[k].y, q, t, 1);
46029                 k++;
46030             }
46031         }
46032 
46033         /* Final exponentiation */
46034         sp_1024_proj_sqr_18(vx, vy, t);
46035         sp_1024_proj_sqr_18(vx, vy, t);
46036 
46037         /* Convert from PF_p[q] to F_p */
46038         sp_1024_mont_inv_18(vx, vx, t);
46039         sp_1024_mont_mul_18(r, vx, vy, p1024_mod, p1024_mp_mod);
46040         XMEMSET(r + 18, 0, sizeof(sp_digit) * 18);
46041         sp_1024_mont_reduce_18(r, p1024_mod, p1024_mp_mod);
46042 
46043         err = sp_1024_to_mp(r, res);
46044     }
46045 
46046 #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && \
46047     !defined(WOLFSSL_SP_NO_MALLOC)
46048     if (td != NULL) {
46049         XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);
46050     }
46051 #endif
46052     sp_1024_point_free_18(c, 1, NULL);
46053     sp_1024_point_free_18(q, 1, NULL);
46054     sp_1024_point_free_18(p, 1, NULL);
46055     return err;
46056 }
46057 
46058 #endif /* WOLFSSL_SP_SMALL */
46059 /* Returns 1 if the number of zero.
46060  * Implementation is constant time.
46061  *
46062  * a  Number to check.
46063  * returns 1 if the number is zero and 0 otherwise.
46064  */
sp_1024_iszero_18(const sp_digit * a)46065 static int sp_1024_iszero_18(const sp_digit* a)
46066 {
46067     return (a[0] | a[1] | a[2] | a[3] | a[4] | a[5] | a[6] | a[7] |
46068             a[8] | a[9] | a[10] | a[11] | a[12] | a[13] | a[14] | a[15] |
46069             a[16] | a[17]) == 0;
46070 }
46071 
46072 #ifdef HAVE_ECC_CHECK_KEY
46073 /* Read big endian unsigned byte array into r.
46074  *
46075  * r  A single precision integer.
46076  * size  Maximum number of bytes to convert
46077  * a  Byte array.
46078  * n  Number of bytes in array to read.
46079  */
sp_1024_from_bin(sp_digit * r,int size,const byte * a,int n)46080 static void sp_1024_from_bin(sp_digit* r, int size, const byte* a, int n)
46081 {
46082     int i;
46083     int j = 0;
46084     word32 s = 0;
46085 
46086     r[0] = 0;
46087     for (i = n-1; i >= 0; i--) {
46088         r[j] |= (((sp_digit)a[i]) << s);
46089         if (s >= 49U) {
46090             r[j] &= 0x1ffffffffffffffL;
46091             s = 57U - s;
46092             if (j + 1 >= size) {
46093                 break;
46094             }
46095             r[++j] = (sp_digit)a[i] >> s;
46096             s = 8U - s;
46097         }
46098         else {
46099             s += 8U;
46100         }
46101     }
46102 
46103     for (j++; j < size; j++) {
46104         r[j] = 0;
46105     }
46106 }
46107 
46108 /* Check that the x and y oridinates are a valid point on the curve.
46109  *
46110  * point  EC point.
46111  * heap   Heap to use if dynamically allocating.
46112  * returns MEMORY_E if dynamic memory allocation fails, MP_VAL if the point is
46113  * not on the curve and MP_OKAY otherwise.
46114  */
sp_1024_ecc_is_point_18(const sp_point_1024 * point,void * heap)46115 static int sp_1024_ecc_is_point_18(const sp_point_1024* point,
46116     void* heap)
46117 {
46118 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
46119     sp_digit* t1 = NULL;
46120 #else
46121     sp_digit t1[18 * 4];
46122 #endif
46123     sp_digit* t2 = NULL;
46124     sp_int64 n;
46125     int err = MP_OKAY;
46126 
46127 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
46128     t1 = (sp_digit*)XMALLOC(sizeof(sp_digit) * 18 * 4, heap, DYNAMIC_TYPE_ECC);
46129     if (t1 == NULL)
46130         err = MEMORY_E;
46131 #endif
46132     (void)heap;
46133 
46134     if (err == MP_OKAY) {
46135         t2 = t1 + 2 * 18;
46136 
46137         sp_1024_sqr_18(t1, point->y);
46138         (void)sp_1024_mod_18(t1, t1, p1024_mod);
46139         sp_1024_sqr_18(t2, point->x);
46140         (void)sp_1024_mod_18(t2, t2, p1024_mod);
46141         sp_1024_mul_18(t2, t2, point->x);
46142         (void)sp_1024_mod_18(t2, t2, p1024_mod);
46143         (void)sp_1024_sub_18(t2, p1024_mod, t2);
46144         sp_1024_mont_add_18(t1, t1, t2, p1024_mod);
46145 
46146         sp_1024_mont_add_18(t1, t1, point->x, p1024_mod);
46147         sp_1024_mont_add_18(t1, t1, point->x, p1024_mod);
46148         sp_1024_mont_add_18(t1, t1, point->x, p1024_mod);
46149 
46150         n = sp_1024_cmp_18(t1, p1024_mod);
46151         sp_1024_cond_sub_18(t1, t1, p1024_mod, 0 - ((n >= 0) ?
46152             (sp_digit)1 : (sp_digit)0));
46153         sp_1024_norm_18(t1);
46154         if (!sp_1024_iszero_18(t1)) {
46155             err = MP_VAL;
46156         }
46157     }
46158 
46159 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
46160     if (t1 != NULL)
46161         XFREE(t1, heap, DYNAMIC_TYPE_ECC);
46162 #endif
46163 
46164     return err;
46165 }
46166 
46167 /* Check that the x and y oridinates are a valid point on the curve.
46168  *
46169  * pX  X ordinate of EC point.
46170  * pY  Y ordinate of EC point.
46171  * returns MEMORY_E if dynamic memory allocation fails, MP_VAL if the point is
46172  * not on the curve and MP_OKAY otherwise.
46173  */
sp_ecc_is_point_1024(const mp_int * pX,const mp_int * pY)46174 int sp_ecc_is_point_1024(const mp_int* pX, const mp_int* pY)
46175 {
46176 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
46177     sp_point_1024* pub = NULL;
46178 #else
46179     sp_point_1024 pub[1];
46180 #endif
46181     const byte one[1] = { 1 };
46182     int err = MP_OKAY;
46183 
46184 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
46185     pub = (sp_point_1024*)XMALLOC(sizeof(sp_point_1024), NULL,
46186                                        DYNAMIC_TYPE_ECC);
46187     if (pub == NULL)
46188         err = MEMORY_E;
46189 #endif
46190 
46191     if (err == MP_OKAY) {
46192         sp_1024_from_mp(pub->x, 18, pX);
46193         sp_1024_from_mp(pub->y, 18, pY);
46194         sp_1024_from_bin(pub->z, 18, one, (int)sizeof(one));
46195 
46196         err = sp_1024_ecc_is_point_18(pub, NULL);
46197     }
46198 
46199 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
46200     if (pub != NULL)
46201         XFREE(pub, NULL, DYNAMIC_TYPE_ECC);
46202 #endif
46203 
46204     return err;
46205 }
46206 
46207 /* Check that the private scalar generates the EC point (px, py), the point is
46208  * on the curve and the point has the correct order.
46209  *
46210  * pX     X ordinate of EC point.
46211  * pY     Y ordinate of EC point.
46212  * privm  Private scalar that generates EC point.
46213  * returns MEMORY_E if dynamic memory allocation fails, MP_VAL if the point is
46214  * not on the curve, ECC_INF_E if the point does not have the correct order,
46215  * ECC_PRIV_KEY_E when the private scalar doesn't generate the EC point and
46216  * MP_OKAY otherwise.
46217  */
sp_ecc_check_key_1024(const mp_int * pX,const mp_int * pY,const mp_int * privm,void * heap)46218 int sp_ecc_check_key_1024(const mp_int* pX, const mp_int* pY,
46219     const mp_int* privm, void* heap)
46220 {
46221 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
46222     sp_digit* priv = NULL;
46223     sp_point_1024* pub = NULL;
46224 #else
46225     sp_digit priv[18];
46226     sp_point_1024 pub[2];
46227 #endif
46228     sp_point_1024* p = NULL;
46229     const byte one[1] = { 1 };
46230     int err = MP_OKAY;
46231 
46232 
46233     /* Quick check the lengs of public key ordinates and private key are in
46234      * range. Proper check later.
46235      */
46236     if (((mp_count_bits(pX) > 1024) ||
46237         (mp_count_bits(pY) > 1024) ||
46238         ((privm != NULL) && (mp_count_bits(privm) > 1024)))) {
46239         err = ECC_OUT_OF_RANGE_E;
46240     }
46241 
46242 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
46243     if (err == MP_OKAY) {
46244         pub = (sp_point_1024*)XMALLOC(sizeof(sp_point_1024) * 2, heap,
46245                                            DYNAMIC_TYPE_ECC);
46246         if (pub == NULL)
46247             err = MEMORY_E;
46248     }
46249     if (err == MP_OKAY && privm) {
46250         priv = (sp_digit*)XMALLOC(sizeof(sp_digit) * 18, heap,
46251                                   DYNAMIC_TYPE_ECC);
46252         if (priv == NULL)
46253             err = MEMORY_E;
46254     }
46255 #endif
46256 
46257     if (err == MP_OKAY) {
46258         p = pub + 1;
46259 
46260         sp_1024_from_mp(pub->x, 18, pX);
46261         sp_1024_from_mp(pub->y, 18, pY);
46262         sp_1024_from_bin(pub->z, 18, one, (int)sizeof(one));
46263         if (privm)
46264             sp_1024_from_mp(priv, 18, privm);
46265 
46266         /* Check point at infinitiy. */
46267         if ((sp_1024_iszero_18(pub->x) != 0) &&
46268             (sp_1024_iszero_18(pub->y) != 0)) {
46269             err = ECC_INF_E;
46270         }
46271     }
46272 
46273     /* Check range of X and Y */
46274     if ((err == MP_OKAY) &&
46275             ((sp_1024_cmp_18(pub->x, p1024_mod) >= 0) ||
46276              (sp_1024_cmp_18(pub->y, p1024_mod) >= 0))) {
46277         err = ECC_OUT_OF_RANGE_E;
46278     }
46279 
46280     if (err == MP_OKAY) {
46281         /* Check point is on curve */
46282         err = sp_1024_ecc_is_point_18(pub, heap);
46283     }
46284 
46285     if (err == MP_OKAY) {
46286         /* Point * order = infinity */
46287             err = sp_1024_ecc_mulmod_18(p, pub, p1024_order, 1, 1, heap);
46288     }
46289     /* Check result is infinity */
46290     if ((err == MP_OKAY) && ((sp_1024_iszero_18(p->x) == 0) ||
46291                              (sp_1024_iszero_18(p->y) == 0))) {
46292         err = ECC_INF_E;
46293     }
46294 
46295     if (privm) {
46296         if (err == MP_OKAY) {
46297             /* Base * private = point */
46298                 err = sp_1024_ecc_mulmod_base_18(p, priv, 1, 1, heap);
46299         }
46300         /* Check result is public key */
46301         if ((err == MP_OKAY) &&
46302                 ((sp_1024_cmp_18(p->x, pub->x) != 0) ||
46303                  (sp_1024_cmp_18(p->y, pub->y) != 0))) {
46304             err = ECC_PRIV_KEY_E;
46305         }
46306     }
46307 
46308 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
46309     if (pub != NULL)
46310         XFREE(pub, heap, DYNAMIC_TYPE_ECC);
46311     if (priv != NULL)
46312         XFREE(priv, heap, DYNAMIC_TYPE_ECC);
46313 #endif
46314 
46315     return err;
46316 }
46317 #endif
46318 #endif /* WOLFSSL_SP_1024 */
46319 #endif /* WOLFSSL_HAVE_SP_ECC */
46320 #endif /* SP_WORD_SIZE == 64 */
46321 #endif /* !WOLFSSL_SP_ASM */
46322 #endif /* WOLFSSL_HAVE_SP_RSA | WOLFSSL_HAVE_SP_DH | WOLFSSL_HAVE_SP_ECC */
46323