xref: /openbsd-src/lib/libcrypto/curve25519/curve25519.c (revision 4d1810fa8b3c3b334f3dffda53e0ffaf875a3f29)
1*4d1810faSbeck /*	$OpenBSD: curve25519.c,v 1.16 2023/07/08 15:12:49 beck Exp $ */
25f5d09a5Sjsing /*
35f5d09a5Sjsing  * Copyright (c) 2015, Google Inc.
45f5d09a5Sjsing  *
55f5d09a5Sjsing  * Permission to use, copy, modify, and/or distribute this software for any
65f5d09a5Sjsing  * purpose with or without fee is hereby granted, provided that the above
75f5d09a5Sjsing  * copyright notice and this permission notice appear in all copies.
85f5d09a5Sjsing  *
95f5d09a5Sjsing  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
105f5d09a5Sjsing  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
115f5d09a5Sjsing  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
125f5d09a5Sjsing  * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
135f5d09a5Sjsing  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
145f5d09a5Sjsing  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
155f5d09a5Sjsing  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
165f5d09a5Sjsing  */
175f5d09a5Sjsing 
185f5d09a5Sjsing /*
195f5d09a5Sjsing  * This code is mostly taken from the ref10 version of Ed25519 in SUPERCOP
205f5d09a5Sjsing  * 20141124 (http://bench.cr.yp.to/supercop.html). That code is released as
215f5d09a5Sjsing  * public domain but this file has the ISC license just to keep licencing
225f5d09a5Sjsing  * simple.
235f5d09a5Sjsing  *
245f5d09a5Sjsing  * The field functions are shared by Ed25519 and X25519 where possible.
255f5d09a5Sjsing  */
265f5d09a5Sjsing 
2721b5f757Stb #include <stdio.h>
285f5d09a5Sjsing #include <stdlib.h>
295f5d09a5Sjsing #include <string.h>
305f5d09a5Sjsing 
315f5d09a5Sjsing #include <openssl/curve25519.h>
325f5d09a5Sjsing #include <openssl/sha.h>
335f5d09a5Sjsing 
345f5d09a5Sjsing #include "curve25519_internal.h"
355f5d09a5Sjsing 
365f5d09a5Sjsing static const int64_t kBottom25Bits = 0x1ffffffLL;
375f5d09a5Sjsing static const int64_t kBottom26Bits = 0x3ffffffLL;
385f5d09a5Sjsing static const int64_t kTop39Bits = 0xfffffffffe000000LL;
395f5d09a5Sjsing static const int64_t kTop38Bits = 0xfffffffffc000000LL;
405f5d09a5Sjsing 
load_3(const uint8_t * in)415f5d09a5Sjsing static uint64_t load_3(const uint8_t *in) {
425f5d09a5Sjsing   uint64_t result;
435f5d09a5Sjsing   result = (uint64_t)in[0];
445f5d09a5Sjsing   result |= ((uint64_t)in[1]) << 8;
455f5d09a5Sjsing   result |= ((uint64_t)in[2]) << 16;
465f5d09a5Sjsing   return result;
475f5d09a5Sjsing }
485f5d09a5Sjsing 
load_4(const uint8_t * in)495f5d09a5Sjsing static uint64_t load_4(const uint8_t *in) {
505f5d09a5Sjsing   uint64_t result;
515f5d09a5Sjsing   result = (uint64_t)in[0];
525f5d09a5Sjsing   result |= ((uint64_t)in[1]) << 8;
535f5d09a5Sjsing   result |= ((uint64_t)in[2]) << 16;
545f5d09a5Sjsing   result |= ((uint64_t)in[3]) << 24;
555f5d09a5Sjsing   return result;
565f5d09a5Sjsing }
575f5d09a5Sjsing 
fe_frombytes(fe h,const uint8_t * s)585f5d09a5Sjsing static void fe_frombytes(fe h, const uint8_t *s) {
595f5d09a5Sjsing   /* Ignores top bit of h. */
605f5d09a5Sjsing   int64_t h0 = load_4(s);
615f5d09a5Sjsing   int64_t h1 = load_3(s + 4) << 6;
625f5d09a5Sjsing   int64_t h2 = load_3(s + 7) << 5;
635f5d09a5Sjsing   int64_t h3 = load_3(s + 10) << 3;
645f5d09a5Sjsing   int64_t h4 = load_3(s + 13) << 2;
655f5d09a5Sjsing   int64_t h5 = load_4(s + 16);
665f5d09a5Sjsing   int64_t h6 = load_3(s + 20) << 7;
675f5d09a5Sjsing   int64_t h7 = load_3(s + 23) << 5;
685f5d09a5Sjsing   int64_t h8 = load_3(s + 26) << 4;
695f5d09a5Sjsing   int64_t h9 = (load_3(s + 29) & 8388607) << 2;
705f5d09a5Sjsing   int64_t carry0;
715f5d09a5Sjsing   int64_t carry1;
725f5d09a5Sjsing   int64_t carry2;
735f5d09a5Sjsing   int64_t carry3;
745f5d09a5Sjsing   int64_t carry4;
755f5d09a5Sjsing   int64_t carry5;
765f5d09a5Sjsing   int64_t carry6;
775f5d09a5Sjsing   int64_t carry7;
785f5d09a5Sjsing   int64_t carry8;
795f5d09a5Sjsing   int64_t carry9;
805f5d09a5Sjsing 
815f5d09a5Sjsing   carry9 = h9 + (1 << 24); h0 += (carry9 >> 25) * 19; h9 -= carry9 & kTop39Bits;
825f5d09a5Sjsing   carry1 = h1 + (1 << 24); h2 += carry1 >> 25; h1 -= carry1 & kTop39Bits;
835f5d09a5Sjsing   carry3 = h3 + (1 << 24); h4 += carry3 >> 25; h3 -= carry3 & kTop39Bits;
845f5d09a5Sjsing   carry5 = h5 + (1 << 24); h6 += carry5 >> 25; h5 -= carry5 & kTop39Bits;
855f5d09a5Sjsing   carry7 = h7 + (1 << 24); h8 += carry7 >> 25; h7 -= carry7 & kTop39Bits;
865f5d09a5Sjsing 
875f5d09a5Sjsing   carry0 = h0 + (1 << 25); h1 += carry0 >> 26; h0 -= carry0 & kTop38Bits;
885f5d09a5Sjsing   carry2 = h2 + (1 << 25); h3 += carry2 >> 26; h2 -= carry2 & kTop38Bits;
895f5d09a5Sjsing   carry4 = h4 + (1 << 25); h5 += carry4 >> 26; h4 -= carry4 & kTop38Bits;
905f5d09a5Sjsing   carry6 = h6 + (1 << 25); h7 += carry6 >> 26; h6 -= carry6 & kTop38Bits;
915f5d09a5Sjsing   carry8 = h8 + (1 << 25); h9 += carry8 >> 26; h8 -= carry8 & kTop38Bits;
925f5d09a5Sjsing 
935f5d09a5Sjsing   h[0] = h0;
945f5d09a5Sjsing   h[1] = h1;
955f5d09a5Sjsing   h[2] = h2;
965f5d09a5Sjsing   h[3] = h3;
975f5d09a5Sjsing   h[4] = h4;
985f5d09a5Sjsing   h[5] = h5;
995f5d09a5Sjsing   h[6] = h6;
1005f5d09a5Sjsing   h[7] = h7;
1015f5d09a5Sjsing   h[8] = h8;
1025f5d09a5Sjsing   h[9] = h9;
1035f5d09a5Sjsing }
1045f5d09a5Sjsing 
1055f5d09a5Sjsing /* Preconditions:
1065f5d09a5Sjsing  *  |h| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc.
1075f5d09a5Sjsing  *
1085f5d09a5Sjsing  * Write p=2^255-19; q=floor(h/p).
1095f5d09a5Sjsing  * Basic claim: q = floor(2^(-255)(h + 19 2^(-25)h9 + 2^(-1))).
1105f5d09a5Sjsing  *
1115f5d09a5Sjsing  * Proof:
1125f5d09a5Sjsing  *   Have |h|<=p so |q|<=1 so |19^2 2^(-255) q|<1/4.
1135f5d09a5Sjsing  *   Also have |h-2^230 h9|<2^231 so |19 2^(-255)(h-2^230 h9)|<1/4.
1145f5d09a5Sjsing  *
1155f5d09a5Sjsing  *   Write y=2^(-1)-19^2 2^(-255)q-19 2^(-255)(h-2^230 h9).
1165f5d09a5Sjsing  *   Then 0<y<1.
1175f5d09a5Sjsing  *
1185f5d09a5Sjsing  *   Write r=h-pq.
1195f5d09a5Sjsing  *   Have 0<=r<=p-1=2^255-20.
1205f5d09a5Sjsing  *   Thus 0<=r+19(2^-255)r<r+19(2^-255)2^255<=2^255-1.
1215f5d09a5Sjsing  *
1225f5d09a5Sjsing  *   Write x=r+19(2^-255)r+y.
1235f5d09a5Sjsing  *   Then 0<x<2^255 so floor(2^(-255)x) = 0 so floor(q+2^(-255)x) = q.
1245f5d09a5Sjsing  *
1255f5d09a5Sjsing  *   Have q+2^(-255)x = 2^(-255)(h + 19 2^(-25) h9 + 2^(-1))
1265f5d09a5Sjsing  *   so floor(2^(-255)(h + 19 2^(-25) h9 + 2^(-1))) = q. */
fe_tobytes(uint8_t * s,const fe h)1275f5d09a5Sjsing static void fe_tobytes(uint8_t *s, const fe h) {
1285f5d09a5Sjsing   int32_t h0 = h[0];
1295f5d09a5Sjsing   int32_t h1 = h[1];
1305f5d09a5Sjsing   int32_t h2 = h[2];
1315f5d09a5Sjsing   int32_t h3 = h[3];
1325f5d09a5Sjsing   int32_t h4 = h[4];
1335f5d09a5Sjsing   int32_t h5 = h[5];
1345f5d09a5Sjsing   int32_t h6 = h[6];
1355f5d09a5Sjsing   int32_t h7 = h[7];
1365f5d09a5Sjsing   int32_t h8 = h[8];
1375f5d09a5Sjsing   int32_t h9 = h[9];
1385f5d09a5Sjsing   int32_t q;
1395f5d09a5Sjsing 
1405f5d09a5Sjsing   q = (19 * h9 + (((int32_t) 1) << 24)) >> 25;
1415f5d09a5Sjsing   q = (h0 + q) >> 26;
1425f5d09a5Sjsing   q = (h1 + q) >> 25;
1435f5d09a5Sjsing   q = (h2 + q) >> 26;
1445f5d09a5Sjsing   q = (h3 + q) >> 25;
1455f5d09a5Sjsing   q = (h4 + q) >> 26;
1465f5d09a5Sjsing   q = (h5 + q) >> 25;
1475f5d09a5Sjsing   q = (h6 + q) >> 26;
1485f5d09a5Sjsing   q = (h7 + q) >> 25;
1495f5d09a5Sjsing   q = (h8 + q) >> 26;
1505f5d09a5Sjsing   q = (h9 + q) >> 25;
1515f5d09a5Sjsing 
1525f5d09a5Sjsing   /* Goal: Output h-(2^255-19)q, which is between 0 and 2^255-20. */
1535f5d09a5Sjsing   h0 += 19 * q;
1545f5d09a5Sjsing   /* Goal: Output h-2^255 q, which is between 0 and 2^255-20. */
1555f5d09a5Sjsing 
1565f5d09a5Sjsing   h1 += h0 >> 26; h0 &= kBottom26Bits;
1575f5d09a5Sjsing   h2 += h1 >> 25; h1 &= kBottom25Bits;
1585f5d09a5Sjsing   h3 += h2 >> 26; h2 &= kBottom26Bits;
1595f5d09a5Sjsing   h4 += h3 >> 25; h3 &= kBottom25Bits;
1605f5d09a5Sjsing   h5 += h4 >> 26; h4 &= kBottom26Bits;
1615f5d09a5Sjsing   h6 += h5 >> 25; h5 &= kBottom25Bits;
1625f5d09a5Sjsing   h7 += h6 >> 26; h6 &= kBottom26Bits;
1635f5d09a5Sjsing   h8 += h7 >> 25; h7 &= kBottom25Bits;
1645f5d09a5Sjsing   h9 += h8 >> 26; h8 &= kBottom26Bits;
1655f5d09a5Sjsing                   h9 &= kBottom25Bits;
1665f5d09a5Sjsing                   /* h10 = carry9 */
1675f5d09a5Sjsing 
1685f5d09a5Sjsing   /* Goal: Output h0+...+2^255 h10-2^255 q, which is between 0 and 2^255-20.
1695f5d09a5Sjsing    * Have h0+...+2^230 h9 between 0 and 2^255-1;
1705f5d09a5Sjsing    * evidently 2^255 h10-2^255 q = 0.
1715f5d09a5Sjsing    * Goal: Output h0+...+2^230 h9.  */
1725f5d09a5Sjsing 
1735f5d09a5Sjsing   s[0] = h0 >> 0;
1745f5d09a5Sjsing   s[1] = h0 >> 8;
1755f5d09a5Sjsing   s[2] = h0 >> 16;
1765f5d09a5Sjsing   s[3] = (h0 >> 24) | ((uint32_t)(h1) << 2);
1775f5d09a5Sjsing   s[4] = h1 >> 6;
1785f5d09a5Sjsing   s[5] = h1 >> 14;
1795f5d09a5Sjsing   s[6] = (h1 >> 22) | ((uint32_t)(h2) << 3);
1805f5d09a5Sjsing   s[7] = h2 >> 5;
1815f5d09a5Sjsing   s[8] = h2 >> 13;
1825f5d09a5Sjsing   s[9] = (h2 >> 21) | ((uint32_t)(h3) << 5);
1835f5d09a5Sjsing   s[10] = h3 >> 3;
1845f5d09a5Sjsing   s[11] = h3 >> 11;
1855f5d09a5Sjsing   s[12] = (h3 >> 19) | ((uint32_t)(h4) << 6);
1865f5d09a5Sjsing   s[13] = h4 >> 2;
1875f5d09a5Sjsing   s[14] = h4 >> 10;
1885f5d09a5Sjsing   s[15] = h4 >> 18;
1895f5d09a5Sjsing   s[16] = h5 >> 0;
1905f5d09a5Sjsing   s[17] = h5 >> 8;
1915f5d09a5Sjsing   s[18] = h5 >> 16;
1925f5d09a5Sjsing   s[19] = (h5 >> 24) | ((uint32_t)(h6) << 1);
1935f5d09a5Sjsing   s[20] = h6 >> 7;
1945f5d09a5Sjsing   s[21] = h6 >> 15;
1955f5d09a5Sjsing   s[22] = (h6 >> 23) | ((uint32_t)(h7) << 3);
1965f5d09a5Sjsing   s[23] = h7 >> 5;
1975f5d09a5Sjsing   s[24] = h7 >> 13;
1985f5d09a5Sjsing   s[25] = (h7 >> 21) | ((uint32_t)(h8) << 4);
1995f5d09a5Sjsing   s[26] = h8 >> 4;
2005f5d09a5Sjsing   s[27] = h8 >> 12;
2015f5d09a5Sjsing   s[28] = (h8 >> 20) | ((uint32_t)(h9) << 6);
2025f5d09a5Sjsing   s[29] = h9 >> 2;
2035f5d09a5Sjsing   s[30] = h9 >> 10;
2045f5d09a5Sjsing   s[31] = h9 >> 18;
2055f5d09a5Sjsing }
2065f5d09a5Sjsing 
2075f5d09a5Sjsing /* h = f */
fe_copy(fe h,const fe f)2085f5d09a5Sjsing static void fe_copy(fe h, const fe f) {
2095f5d09a5Sjsing   memmove(h, f, sizeof(int32_t) * 10);
2105f5d09a5Sjsing }
2115f5d09a5Sjsing 
2125f5d09a5Sjsing /* h = 0 */
fe_0(fe h)2135f5d09a5Sjsing static void fe_0(fe h) { memset(h, 0, sizeof(int32_t) * 10); }
2145f5d09a5Sjsing 
2155f5d09a5Sjsing /* h = 1 */
fe_1(fe h)2165f5d09a5Sjsing static void fe_1(fe h) {
2175f5d09a5Sjsing   memset(h, 0, sizeof(int32_t) * 10);
2185f5d09a5Sjsing   h[0] = 1;
2195f5d09a5Sjsing }
2205f5d09a5Sjsing 
2215f5d09a5Sjsing /* h = f + g
2225f5d09a5Sjsing  * Can overlap h with f or g.
2235f5d09a5Sjsing  *
2245f5d09a5Sjsing  * Preconditions:
2255f5d09a5Sjsing  *    |f| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc.
2265f5d09a5Sjsing  *    |g| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc.
2275f5d09a5Sjsing  *
2285f5d09a5Sjsing  * Postconditions:
2295f5d09a5Sjsing  *    |h| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc. */
fe_add(fe h,const fe f,const fe g)2305f5d09a5Sjsing static void fe_add(fe h, const fe f, const fe g) {
2315f5d09a5Sjsing   unsigned i;
2325f5d09a5Sjsing   for (i = 0; i < 10; i++) {
2335f5d09a5Sjsing     h[i] = f[i] + g[i];
2345f5d09a5Sjsing   }
2355f5d09a5Sjsing }
2365f5d09a5Sjsing 
2375f5d09a5Sjsing /* h = f - g
2385f5d09a5Sjsing  * Can overlap h with f or g.
2395f5d09a5Sjsing  *
2405f5d09a5Sjsing  * Preconditions:
2415f5d09a5Sjsing  *    |f| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc.
2425f5d09a5Sjsing  *    |g| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc.
2435f5d09a5Sjsing  *
2445f5d09a5Sjsing  * Postconditions:
2455f5d09a5Sjsing  *    |h| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc. */
fe_sub(fe h,const fe f,const fe g)2465f5d09a5Sjsing static void fe_sub(fe h, const fe f, const fe g) {
2475f5d09a5Sjsing   unsigned i;
2485f5d09a5Sjsing   for (i = 0; i < 10; i++) {
2495f5d09a5Sjsing     h[i] = f[i] - g[i];
2505f5d09a5Sjsing   }
2515f5d09a5Sjsing }
2525f5d09a5Sjsing 
2535f5d09a5Sjsing /* h = f * g
2545f5d09a5Sjsing  * Can overlap h with f or g.
2555f5d09a5Sjsing  *
2565f5d09a5Sjsing  * Preconditions:
2575f5d09a5Sjsing  *    |f| bounded by 1.65*2^26,1.65*2^25,1.65*2^26,1.65*2^25,etc.
2585f5d09a5Sjsing  *    |g| bounded by 1.65*2^26,1.65*2^25,1.65*2^26,1.65*2^25,etc.
2595f5d09a5Sjsing  *
2605f5d09a5Sjsing  * Postconditions:
2615f5d09a5Sjsing  *    |h| bounded by 1.01*2^25,1.01*2^24,1.01*2^25,1.01*2^24,etc.
2625f5d09a5Sjsing  *
2635f5d09a5Sjsing  * Notes on implementation strategy:
2645f5d09a5Sjsing  *
2655f5d09a5Sjsing  * Using schoolbook multiplication.
2665f5d09a5Sjsing  * Karatsuba would save a little in some cost models.
2675f5d09a5Sjsing  *
2685f5d09a5Sjsing  * Most multiplications by 2 and 19 are 32-bit precomputations;
2695f5d09a5Sjsing  * cheaper than 64-bit postcomputations.
2705f5d09a5Sjsing  *
2715f5d09a5Sjsing  * There is one remaining multiplication by 19 in the carry chain;
2725f5d09a5Sjsing  * one *19 precomputation can be merged into this,
2735f5d09a5Sjsing  * but the resulting data flow is considerably less clean.
2745f5d09a5Sjsing  *
2755f5d09a5Sjsing  * There are 12 carries below.
2765f5d09a5Sjsing  * 10 of them are 2-way parallelizable and vectorizable.
2775f5d09a5Sjsing  * Can get away with 11 carries, but then data flow is much deeper.
2785f5d09a5Sjsing  *
2795f5d09a5Sjsing  * With tighter constraints on inputs can squeeze carries into int32. */
fe_mul(fe h,const fe f,const fe g)2805f5d09a5Sjsing static void fe_mul(fe h, const fe f, const fe g) {
2815f5d09a5Sjsing   int32_t f0 = f[0];
2825f5d09a5Sjsing   int32_t f1 = f[1];
2835f5d09a5Sjsing   int32_t f2 = f[2];
2845f5d09a5Sjsing   int32_t f3 = f[3];
2855f5d09a5Sjsing   int32_t f4 = f[4];
2865f5d09a5Sjsing   int32_t f5 = f[5];
2875f5d09a5Sjsing   int32_t f6 = f[6];
2885f5d09a5Sjsing   int32_t f7 = f[7];
2895f5d09a5Sjsing   int32_t f8 = f[8];
2905f5d09a5Sjsing   int32_t f9 = f[9];
2915f5d09a5Sjsing   int32_t g0 = g[0];
2925f5d09a5Sjsing   int32_t g1 = g[1];
2935f5d09a5Sjsing   int32_t g2 = g[2];
2945f5d09a5Sjsing   int32_t g3 = g[3];
2955f5d09a5Sjsing   int32_t g4 = g[4];
2965f5d09a5Sjsing   int32_t g5 = g[5];
2975f5d09a5Sjsing   int32_t g6 = g[6];
2985f5d09a5Sjsing   int32_t g7 = g[7];
2995f5d09a5Sjsing   int32_t g8 = g[8];
3005f5d09a5Sjsing   int32_t g9 = g[9];
3015f5d09a5Sjsing   int32_t g1_19 = 19 * g1; /* 1.959375*2^29 */
3025f5d09a5Sjsing   int32_t g2_19 = 19 * g2; /* 1.959375*2^30; still ok */
3035f5d09a5Sjsing   int32_t g3_19 = 19 * g3;
3045f5d09a5Sjsing   int32_t g4_19 = 19 * g4;
3055f5d09a5Sjsing   int32_t g5_19 = 19 * g5;
3065f5d09a5Sjsing   int32_t g6_19 = 19 * g6;
3075f5d09a5Sjsing   int32_t g7_19 = 19 * g7;
3085f5d09a5Sjsing   int32_t g8_19 = 19 * g8;
3095f5d09a5Sjsing   int32_t g9_19 = 19 * g9;
3105f5d09a5Sjsing   int32_t f1_2 = 2 * f1;
3115f5d09a5Sjsing   int32_t f3_2 = 2 * f3;
3125f5d09a5Sjsing   int32_t f5_2 = 2 * f5;
3135f5d09a5Sjsing   int32_t f7_2 = 2 * f7;
3145f5d09a5Sjsing   int32_t f9_2 = 2 * f9;
3155f5d09a5Sjsing   int64_t f0g0    = f0   * (int64_t) g0;
3165f5d09a5Sjsing   int64_t f0g1    = f0   * (int64_t) g1;
3175f5d09a5Sjsing   int64_t f0g2    = f0   * (int64_t) g2;
3185f5d09a5Sjsing   int64_t f0g3    = f0   * (int64_t) g3;
3195f5d09a5Sjsing   int64_t f0g4    = f0   * (int64_t) g4;
3205f5d09a5Sjsing   int64_t f0g5    = f0   * (int64_t) g5;
3215f5d09a5Sjsing   int64_t f0g6    = f0   * (int64_t) g6;
3225f5d09a5Sjsing   int64_t f0g7    = f0   * (int64_t) g7;
3235f5d09a5Sjsing   int64_t f0g8    = f0   * (int64_t) g8;
3245f5d09a5Sjsing   int64_t f0g9    = f0   * (int64_t) g9;
3255f5d09a5Sjsing   int64_t f1g0    = f1   * (int64_t) g0;
3265f5d09a5Sjsing   int64_t f1g1_2  = f1_2 * (int64_t) g1;
3275f5d09a5Sjsing   int64_t f1g2    = f1   * (int64_t) g2;
3285f5d09a5Sjsing   int64_t f1g3_2  = f1_2 * (int64_t) g3;
3295f5d09a5Sjsing   int64_t f1g4    = f1   * (int64_t) g4;
3305f5d09a5Sjsing   int64_t f1g5_2  = f1_2 * (int64_t) g5;
3315f5d09a5Sjsing   int64_t f1g6    = f1   * (int64_t) g6;
3325f5d09a5Sjsing   int64_t f1g7_2  = f1_2 * (int64_t) g7;
3335f5d09a5Sjsing   int64_t f1g8    = f1   * (int64_t) g8;
3345f5d09a5Sjsing   int64_t f1g9_38 = f1_2 * (int64_t) g9_19;
3355f5d09a5Sjsing   int64_t f2g0    = f2   * (int64_t) g0;
3365f5d09a5Sjsing   int64_t f2g1    = f2   * (int64_t) g1;
3375f5d09a5Sjsing   int64_t f2g2    = f2   * (int64_t) g2;
3385f5d09a5Sjsing   int64_t f2g3    = f2   * (int64_t) g3;
3395f5d09a5Sjsing   int64_t f2g4    = f2   * (int64_t) g4;
3405f5d09a5Sjsing   int64_t f2g5    = f2   * (int64_t) g5;
3415f5d09a5Sjsing   int64_t f2g6    = f2   * (int64_t) g6;
3425f5d09a5Sjsing   int64_t f2g7    = f2   * (int64_t) g7;
3435f5d09a5Sjsing   int64_t f2g8_19 = f2   * (int64_t) g8_19;
3445f5d09a5Sjsing   int64_t f2g9_19 = f2   * (int64_t) g9_19;
3455f5d09a5Sjsing   int64_t f3g0    = f3   * (int64_t) g0;
3465f5d09a5Sjsing   int64_t f3g1_2  = f3_2 * (int64_t) g1;
3475f5d09a5Sjsing   int64_t f3g2    = f3   * (int64_t) g2;
3485f5d09a5Sjsing   int64_t f3g3_2  = f3_2 * (int64_t) g3;
3495f5d09a5Sjsing   int64_t f3g4    = f3   * (int64_t) g4;
3505f5d09a5Sjsing   int64_t f3g5_2  = f3_2 * (int64_t) g5;
3515f5d09a5Sjsing   int64_t f3g6    = f3   * (int64_t) g6;
3525f5d09a5Sjsing   int64_t f3g7_38 = f3_2 * (int64_t) g7_19;
3535f5d09a5Sjsing   int64_t f3g8_19 = f3   * (int64_t) g8_19;
3545f5d09a5Sjsing   int64_t f3g9_38 = f3_2 * (int64_t) g9_19;
3555f5d09a5Sjsing   int64_t f4g0    = f4   * (int64_t) g0;
3565f5d09a5Sjsing   int64_t f4g1    = f4   * (int64_t) g1;
3575f5d09a5Sjsing   int64_t f4g2    = f4   * (int64_t) g2;
3585f5d09a5Sjsing   int64_t f4g3    = f4   * (int64_t) g3;
3595f5d09a5Sjsing   int64_t f4g4    = f4   * (int64_t) g4;
3605f5d09a5Sjsing   int64_t f4g5    = f4   * (int64_t) g5;
3615f5d09a5Sjsing   int64_t f4g6_19 = f4   * (int64_t) g6_19;
3625f5d09a5Sjsing   int64_t f4g7_19 = f4   * (int64_t) g7_19;
3635f5d09a5Sjsing   int64_t f4g8_19 = f4   * (int64_t) g8_19;
3645f5d09a5Sjsing   int64_t f4g9_19 = f4   * (int64_t) g9_19;
3655f5d09a5Sjsing   int64_t f5g0    = f5   * (int64_t) g0;
3665f5d09a5Sjsing   int64_t f5g1_2  = f5_2 * (int64_t) g1;
3675f5d09a5Sjsing   int64_t f5g2    = f5   * (int64_t) g2;
3685f5d09a5Sjsing   int64_t f5g3_2  = f5_2 * (int64_t) g3;
3695f5d09a5Sjsing   int64_t f5g4    = f5   * (int64_t) g4;
3705f5d09a5Sjsing   int64_t f5g5_38 = f5_2 * (int64_t) g5_19;
3715f5d09a5Sjsing   int64_t f5g6_19 = f5   * (int64_t) g6_19;
3725f5d09a5Sjsing   int64_t f5g7_38 = f5_2 * (int64_t) g7_19;
3735f5d09a5Sjsing   int64_t f5g8_19 = f5   * (int64_t) g8_19;
3745f5d09a5Sjsing   int64_t f5g9_38 = f5_2 * (int64_t) g9_19;
3755f5d09a5Sjsing   int64_t f6g0    = f6   * (int64_t) g0;
3765f5d09a5Sjsing   int64_t f6g1    = f6   * (int64_t) g1;
3775f5d09a5Sjsing   int64_t f6g2    = f6   * (int64_t) g2;
3785f5d09a5Sjsing   int64_t f6g3    = f6   * (int64_t) g3;
3795f5d09a5Sjsing   int64_t f6g4_19 = f6   * (int64_t) g4_19;
3805f5d09a5Sjsing   int64_t f6g5_19 = f6   * (int64_t) g5_19;
3815f5d09a5Sjsing   int64_t f6g6_19 = f6   * (int64_t) g6_19;
3825f5d09a5Sjsing   int64_t f6g7_19 = f6   * (int64_t) g7_19;
3835f5d09a5Sjsing   int64_t f6g8_19 = f6   * (int64_t) g8_19;
3845f5d09a5Sjsing   int64_t f6g9_19 = f6   * (int64_t) g9_19;
3855f5d09a5Sjsing   int64_t f7g0    = f7   * (int64_t) g0;
3865f5d09a5Sjsing   int64_t f7g1_2  = f7_2 * (int64_t) g1;
3875f5d09a5Sjsing   int64_t f7g2    = f7   * (int64_t) g2;
3885f5d09a5Sjsing   int64_t f7g3_38 = f7_2 * (int64_t) g3_19;
3895f5d09a5Sjsing   int64_t f7g4_19 = f7   * (int64_t) g4_19;
3905f5d09a5Sjsing   int64_t f7g5_38 = f7_2 * (int64_t) g5_19;
3915f5d09a5Sjsing   int64_t f7g6_19 = f7   * (int64_t) g6_19;
3925f5d09a5Sjsing   int64_t f7g7_38 = f7_2 * (int64_t) g7_19;
3935f5d09a5Sjsing   int64_t f7g8_19 = f7   * (int64_t) g8_19;
3945f5d09a5Sjsing   int64_t f7g9_38 = f7_2 * (int64_t) g9_19;
3955f5d09a5Sjsing   int64_t f8g0    = f8   * (int64_t) g0;
3965f5d09a5Sjsing   int64_t f8g1    = f8   * (int64_t) g1;
3975f5d09a5Sjsing   int64_t f8g2_19 = f8   * (int64_t) g2_19;
3985f5d09a5Sjsing   int64_t f8g3_19 = f8   * (int64_t) g3_19;
3995f5d09a5Sjsing   int64_t f8g4_19 = f8   * (int64_t) g4_19;
4005f5d09a5Sjsing   int64_t f8g5_19 = f8   * (int64_t) g5_19;
4015f5d09a5Sjsing   int64_t f8g6_19 = f8   * (int64_t) g6_19;
4025f5d09a5Sjsing   int64_t f8g7_19 = f8   * (int64_t) g7_19;
4035f5d09a5Sjsing   int64_t f8g8_19 = f8   * (int64_t) g8_19;
4045f5d09a5Sjsing   int64_t f8g9_19 = f8   * (int64_t) g9_19;
4055f5d09a5Sjsing   int64_t f9g0    = f9   * (int64_t) g0;
4065f5d09a5Sjsing   int64_t f9g1_38 = f9_2 * (int64_t) g1_19;
4075f5d09a5Sjsing   int64_t f9g2_19 = f9   * (int64_t) g2_19;
4085f5d09a5Sjsing   int64_t f9g3_38 = f9_2 * (int64_t) g3_19;
4095f5d09a5Sjsing   int64_t f9g4_19 = f9   * (int64_t) g4_19;
4105f5d09a5Sjsing   int64_t f9g5_38 = f9_2 * (int64_t) g5_19;
4115f5d09a5Sjsing   int64_t f9g6_19 = f9   * (int64_t) g6_19;
4125f5d09a5Sjsing   int64_t f9g7_38 = f9_2 * (int64_t) g7_19;
4135f5d09a5Sjsing   int64_t f9g8_19 = f9   * (int64_t) g8_19;
4145f5d09a5Sjsing   int64_t f9g9_38 = f9_2 * (int64_t) g9_19;
4155f5d09a5Sjsing   int64_t h0 = f0g0+f1g9_38+f2g8_19+f3g7_38+f4g6_19+f5g5_38+f6g4_19+f7g3_38+f8g2_19+f9g1_38;
4165f5d09a5Sjsing   int64_t h1 = f0g1+f1g0   +f2g9_19+f3g8_19+f4g7_19+f5g6_19+f6g5_19+f7g4_19+f8g3_19+f9g2_19;
4175f5d09a5Sjsing   int64_t h2 = f0g2+f1g1_2 +f2g0   +f3g9_38+f4g8_19+f5g7_38+f6g6_19+f7g5_38+f8g4_19+f9g3_38;
4185f5d09a5Sjsing   int64_t h3 = f0g3+f1g2   +f2g1   +f3g0   +f4g9_19+f5g8_19+f6g7_19+f7g6_19+f8g5_19+f9g4_19;
4195f5d09a5Sjsing   int64_t h4 = f0g4+f1g3_2 +f2g2   +f3g1_2 +f4g0   +f5g9_38+f6g8_19+f7g7_38+f8g6_19+f9g5_38;
4205f5d09a5Sjsing   int64_t h5 = f0g5+f1g4   +f2g3   +f3g2   +f4g1   +f5g0   +f6g9_19+f7g8_19+f8g7_19+f9g6_19;
4215f5d09a5Sjsing   int64_t h6 = f0g6+f1g5_2 +f2g4   +f3g3_2 +f4g2   +f5g1_2 +f6g0   +f7g9_38+f8g8_19+f9g7_38;
4225f5d09a5Sjsing   int64_t h7 = f0g7+f1g6   +f2g5   +f3g4   +f4g3   +f5g2   +f6g1   +f7g0   +f8g9_19+f9g8_19;
4235f5d09a5Sjsing   int64_t h8 = f0g8+f1g7_2 +f2g6   +f3g5_2 +f4g4   +f5g3_2 +f6g2   +f7g1_2 +f8g0   +f9g9_38;
4245f5d09a5Sjsing   int64_t h9 = f0g9+f1g8   +f2g7   +f3g6   +f4g5   +f5g4   +f6g3   +f7g2   +f8g1   +f9g0   ;
4255f5d09a5Sjsing   int64_t carry0;
4265f5d09a5Sjsing   int64_t carry1;
4275f5d09a5Sjsing   int64_t carry2;
4285f5d09a5Sjsing   int64_t carry3;
4295f5d09a5Sjsing   int64_t carry4;
4305f5d09a5Sjsing   int64_t carry5;
4315f5d09a5Sjsing   int64_t carry6;
4325f5d09a5Sjsing   int64_t carry7;
4335f5d09a5Sjsing   int64_t carry8;
4345f5d09a5Sjsing   int64_t carry9;
4355f5d09a5Sjsing 
4365f5d09a5Sjsing   /* |h0| <= (1.65*1.65*2^52*(1+19+19+19+19)+1.65*1.65*2^50*(38+38+38+38+38))
4375f5d09a5Sjsing    *   i.e. |h0| <= 1.4*2^60; narrower ranges for h2, h4, h6, h8
4385f5d09a5Sjsing    * |h1| <= (1.65*1.65*2^51*(1+1+19+19+19+19+19+19+19+19))
4395f5d09a5Sjsing    *   i.e. |h1| <= 1.7*2^59; narrower ranges for h3, h5, h7, h9 */
4405f5d09a5Sjsing 
4415f5d09a5Sjsing   carry0 = h0 + (1 << 25); h1 += carry0 >> 26; h0 -= carry0 & kTop38Bits;
4425f5d09a5Sjsing   carry4 = h4 + (1 << 25); h5 += carry4 >> 26; h4 -= carry4 & kTop38Bits;
4435f5d09a5Sjsing   /* |h0| <= 2^25 */
4445f5d09a5Sjsing   /* |h4| <= 2^25 */
4455f5d09a5Sjsing   /* |h1| <= 1.71*2^59 */
4465f5d09a5Sjsing   /* |h5| <= 1.71*2^59 */
4475f5d09a5Sjsing 
4485f5d09a5Sjsing   carry1 = h1 + (1 << 24); h2 += carry1 >> 25; h1 -= carry1 & kTop39Bits;
4495f5d09a5Sjsing   carry5 = h5 + (1 << 24); h6 += carry5 >> 25; h5 -= carry5 & kTop39Bits;
4505f5d09a5Sjsing   /* |h1| <= 2^24; from now on fits into int32 */
4515f5d09a5Sjsing   /* |h5| <= 2^24; from now on fits into int32 */
4525f5d09a5Sjsing   /* |h2| <= 1.41*2^60 */
4535f5d09a5Sjsing   /* |h6| <= 1.41*2^60 */
4545f5d09a5Sjsing 
4555f5d09a5Sjsing   carry2 = h2 + (1 << 25); h3 += carry2 >> 26; h2 -= carry2 & kTop38Bits;
4565f5d09a5Sjsing   carry6 = h6 + (1 << 25); h7 += carry6 >> 26; h6 -= carry6 & kTop38Bits;
4575f5d09a5Sjsing   /* |h2| <= 2^25; from now on fits into int32 unchanged */
4585f5d09a5Sjsing   /* |h6| <= 2^25; from now on fits into int32 unchanged */
4595f5d09a5Sjsing   /* |h3| <= 1.71*2^59 */
4605f5d09a5Sjsing   /* |h7| <= 1.71*2^59 */
4615f5d09a5Sjsing 
4625f5d09a5Sjsing   carry3 = h3 + (1 << 24); h4 += carry3 >> 25; h3 -= carry3 & kTop39Bits;
4635f5d09a5Sjsing   carry7 = h7 + (1 << 24); h8 += carry7 >> 25; h7 -= carry7 & kTop39Bits;
4645f5d09a5Sjsing   /* |h3| <= 2^24; from now on fits into int32 unchanged */
4655f5d09a5Sjsing   /* |h7| <= 2^24; from now on fits into int32 unchanged */
4665f5d09a5Sjsing   /* |h4| <= 1.72*2^34 */
4675f5d09a5Sjsing   /* |h8| <= 1.41*2^60 */
4685f5d09a5Sjsing 
4695f5d09a5Sjsing   carry4 = h4 + (1 << 25); h5 += carry4 >> 26; h4 -= carry4 & kTop38Bits;
4705f5d09a5Sjsing   carry8 = h8 + (1 << 25); h9 += carry8 >> 26; h8 -= carry8 & kTop38Bits;
4715f5d09a5Sjsing   /* |h4| <= 2^25; from now on fits into int32 unchanged */
4725f5d09a5Sjsing   /* |h8| <= 2^25; from now on fits into int32 unchanged */
4735f5d09a5Sjsing   /* |h5| <= 1.01*2^24 */
4745f5d09a5Sjsing   /* |h9| <= 1.71*2^59 */
4755f5d09a5Sjsing 
4765f5d09a5Sjsing   carry9 = h9 + (1 << 24); h0 += (carry9 >> 25) * 19; h9 -= carry9 & kTop39Bits;
4775f5d09a5Sjsing   /* |h9| <= 2^24; from now on fits into int32 unchanged */
4785f5d09a5Sjsing   /* |h0| <= 1.1*2^39 */
4795f5d09a5Sjsing 
4805f5d09a5Sjsing   carry0 = h0 + (1 << 25); h1 += carry0 >> 26; h0 -= carry0 & kTop38Bits;
4815f5d09a5Sjsing   /* |h0| <= 2^25; from now on fits into int32 unchanged */
4825f5d09a5Sjsing   /* |h1| <= 1.01*2^24 */
4835f5d09a5Sjsing 
4845f5d09a5Sjsing   h[0] = h0;
4855f5d09a5Sjsing   h[1] = h1;
4865f5d09a5Sjsing   h[2] = h2;
4875f5d09a5Sjsing   h[3] = h3;
4885f5d09a5Sjsing   h[4] = h4;
4895f5d09a5Sjsing   h[5] = h5;
4905f5d09a5Sjsing   h[6] = h6;
4915f5d09a5Sjsing   h[7] = h7;
4925f5d09a5Sjsing   h[8] = h8;
4935f5d09a5Sjsing   h[9] = h9;
4945f5d09a5Sjsing }
4955f5d09a5Sjsing 
4965f5d09a5Sjsing /* h = f * f
4975f5d09a5Sjsing  * Can overlap h with f.
4985f5d09a5Sjsing  *
4995f5d09a5Sjsing  * Preconditions:
5005f5d09a5Sjsing  *    |f| bounded by 1.65*2^26,1.65*2^25,1.65*2^26,1.65*2^25,etc.
5015f5d09a5Sjsing  *
5025f5d09a5Sjsing  * Postconditions:
5035f5d09a5Sjsing  *    |h| bounded by 1.01*2^25,1.01*2^24,1.01*2^25,1.01*2^24,etc.
5045f5d09a5Sjsing  *
5055f5d09a5Sjsing  * See fe_mul.c for discussion of implementation strategy. */
fe_sq(fe h,const fe f)5065f5d09a5Sjsing static void fe_sq(fe h, const fe f) {
5075f5d09a5Sjsing   int32_t f0 = f[0];
5085f5d09a5Sjsing   int32_t f1 = f[1];
5095f5d09a5Sjsing   int32_t f2 = f[2];
5105f5d09a5Sjsing   int32_t f3 = f[3];
5115f5d09a5Sjsing   int32_t f4 = f[4];
5125f5d09a5Sjsing   int32_t f5 = f[5];
5135f5d09a5Sjsing   int32_t f6 = f[6];
5145f5d09a5Sjsing   int32_t f7 = f[7];
5155f5d09a5Sjsing   int32_t f8 = f[8];
5165f5d09a5Sjsing   int32_t f9 = f[9];
5175f5d09a5Sjsing   int32_t f0_2 = 2 * f0;
5185f5d09a5Sjsing   int32_t f1_2 = 2 * f1;
5195f5d09a5Sjsing   int32_t f2_2 = 2 * f2;
5205f5d09a5Sjsing   int32_t f3_2 = 2 * f3;
5215f5d09a5Sjsing   int32_t f4_2 = 2 * f4;
5225f5d09a5Sjsing   int32_t f5_2 = 2 * f5;
5235f5d09a5Sjsing   int32_t f6_2 = 2 * f6;
5245f5d09a5Sjsing   int32_t f7_2 = 2 * f7;
5255f5d09a5Sjsing   int32_t f5_38 = 38 * f5; /* 1.959375*2^30 */
5265f5d09a5Sjsing   int32_t f6_19 = 19 * f6; /* 1.959375*2^30 */
5275f5d09a5Sjsing   int32_t f7_38 = 38 * f7; /* 1.959375*2^30 */
5285f5d09a5Sjsing   int32_t f8_19 = 19 * f8; /* 1.959375*2^30 */
5295f5d09a5Sjsing   int32_t f9_38 = 38 * f9; /* 1.959375*2^30 */
5305f5d09a5Sjsing   int64_t f0f0    = f0   * (int64_t) f0;
5315f5d09a5Sjsing   int64_t f0f1_2  = f0_2 * (int64_t) f1;
5325f5d09a5Sjsing   int64_t f0f2_2  = f0_2 * (int64_t) f2;
5335f5d09a5Sjsing   int64_t f0f3_2  = f0_2 * (int64_t) f3;
5345f5d09a5Sjsing   int64_t f0f4_2  = f0_2 * (int64_t) f4;
5355f5d09a5Sjsing   int64_t f0f5_2  = f0_2 * (int64_t) f5;
5365f5d09a5Sjsing   int64_t f0f6_2  = f0_2 * (int64_t) f6;
5375f5d09a5Sjsing   int64_t f0f7_2  = f0_2 * (int64_t) f7;
5385f5d09a5Sjsing   int64_t f0f8_2  = f0_2 * (int64_t) f8;
5395f5d09a5Sjsing   int64_t f0f9_2  = f0_2 * (int64_t) f9;
5405f5d09a5Sjsing   int64_t f1f1_2  = f1_2 * (int64_t) f1;
5415f5d09a5Sjsing   int64_t f1f2_2  = f1_2 * (int64_t) f2;
5425f5d09a5Sjsing   int64_t f1f3_4  = f1_2 * (int64_t) f3_2;
5435f5d09a5Sjsing   int64_t f1f4_2  = f1_2 * (int64_t) f4;
5445f5d09a5Sjsing   int64_t f1f5_4  = f1_2 * (int64_t) f5_2;
5455f5d09a5Sjsing   int64_t f1f6_2  = f1_2 * (int64_t) f6;
5465f5d09a5Sjsing   int64_t f1f7_4  = f1_2 * (int64_t) f7_2;
5475f5d09a5Sjsing   int64_t f1f8_2  = f1_2 * (int64_t) f8;
5485f5d09a5Sjsing   int64_t f1f9_76 = f1_2 * (int64_t) f9_38;
5495f5d09a5Sjsing   int64_t f2f2    = f2   * (int64_t) f2;
5505f5d09a5Sjsing   int64_t f2f3_2  = f2_2 * (int64_t) f3;
5515f5d09a5Sjsing   int64_t f2f4_2  = f2_2 * (int64_t) f4;
5525f5d09a5Sjsing   int64_t f2f5_2  = f2_2 * (int64_t) f5;
5535f5d09a5Sjsing   int64_t f2f6_2  = f2_2 * (int64_t) f6;
5545f5d09a5Sjsing   int64_t f2f7_2  = f2_2 * (int64_t) f7;
5555f5d09a5Sjsing   int64_t f2f8_38 = f2_2 * (int64_t) f8_19;
5565f5d09a5Sjsing   int64_t f2f9_38 = f2   * (int64_t) f9_38;
5575f5d09a5Sjsing   int64_t f3f3_2  = f3_2 * (int64_t) f3;
5585f5d09a5Sjsing   int64_t f3f4_2  = f3_2 * (int64_t) f4;
5595f5d09a5Sjsing   int64_t f3f5_4  = f3_2 * (int64_t) f5_2;
5605f5d09a5Sjsing   int64_t f3f6_2  = f3_2 * (int64_t) f6;
5615f5d09a5Sjsing   int64_t f3f7_76 = f3_2 * (int64_t) f7_38;
5625f5d09a5Sjsing   int64_t f3f8_38 = f3_2 * (int64_t) f8_19;
5635f5d09a5Sjsing   int64_t f3f9_76 = f3_2 * (int64_t) f9_38;
5645f5d09a5Sjsing   int64_t f4f4    = f4   * (int64_t) f4;
5655f5d09a5Sjsing   int64_t f4f5_2  = f4_2 * (int64_t) f5;
5665f5d09a5Sjsing   int64_t f4f6_38 = f4_2 * (int64_t) f6_19;
5675f5d09a5Sjsing   int64_t f4f7_38 = f4   * (int64_t) f7_38;
5685f5d09a5Sjsing   int64_t f4f8_38 = f4_2 * (int64_t) f8_19;
5695f5d09a5Sjsing   int64_t f4f9_38 = f4   * (int64_t) f9_38;
5705f5d09a5Sjsing   int64_t f5f5_38 = f5   * (int64_t) f5_38;
5715f5d09a5Sjsing   int64_t f5f6_38 = f5_2 * (int64_t) f6_19;
5725f5d09a5Sjsing   int64_t f5f7_76 = f5_2 * (int64_t) f7_38;
5735f5d09a5Sjsing   int64_t f5f8_38 = f5_2 * (int64_t) f8_19;
5745f5d09a5Sjsing   int64_t f5f9_76 = f5_2 * (int64_t) f9_38;
5755f5d09a5Sjsing   int64_t f6f6_19 = f6   * (int64_t) f6_19;
5765f5d09a5Sjsing   int64_t f6f7_38 = f6   * (int64_t) f7_38;
5775f5d09a5Sjsing   int64_t f6f8_38 = f6_2 * (int64_t) f8_19;
5785f5d09a5Sjsing   int64_t f6f9_38 = f6   * (int64_t) f9_38;
5795f5d09a5Sjsing   int64_t f7f7_38 = f7   * (int64_t) f7_38;
5805f5d09a5Sjsing   int64_t f7f8_38 = f7_2 * (int64_t) f8_19;
5815f5d09a5Sjsing   int64_t f7f9_76 = f7_2 * (int64_t) f9_38;
5825f5d09a5Sjsing   int64_t f8f8_19 = f8   * (int64_t) f8_19;
5835f5d09a5Sjsing   int64_t f8f9_38 = f8   * (int64_t) f9_38;
5845f5d09a5Sjsing   int64_t f9f9_38 = f9   * (int64_t) f9_38;
5855f5d09a5Sjsing   int64_t h0 = f0f0  +f1f9_76+f2f8_38+f3f7_76+f4f6_38+f5f5_38;
5865f5d09a5Sjsing   int64_t h1 = f0f1_2+f2f9_38+f3f8_38+f4f7_38+f5f6_38;
5875f5d09a5Sjsing   int64_t h2 = f0f2_2+f1f1_2 +f3f9_76+f4f8_38+f5f7_76+f6f6_19;
5885f5d09a5Sjsing   int64_t h3 = f0f3_2+f1f2_2 +f4f9_38+f5f8_38+f6f7_38;
5895f5d09a5Sjsing   int64_t h4 = f0f4_2+f1f3_4 +f2f2   +f5f9_76+f6f8_38+f7f7_38;
5905f5d09a5Sjsing   int64_t h5 = f0f5_2+f1f4_2 +f2f3_2 +f6f9_38+f7f8_38;
5915f5d09a5Sjsing   int64_t h6 = f0f6_2+f1f5_4 +f2f4_2 +f3f3_2 +f7f9_76+f8f8_19;
5925f5d09a5Sjsing   int64_t h7 = f0f7_2+f1f6_2 +f2f5_2 +f3f4_2 +f8f9_38;
5935f5d09a5Sjsing   int64_t h8 = f0f8_2+f1f7_4 +f2f6_2 +f3f5_4 +f4f4   +f9f9_38;
5945f5d09a5Sjsing   int64_t h9 = f0f9_2+f1f8_2 +f2f7_2 +f3f6_2 +f4f5_2;
5955f5d09a5Sjsing   int64_t carry0;
5965f5d09a5Sjsing   int64_t carry1;
5975f5d09a5Sjsing   int64_t carry2;
5985f5d09a5Sjsing   int64_t carry3;
5995f5d09a5Sjsing   int64_t carry4;
6005f5d09a5Sjsing   int64_t carry5;
6015f5d09a5Sjsing   int64_t carry6;
6025f5d09a5Sjsing   int64_t carry7;
6035f5d09a5Sjsing   int64_t carry8;
6045f5d09a5Sjsing   int64_t carry9;
6055f5d09a5Sjsing 
6065f5d09a5Sjsing   carry0 = h0 + (1 << 25); h1 += carry0 >> 26; h0 -= carry0 & kTop38Bits;
6075f5d09a5Sjsing   carry4 = h4 + (1 << 25); h5 += carry4 >> 26; h4 -= carry4 & kTop38Bits;
6085f5d09a5Sjsing 
6095f5d09a5Sjsing   carry1 = h1 + (1 << 24); h2 += carry1 >> 25; h1 -= carry1 & kTop39Bits;
6105f5d09a5Sjsing   carry5 = h5 + (1 << 24); h6 += carry5 >> 25; h5 -= carry5 & kTop39Bits;
6115f5d09a5Sjsing 
6125f5d09a5Sjsing   carry2 = h2 + (1 << 25); h3 += carry2 >> 26; h2 -= carry2 & kTop38Bits;
6135f5d09a5Sjsing   carry6 = h6 + (1 << 25); h7 += carry6 >> 26; h6 -= carry6 & kTop38Bits;
6145f5d09a5Sjsing 
6155f5d09a5Sjsing   carry3 = h3 + (1 << 24); h4 += carry3 >> 25; h3 -= carry3 & kTop39Bits;
6165f5d09a5Sjsing   carry7 = h7 + (1 << 24); h8 += carry7 >> 25; h7 -= carry7 & kTop39Bits;
6175f5d09a5Sjsing 
6185f5d09a5Sjsing   carry4 = h4 + (1 << 25); h5 += carry4 >> 26; h4 -= carry4 & kTop38Bits;
6195f5d09a5Sjsing   carry8 = h8 + (1 << 25); h9 += carry8 >> 26; h8 -= carry8 & kTop38Bits;
6205f5d09a5Sjsing 
6215f5d09a5Sjsing   carry9 = h9 + (1 << 24); h0 += (carry9 >> 25) * 19; h9 -= carry9 & kTop39Bits;
6225f5d09a5Sjsing 
6235f5d09a5Sjsing   carry0 = h0 + (1 << 25); h1 += carry0 >> 26; h0 -= carry0 & kTop38Bits;
6245f5d09a5Sjsing 
6255f5d09a5Sjsing   h[0] = h0;
6265f5d09a5Sjsing   h[1] = h1;
6275f5d09a5Sjsing   h[2] = h2;
6285f5d09a5Sjsing   h[3] = h3;
6295f5d09a5Sjsing   h[4] = h4;
6305f5d09a5Sjsing   h[5] = h5;
6315f5d09a5Sjsing   h[6] = h6;
6325f5d09a5Sjsing   h[7] = h7;
6335f5d09a5Sjsing   h[8] = h8;
6345f5d09a5Sjsing   h[9] = h9;
6355f5d09a5Sjsing }
6365f5d09a5Sjsing 
fe_invert(fe out,const fe z)6375f5d09a5Sjsing static void fe_invert(fe out, const fe z) {
6385f5d09a5Sjsing   fe t0;
6395f5d09a5Sjsing   fe t1;
6405f5d09a5Sjsing   fe t2;
6415f5d09a5Sjsing   fe t3;
6425f5d09a5Sjsing   int i;
6435f5d09a5Sjsing 
6445f5d09a5Sjsing   fe_sq(t0, z);
6455f5d09a5Sjsing   fe_sq(t1, t0);
6465f5d09a5Sjsing   for (i = 1; i < 2; ++i) {
6475f5d09a5Sjsing     fe_sq(t1, t1);
6485f5d09a5Sjsing   }
6495f5d09a5Sjsing   fe_mul(t1, z, t1);
6505f5d09a5Sjsing   fe_mul(t0, t0, t1);
6515f5d09a5Sjsing   fe_sq(t2, t0);
6525f5d09a5Sjsing   fe_mul(t1, t1, t2);
6535f5d09a5Sjsing   fe_sq(t2, t1);
6545f5d09a5Sjsing   for (i = 1; i < 5; ++i) {
6555f5d09a5Sjsing     fe_sq(t2, t2);
6565f5d09a5Sjsing   }
6575f5d09a5Sjsing   fe_mul(t1, t2, t1);
6585f5d09a5Sjsing   fe_sq(t2, t1);
6595f5d09a5Sjsing   for (i = 1; i < 10; ++i) {
6605f5d09a5Sjsing     fe_sq(t2, t2);
6615f5d09a5Sjsing   }
6625f5d09a5Sjsing   fe_mul(t2, t2, t1);
6635f5d09a5Sjsing   fe_sq(t3, t2);
6645f5d09a5Sjsing   for (i = 1; i < 20; ++i) {
6655f5d09a5Sjsing     fe_sq(t3, t3);
6665f5d09a5Sjsing   }
6675f5d09a5Sjsing   fe_mul(t2, t3, t2);
6685f5d09a5Sjsing   fe_sq(t2, t2);
6695f5d09a5Sjsing   for (i = 1; i < 10; ++i) {
6705f5d09a5Sjsing     fe_sq(t2, t2);
6715f5d09a5Sjsing   }
6725f5d09a5Sjsing   fe_mul(t1, t2, t1);
6735f5d09a5Sjsing   fe_sq(t2, t1);
6745f5d09a5Sjsing   for (i = 1; i < 50; ++i) {
6755f5d09a5Sjsing     fe_sq(t2, t2);
6765f5d09a5Sjsing   }
6775f5d09a5Sjsing   fe_mul(t2, t2, t1);
6785f5d09a5Sjsing   fe_sq(t3, t2);
6795f5d09a5Sjsing   for (i = 1; i < 100; ++i) {
6805f5d09a5Sjsing     fe_sq(t3, t3);
6815f5d09a5Sjsing   }
6825f5d09a5Sjsing   fe_mul(t2, t3, t2);
6835f5d09a5Sjsing   fe_sq(t2, t2);
6845f5d09a5Sjsing   for (i = 1; i < 50; ++i) {
6855f5d09a5Sjsing     fe_sq(t2, t2);
6865f5d09a5Sjsing   }
6875f5d09a5Sjsing   fe_mul(t1, t2, t1);
6885f5d09a5Sjsing   fe_sq(t1, t1);
6895f5d09a5Sjsing   for (i = 1; i < 5; ++i) {
6905f5d09a5Sjsing     fe_sq(t1, t1);
6915f5d09a5Sjsing   }
6925f5d09a5Sjsing   fe_mul(out, t1, t0);
6935f5d09a5Sjsing }
6945f5d09a5Sjsing 
6955f5d09a5Sjsing /* h = -f
6965f5d09a5Sjsing  *
6975f5d09a5Sjsing  * Preconditions:
6985f5d09a5Sjsing  *    |f| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc.
6995f5d09a5Sjsing  *
7005f5d09a5Sjsing  * Postconditions:
7015f5d09a5Sjsing  *    |h| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc. */
fe_neg(fe h,const fe f)7025f5d09a5Sjsing static void fe_neg(fe h, const fe f) {
7035f5d09a5Sjsing   unsigned i;
7045f5d09a5Sjsing   for (i = 0; i < 10; i++) {
7055f5d09a5Sjsing     h[i] = -f[i];
7065f5d09a5Sjsing   }
7075f5d09a5Sjsing }
7085f5d09a5Sjsing 
7095f5d09a5Sjsing /* Replace (f,g) with (g,g) if b == 1;
7105f5d09a5Sjsing  * replace (f,g) with (f,g) if b == 0.
7115f5d09a5Sjsing  *
7125f5d09a5Sjsing  * Preconditions: b in {0,1}. */
fe_cmov(fe f,const fe g,unsigned b)7135f5d09a5Sjsing static void fe_cmov(fe f, const fe g, unsigned b) {
7145f5d09a5Sjsing   b = 0-b;
7155f5d09a5Sjsing   unsigned i;
7165f5d09a5Sjsing   for (i = 0; i < 10; i++) {
7175f5d09a5Sjsing     int32_t x = f[i] ^ g[i];
7185f5d09a5Sjsing     x &= b;
7195f5d09a5Sjsing     f[i] ^= x;
7205f5d09a5Sjsing   }
7215f5d09a5Sjsing }
7225f5d09a5Sjsing 
7235f5d09a5Sjsing /* return 0 if f == 0
7245f5d09a5Sjsing  * return 1 if f != 0
7255f5d09a5Sjsing  *
7265f5d09a5Sjsing  * Preconditions:
7275f5d09a5Sjsing  *    |f| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc. */
fe_isnonzero(const fe f)7285f5d09a5Sjsing static int fe_isnonzero(const fe f) {
7295f5d09a5Sjsing   uint8_t s[32];
7305f5d09a5Sjsing   fe_tobytes(s, f);
7315f5d09a5Sjsing 
7325f5d09a5Sjsing   static const uint8_t zero[32] = {0};
7335f5d09a5Sjsing   return timingsafe_memcmp(s, zero, sizeof(zero)) != 0;
7345f5d09a5Sjsing }
7355f5d09a5Sjsing 
7365f5d09a5Sjsing /* return 1 if f is in {1,3,5,...,q-2}
7375f5d09a5Sjsing  * return 0 if f is in {0,2,4,...,q-1}
7385f5d09a5Sjsing  *
7395f5d09a5Sjsing  * Preconditions:
7405f5d09a5Sjsing  *    |f| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc. */
fe_isnegative(const fe f)7415f5d09a5Sjsing static int fe_isnegative(const fe f) {
7425f5d09a5Sjsing   uint8_t s[32];
7435f5d09a5Sjsing   fe_tobytes(s, f);
7445f5d09a5Sjsing   return s[0] & 1;
7455f5d09a5Sjsing }
7465f5d09a5Sjsing 
7475f5d09a5Sjsing /* h = 2 * f * f
7485f5d09a5Sjsing  * Can overlap h with f.
7495f5d09a5Sjsing  *
7505f5d09a5Sjsing  * Preconditions:
7515f5d09a5Sjsing  *    |f| bounded by 1.65*2^26,1.65*2^25,1.65*2^26,1.65*2^25,etc.
7525f5d09a5Sjsing  *
7535f5d09a5Sjsing  * Postconditions:
7545f5d09a5Sjsing  *    |h| bounded by 1.01*2^25,1.01*2^24,1.01*2^25,1.01*2^24,etc.
7555f5d09a5Sjsing  *
7565f5d09a5Sjsing  * See fe_mul.c for discussion of implementation strategy. */
fe_sq2(fe h,const fe f)7575f5d09a5Sjsing static void fe_sq2(fe h, const fe f) {
7585f5d09a5Sjsing   int32_t f0 = f[0];
7595f5d09a5Sjsing   int32_t f1 = f[1];
7605f5d09a5Sjsing   int32_t f2 = f[2];
7615f5d09a5Sjsing   int32_t f3 = f[3];
7625f5d09a5Sjsing   int32_t f4 = f[4];
7635f5d09a5Sjsing   int32_t f5 = f[5];
7645f5d09a5Sjsing   int32_t f6 = f[6];
7655f5d09a5Sjsing   int32_t f7 = f[7];
7665f5d09a5Sjsing   int32_t f8 = f[8];
7675f5d09a5Sjsing   int32_t f9 = f[9];
7685f5d09a5Sjsing   int32_t f0_2 = 2 * f0;
7695f5d09a5Sjsing   int32_t f1_2 = 2 * f1;
7705f5d09a5Sjsing   int32_t f2_2 = 2 * f2;
7715f5d09a5Sjsing   int32_t f3_2 = 2 * f3;
7725f5d09a5Sjsing   int32_t f4_2 = 2 * f4;
7735f5d09a5Sjsing   int32_t f5_2 = 2 * f5;
7745f5d09a5Sjsing   int32_t f6_2 = 2 * f6;
7755f5d09a5Sjsing   int32_t f7_2 = 2 * f7;
7765f5d09a5Sjsing   int32_t f5_38 = 38 * f5; /* 1.959375*2^30 */
7775f5d09a5Sjsing   int32_t f6_19 = 19 * f6; /* 1.959375*2^30 */
7785f5d09a5Sjsing   int32_t f7_38 = 38 * f7; /* 1.959375*2^30 */
7795f5d09a5Sjsing   int32_t f8_19 = 19 * f8; /* 1.959375*2^30 */
7805f5d09a5Sjsing   int32_t f9_38 = 38 * f9; /* 1.959375*2^30 */
7815f5d09a5Sjsing   int64_t f0f0    = f0   * (int64_t) f0;
7825f5d09a5Sjsing   int64_t f0f1_2  = f0_2 * (int64_t) f1;
7835f5d09a5Sjsing   int64_t f0f2_2  = f0_2 * (int64_t) f2;
7845f5d09a5Sjsing   int64_t f0f3_2  = f0_2 * (int64_t) f3;
7855f5d09a5Sjsing   int64_t f0f4_2  = f0_2 * (int64_t) f4;
7865f5d09a5Sjsing   int64_t f0f5_2  = f0_2 * (int64_t) f5;
7875f5d09a5Sjsing   int64_t f0f6_2  = f0_2 * (int64_t) f6;
7885f5d09a5Sjsing   int64_t f0f7_2  = f0_2 * (int64_t) f7;
7895f5d09a5Sjsing   int64_t f0f8_2  = f0_2 * (int64_t) f8;
7905f5d09a5Sjsing   int64_t f0f9_2  = f0_2 * (int64_t) f9;
7915f5d09a5Sjsing   int64_t f1f1_2  = f1_2 * (int64_t) f1;
7925f5d09a5Sjsing   int64_t f1f2_2  = f1_2 * (int64_t) f2;
7935f5d09a5Sjsing   int64_t f1f3_4  = f1_2 * (int64_t) f3_2;
7945f5d09a5Sjsing   int64_t f1f4_2  = f1_2 * (int64_t) f4;
7955f5d09a5Sjsing   int64_t f1f5_4  = f1_2 * (int64_t) f5_2;
7965f5d09a5Sjsing   int64_t f1f6_2  = f1_2 * (int64_t) f6;
7975f5d09a5Sjsing   int64_t f1f7_4  = f1_2 * (int64_t) f7_2;
7985f5d09a5Sjsing   int64_t f1f8_2  = f1_2 * (int64_t) f8;
7995f5d09a5Sjsing   int64_t f1f9_76 = f1_2 * (int64_t) f9_38;
8005f5d09a5Sjsing   int64_t f2f2    = f2   * (int64_t) f2;
8015f5d09a5Sjsing   int64_t f2f3_2  = f2_2 * (int64_t) f3;
8025f5d09a5Sjsing   int64_t f2f4_2  = f2_2 * (int64_t) f4;
8035f5d09a5Sjsing   int64_t f2f5_2  = f2_2 * (int64_t) f5;
8045f5d09a5Sjsing   int64_t f2f6_2  = f2_2 * (int64_t) f6;
8055f5d09a5Sjsing   int64_t f2f7_2  = f2_2 * (int64_t) f7;
8065f5d09a5Sjsing   int64_t f2f8_38 = f2_2 * (int64_t) f8_19;
8075f5d09a5Sjsing   int64_t f2f9_38 = f2   * (int64_t) f9_38;
8085f5d09a5Sjsing   int64_t f3f3_2  = f3_2 * (int64_t) f3;
8095f5d09a5Sjsing   int64_t f3f4_2  = f3_2 * (int64_t) f4;
8105f5d09a5Sjsing   int64_t f3f5_4  = f3_2 * (int64_t) f5_2;
8115f5d09a5Sjsing   int64_t f3f6_2  = f3_2 * (int64_t) f6;
8125f5d09a5Sjsing   int64_t f3f7_76 = f3_2 * (int64_t) f7_38;
8135f5d09a5Sjsing   int64_t f3f8_38 = f3_2 * (int64_t) f8_19;
8145f5d09a5Sjsing   int64_t f3f9_76 = f3_2 * (int64_t) f9_38;
8155f5d09a5Sjsing   int64_t f4f4    = f4   * (int64_t) f4;
8165f5d09a5Sjsing   int64_t f4f5_2  = f4_2 * (int64_t) f5;
8175f5d09a5Sjsing   int64_t f4f6_38 = f4_2 * (int64_t) f6_19;
8185f5d09a5Sjsing   int64_t f4f7_38 = f4   * (int64_t) f7_38;
8195f5d09a5Sjsing   int64_t f4f8_38 = f4_2 * (int64_t) f8_19;
8205f5d09a5Sjsing   int64_t f4f9_38 = f4   * (int64_t) f9_38;
8215f5d09a5Sjsing   int64_t f5f5_38 = f5   * (int64_t) f5_38;
8225f5d09a5Sjsing   int64_t f5f6_38 = f5_2 * (int64_t) f6_19;
8235f5d09a5Sjsing   int64_t f5f7_76 = f5_2 * (int64_t) f7_38;
8245f5d09a5Sjsing   int64_t f5f8_38 = f5_2 * (int64_t) f8_19;
8255f5d09a5Sjsing   int64_t f5f9_76 = f5_2 * (int64_t) f9_38;
8265f5d09a5Sjsing   int64_t f6f6_19 = f6   * (int64_t) f6_19;
8275f5d09a5Sjsing   int64_t f6f7_38 = f6   * (int64_t) f7_38;
8285f5d09a5Sjsing   int64_t f6f8_38 = f6_2 * (int64_t) f8_19;
8295f5d09a5Sjsing   int64_t f6f9_38 = f6   * (int64_t) f9_38;
8305f5d09a5Sjsing   int64_t f7f7_38 = f7   * (int64_t) f7_38;
8315f5d09a5Sjsing   int64_t f7f8_38 = f7_2 * (int64_t) f8_19;
8325f5d09a5Sjsing   int64_t f7f9_76 = f7_2 * (int64_t) f9_38;
8335f5d09a5Sjsing   int64_t f8f8_19 = f8   * (int64_t) f8_19;
8345f5d09a5Sjsing   int64_t f8f9_38 = f8   * (int64_t) f9_38;
8355f5d09a5Sjsing   int64_t f9f9_38 = f9   * (int64_t) f9_38;
8365f5d09a5Sjsing   int64_t h0 = f0f0  +f1f9_76+f2f8_38+f3f7_76+f4f6_38+f5f5_38;
8375f5d09a5Sjsing   int64_t h1 = f0f1_2+f2f9_38+f3f8_38+f4f7_38+f5f6_38;
8385f5d09a5Sjsing   int64_t h2 = f0f2_2+f1f1_2 +f3f9_76+f4f8_38+f5f7_76+f6f6_19;
8395f5d09a5Sjsing   int64_t h3 = f0f3_2+f1f2_2 +f4f9_38+f5f8_38+f6f7_38;
8405f5d09a5Sjsing   int64_t h4 = f0f4_2+f1f3_4 +f2f2   +f5f9_76+f6f8_38+f7f7_38;
8415f5d09a5Sjsing   int64_t h5 = f0f5_2+f1f4_2 +f2f3_2 +f6f9_38+f7f8_38;
8425f5d09a5Sjsing   int64_t h6 = f0f6_2+f1f5_4 +f2f4_2 +f3f3_2 +f7f9_76+f8f8_19;
8435f5d09a5Sjsing   int64_t h7 = f0f7_2+f1f6_2 +f2f5_2 +f3f4_2 +f8f9_38;
8445f5d09a5Sjsing   int64_t h8 = f0f8_2+f1f7_4 +f2f6_2 +f3f5_4 +f4f4   +f9f9_38;
8455f5d09a5Sjsing   int64_t h9 = f0f9_2+f1f8_2 +f2f7_2 +f3f6_2 +f4f5_2;
8465f5d09a5Sjsing   int64_t carry0;
8475f5d09a5Sjsing   int64_t carry1;
8485f5d09a5Sjsing   int64_t carry2;
8495f5d09a5Sjsing   int64_t carry3;
8505f5d09a5Sjsing   int64_t carry4;
8515f5d09a5Sjsing   int64_t carry5;
8525f5d09a5Sjsing   int64_t carry6;
8535f5d09a5Sjsing   int64_t carry7;
8545f5d09a5Sjsing   int64_t carry8;
8555f5d09a5Sjsing   int64_t carry9;
8565f5d09a5Sjsing 
8575f5d09a5Sjsing   h0 += h0;
8585f5d09a5Sjsing   h1 += h1;
8595f5d09a5Sjsing   h2 += h2;
8605f5d09a5Sjsing   h3 += h3;
8615f5d09a5Sjsing   h4 += h4;
8625f5d09a5Sjsing   h5 += h5;
8635f5d09a5Sjsing   h6 += h6;
8645f5d09a5Sjsing   h7 += h7;
8655f5d09a5Sjsing   h8 += h8;
8665f5d09a5Sjsing   h9 += h9;
8675f5d09a5Sjsing 
8685f5d09a5Sjsing   carry0 = h0 + (1 << 25); h1 += carry0 >> 26; h0 -= carry0 & kTop38Bits;
8695f5d09a5Sjsing   carry4 = h4 + (1 << 25); h5 += carry4 >> 26; h4 -= carry4 & kTop38Bits;
8705f5d09a5Sjsing 
8715f5d09a5Sjsing   carry1 = h1 + (1 << 24); h2 += carry1 >> 25; h1 -= carry1 & kTop39Bits;
8725f5d09a5Sjsing   carry5 = h5 + (1 << 24); h6 += carry5 >> 25; h5 -= carry5 & kTop39Bits;
8735f5d09a5Sjsing 
8745f5d09a5Sjsing   carry2 = h2 + (1 << 25); h3 += carry2 >> 26; h2 -= carry2 & kTop38Bits;
8755f5d09a5Sjsing   carry6 = h6 + (1 << 25); h7 += carry6 >> 26; h6 -= carry6 & kTop38Bits;
8765f5d09a5Sjsing 
8775f5d09a5Sjsing   carry3 = h3 + (1 << 24); h4 += carry3 >> 25; h3 -= carry3 & kTop39Bits;
8785f5d09a5Sjsing   carry7 = h7 + (1 << 24); h8 += carry7 >> 25; h7 -= carry7 & kTop39Bits;
8795f5d09a5Sjsing 
8805f5d09a5Sjsing   carry4 = h4 + (1 << 25); h5 += carry4 >> 26; h4 -= carry4 & kTop38Bits;
8815f5d09a5Sjsing   carry8 = h8 + (1 << 25); h9 += carry8 >> 26; h8 -= carry8 & kTop38Bits;
8825f5d09a5Sjsing 
8835f5d09a5Sjsing   carry9 = h9 + (1 << 24); h0 += (carry9 >> 25) * 19; h9 -= carry9 & kTop39Bits;
8845f5d09a5Sjsing 
8855f5d09a5Sjsing   carry0 = h0 + (1 << 25); h1 += carry0 >> 26; h0 -= carry0 & kTop38Bits;
8865f5d09a5Sjsing 
8875f5d09a5Sjsing   h[0] = h0;
8885f5d09a5Sjsing   h[1] = h1;
8895f5d09a5Sjsing   h[2] = h2;
8905f5d09a5Sjsing   h[3] = h3;
8915f5d09a5Sjsing   h[4] = h4;
8925f5d09a5Sjsing   h[5] = h5;
8935f5d09a5Sjsing   h[6] = h6;
8945f5d09a5Sjsing   h[7] = h7;
8955f5d09a5Sjsing   h[8] = h8;
8965f5d09a5Sjsing   h[9] = h9;
8975f5d09a5Sjsing }
8985f5d09a5Sjsing 
fe_pow22523(fe out,const fe z)8995f5d09a5Sjsing static void fe_pow22523(fe out, const fe z) {
9005f5d09a5Sjsing   fe t0;
9015f5d09a5Sjsing   fe t1;
9025f5d09a5Sjsing   fe t2;
9035f5d09a5Sjsing   int i;
9045f5d09a5Sjsing 
9055f5d09a5Sjsing   fe_sq(t0, z);
9065f5d09a5Sjsing   fe_sq(t1, t0);
9075f5d09a5Sjsing   for (i = 1; i < 2; ++i) {
9085f5d09a5Sjsing     fe_sq(t1, t1);
9095f5d09a5Sjsing   }
9105f5d09a5Sjsing   fe_mul(t1, z, t1);
9115f5d09a5Sjsing   fe_mul(t0, t0, t1);
9125f5d09a5Sjsing   fe_sq(t0, t0);
9135f5d09a5Sjsing   fe_mul(t0, t1, t0);
9145f5d09a5Sjsing   fe_sq(t1, t0);
9155f5d09a5Sjsing   for (i = 1; i < 5; ++i) {
9165f5d09a5Sjsing     fe_sq(t1, t1);
9175f5d09a5Sjsing   }
9185f5d09a5Sjsing   fe_mul(t0, t1, t0);
9195f5d09a5Sjsing   fe_sq(t1, t0);
9205f5d09a5Sjsing   for (i = 1; i < 10; ++i) {
9215f5d09a5Sjsing     fe_sq(t1, t1);
9225f5d09a5Sjsing   }
9235f5d09a5Sjsing   fe_mul(t1, t1, t0);
9245f5d09a5Sjsing   fe_sq(t2, t1);
9255f5d09a5Sjsing   for (i = 1; i < 20; ++i) {
9265f5d09a5Sjsing     fe_sq(t2, t2);
9275f5d09a5Sjsing   }
9285f5d09a5Sjsing   fe_mul(t1, t2, t1);
9295f5d09a5Sjsing   fe_sq(t1, t1);
9305f5d09a5Sjsing   for (i = 1; i < 10; ++i) {
9315f5d09a5Sjsing     fe_sq(t1, t1);
9325f5d09a5Sjsing   }
9335f5d09a5Sjsing   fe_mul(t0, t1, t0);
9345f5d09a5Sjsing   fe_sq(t1, t0);
9355f5d09a5Sjsing   for (i = 1; i < 50; ++i) {
9365f5d09a5Sjsing     fe_sq(t1, t1);
9375f5d09a5Sjsing   }
9385f5d09a5Sjsing   fe_mul(t1, t1, t0);
9395f5d09a5Sjsing   fe_sq(t2, t1);
9405f5d09a5Sjsing   for (i = 1; i < 100; ++i) {
9415f5d09a5Sjsing     fe_sq(t2, t2);
9425f5d09a5Sjsing   }
9435f5d09a5Sjsing   fe_mul(t1, t2, t1);
9445f5d09a5Sjsing   fe_sq(t1, t1);
9455f5d09a5Sjsing   for (i = 1; i < 50; ++i) {
9465f5d09a5Sjsing     fe_sq(t1, t1);
9475f5d09a5Sjsing   }
9485f5d09a5Sjsing   fe_mul(t0, t1, t0);
9495f5d09a5Sjsing   fe_sq(t0, t0);
9505f5d09a5Sjsing   for (i = 1; i < 2; ++i) {
9515f5d09a5Sjsing     fe_sq(t0, t0);
9525f5d09a5Sjsing   }
9535f5d09a5Sjsing   fe_mul(out, t0, z);
9545f5d09a5Sjsing }
9555f5d09a5Sjsing 
x25519_ge_tobytes(uint8_t * s,const ge_p2 * h)9565f5d09a5Sjsing void x25519_ge_tobytes(uint8_t *s, const ge_p2 *h) {
9575f5d09a5Sjsing   fe recip;
9585f5d09a5Sjsing   fe x;
9595f5d09a5Sjsing   fe y;
9605f5d09a5Sjsing 
9615f5d09a5Sjsing   fe_invert(recip, h->Z);
9625f5d09a5Sjsing   fe_mul(x, h->X, recip);
9635f5d09a5Sjsing   fe_mul(y, h->Y, recip);
9645f5d09a5Sjsing   fe_tobytes(s, y);
9655f5d09a5Sjsing   s[31] ^= fe_isnegative(x) << 7;
9665f5d09a5Sjsing }
9675f5d09a5Sjsing 
ge_p3_tobytes(uint8_t * s,const ge_p3 * h)9685f5d09a5Sjsing static void ge_p3_tobytes(uint8_t *s, const ge_p3 *h) {
9695f5d09a5Sjsing   fe recip;
9705f5d09a5Sjsing   fe x;
9715f5d09a5Sjsing   fe y;
9725f5d09a5Sjsing 
9735f5d09a5Sjsing   fe_invert(recip, h->Z);
9745f5d09a5Sjsing   fe_mul(x, h->X, recip);
9755f5d09a5Sjsing   fe_mul(y, h->Y, recip);
9765f5d09a5Sjsing   fe_tobytes(s, y);
9775f5d09a5Sjsing   s[31] ^= fe_isnegative(x) << 7;
9785f5d09a5Sjsing }
9795f5d09a5Sjsing 
9805f5d09a5Sjsing static const fe d = {-10913610, 13857413, -15372611, 6949391,   114729,
9815f5d09a5Sjsing                      -8787816,  -6275908, -3247719,  -18696448, -12055116};
9825f5d09a5Sjsing 
9835f5d09a5Sjsing static const fe sqrtm1 = {-32595792, -7943725,  9377950,  3500415, 12389472,
9845f5d09a5Sjsing                           -272473,   -25146209, -2005654, 326686,  11406482};
9855f5d09a5Sjsing 
x25519_ge_frombytes_vartime(ge_p3 * h,const uint8_t * s)9865f5d09a5Sjsing int x25519_ge_frombytes_vartime(ge_p3 *h, const uint8_t *s) {
9875f5d09a5Sjsing   fe u;
9885f5d09a5Sjsing   fe v;
9895f5d09a5Sjsing   fe v3;
9905f5d09a5Sjsing   fe vxx;
9915f5d09a5Sjsing   fe check;
9925f5d09a5Sjsing 
9935f5d09a5Sjsing   fe_frombytes(h->Y, s);
9945f5d09a5Sjsing   fe_1(h->Z);
9955f5d09a5Sjsing   fe_sq(u, h->Y);
9965f5d09a5Sjsing   fe_mul(v, u, d);
9975f5d09a5Sjsing   fe_sub(u, u, h->Z); /* u = y^2-1 */
9985f5d09a5Sjsing   fe_add(v, v, h->Z); /* v = dy^2+1 */
9995f5d09a5Sjsing 
10005f5d09a5Sjsing   fe_sq(v3, v);
10015f5d09a5Sjsing   fe_mul(v3, v3, v); /* v3 = v^3 */
10025f5d09a5Sjsing   fe_sq(h->X, v3);
10035f5d09a5Sjsing   fe_mul(h->X, h->X, v);
10045f5d09a5Sjsing   fe_mul(h->X, h->X, u); /* x = uv^7 */
10055f5d09a5Sjsing 
10065f5d09a5Sjsing   fe_pow22523(h->X, h->X); /* x = (uv^7)^((q-5)/8) */
10075f5d09a5Sjsing   fe_mul(h->X, h->X, v3);
10085f5d09a5Sjsing   fe_mul(h->X, h->X, u); /* x = uv^3(uv^7)^((q-5)/8) */
10095f5d09a5Sjsing 
10105f5d09a5Sjsing   fe_sq(vxx, h->X);
10115f5d09a5Sjsing   fe_mul(vxx, vxx, v);
10125f5d09a5Sjsing   fe_sub(check, vxx, u); /* vx^2-u */
10135f5d09a5Sjsing   if (fe_isnonzero(check)) {
10145f5d09a5Sjsing     fe_add(check, vxx, u); /* vx^2+u */
10155f5d09a5Sjsing     if (fe_isnonzero(check)) {
10165f5d09a5Sjsing       return -1;
10175f5d09a5Sjsing     }
10185f5d09a5Sjsing     fe_mul(h->X, h->X, sqrtm1);
10195f5d09a5Sjsing   }
10205f5d09a5Sjsing 
10215f5d09a5Sjsing   if (fe_isnegative(h->X) != (s[31] >> 7)) {
10225f5d09a5Sjsing     fe_neg(h->X, h->X);
10235f5d09a5Sjsing   }
10245f5d09a5Sjsing 
10255f5d09a5Sjsing   fe_mul(h->T, h->X, h->Y);
10265f5d09a5Sjsing   return 0;
10275f5d09a5Sjsing }
10285f5d09a5Sjsing 
ge_p2_0(ge_p2 * h)10295f5d09a5Sjsing static void ge_p2_0(ge_p2 *h) {
10305f5d09a5Sjsing   fe_0(h->X);
10315f5d09a5Sjsing   fe_1(h->Y);
10325f5d09a5Sjsing   fe_1(h->Z);
10335f5d09a5Sjsing }
10345f5d09a5Sjsing 
ge_p3_0(ge_p3 * h)10355f5d09a5Sjsing static void ge_p3_0(ge_p3 *h) {
10365f5d09a5Sjsing   fe_0(h->X);
10375f5d09a5Sjsing   fe_1(h->Y);
10385f5d09a5Sjsing   fe_1(h->Z);
10395f5d09a5Sjsing   fe_0(h->T);
10405f5d09a5Sjsing }
10415f5d09a5Sjsing 
ge_cached_0(ge_cached * h)10425f5d09a5Sjsing static void ge_cached_0(ge_cached *h) {
10435f5d09a5Sjsing   fe_1(h->YplusX);
10445f5d09a5Sjsing   fe_1(h->YminusX);
10455f5d09a5Sjsing   fe_1(h->Z);
10465f5d09a5Sjsing   fe_0(h->T2d);
10475f5d09a5Sjsing }
10485f5d09a5Sjsing 
ge_precomp_0(ge_precomp * h)10495f5d09a5Sjsing static void ge_precomp_0(ge_precomp *h) {
10505f5d09a5Sjsing   fe_1(h->yplusx);
10515f5d09a5Sjsing   fe_1(h->yminusx);
10525f5d09a5Sjsing   fe_0(h->xy2d);
10535f5d09a5Sjsing }
10545f5d09a5Sjsing 
10555f5d09a5Sjsing /* r = p */
ge_p3_to_p2(ge_p2 * r,const ge_p3 * p)10565f5d09a5Sjsing static void ge_p3_to_p2(ge_p2 *r, const ge_p3 *p) {
10575f5d09a5Sjsing   fe_copy(r->X, p->X);
10585f5d09a5Sjsing   fe_copy(r->Y, p->Y);
10595f5d09a5Sjsing   fe_copy(r->Z, p->Z);
10605f5d09a5Sjsing }
10615f5d09a5Sjsing 
10625f5d09a5Sjsing static const fe d2 = {-21827239, -5839606,  -30745221, 13898782, 229458,
10635f5d09a5Sjsing                       15978800,  -12551817, -6495438,  29715968, 9444199};
10645f5d09a5Sjsing 
10655f5d09a5Sjsing /* r = p */
x25519_ge_p3_to_cached(ge_cached * r,const ge_p3 * p)10665f5d09a5Sjsing void x25519_ge_p3_to_cached(ge_cached *r, const ge_p3 *p) {
10675f5d09a5Sjsing   fe_add(r->YplusX, p->Y, p->X);
10685f5d09a5Sjsing   fe_sub(r->YminusX, p->Y, p->X);
10695f5d09a5Sjsing   fe_copy(r->Z, p->Z);
10705f5d09a5Sjsing   fe_mul(r->T2d, p->T, d2);
10715f5d09a5Sjsing }
10725f5d09a5Sjsing 
10735f5d09a5Sjsing /* r = p */
x25519_ge_p1p1_to_p2(ge_p2 * r,const ge_p1p1 * p)10745f5d09a5Sjsing void x25519_ge_p1p1_to_p2(ge_p2 *r, const ge_p1p1 *p) {
10755f5d09a5Sjsing   fe_mul(r->X, p->X, p->T);
10765f5d09a5Sjsing   fe_mul(r->Y, p->Y, p->Z);
10775f5d09a5Sjsing   fe_mul(r->Z, p->Z, p->T);
10785f5d09a5Sjsing }
10795f5d09a5Sjsing 
10805f5d09a5Sjsing /* r = p */
x25519_ge_p1p1_to_p3(ge_p3 * r,const ge_p1p1 * p)10815f5d09a5Sjsing void x25519_ge_p1p1_to_p3(ge_p3 *r, const ge_p1p1 *p) {
10825f5d09a5Sjsing   fe_mul(r->X, p->X, p->T);
10835f5d09a5Sjsing   fe_mul(r->Y, p->Y, p->Z);
10845f5d09a5Sjsing   fe_mul(r->Z, p->Z, p->T);
10855f5d09a5Sjsing   fe_mul(r->T, p->X, p->Y);
10865f5d09a5Sjsing }
10875f5d09a5Sjsing 
10885f5d09a5Sjsing /* r = p */
ge_p1p1_to_cached(ge_cached * r,const ge_p1p1 * p)10895f5d09a5Sjsing static void ge_p1p1_to_cached(ge_cached *r, const ge_p1p1 *p) {
10905f5d09a5Sjsing   ge_p3 t;
10915f5d09a5Sjsing   x25519_ge_p1p1_to_p3(&t, p);
10925f5d09a5Sjsing   x25519_ge_p3_to_cached(r, &t);
10935f5d09a5Sjsing }
10945f5d09a5Sjsing 
10955f5d09a5Sjsing /* r = 2 * p */
ge_p2_dbl(ge_p1p1 * r,const ge_p2 * p)10965f5d09a5Sjsing static void ge_p2_dbl(ge_p1p1 *r, const ge_p2 *p) {
10975f5d09a5Sjsing   fe t0;
10985f5d09a5Sjsing 
10995f5d09a5Sjsing   fe_sq(r->X, p->X);
11005f5d09a5Sjsing   fe_sq(r->Z, p->Y);
11015f5d09a5Sjsing   fe_sq2(r->T, p->Z);
11025f5d09a5Sjsing   fe_add(r->Y, p->X, p->Y);
11035f5d09a5Sjsing   fe_sq(t0, r->Y);
11045f5d09a5Sjsing   fe_add(r->Y, r->Z, r->X);
11055f5d09a5Sjsing   fe_sub(r->Z, r->Z, r->X);
11065f5d09a5Sjsing   fe_sub(r->X, t0, r->Y);
11075f5d09a5Sjsing   fe_sub(r->T, r->T, r->Z);
11085f5d09a5Sjsing }
11095f5d09a5Sjsing 
11105f5d09a5Sjsing /* r = 2 * p */
ge_p3_dbl(ge_p1p1 * r,const ge_p3 * p)11115f5d09a5Sjsing static void ge_p3_dbl(ge_p1p1 *r, const ge_p3 *p) {
11125f5d09a5Sjsing   ge_p2 q;
11135f5d09a5Sjsing   ge_p3_to_p2(&q, p);
11145f5d09a5Sjsing   ge_p2_dbl(r, &q);
11155f5d09a5Sjsing }
11165f5d09a5Sjsing 
11175f5d09a5Sjsing /* r = p + q */
ge_madd(ge_p1p1 * r,const ge_p3 * p,const ge_precomp * q)11185f5d09a5Sjsing static void ge_madd(ge_p1p1 *r, const ge_p3 *p, const ge_precomp *q) {
11195f5d09a5Sjsing   fe t0;
11205f5d09a5Sjsing 
11215f5d09a5Sjsing   fe_add(r->X, p->Y, p->X);
11225f5d09a5Sjsing   fe_sub(r->Y, p->Y, p->X);
11235f5d09a5Sjsing   fe_mul(r->Z, r->X, q->yplusx);
11245f5d09a5Sjsing   fe_mul(r->Y, r->Y, q->yminusx);
11255f5d09a5Sjsing   fe_mul(r->T, q->xy2d, p->T);
11265f5d09a5Sjsing   fe_add(t0, p->Z, p->Z);
11275f5d09a5Sjsing   fe_sub(r->X, r->Z, r->Y);
11285f5d09a5Sjsing   fe_add(r->Y, r->Z, r->Y);
11295f5d09a5Sjsing   fe_add(r->Z, t0, r->T);
11305f5d09a5Sjsing   fe_sub(r->T, t0, r->T);
11315f5d09a5Sjsing }
11325f5d09a5Sjsing 
11335f5d09a5Sjsing /* r = p - q */
ge_msub(ge_p1p1 * r,const ge_p3 * p,const ge_precomp * q)11345f5d09a5Sjsing static void ge_msub(ge_p1p1 *r, const ge_p3 *p, const ge_precomp *q) {
11355f5d09a5Sjsing   fe t0;
11365f5d09a5Sjsing 
11375f5d09a5Sjsing   fe_add(r->X, p->Y, p->X);
11385f5d09a5Sjsing   fe_sub(r->Y, p->Y, p->X);
11395f5d09a5Sjsing   fe_mul(r->Z, r->X, q->yminusx);
11405f5d09a5Sjsing   fe_mul(r->Y, r->Y, q->yplusx);
11415f5d09a5Sjsing   fe_mul(r->T, q->xy2d, p->T);
11425f5d09a5Sjsing   fe_add(t0, p->Z, p->Z);
11435f5d09a5Sjsing   fe_sub(r->X, r->Z, r->Y);
11445f5d09a5Sjsing   fe_add(r->Y, r->Z, r->Y);
11455f5d09a5Sjsing   fe_sub(r->Z, t0, r->T);
11465f5d09a5Sjsing   fe_add(r->T, t0, r->T);
11475f5d09a5Sjsing }
11485f5d09a5Sjsing 
11495f5d09a5Sjsing /* r = p + q */
x25519_ge_add(ge_p1p1 * r,const ge_p3 * p,const ge_cached * q)11505f5d09a5Sjsing void x25519_ge_add(ge_p1p1 *r, const ge_p3 *p, const ge_cached *q) {
11515f5d09a5Sjsing   fe t0;
11525f5d09a5Sjsing 
11535f5d09a5Sjsing   fe_add(r->X, p->Y, p->X);
11545f5d09a5Sjsing   fe_sub(r->Y, p->Y, p->X);
11555f5d09a5Sjsing   fe_mul(r->Z, r->X, q->YplusX);
11565f5d09a5Sjsing   fe_mul(r->Y, r->Y, q->YminusX);
11575f5d09a5Sjsing   fe_mul(r->T, q->T2d, p->T);
11585f5d09a5Sjsing   fe_mul(r->X, p->Z, q->Z);
11595f5d09a5Sjsing   fe_add(t0, r->X, r->X);
11605f5d09a5Sjsing   fe_sub(r->X, r->Z, r->Y);
11615f5d09a5Sjsing   fe_add(r->Y, r->Z, r->Y);
11625f5d09a5Sjsing   fe_add(r->Z, t0, r->T);
11635f5d09a5Sjsing   fe_sub(r->T, t0, r->T);
11645f5d09a5Sjsing }
11655f5d09a5Sjsing 
11665f5d09a5Sjsing /* r = p - q */
x25519_ge_sub(ge_p1p1 * r,const ge_p3 * p,const ge_cached * q)11675f5d09a5Sjsing void x25519_ge_sub(ge_p1p1 *r, const ge_p3 *p, const ge_cached *q) {
11685f5d09a5Sjsing   fe t0;
11695f5d09a5Sjsing 
11705f5d09a5Sjsing   fe_add(r->X, p->Y, p->X);
11715f5d09a5Sjsing   fe_sub(r->Y, p->Y, p->X);
11725f5d09a5Sjsing   fe_mul(r->Z, r->X, q->YminusX);
11735f5d09a5Sjsing   fe_mul(r->Y, r->Y, q->YplusX);
11745f5d09a5Sjsing   fe_mul(r->T, q->T2d, p->T);
11755f5d09a5Sjsing   fe_mul(r->X, p->Z, q->Z);
11765f5d09a5Sjsing   fe_add(t0, r->X, r->X);
11775f5d09a5Sjsing   fe_sub(r->X, r->Z, r->Y);
11785f5d09a5Sjsing   fe_add(r->Y, r->Z, r->Y);
11795f5d09a5Sjsing   fe_sub(r->Z, t0, r->T);
11805f5d09a5Sjsing   fe_add(r->T, t0, r->T);
11815f5d09a5Sjsing }
11825f5d09a5Sjsing 
equal(signed char b,signed char c)11835f5d09a5Sjsing static uint8_t equal(signed char b, signed char c) {
11845f5d09a5Sjsing   uint8_t ub = b;
11855f5d09a5Sjsing   uint8_t uc = c;
11865f5d09a5Sjsing   uint8_t x = ub ^ uc; /* 0: yes; 1..255: no */
11875f5d09a5Sjsing   uint32_t y = x;      /* 0: yes; 1..255: no */
11885f5d09a5Sjsing   y -= 1;              /* 4294967295: yes; 0..254: no */
11895f5d09a5Sjsing   y >>= 31;            /* 1: yes; 0: no */
11905f5d09a5Sjsing   return y;
11915f5d09a5Sjsing }
11925f5d09a5Sjsing 
cmov(ge_precomp * t,const ge_precomp * u,uint8_t b)11935f5d09a5Sjsing static void cmov(ge_precomp *t, const ge_precomp *u, uint8_t b) {
11945f5d09a5Sjsing   fe_cmov(t->yplusx, u->yplusx, b);
11955f5d09a5Sjsing   fe_cmov(t->yminusx, u->yminusx, b);
11965f5d09a5Sjsing   fe_cmov(t->xy2d, u->xy2d, b);
11975f5d09a5Sjsing }
11985f5d09a5Sjsing 
x25519_ge_scalarmult_small_precomp(ge_p3 * h,const uint8_t a[32],const uint8_t precomp_table[15* 2* 32])11995f5d09a5Sjsing void x25519_ge_scalarmult_small_precomp(
12005f5d09a5Sjsing     ge_p3 *h, const uint8_t a[32], const uint8_t precomp_table[15 * 2 * 32]) {
12015f5d09a5Sjsing   /* precomp_table is first expanded into matching |ge_precomp|
12025f5d09a5Sjsing    * elements. */
12035f5d09a5Sjsing   ge_precomp multiples[15];
12045f5d09a5Sjsing 
12055f5d09a5Sjsing   unsigned i;
12065f5d09a5Sjsing   for (i = 0; i < 15; i++) {
12075f5d09a5Sjsing     const uint8_t *bytes = &precomp_table[i*(2 * 32)];
12085f5d09a5Sjsing     fe x, y;
12095f5d09a5Sjsing     fe_frombytes(x, bytes);
12105f5d09a5Sjsing     fe_frombytes(y, bytes + 32);
12115f5d09a5Sjsing 
12125f5d09a5Sjsing     ge_precomp *out = &multiples[i];
12135f5d09a5Sjsing     fe_add(out->yplusx, y, x);
12145f5d09a5Sjsing     fe_sub(out->yminusx, y, x);
12155f5d09a5Sjsing     fe_mul(out->xy2d, x, y);
12165f5d09a5Sjsing     fe_mul(out->xy2d, out->xy2d, d2);
12175f5d09a5Sjsing   }
12185f5d09a5Sjsing 
12195f5d09a5Sjsing   /* See the comment above |k25519SmallPrecomp| about the structure of the
12205f5d09a5Sjsing    * precomputed elements. This loop does 64 additions and 64 doublings to
12215f5d09a5Sjsing    * calculate the result. */
12225f5d09a5Sjsing   ge_p3_0(h);
12235f5d09a5Sjsing 
12245f5d09a5Sjsing   for (i = 63; i < 64; i--) {
12255f5d09a5Sjsing     unsigned j;
12265f5d09a5Sjsing     signed char index = 0;
12275f5d09a5Sjsing 
12285f5d09a5Sjsing     for (j = 0; j < 4; j++) {
12295f5d09a5Sjsing       const uint8_t bit = 1 & (a[(8 * j) + (i / 8)] >> (i & 7));
12305f5d09a5Sjsing       index |= (bit << j);
12315f5d09a5Sjsing     }
12325f5d09a5Sjsing 
12335f5d09a5Sjsing     ge_precomp e;
12345f5d09a5Sjsing     ge_precomp_0(&e);
12355f5d09a5Sjsing 
12365f5d09a5Sjsing     for (j = 1; j < 16; j++) {
12375f5d09a5Sjsing       cmov(&e, &multiples[j-1], equal(index, j));
12385f5d09a5Sjsing     }
12395f5d09a5Sjsing 
12405f5d09a5Sjsing     ge_cached cached;
12415f5d09a5Sjsing     ge_p1p1 r;
12425f5d09a5Sjsing     x25519_ge_p3_to_cached(&cached, h);
12435f5d09a5Sjsing     x25519_ge_add(&r, h, &cached);
12445f5d09a5Sjsing     x25519_ge_p1p1_to_p3(h, &r);
12455f5d09a5Sjsing 
12465f5d09a5Sjsing     ge_madd(&r, h, &e);
12475f5d09a5Sjsing     x25519_ge_p1p1_to_p3(h, &r);
12485f5d09a5Sjsing   }
12495f5d09a5Sjsing }
12505f5d09a5Sjsing 
12515f5d09a5Sjsing #if defined(OPENSSL_SMALL)
12525f5d09a5Sjsing 
12535f5d09a5Sjsing /* This block of code replaces the standard base-point table with a much smaller
12545f5d09a5Sjsing  * one. The standard table is 30,720 bytes while this one is just 960.
12555f5d09a5Sjsing  *
12565f5d09a5Sjsing  * This table contains 15 pairs of group elements, (x, y), where each field
12575f5d09a5Sjsing  * element is serialised with |fe_tobytes|. If |i| is the index of the group
12585f5d09a5Sjsing  * element then consider i+1 as a four-bit number: (i₀, i₁, i₂, i₃) (where i₀
12595f5d09a5Sjsing  * is the most significant bit). The value of the group element is then:
12605f5d09a5Sjsing  * (i₀×2^192 + i₁×2^128 + i₂×2^64 + i₃)G, where G is the generator. */
12615f5d09a5Sjsing static const uint8_t k25519SmallPrecomp[15 * 2 * 32] = {
12625f5d09a5Sjsing     0x1a, 0xd5, 0x25, 0x8f, 0x60, 0x2d, 0x56, 0xc9, 0xb2, 0xa7, 0x25, 0x95,
12635f5d09a5Sjsing     0x60, 0xc7, 0x2c, 0x69, 0x5c, 0xdc, 0xd6, 0xfd, 0x31, 0xe2, 0xa4, 0xc0,
12645f5d09a5Sjsing     0xfe, 0x53, 0x6e, 0xcd, 0xd3, 0x36, 0x69, 0x21, 0x58, 0x66, 0x66, 0x66,
12655f5d09a5Sjsing     0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
12665f5d09a5Sjsing     0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
12675f5d09a5Sjsing     0x66, 0x66, 0x66, 0x66, 0x02, 0xa2, 0xed, 0xf4, 0x8f, 0x6b, 0x0b, 0x3e,
12685f5d09a5Sjsing     0xeb, 0x35, 0x1a, 0xd5, 0x7e, 0xdb, 0x78, 0x00, 0x96, 0x8a, 0xa0, 0xb4,
12695f5d09a5Sjsing     0xcf, 0x60, 0x4b, 0xd4, 0xd5, 0xf9, 0x2d, 0xbf, 0x88, 0xbd, 0x22, 0x62,
12705f5d09a5Sjsing     0x13, 0x53, 0xe4, 0x82, 0x57, 0xfa, 0x1e, 0x8f, 0x06, 0x2b, 0x90, 0xba,
12715f5d09a5Sjsing     0x08, 0xb6, 0x10, 0x54, 0x4f, 0x7c, 0x1b, 0x26, 0xed, 0xda, 0x6b, 0xdd,
12725f5d09a5Sjsing     0x25, 0xd0, 0x4e, 0xea, 0x42, 0xbb, 0x25, 0x03, 0xa2, 0xfb, 0xcc, 0x61,
12735f5d09a5Sjsing     0x67, 0x06, 0x70, 0x1a, 0xc4, 0x78, 0x3a, 0xff, 0x32, 0x62, 0xdd, 0x2c,
12745f5d09a5Sjsing     0xab, 0x50, 0x19, 0x3b, 0xf2, 0x9b, 0x7d, 0xb8, 0xfd, 0x4f, 0x29, 0x9c,
12755f5d09a5Sjsing     0xa7, 0x91, 0xba, 0x0e, 0x46, 0x5e, 0x51, 0xfe, 0x1d, 0xbf, 0xe5, 0xe5,
12765f5d09a5Sjsing     0x9b, 0x95, 0x0d, 0x67, 0xf8, 0xd1, 0xb5, 0x5a, 0xa1, 0x93, 0x2c, 0xc3,
12775f5d09a5Sjsing     0xde, 0x0e, 0x97, 0x85, 0x2d, 0x7f, 0xea, 0xab, 0x3e, 0x47, 0x30, 0x18,
12785f5d09a5Sjsing     0x24, 0xe8, 0xb7, 0x60, 0xae, 0x47, 0x80, 0xfc, 0xe5, 0x23, 0xe7, 0xc2,
12795f5d09a5Sjsing     0xc9, 0x85, 0xe6, 0x98, 0xa0, 0x29, 0x4e, 0xe1, 0x84, 0x39, 0x2d, 0x95,
12805f5d09a5Sjsing     0x2c, 0xf3, 0x45, 0x3c, 0xff, 0xaf, 0x27, 0x4c, 0x6b, 0xa6, 0xf5, 0x4b,
12815f5d09a5Sjsing     0x11, 0xbd, 0xba, 0x5b, 0x9e, 0xc4, 0xa4, 0x51, 0x1e, 0xbe, 0xd0, 0x90,
12825f5d09a5Sjsing     0x3a, 0x9c, 0xc2, 0x26, 0xb6, 0x1e, 0xf1, 0x95, 0x7d, 0xc8, 0x6d, 0x52,
12835f5d09a5Sjsing     0xe6, 0x99, 0x2c, 0x5f, 0x9a, 0x96, 0x0c, 0x68, 0x29, 0xfd, 0xe2, 0xfb,
12845f5d09a5Sjsing     0xe6, 0xbc, 0xec, 0x31, 0x08, 0xec, 0xe6, 0xb0, 0x53, 0x60, 0xc3, 0x8c,
12855f5d09a5Sjsing     0xbe, 0xc1, 0xb3, 0x8a, 0x8f, 0xe4, 0x88, 0x2b, 0x55, 0xe5, 0x64, 0x6e,
12865f5d09a5Sjsing     0x9b, 0xd0, 0xaf, 0x7b, 0x64, 0x2a, 0x35, 0x25, 0x10, 0x52, 0xc5, 0x9e,
12875f5d09a5Sjsing     0x58, 0x11, 0x39, 0x36, 0x45, 0x51, 0xb8, 0x39, 0x93, 0xfc, 0x9d, 0x6a,
12885f5d09a5Sjsing     0xbe, 0x58, 0xcb, 0xa4, 0x0f, 0x51, 0x3c, 0x38, 0x05, 0xca, 0xab, 0x43,
12895f5d09a5Sjsing     0x63, 0x0e, 0xf3, 0x8b, 0x41, 0xa6, 0xf8, 0x9b, 0x53, 0x70, 0x80, 0x53,
12905f5d09a5Sjsing     0x86, 0x5e, 0x8f, 0xe3, 0xc3, 0x0d, 0x18, 0xc8, 0x4b, 0x34, 0x1f, 0xd8,
12915f5d09a5Sjsing     0x1d, 0xbc, 0xf2, 0x6d, 0x34, 0x3a, 0xbe, 0xdf, 0xd9, 0xf6, 0xf3, 0x89,
12925f5d09a5Sjsing     0xa1, 0xe1, 0x94, 0x9f, 0x5d, 0x4c, 0x5d, 0xe9, 0xa1, 0x49, 0x92, 0xef,
12935f5d09a5Sjsing     0x0e, 0x53, 0x81, 0x89, 0x58, 0x87, 0xa6, 0x37, 0xf1, 0xdd, 0x62, 0x60,
12945f5d09a5Sjsing     0x63, 0x5a, 0x9d, 0x1b, 0x8c, 0xc6, 0x7d, 0x52, 0xea, 0x70, 0x09, 0x6a,
12955f5d09a5Sjsing     0xe1, 0x32, 0xf3, 0x73, 0x21, 0x1f, 0x07, 0x7b, 0x7c, 0x9b, 0x49, 0xd8,
12965f5d09a5Sjsing     0xc0, 0xf3, 0x25, 0x72, 0x6f, 0x9d, 0xed, 0x31, 0x67, 0x36, 0x36, 0x54,
12975f5d09a5Sjsing     0x40, 0x92, 0x71, 0xe6, 0x11, 0x28, 0x11, 0xad, 0x93, 0x32, 0x85, 0x7b,
12985f5d09a5Sjsing     0x3e, 0xb7, 0x3b, 0x49, 0x13, 0x1c, 0x07, 0xb0, 0x2e, 0x93, 0xaa, 0xfd,
12995f5d09a5Sjsing     0xfd, 0x28, 0x47, 0x3d, 0x8d, 0xd2, 0xda, 0xc7, 0x44, 0xd6, 0x7a, 0xdb,
13005f5d09a5Sjsing     0x26, 0x7d, 0x1d, 0xb8, 0xe1, 0xde, 0x9d, 0x7a, 0x7d, 0x17, 0x7e, 0x1c,
13015f5d09a5Sjsing     0x37, 0x04, 0x8d, 0x2d, 0x7c, 0x5e, 0x18, 0x38, 0x1e, 0xaf, 0xc7, 0x1b,
13025f5d09a5Sjsing     0x33, 0x48, 0x31, 0x00, 0x59, 0xf6, 0xf2, 0xca, 0x0f, 0x27, 0x1b, 0x63,
13035f5d09a5Sjsing     0x12, 0x7e, 0x02, 0x1d, 0x49, 0xc0, 0x5d, 0x79, 0x87, 0xef, 0x5e, 0x7a,
13045f5d09a5Sjsing     0x2f, 0x1f, 0x66, 0x55, 0xd8, 0x09, 0xd9, 0x61, 0x38, 0x68, 0xb0, 0x07,
13055f5d09a5Sjsing     0xa3, 0xfc, 0xcc, 0x85, 0x10, 0x7f, 0x4c, 0x65, 0x65, 0xb3, 0xfa, 0xfa,
13065f5d09a5Sjsing     0xa5, 0x53, 0x6f, 0xdb, 0x74, 0x4c, 0x56, 0x46, 0x03, 0xe2, 0xd5, 0x7a,
13075f5d09a5Sjsing     0x29, 0x1c, 0xc6, 0x02, 0xbc, 0x59, 0xf2, 0x04, 0x75, 0x63, 0xc0, 0x84,
13085f5d09a5Sjsing     0x2f, 0x60, 0x1c, 0x67, 0x76, 0xfd, 0x63, 0x86, 0xf3, 0xfa, 0xbf, 0xdc,
13095f5d09a5Sjsing     0xd2, 0x2d, 0x90, 0x91, 0xbd, 0x33, 0xa9, 0xe5, 0x66, 0x0c, 0xda, 0x42,
13105f5d09a5Sjsing     0x27, 0xca, 0xf4, 0x66, 0xc2, 0xec, 0x92, 0x14, 0x57, 0x06, 0x63, 0xd0,
13115f5d09a5Sjsing     0x4d, 0x15, 0x06, 0xeb, 0x69, 0x58, 0x4f, 0x77, 0xc5, 0x8b, 0xc7, 0xf0,
13125f5d09a5Sjsing     0x8e, 0xed, 0x64, 0xa0, 0xb3, 0x3c, 0x66, 0x71, 0xc6, 0x2d, 0xda, 0x0a,
13135f5d09a5Sjsing     0x0d, 0xfe, 0x70, 0x27, 0x64, 0xf8, 0x27, 0xfa, 0xf6, 0x5f, 0x30, 0xa5,
13145f5d09a5Sjsing     0x0d, 0x6c, 0xda, 0xf2, 0x62, 0x5e, 0x78, 0x47, 0xd3, 0x66, 0x00, 0x1c,
13155f5d09a5Sjsing     0xfd, 0x56, 0x1f, 0x5d, 0x3f, 0x6f, 0xf4, 0x4c, 0xd8, 0xfd, 0x0e, 0x27,
13165f5d09a5Sjsing     0xc9, 0x5c, 0x2b, 0xbc, 0xc0, 0xa4, 0xe7, 0x23, 0x29, 0x02, 0x9f, 0x31,
13175f5d09a5Sjsing     0xd6, 0xe9, 0xd7, 0x96, 0xf4, 0xe0, 0x5e, 0x0b, 0x0e, 0x13, 0xee, 0x3c,
13185f5d09a5Sjsing     0x09, 0xed, 0xf2, 0x3d, 0x76, 0x91, 0xc3, 0xa4, 0x97, 0xae, 0xd4, 0x87,
13195f5d09a5Sjsing     0xd0, 0x5d, 0xf6, 0x18, 0x47, 0x1f, 0x1d, 0x67, 0xf2, 0xcf, 0x63, 0xa0,
13205f5d09a5Sjsing     0x91, 0x27, 0xf8, 0x93, 0x45, 0x75, 0x23, 0x3f, 0xd1, 0xf1, 0xad, 0x23,
13215f5d09a5Sjsing     0xdd, 0x64, 0x93, 0x96, 0x41, 0x70, 0x7f, 0xf7, 0xf5, 0xa9, 0x89, 0xa2,
13225f5d09a5Sjsing     0x34, 0xb0, 0x8d, 0x1b, 0xae, 0x19, 0x15, 0x49, 0x58, 0x23, 0x6d, 0x87,
13235f5d09a5Sjsing     0x15, 0x4f, 0x81, 0x76, 0xfb, 0x23, 0xb5, 0xea, 0xcf, 0xac, 0x54, 0x8d,
13245f5d09a5Sjsing     0x4e, 0x42, 0x2f, 0xeb, 0x0f, 0x63, 0xdb, 0x68, 0x37, 0xa8, 0xcf, 0x8b,
13255f5d09a5Sjsing     0xab, 0xf5, 0xa4, 0x6e, 0x96, 0x2a, 0xb2, 0xd6, 0xbe, 0x9e, 0xbd, 0x0d,
13265f5d09a5Sjsing     0xb4, 0x42, 0xa9, 0xcf, 0x01, 0x83, 0x8a, 0x17, 0x47, 0x76, 0xc4, 0xc6,
13275f5d09a5Sjsing     0x83, 0x04, 0x95, 0x0b, 0xfc, 0x11, 0xc9, 0x62, 0xb8, 0x0c, 0x76, 0x84,
13285f5d09a5Sjsing     0xd9, 0xb9, 0x37, 0xfa, 0xfc, 0x7c, 0xc2, 0x6d, 0x58, 0x3e, 0xb3, 0x04,
13295f5d09a5Sjsing     0xbb, 0x8c, 0x8f, 0x48, 0xbc, 0x91, 0x27, 0xcc, 0xf9, 0xb7, 0x22, 0x19,
13305f5d09a5Sjsing     0x83, 0x2e, 0x09, 0xb5, 0x72, 0xd9, 0x54, 0x1c, 0x4d, 0xa1, 0xea, 0x0b,
13315f5d09a5Sjsing     0xf1, 0xc6, 0x08, 0x72, 0x46, 0x87, 0x7a, 0x6e, 0x80, 0x56, 0x0a, 0x8a,
13325f5d09a5Sjsing     0xc0, 0xdd, 0x11, 0x6b, 0xd6, 0xdd, 0x47, 0xdf, 0x10, 0xd9, 0xd8, 0xea,
13335f5d09a5Sjsing     0x7c, 0xb0, 0x8f, 0x03, 0x00, 0x2e, 0xc1, 0x8f, 0x44, 0xa8, 0xd3, 0x30,
13345f5d09a5Sjsing     0x06, 0x89, 0xa2, 0xf9, 0x34, 0xad, 0xdc, 0x03, 0x85, 0xed, 0x51, 0xa7,
13355f5d09a5Sjsing     0x82, 0x9c, 0xe7, 0x5d, 0x52, 0x93, 0x0c, 0x32, 0x9a, 0x5b, 0xe1, 0xaa,
13365f5d09a5Sjsing     0xca, 0xb8, 0x02, 0x6d, 0x3a, 0xd4, 0xb1, 0x3a, 0xf0, 0x5f, 0xbe, 0xb5,
13375f5d09a5Sjsing     0x0d, 0x10, 0x6b, 0x38, 0x32, 0xac, 0x76, 0x80, 0xbd, 0xca, 0x94, 0x71,
13385f5d09a5Sjsing     0x7a, 0xf2, 0xc9, 0x35, 0x2a, 0xde, 0x9f, 0x42, 0x49, 0x18, 0x01, 0xab,
13395f5d09a5Sjsing     0xbc, 0xef, 0x7c, 0x64, 0x3f, 0x58, 0x3d, 0x92, 0x59, 0xdb, 0x13, 0xdb,
13405f5d09a5Sjsing     0x58, 0x6e, 0x0a, 0xe0, 0xb7, 0x91, 0x4a, 0x08, 0x20, 0xd6, 0x2e, 0x3c,
13415f5d09a5Sjsing     0x45, 0xc9, 0x8b, 0x17, 0x79, 0xe7, 0xc7, 0x90, 0x99, 0x3a, 0x18, 0x25,
13425f5d09a5Sjsing };
13435f5d09a5Sjsing 
x25519_ge_scalarmult_base(ge_p3 * h,const uint8_t a[32])13445f5d09a5Sjsing void x25519_ge_scalarmult_base(ge_p3 *h, const uint8_t a[32]) {
13455f5d09a5Sjsing   x25519_ge_scalarmult_small_precomp(h, a, k25519SmallPrecomp);
13465f5d09a5Sjsing }
13475f5d09a5Sjsing 
13485f5d09a5Sjsing #else
13495f5d09a5Sjsing 
13505f5d09a5Sjsing /* k25519Precomp[i][j] = (j+1)*256^i*B */
13515f5d09a5Sjsing static const ge_precomp k25519Precomp[32][8] = {
13525f5d09a5Sjsing     {
13535f5d09a5Sjsing         {
13545f5d09a5Sjsing             {25967493, -14356035, 29566456, 3660896, -12694345, 4014787,
13555f5d09a5Sjsing              27544626, -11754271, -6079156, 2047605},
13565f5d09a5Sjsing             {-12545711, 934262, -2722910, 3049990, -727428, 9406986, 12720692,
13575f5d09a5Sjsing              5043384, 19500929, -15469378},
13585f5d09a5Sjsing             {-8738181, 4489570, 9688441, -14785194, 10184609, -12363380,
13595f5d09a5Sjsing              29287919, 11864899, -24514362, -4438546},
13605f5d09a5Sjsing         },
13615f5d09a5Sjsing         {
13625f5d09a5Sjsing             {-12815894, -12976347, -21581243, 11784320, -25355658, -2750717,
13635f5d09a5Sjsing              -11717903, -3814571, -358445, -10211303},
13645f5d09a5Sjsing             {-21703237, 6903825, 27185491, 6451973, -29577724, -9554005,
13655f5d09a5Sjsing              -15616551, 11189268, -26829678, -5319081},
13665f5d09a5Sjsing             {26966642, 11152617, 32442495, 15396054, 14353839, -12752335,
13675f5d09a5Sjsing              -3128826, -9541118, -15472047, -4166697},
13685f5d09a5Sjsing         },
13695f5d09a5Sjsing         {
13705f5d09a5Sjsing             {15636291, -9688557, 24204773, -7912398, 616977, -16685262,
13715f5d09a5Sjsing              27787600, -14772189, 28944400, -1550024},
13725f5d09a5Sjsing             {16568933, 4717097, -11556148, -1102322, 15682896, -11807043,
13735f5d09a5Sjsing              16354577, -11775962, 7689662, 11199574},
13745f5d09a5Sjsing             {30464156, -5976125, -11779434, -15670865, 23220365, 15915852,
13755f5d09a5Sjsing              7512774, 10017326, -17749093, -9920357},
13765f5d09a5Sjsing         },
13775f5d09a5Sjsing         {
13785f5d09a5Sjsing             {-17036878, 13921892, 10945806, -6033431, 27105052, -16084379,
13795f5d09a5Sjsing              -28926210, 15006023, 3284568, -6276540},
13805f5d09a5Sjsing             {23599295, -8306047, -11193664, -7687416, 13236774, 10506355,
13815f5d09a5Sjsing              7464579, 9656445, 13059162, 10374397},
13825f5d09a5Sjsing             {7798556, 16710257, 3033922, 2874086, 28997861, 2835604, 32406664,
13835f5d09a5Sjsing              -3839045, -641708, -101325},
13845f5d09a5Sjsing         },
13855f5d09a5Sjsing         {
13865f5d09a5Sjsing             {10861363, 11473154, 27284546, 1981175, -30064349, 12577861,
13875f5d09a5Sjsing              32867885, 14515107, -15438304, 10819380},
13885f5d09a5Sjsing             {4708026, 6336745, 20377586, 9066809, -11272109, 6594696, -25653668,
13895f5d09a5Sjsing              12483688, -12668491, 5581306},
13905f5d09a5Sjsing             {19563160, 16186464, -29386857, 4097519, 10237984, -4348115,
13915f5d09a5Sjsing              28542350, 13850243, -23678021, -15815942},
13925f5d09a5Sjsing         },
13935f5d09a5Sjsing         {
13945f5d09a5Sjsing             {-15371964, -12862754, 32573250, 4720197, -26436522, 5875511,
13955f5d09a5Sjsing              -19188627, -15224819, -9818940, -12085777},
13965f5d09a5Sjsing             {-8549212, 109983, 15149363, 2178705, 22900618, 4543417, 3044240,
13975f5d09a5Sjsing              -15689887, 1762328, 14866737},
13985f5d09a5Sjsing             {-18199695, -15951423, -10473290, 1707278, -17185920, 3916101,
13995f5d09a5Sjsing              -28236412, 3959421, 27914454, 4383652},
14005f5d09a5Sjsing         },
14015f5d09a5Sjsing         {
14025f5d09a5Sjsing             {5153746, 9909285, 1723747, -2777874, 30523605, 5516873, 19480852,
14035f5d09a5Sjsing              5230134, -23952439, -15175766},
14045f5d09a5Sjsing             {-30269007, -3463509, 7665486, 10083793, 28475525, 1649722,
14055f5d09a5Sjsing              20654025, 16520125, 30598449, 7715701},
14065f5d09a5Sjsing             {28881845, 14381568, 9657904, 3680757, -20181635, 7843316,
14075f5d09a5Sjsing              -31400660, 1370708, 29794553, -1409300},
14085f5d09a5Sjsing         },
14095f5d09a5Sjsing         {
14105f5d09a5Sjsing             {14499471, -2729599, -33191113, -4254652, 28494862, 14271267,
14115f5d09a5Sjsing              30290735, 10876454, -33154098, 2381726},
14125f5d09a5Sjsing             {-7195431, -2655363, -14730155, 462251, -27724326, 3941372,
14135f5d09a5Sjsing              -6236617, 3696005, -32300832, 15351955},
14145f5d09a5Sjsing             {27431194, 8222322, 16448760, -3907995, -18707002, 11938355,
14155f5d09a5Sjsing              -32961401, -2970515, 29551813, 10109425},
14165f5d09a5Sjsing         },
14175f5d09a5Sjsing     },
14185f5d09a5Sjsing     {
14195f5d09a5Sjsing         {
14205f5d09a5Sjsing             {-13657040, -13155431, -31283750, 11777098, 21447386, 6519384,
14215f5d09a5Sjsing              -2378284, -1627556, 10092783, -4764171},
14225f5d09a5Sjsing             {27939166, 14210322, 4677035, 16277044, -22964462, -12398139,
14235f5d09a5Sjsing              -32508754, 12005538, -17810127, 12803510},
14245f5d09a5Sjsing             {17228999, -15661624, -1233527, 300140, -1224870, -11714777,
14255f5d09a5Sjsing              30364213, -9038194, 18016357, 4397660},
14265f5d09a5Sjsing         },
14275f5d09a5Sjsing         {
14285f5d09a5Sjsing             {-10958843, -7690207, 4776341, -14954238, 27850028, -15602212,
14295f5d09a5Sjsing              -26619106, 14544525, -17477504, 982639},
14305f5d09a5Sjsing             {29253598, 15796703, -2863982, -9908884, 10057023, 3163536, 7332899,
14315f5d09a5Sjsing              -4120128, -21047696, 9934963},
14325f5d09a5Sjsing             {5793303, 16271923, -24131614, -10116404, 29188560, 1206517,
14335f5d09a5Sjsing              -14747930, 4559895, -30123922, -10897950},
14345f5d09a5Sjsing         },
14355f5d09a5Sjsing         {
14365f5d09a5Sjsing             {-27643952, -11493006, 16282657, -11036493, 28414021, -15012264,
14375f5d09a5Sjsing              24191034, 4541697, -13338309, 5500568},
14385f5d09a5Sjsing             {12650548, -1497113, 9052871, 11355358, -17680037, -8400164,
14395f5d09a5Sjsing              -17430592, 12264343, 10874051, 13524335},
14405f5d09a5Sjsing             {25556948, -3045990, 714651, 2510400, 23394682, -10415330, 33119038,
14415f5d09a5Sjsing              5080568, -22528059, 5376628},
14425f5d09a5Sjsing         },
14435f5d09a5Sjsing         {
14445f5d09a5Sjsing             {-26088264, -4011052, -17013699, -3537628, -6726793, 1920897,
14455f5d09a5Sjsing              -22321305, -9447443, 4535768, 1569007},
14465f5d09a5Sjsing             {-2255422, 14606630, -21692440, -8039818, 28430649, 8775819,
14475f5d09a5Sjsing              -30494562, 3044290, 31848280, 12543772},
14485f5d09a5Sjsing             {-22028579, 2943893, -31857513, 6777306, 13784462, -4292203,
14495f5d09a5Sjsing              -27377195, -2062731, 7718482, 14474653},
14505f5d09a5Sjsing         },
14515f5d09a5Sjsing         {
14525f5d09a5Sjsing             {2385315, 2454213, -22631320, 46603, -4437935, -15680415, 656965,
14535f5d09a5Sjsing              -7236665, 24316168, -5253567},
14545f5d09a5Sjsing             {13741529, 10911568, -33233417, -8603737, -20177830, -1033297,
14555f5d09a5Sjsing              33040651, -13424532, -20729456, 8321686},
14565f5d09a5Sjsing             {21060490, -2212744, 15712757, -4336099, 1639040, 10656336,
14575f5d09a5Sjsing              23845965, -11874838, -9984458, 608372},
14585f5d09a5Sjsing         },
14595f5d09a5Sjsing         {
14605f5d09a5Sjsing             {-13672732, -15087586, -10889693, -7557059, -6036909, 11305547,
14615f5d09a5Sjsing              1123968, -6780577, 27229399, 23887},
14625f5d09a5Sjsing             {-23244140, -294205, -11744728, 14712571, -29465699, -2029617,
14635f5d09a5Sjsing              12797024, -6440308, -1633405, 16678954},
14645f5d09a5Sjsing             {-29500620, 4770662, -16054387, 14001338, 7830047, 9564805,
14655f5d09a5Sjsing              -1508144, -4795045, -17169265, 4904953},
14665f5d09a5Sjsing         },
14675f5d09a5Sjsing         {
14685f5d09a5Sjsing             {24059557, 14617003, 19037157, -15039908, 19766093, -14906429,
14695f5d09a5Sjsing              5169211, 16191880, 2128236, -4326833},
14705f5d09a5Sjsing             {-16981152, 4124966, -8540610, -10653797, 30336522, -14105247,
14715f5d09a5Sjsing              -29806336, 916033, -6882542, -2986532},
14725f5d09a5Sjsing             {-22630907, 12419372, -7134229, -7473371, -16478904, 16739175,
14735f5d09a5Sjsing              285431, 2763829, 15736322, 4143876},
14745f5d09a5Sjsing         },
14755f5d09a5Sjsing         {
14765f5d09a5Sjsing             {2379352, 11839345, -4110402, -5988665, 11274298, 794957, 212801,
14775f5d09a5Sjsing              -14594663, 23527084, -16458268},
14785f5d09a5Sjsing             {33431127, -11130478, -17838966, -15626900, 8909499, 8376530,
14795f5d09a5Sjsing              -32625340, 4087881, -15188911, -14416214},
14805f5d09a5Sjsing             {1767683, 7197987, -13205226, -2022635, -13091350, 448826, 5799055,
14815f5d09a5Sjsing              4357868, -4774191, -16323038},
14825f5d09a5Sjsing         },
14835f5d09a5Sjsing     },
14845f5d09a5Sjsing     {
14855f5d09a5Sjsing         {
14865f5d09a5Sjsing             {6721966, 13833823, -23523388, -1551314, 26354293, -11863321,
14875f5d09a5Sjsing              23365147, -3949732, 7390890, 2759800},
14885f5d09a5Sjsing             {4409041, 2052381, 23373853, 10530217, 7676779, -12885954, 21302353,
14895f5d09a5Sjsing              -4264057, 1244380, -12919645},
14905f5d09a5Sjsing             {-4421239, 7169619, 4982368, -2957590, 30256825, -2777540, 14086413,
14915f5d09a5Sjsing              9208236, 15886429, 16489664},
14925f5d09a5Sjsing         },
14935f5d09a5Sjsing         {
14945f5d09a5Sjsing             {1996075, 10375649, 14346367, 13311202, -6874135, -16438411,
14955f5d09a5Sjsing              -13693198, 398369, -30606455, -712933},
14965f5d09a5Sjsing             {-25307465, 9795880, -2777414, 14878809, -33531835, 14780363,
14975f5d09a5Sjsing              13348553, 12076947, -30836462, 5113182},
14985f5d09a5Sjsing             {-17770784, 11797796, 31950843, 13929123, -25888302, 12288344,
14995f5d09a5Sjsing              -30341101, -7336386, 13847711, 5387222},
15005f5d09a5Sjsing         },
15015f5d09a5Sjsing         {
15025f5d09a5Sjsing             {-18582163, -3416217, 17824843, -2340966, 22744343, -10442611,
15035f5d09a5Sjsing              8763061, 3617786, -19600662, 10370991},
15045f5d09a5Sjsing             {20246567, -14369378, 22358229, -543712, 18507283, -10413996,
15055f5d09a5Sjsing              14554437, -8746092, 32232924, 16763880},
15065f5d09a5Sjsing             {9648505, 10094563, 26416693, 14745928, -30374318, -6472621,
15075f5d09a5Sjsing              11094161, 15689506, 3140038, -16510092},
15085f5d09a5Sjsing         },
15095f5d09a5Sjsing         {
15105f5d09a5Sjsing             {-16160072, 5472695, 31895588, 4744994, 8823515, 10365685,
15115f5d09a5Sjsing              -27224800, 9448613, -28774454, 366295},
15125f5d09a5Sjsing             {19153450, 11523972, -11096490, -6503142, -24647631, 5420647,
15135f5d09a5Sjsing              28344573, 8041113, 719605, 11671788},
15145f5d09a5Sjsing             {8678025, 2694440, -6808014, 2517372, 4964326, 11152271, -15432916,
15155f5d09a5Sjsing              -15266516, 27000813, -10195553},
15165f5d09a5Sjsing         },
15175f5d09a5Sjsing         {
15185f5d09a5Sjsing             {-15157904, 7134312, 8639287, -2814877, -7235688, 10421742, 564065,
15195f5d09a5Sjsing              5336097, 6750977, -14521026},
15205f5d09a5Sjsing             {11836410, -3979488, 26297894, 16080799, 23455045, 15735944,
15215f5d09a5Sjsing              1695823, -8819122, 8169720, 16220347},
15225f5d09a5Sjsing             {-18115838, 8653647, 17578566, -6092619, -8025777, -16012763,
15235f5d09a5Sjsing              -11144307, -2627664, -5990708, -14166033},
15245f5d09a5Sjsing         },
15255f5d09a5Sjsing         {
15265f5d09a5Sjsing             {-23308498, -10968312, 15213228, -10081214, -30853605, -11050004,
15275f5d09a5Sjsing              27884329, 2847284, 2655861, 1738395},
15285f5d09a5Sjsing             {-27537433, -14253021, -25336301, -8002780, -9370762, 8129821,
15295f5d09a5Sjsing              21651608, -3239336, -19087449, -11005278},
15305f5d09a5Sjsing             {1533110, 3437855, 23735889, 459276, 29970501, 11335377, 26030092,
15315f5d09a5Sjsing              5821408, 10478196, 8544890},
15325f5d09a5Sjsing         },
15335f5d09a5Sjsing         {
15345f5d09a5Sjsing             {32173121, -16129311, 24896207, 3921497, 22579056, -3410854,
15355f5d09a5Sjsing              19270449, 12217473, 17789017, -3395995},
15365f5d09a5Sjsing             {-30552961, -2228401, -15578829, -10147201, 13243889, 517024,
15375f5d09a5Sjsing              15479401, -3853233, 30460520, 1052596},
15385f5d09a5Sjsing             {-11614875, 13323618, 32618793, 8175907, -15230173, 12596687,
15395f5d09a5Sjsing              27491595, -4612359, 3179268, -9478891},
15405f5d09a5Sjsing         },
15415f5d09a5Sjsing         {
15425f5d09a5Sjsing             {31947069, -14366651, -4640583, -15339921, -15125977, -6039709,
15435f5d09a5Sjsing              -14756777, -16411740, 19072640, -9511060},
15445f5d09a5Sjsing             {11685058, 11822410, 3158003, -13952594, 33402194, -4165066,
15455f5d09a5Sjsing              5977896, -5215017, 473099, 5040608},
15465f5d09a5Sjsing             {-20290863, 8198642, -27410132, 11602123, 1290375, -2799760,
15475f5d09a5Sjsing              28326862, 1721092, -19558642, -3131606},
15485f5d09a5Sjsing         },
15495f5d09a5Sjsing     },
15505f5d09a5Sjsing     {
15515f5d09a5Sjsing         {
15525f5d09a5Sjsing             {7881532, 10687937, 7578723, 7738378, -18951012, -2553952, 21820786,
15535f5d09a5Sjsing              8076149, -27868496, 11538389},
15545f5d09a5Sjsing             {-19935666, 3899861, 18283497, -6801568, -15728660, -11249211,
15555f5d09a5Sjsing              8754525, 7446702, -5676054, 5797016},
15565f5d09a5Sjsing             {-11295600, -3793569, -15782110, -7964573, 12708869, -8456199,
15575f5d09a5Sjsing              2014099, -9050574, -2369172, -5877341},
15585f5d09a5Sjsing         },
15595f5d09a5Sjsing         {
15605f5d09a5Sjsing             {-22472376, -11568741, -27682020, 1146375, 18956691, 16640559,
15615f5d09a5Sjsing              1192730, -3714199, 15123619, 10811505},
15625f5d09a5Sjsing             {14352098, -3419715, -18942044, 10822655, 32750596, 4699007, -70363,
15635f5d09a5Sjsing              15776356, -28886779, -11974553},
15645f5d09a5Sjsing             {-28241164, -8072475, -4978962, -5315317, 29416931, 1847569,
15655f5d09a5Sjsing              -20654173, -16484855, 4714547, -9600655},
15665f5d09a5Sjsing         },
15675f5d09a5Sjsing         {
15685f5d09a5Sjsing             {15200332, 8368572, 19679101, 15970074, -31872674, 1959451,
15695f5d09a5Sjsing              24611599, -4543832, -11745876, 12340220},
15705f5d09a5Sjsing             {12876937, -10480056, 33134381, 6590940, -6307776, 14872440,
15715f5d09a5Sjsing              9613953, 8241152, 15370987, 9608631},
15725f5d09a5Sjsing             {-4143277, -12014408, 8446281, -391603, 4407738, 13629032, -7724868,
15735f5d09a5Sjsing              15866074, -28210621, -8814099},
15745f5d09a5Sjsing         },
15755f5d09a5Sjsing         {
15765f5d09a5Sjsing             {26660628, -15677655, 8393734, 358047, -7401291, 992988, -23904233,
15775f5d09a5Sjsing              858697, 20571223, 8420556},
15785f5d09a5Sjsing             {14620715, 13067227, -15447274, 8264467, 14106269, 15080814,
15795f5d09a5Sjsing              33531827, 12516406, -21574435, -12476749},
15805f5d09a5Sjsing             {236881, 10476226, 57258, -14677024, 6472998, 2466984, 17258519,
15815f5d09a5Sjsing              7256740, 8791136, 15069930},
15825f5d09a5Sjsing         },
15835f5d09a5Sjsing         {
15845f5d09a5Sjsing             {1276410, -9371918, 22949635, -16322807, -23493039, -5702186,
15855f5d09a5Sjsing              14711875, 4874229, -30663140, -2331391},
15865f5d09a5Sjsing             {5855666, 4990204, -13711848, 7294284, -7804282, 1924647, -1423175,
15875f5d09a5Sjsing              -7912378, -33069337, 9234253},
15885f5d09a5Sjsing             {20590503, -9018988, 31529744, -7352666, -2706834, 10650548,
15895f5d09a5Sjsing              31559055, -11609587, 18979186, 13396066},
15905f5d09a5Sjsing         },
15915f5d09a5Sjsing         {
15925f5d09a5Sjsing             {24474287, 4968103, 22267082, 4407354, 24063882, -8325180,
15935f5d09a5Sjsing              -18816887, 13594782, 33514650, 7021958},
15945f5d09a5Sjsing             {-11566906, -6565505, -21365085, 15928892, -26158305, 4315421,
15955f5d09a5Sjsing              -25948728, -3916677, -21480480, 12868082},
15965f5d09a5Sjsing             {-28635013, 13504661, 19988037, -2132761, 21078225, 6443208,
15975f5d09a5Sjsing              -21446107, 2244500, -12455797, -8089383},
15985f5d09a5Sjsing         },
15995f5d09a5Sjsing         {
16005f5d09a5Sjsing             {-30595528, 13793479, -5852820, 319136, -25723172, -6263899,
16015f5d09a5Sjsing              33086546, 8957937, -15233648, 5540521},
16025f5d09a5Sjsing             {-11630176, -11503902, -8119500, -7643073, 2620056, 1022908,
16035f5d09a5Sjsing              -23710744, -1568984, -16128528, -14962807},
16045f5d09a5Sjsing             {23152971, 775386, 27395463, 14006635, -9701118, 4649512, 1689819,
16055f5d09a5Sjsing              892185, -11513277, -15205948},
16065f5d09a5Sjsing         },
16075f5d09a5Sjsing         {
16085f5d09a5Sjsing             {9770129, 9586738, 26496094, 4324120, 1556511, -3550024, 27453819,
16095f5d09a5Sjsing              4763127, -19179614, 5867134},
16105f5d09a5Sjsing             {-32765025, 1927590, 31726409, -4753295, 23962434, -16019500,
16115f5d09a5Sjsing              27846559, 5931263, -29749703, -16108455},
16125f5d09a5Sjsing             {27461885, -2977536, 22380810, 1815854, -23033753, -3031938,
16135f5d09a5Sjsing              7283490, -15148073, -19526700, 7734629},
16145f5d09a5Sjsing         },
16155f5d09a5Sjsing     },
16165f5d09a5Sjsing     {
16175f5d09a5Sjsing         {
16185f5d09a5Sjsing             {-8010264, -9590817, -11120403, 6196038, 29344158, -13430885,
16195f5d09a5Sjsing              7585295, -3176626, 18549497, 15302069},
16205f5d09a5Sjsing             {-32658337, -6171222, -7672793, -11051681, 6258878, 13504381,
16215f5d09a5Sjsing              10458790, -6418461, -8872242, 8424746},
16225f5d09a5Sjsing             {24687205, 8613276, -30667046, -3233545, 1863892, -1830544,
16235f5d09a5Sjsing              19206234, 7134917, -11284482, -828919},
16245f5d09a5Sjsing         },
16255f5d09a5Sjsing         {
16265f5d09a5Sjsing             {11334899, -9218022, 8025293, 12707519, 17523892, -10476071,
16275f5d09a5Sjsing              10243738, -14685461, -5066034, 16498837},
16285f5d09a5Sjsing             {8911542, 6887158, -9584260, -6958590, 11145641, -9543680, 17303925,
16295f5d09a5Sjsing              -14124238, 6536641, 10543906},
16305f5d09a5Sjsing             {-28946384, 15479763, -17466835, 568876, -1497683, 11223454,
16315f5d09a5Sjsing              -2669190, -16625574, -27235709, 8876771},
16325f5d09a5Sjsing         },
16335f5d09a5Sjsing         {
16345f5d09a5Sjsing             {-25742899, -12566864, -15649966, -846607, -33026686, -796288,
16355f5d09a5Sjsing              -33481822, 15824474, -604426, -9039817},
16365f5d09a5Sjsing             {10330056, 70051, 7957388, -9002667, 9764902, 15609756, 27698697,
16375f5d09a5Sjsing              -4890037, 1657394, 3084098},
16385f5d09a5Sjsing             {10477963, -7470260, 12119566, -13250805, 29016247, -5365589,
16395f5d09a5Sjsing              31280319, 14396151, -30233575, 15272409},
16405f5d09a5Sjsing         },
16415f5d09a5Sjsing         {
16425f5d09a5Sjsing             {-12288309, 3169463, 28813183, 16658753, 25116432, -5630466,
16435f5d09a5Sjsing              -25173957, -12636138, -25014757, 1950504},
16445f5d09a5Sjsing             {-26180358, 9489187, 11053416, -14746161, -31053720, 5825630,
16455f5d09a5Sjsing              -8384306, -8767532, 15341279, 8373727},
16465f5d09a5Sjsing             {28685821, 7759505, -14378516, -12002860, -31971820, 4079242,
16475f5d09a5Sjsing              298136, -10232602, -2878207, 15190420},
16485f5d09a5Sjsing         },
16495f5d09a5Sjsing         {
16505f5d09a5Sjsing             {-32932876, 13806336, -14337485, -15794431, -24004620, 10940928,
16515f5d09a5Sjsing              8669718, 2742393, -26033313, -6875003},
16525f5d09a5Sjsing             {-1580388, -11729417, -25979658, -11445023, -17411874, -10912854,
16535f5d09a5Sjsing              9291594, -16247779, -12154742, 6048605},
16545f5d09a5Sjsing             {-30305315, 14843444, 1539301, 11864366, 20201677, 1900163,
16555f5d09a5Sjsing              13934231, 5128323, 11213262, 9168384},
16565f5d09a5Sjsing         },
16575f5d09a5Sjsing         {
16585f5d09a5Sjsing             {-26280513, 11007847, 19408960, -940758, -18592965, -4328580,
16595f5d09a5Sjsing              -5088060, -11105150, 20470157, -16398701},
16605f5d09a5Sjsing             {-23136053, 9282192, 14855179, -15390078, -7362815, -14408560,
16615f5d09a5Sjsing              -22783952, 14461608, 14042978, 5230683},
16625f5d09a5Sjsing             {29969567, -2741594, -16711867, -8552442, 9175486, -2468974,
16635f5d09a5Sjsing              21556951, 3506042, -5933891, -12449708},
16645f5d09a5Sjsing         },
16655f5d09a5Sjsing         {
16665f5d09a5Sjsing             {-3144746, 8744661, 19704003, 4581278, -20430686, 6830683,
16675f5d09a5Sjsing              -21284170, 8971513, -28539189, 15326563},
16685f5d09a5Sjsing             {-19464629, 10110288, -17262528, -3503892, -23500387, 1355669,
16695f5d09a5Sjsing              -15523050, 15300988, -20514118, 9168260},
16705f5d09a5Sjsing             {-5353335, 4488613, -23803248, 16314347, 7780487, -15638939,
16715f5d09a5Sjsing              -28948358, 9601605, 33087103, -9011387},
16725f5d09a5Sjsing         },
16735f5d09a5Sjsing         {
16745f5d09a5Sjsing             {-19443170, -15512900, -20797467, -12445323, -29824447, 10229461,
16755f5d09a5Sjsing              -27444329, -15000531, -5996870, 15664672},
16765f5d09a5Sjsing             {23294591, -16632613, -22650781, -8470978, 27844204, 11461195,
16775f5d09a5Sjsing              13099750, -2460356, 18151676, 13417686},
16785f5d09a5Sjsing             {-24722913, -4176517, -31150679, 5988919, -26858785, 6685065,
16795f5d09a5Sjsing              1661597, -12551441, 15271676, -15452665},
16805f5d09a5Sjsing         },
16815f5d09a5Sjsing     },
16825f5d09a5Sjsing     {
16835f5d09a5Sjsing         {
16845f5d09a5Sjsing             {11433042, -13228665, 8239631, -5279517, -1985436, -725718,
16855f5d09a5Sjsing              -18698764, 2167544, -6921301, -13440182},
16865f5d09a5Sjsing             {-31436171, 15575146, 30436815, 12192228, -22463353, 9395379,
16875f5d09a5Sjsing              -9917708, -8638997, 12215110, 12028277},
16885f5d09a5Sjsing             {14098400, 6555944, 23007258, 5757252, -15427832, -12950502,
16895f5d09a5Sjsing              30123440, 4617780, -16900089, -655628},
16905f5d09a5Sjsing         },
16915f5d09a5Sjsing         {
16925f5d09a5Sjsing             {-4026201, -15240835, 11893168, 13718664, -14809462, 1847385,
16935f5d09a5Sjsing              -15819999, 10154009, 23973261, -12684474},
16945f5d09a5Sjsing             {-26531820, -3695990, -1908898, 2534301, -31870557, -16550355,
16955f5d09a5Sjsing              18341390, -11419951, 32013174, -10103539},
16965f5d09a5Sjsing             {-25479301, 10876443, -11771086, -14625140, -12369567, 1838104,
16975f5d09a5Sjsing              21911214, 6354752, 4425632, -837822},
16985f5d09a5Sjsing         },
16995f5d09a5Sjsing         {
17005f5d09a5Sjsing             {-10433389, -14612966, 22229858, -3091047, -13191166, 776729,
17015f5d09a5Sjsing              -17415375, -12020462, 4725005, 14044970},
17025f5d09a5Sjsing             {19268650, -7304421, 1555349, 8692754, -21474059, -9910664, 6347390,
17035f5d09a5Sjsing              -1411784, -19522291, -16109756},
17045f5d09a5Sjsing             {-24864089, 12986008, -10898878, -5558584, -11312371, -148526,
17055f5d09a5Sjsing              19541418, 8180106, 9282262, 10282508},
17065f5d09a5Sjsing         },
17075f5d09a5Sjsing         {
17085f5d09a5Sjsing             {-26205082, 4428547, -8661196, -13194263, 4098402, -14165257,
17095f5d09a5Sjsing              15522535, 8372215, 5542595, -10702683},
17105f5d09a5Sjsing             {-10562541, 14895633, 26814552, -16673850, -17480754, -2489360,
17115f5d09a5Sjsing              -2781891, 6993761, -18093885, 10114655},
17125f5d09a5Sjsing             {-20107055, -929418, 31422704, 10427861, -7110749, 6150669,
17135f5d09a5Sjsing              -29091755, -11529146, 25953725, -106158},
17145f5d09a5Sjsing         },
17155f5d09a5Sjsing         {
17165f5d09a5Sjsing             {-4234397, -8039292, -9119125, 3046000, 2101609, -12607294,
17175f5d09a5Sjsing              19390020, 6094296, -3315279, 12831125},
17185f5d09a5Sjsing             {-15998678, 7578152, 5310217, 14408357, -33548620, -224739,
17195f5d09a5Sjsing              31575954, 6326196, 7381791, -2421839},
17205f5d09a5Sjsing             {-20902779, 3296811, 24736065, -16328389, 18374254, 7318640,
17215f5d09a5Sjsing              6295303, 8082724, -15362489, 12339664},
17225f5d09a5Sjsing         },
17235f5d09a5Sjsing         {
17245f5d09a5Sjsing             {27724736, 2291157, 6088201, -14184798, 1792727, 5857634, 13848414,
17255f5d09a5Sjsing              15768922, 25091167, 14856294},
17265f5d09a5Sjsing             {-18866652, 8331043, 24373479, 8541013, -701998, -9269457, 12927300,
17275f5d09a5Sjsing              -12695493, -22182473, -9012899},
17285f5d09a5Sjsing             {-11423429, -5421590, 11632845, 3405020, 30536730, -11674039,
17295f5d09a5Sjsing              -27260765, 13866390, 30146206, 9142070},
17305f5d09a5Sjsing         },
17315f5d09a5Sjsing         {
17325f5d09a5Sjsing             {3924129, -15307516, -13817122, -10054960, 12291820, -668366,
17335f5d09a5Sjsing              -27702774, 9326384, -8237858, 4171294},
17345f5d09a5Sjsing             {-15921940, 16037937, 6713787, 16606682, -21612135, 2790944,
17355f5d09a5Sjsing              26396185, 3731949, 345228, -5462949},
17365f5d09a5Sjsing             {-21327538, 13448259, 25284571, 1143661, 20614966, -8849387,
17375f5d09a5Sjsing              2031539, -12391231, -16253183, -13582083},
17385f5d09a5Sjsing         },
17395f5d09a5Sjsing         {
17405f5d09a5Sjsing             {31016211, -16722429, 26371392, -14451233, -5027349, 14854137,
17415f5d09a5Sjsing              17477601, 3842657, 28012650, -16405420},
17425f5d09a5Sjsing             {-5075835, 9368966, -8562079, -4600902, -15249953, 6970560,
17435f5d09a5Sjsing              -9189873, 16292057, -8867157, 3507940},
17445f5d09a5Sjsing             {29439664, 3537914, 23333589, 6997794, -17555561, -11018068,
17455f5d09a5Sjsing              -15209202, -15051267, -9164929, 6580396},
17465f5d09a5Sjsing         },
17475f5d09a5Sjsing     },
17485f5d09a5Sjsing     {
17495f5d09a5Sjsing         {
17505f5d09a5Sjsing             {-12185861, -7679788, 16438269, 10826160, -8696817, -6235611,
17515f5d09a5Sjsing              17860444, -9273846, -2095802, 9304567},
17525f5d09a5Sjsing             {20714564, -4336911, 29088195, 7406487, 11426967, -5095705,
17535f5d09a5Sjsing              14792667, -14608617, 5289421, -477127},
17545f5d09a5Sjsing             {-16665533, -10650790, -6160345, -13305760, 9192020, -1802462,
17555f5d09a5Sjsing              17271490, 12349094, 26939669, -3752294},
17565f5d09a5Sjsing         },
17575f5d09a5Sjsing         {
17585f5d09a5Sjsing             {-12889898, 9373458, 31595848, 16374215, 21471720, 13221525,
17595f5d09a5Sjsing              -27283495, -12348559, -3698806, 117887},
17605f5d09a5Sjsing             {22263325, -6560050, 3984570, -11174646, -15114008, -566785,
17615f5d09a5Sjsing              28311253, 5358056, -23319780, 541964},
17625f5d09a5Sjsing             {16259219, 3261970, 2309254, -15534474, -16885711, -4581916,
17635f5d09a5Sjsing              24134070, -16705829, -13337066, -13552195},
17645f5d09a5Sjsing         },
17655f5d09a5Sjsing         {
17665f5d09a5Sjsing             {9378160, -13140186, -22845982, -12745264, 28198281, -7244098,
17675f5d09a5Sjsing              -2399684, -717351, 690426, 14876244},
17685f5d09a5Sjsing             {24977353, -314384, -8223969, -13465086, 28432343, -1176353,
17695f5d09a5Sjsing              -13068804, -12297348, -22380984, 6618999},
17705f5d09a5Sjsing             {-1538174, 11685646, 12944378, 13682314, -24389511, -14413193,
17715f5d09a5Sjsing              8044829, -13817328, 32239829, -5652762},
17725f5d09a5Sjsing         },
17735f5d09a5Sjsing         {
17745f5d09a5Sjsing             {-18603066, 4762990, -926250, 8885304, -28412480, -3187315, 9781647,
17755f5d09a5Sjsing              -10350059, 32779359, 5095274},
17765f5d09a5Sjsing             {-33008130, -5214506, -32264887, -3685216, 9460461, -9327423,
17775f5d09a5Sjsing              -24601656, 14506724, 21639561, -2630236},
17785f5d09a5Sjsing             {-16400943, -13112215, 25239338, 15531969, 3987758, -4499318,
17795f5d09a5Sjsing              -1289502, -6863535, 17874574, 558605},
17805f5d09a5Sjsing         },
17815f5d09a5Sjsing         {
17825f5d09a5Sjsing             {-13600129, 10240081, 9171883, 16131053, -20869254, 9599700,
17835f5d09a5Sjsing              33499487, 5080151, 2085892, 5119761},
17845f5d09a5Sjsing             {-22205145, -2519528, -16381601, 414691, -25019550, 2170430,
17855f5d09a5Sjsing              30634760, -8363614, -31999993, -5759884},
17865f5d09a5Sjsing             {-6845704, 15791202, 8550074, -1312654, 29928809, -12092256,
17875f5d09a5Sjsing              27534430, -7192145, -22351378, 12961482},
17885f5d09a5Sjsing         },
17895f5d09a5Sjsing         {
17905f5d09a5Sjsing             {-24492060, -9570771, 10368194, 11582341, -23397293, -2245287,
17915f5d09a5Sjsing              16533930, 8206996, -30194652, -5159638},
17925f5d09a5Sjsing             {-11121496, -3382234, 2307366, 6362031, -135455, 8868177, -16835630,
17935f5d09a5Sjsing              7031275, 7589640, 8945490},
17945f5d09a5Sjsing             {-32152748, 8917967, 6661220, -11677616, -1192060, -15793393,
17955f5d09a5Sjsing              7251489, -11182180, 24099109, -14456170},
17965f5d09a5Sjsing         },
17975f5d09a5Sjsing         {
17985f5d09a5Sjsing             {5019558, -7907470, 4244127, -14714356, -26933272, 6453165,
17995f5d09a5Sjsing              -19118182, -13289025, -6231896, -10280736},
18005f5d09a5Sjsing             {10853594, 10721687, 26480089, 5861829, -22995819, 1972175,
18015f5d09a5Sjsing              -1866647, -10557898, -3363451, -6441124},
18025f5d09a5Sjsing             {-17002408, 5906790, 221599, -6563147, 7828208, -13248918, 24362661,
18035f5d09a5Sjsing              -2008168, -13866408, 7421392},
18045f5d09a5Sjsing         },
18055f5d09a5Sjsing         {
18065f5d09a5Sjsing             {8139927, -6546497, 32257646, -5890546, 30375719, 1886181,
18075f5d09a5Sjsing              -21175108, 15441252, 28826358, -4123029},
18085f5d09a5Sjsing             {6267086, 9695052, 7709135, -16603597, -32869068, -1886135,
18095f5d09a5Sjsing              14795160, -7840124, 13746021, -1742048},
18105f5d09a5Sjsing             {28584902, 7787108, -6732942, -15050729, 22846041, -7571236,
18115f5d09a5Sjsing              -3181936, -363524, 4771362, -8419958},
18125f5d09a5Sjsing         },
18135f5d09a5Sjsing     },
18145f5d09a5Sjsing     {
18155f5d09a5Sjsing         {
18165f5d09a5Sjsing             {24949256, 6376279, -27466481, -8174608, -18646154, -9930606,
18175f5d09a5Sjsing              33543569, -12141695, 3569627, 11342593},
18185f5d09a5Sjsing             {26514989, 4740088, 27912651, 3697550, 19331575, -11472339, 6809886,
18195f5d09a5Sjsing              4608608, 7325975, -14801071},
18205f5d09a5Sjsing             {-11618399, -14554430, -24321212, 7655128, -1369274, 5214312,
18215f5d09a5Sjsing              -27400540, 10258390, -17646694, -8186692},
18225f5d09a5Sjsing         },
18235f5d09a5Sjsing         {
18245f5d09a5Sjsing             {11431204, 15823007, 26570245, 14329124, 18029990, 4796082,
18255f5d09a5Sjsing              -31446179, 15580664, 9280358, -3973687},
18265f5d09a5Sjsing             {-160783, -10326257, -22855316, -4304997, -20861367, -13621002,
18275f5d09a5Sjsing              -32810901, -11181622, -15545091, 4387441},
18285f5d09a5Sjsing             {-20799378, 12194512, 3937617, -5805892, -27154820, 9340370,
18295f5d09a5Sjsing              -24513992, 8548137, 20617071, -7482001},
18305f5d09a5Sjsing         },
18315f5d09a5Sjsing         {
18325f5d09a5Sjsing             {-938825, -3930586, -8714311, 16124718, 24603125, -6225393,
18335f5d09a5Sjsing              -13775352, -11875822, 24345683, 10325460},
18345f5d09a5Sjsing             {-19855277, -1568885, -22202708, 8714034, 14007766, 6928528,
18355f5d09a5Sjsing              16318175, -1010689, 4766743, 3552007},
18365f5d09a5Sjsing             {-21751364, -16730916, 1351763, -803421, -4009670, 3950935, 3217514,
18375f5d09a5Sjsing              14481909, 10988822, -3994762},
18385f5d09a5Sjsing         },
18395f5d09a5Sjsing         {
18405f5d09a5Sjsing             {15564307, -14311570, 3101243, 5684148, 30446780, -8051356,
18415f5d09a5Sjsing              12677127, -6505343, -8295852, 13296005},
18425f5d09a5Sjsing             {-9442290, 6624296, -30298964, -11913677, -4670981, -2057379,
18435f5d09a5Sjsing              31521204, 9614054, -30000824, 12074674},
18445f5d09a5Sjsing             {4771191, -135239, 14290749, -13089852, 27992298, 14998318,
18455f5d09a5Sjsing              -1413936, -1556716, 29832613, -16391035},
18465f5d09a5Sjsing         },
18475f5d09a5Sjsing         {
18485f5d09a5Sjsing             {7064884, -7541174, -19161962, -5067537, -18891269, -2912736,
18495f5d09a5Sjsing              25825242, 5293297, -27122660, 13101590},
18505f5d09a5Sjsing             {-2298563, 2439670, -7466610, 1719965, -27267541, -16328445,
18515f5d09a5Sjsing              32512469, -5317593, -30356070, -4190957},
18525f5d09a5Sjsing             {-30006540, 10162316, -33180176, 3981723, -16482138, -13070044,
18535f5d09a5Sjsing              14413974, 9515896, 19568978, 9628812},
18545f5d09a5Sjsing         },
18555f5d09a5Sjsing         {
18565f5d09a5Sjsing             {33053803, 199357, 15894591, 1583059, 27380243, -4580435, -17838894,
18575f5d09a5Sjsing              -6106839, -6291786, 3437740},
18585f5d09a5Sjsing             {-18978877, 3884493, 19469877, 12726490, 15913552, 13614290,
18595f5d09a5Sjsing              -22961733, 70104, 7463304, 4176122},
18605f5d09a5Sjsing             {-27124001, 10659917, 11482427, -16070381, 12771467, -6635117,
18615f5d09a5Sjsing              -32719404, -5322751, 24216882, 5944158},
18625f5d09a5Sjsing         },
18635f5d09a5Sjsing         {
18645f5d09a5Sjsing             {8894125, 7450974, -2664149, -9765752, -28080517, -12389115,
18655f5d09a5Sjsing              19345746, 14680796, 11632993, 5847885},
18665f5d09a5Sjsing             {26942781, -2315317, 9129564, -4906607, 26024105, 11769399,
18675f5d09a5Sjsing              -11518837, 6367194, -9727230, 4782140},
18685f5d09a5Sjsing             {19916461, -4828410, -22910704, -11414391, 25606324, -5972441,
18695f5d09a5Sjsing              33253853, 8220911, 6358847, -1873857},
18705f5d09a5Sjsing         },
18715f5d09a5Sjsing         {
18725f5d09a5Sjsing             {801428, -2081702, 16569428, 11065167, 29875704, 96627, 7908388,
18735f5d09a5Sjsing              -4480480, -13538503, 1387155},
18745f5d09a5Sjsing             {19646058, 5720633, -11416706, 12814209, 11607948, 12749789,
18755f5d09a5Sjsing              14147075, 15156355, -21866831, 11835260},
18765f5d09a5Sjsing             {19299512, 1155910, 28703737, 14890794, 2925026, 7269399, 26121523,
18775f5d09a5Sjsing              15467869, -26560550, 5052483},
18785f5d09a5Sjsing         },
18795f5d09a5Sjsing     },
18805f5d09a5Sjsing     {
18815f5d09a5Sjsing         {
18825f5d09a5Sjsing             {-3017432, 10058206, 1980837, 3964243, 22160966, 12322533, -6431123,
18835f5d09a5Sjsing              -12618185, 12228557, -7003677},
18845f5d09a5Sjsing             {32944382, 14922211, -22844894, 5188528, 21913450, -8719943,
18855f5d09a5Sjsing              4001465, 13238564, -6114803, 8653815},
18865f5d09a5Sjsing             {22865569, -4652735, 27603668, -12545395, 14348958, 8234005,
18875f5d09a5Sjsing              24808405, 5719875, 28483275, 2841751},
18885f5d09a5Sjsing         },
18895f5d09a5Sjsing         {
18905f5d09a5Sjsing             {-16420968, -1113305, -327719, -12107856, 21886282, -15552774,
18915f5d09a5Sjsing              -1887966, -315658, 19932058, -12739203},
18925f5d09a5Sjsing             {-11656086, 10087521, -8864888, -5536143, -19278573, -3055912,
18935f5d09a5Sjsing              3999228, 13239134, -4777469, -13910208},
18945f5d09a5Sjsing             {1382174, -11694719, 17266790, 9194690, -13324356, 9720081,
18955f5d09a5Sjsing              20403944, 11284705, -14013818, 3093230},
18965f5d09a5Sjsing         },
18975f5d09a5Sjsing         {
18985f5d09a5Sjsing             {16650921, -11037932, -1064178, 1570629, -8329746, 7352753, -302424,
18995f5d09a5Sjsing              16271225, -24049421, -6691850},
19005f5d09a5Sjsing             {-21911077, -5927941, -4611316, -5560156, -31744103, -10785293,
19015f5d09a5Sjsing              24123614, 15193618, -21652117, -16739389},
19025f5d09a5Sjsing             {-9935934, -4289447, -25279823, 4372842, 2087473, 10399484,
19035f5d09a5Sjsing              31870908, 14690798, 17361620, 11864968},
19045f5d09a5Sjsing         },
19055f5d09a5Sjsing         {
19065f5d09a5Sjsing             {-11307610, 6210372, 13206574, 5806320, -29017692, -13967200,
19075f5d09a5Sjsing              -12331205, -7486601, -25578460, -16240689},
19085f5d09a5Sjsing             {14668462, -12270235, 26039039, 15305210, 25515617, 4542480,
19095f5d09a5Sjsing              10453892, 6577524, 9145645, -6443880},
19105f5d09a5Sjsing             {5974874, 3053895, -9433049, -10385191, -31865124, 3225009,
19115f5d09a5Sjsing              -7972642, 3936128, -5652273, -3050304},
19125f5d09a5Sjsing         },
19135f5d09a5Sjsing         {
19145f5d09a5Sjsing             {30625386, -4729400, -25555961, -12792866, -20484575, 7695099,
19155f5d09a5Sjsing              17097188, -16303496, -27999779, 1803632},
19165f5d09a5Sjsing             {-3553091, 9865099, -5228566, 4272701, -5673832, -16689700,
19175f5d09a5Sjsing              14911344, 12196514, -21405489, 7047412},
19185f5d09a5Sjsing             {20093277, 9920966, -11138194, -5343857, 13161587, 12044805,
19195f5d09a5Sjsing              -32856851, 4124601, -32343828, -10257566},
19205f5d09a5Sjsing         },
19215f5d09a5Sjsing         {
19225f5d09a5Sjsing             {-20788824, 14084654, -13531713, 7842147, 19119038, -13822605,
19235f5d09a5Sjsing              4752377, -8714640, -21679658, 2288038},
19245f5d09a5Sjsing             {-26819236, -3283715, 29965059, 3039786, -14473765, 2540457,
19255f5d09a5Sjsing              29457502, 14625692, -24819617, 12570232},
19265f5d09a5Sjsing             {-1063558, -11551823, 16920318, 12494842, 1278292, -5869109,
19275f5d09a5Sjsing              -21159943, -3498680, -11974704, 4724943},
19285f5d09a5Sjsing         },
19295f5d09a5Sjsing         {
19305f5d09a5Sjsing             {17960970, -11775534, -4140968, -9702530, -8876562, -1410617,
19315f5d09a5Sjsing              -12907383, -8659932, -29576300, 1903856},
19325f5d09a5Sjsing             {23134274, -14279132, -10681997, -1611936, 20684485, 15770816,
19335f5d09a5Sjsing              -12989750, 3190296, 26955097, 14109738},
19345f5d09a5Sjsing             {15308788, 5320727, -30113809, -14318877, 22902008, 7767164,
19355f5d09a5Sjsing              29425325, -11277562, 31960942, 11934971},
19365f5d09a5Sjsing         },
19375f5d09a5Sjsing         {
19385f5d09a5Sjsing             {-27395711, 8435796, 4109644, 12222639, -24627868, 14818669,
19395f5d09a5Sjsing              20638173, 4875028, 10491392, 1379718},
19405f5d09a5Sjsing             {-13159415, 9197841, 3875503, -8936108, -1383712, -5879801,
19415f5d09a5Sjsing              33518459, 16176658, 21432314, 12180697},
19425f5d09a5Sjsing             {-11787308, 11500838, 13787581, -13832590, -22430679, 10140205,
19435f5d09a5Sjsing              1465425, 12689540, -10301319, -13872883},
19445f5d09a5Sjsing         },
19455f5d09a5Sjsing     },
19465f5d09a5Sjsing     {
19475f5d09a5Sjsing         {
19485f5d09a5Sjsing             {5414091, -15386041, -21007664, 9643570, 12834970, 1186149,
19495f5d09a5Sjsing              -2622916, -1342231, 26128231, 6032912},
19505f5d09a5Sjsing             {-26337395, -13766162, 32496025, -13653919, 17847801, -12669156,
19515f5d09a5Sjsing              3604025, 8316894, -25875034, -10437358},
19525f5d09a5Sjsing             {3296484, 6223048, 24680646, -12246460, -23052020, 5903205,
19535f5d09a5Sjsing              -8862297, -4639164, 12376617, 3188849},
19545f5d09a5Sjsing         },
19555f5d09a5Sjsing         {
19565f5d09a5Sjsing             {29190488, -14659046, 27549113, -1183516, 3520066, -10697301,
19575f5d09a5Sjsing              32049515, -7309113, -16109234, -9852307},
19585f5d09a5Sjsing             {-14744486, -9309156, 735818, -598978, -20407687, -5057904,
19595f5d09a5Sjsing              25246078, -15795669, 18640741, -960977},
19605f5d09a5Sjsing             {-6928835, -16430795, 10361374, 5642961, 4910474, 12345252,
19615f5d09a5Sjsing              -31638386, -494430, 10530747, 1053335},
19625f5d09a5Sjsing         },
19635f5d09a5Sjsing         {
19645f5d09a5Sjsing             {-29265967, -14186805, -13538216, -12117373, -19457059, -10655384,
19655f5d09a5Sjsing              -31462369, -2948985, 24018831, 15026644},
19665f5d09a5Sjsing             {-22592535, -3145277, -2289276, 5953843, -13440189, 9425631,
19675f5d09a5Sjsing              25310643, 13003497, -2314791, -15145616},
19685f5d09a5Sjsing             {-27419985, -603321, -8043984, -1669117, -26092265, 13987819,
19695f5d09a5Sjsing              -27297622, 187899, -23166419, -2531735},
19705f5d09a5Sjsing         },
19715f5d09a5Sjsing         {
19725f5d09a5Sjsing             {-21744398, -13810475, 1844840, 5021428, -10434399, -15911473,
19735f5d09a5Sjsing              9716667, 16266922, -5070217, 726099},
19745f5d09a5Sjsing             {29370922, -6053998, 7334071, -15342259, 9385287, 2247707,
19755f5d09a5Sjsing              -13661962, -4839461, 30007388, -15823341},
19765f5d09a5Sjsing             {-936379, 16086691, 23751945, -543318, -1167538, -5189036, 9137109,
19775f5d09a5Sjsing              730663, 9835848, 4555336},
19785f5d09a5Sjsing         },
19795f5d09a5Sjsing         {
19805f5d09a5Sjsing             {-23376435, 1410446, -22253753, -12899614, 30867635, 15826977,
19815f5d09a5Sjsing              17693930, 544696, -11985298, 12422646},
19825f5d09a5Sjsing             {31117226, -12215734, -13502838, 6561947, -9876867, -12757670,
19835f5d09a5Sjsing              -5118685, -4096706, 29120153, 13924425},
19845f5d09a5Sjsing             {-17400879, -14233209, 19675799, -2734756, -11006962, -5858820,
19855f5d09a5Sjsing              -9383939, -11317700, 7240931, -237388},
19865f5d09a5Sjsing         },
19875f5d09a5Sjsing         {
19885f5d09a5Sjsing             {-31361739, -11346780, -15007447, -5856218, -22453340, -12152771,
19895f5d09a5Sjsing              1222336, 4389483, 3293637, -15551743},
19905f5d09a5Sjsing             {-16684801, -14444245, 11038544, 11054958, -13801175, -3338533,
19915f5d09a5Sjsing              -24319580, 7733547, 12796905, -6335822},
19925f5d09a5Sjsing             {-8759414, -10817836, -25418864, 10783769, -30615557, -9746811,
19935f5d09a5Sjsing              -28253339, 3647836, 3222231, -11160462},
19945f5d09a5Sjsing         },
19955f5d09a5Sjsing         {
19965f5d09a5Sjsing             {18606113, 1693100, -25448386, -15170272, 4112353, 10045021,
19975f5d09a5Sjsing              23603893, -2048234, -7550776, 2484985},
19985f5d09a5Sjsing             {9255317, -3131197, -12156162, -1004256, 13098013, -9214866,
19995f5d09a5Sjsing              16377220, -2102812, -19802075, -3034702},
20005f5d09a5Sjsing             {-22729289, 7496160, -5742199, 11329249, 19991973, -3347502,
20015f5d09a5Sjsing              -31718148, 9936966, -30097688, -10618797},
20025f5d09a5Sjsing         },
20035f5d09a5Sjsing         {
20045f5d09a5Sjsing             {21878590, -5001297, 4338336, 13643897, -3036865, 13160960,
20055f5d09a5Sjsing              19708896, 5415497, -7360503, -4109293},
20065f5d09a5Sjsing             {27736861, 10103576, 12500508, 8502413, -3413016, -9633558,
20075f5d09a5Sjsing              10436918, -1550276, -23659143, -8132100},
20085f5d09a5Sjsing             {19492550, -12104365, -29681976, -852630, -3208171, 12403437,
20095f5d09a5Sjsing              30066266, 8367329, 13243957, 8709688},
20105f5d09a5Sjsing         },
20115f5d09a5Sjsing     },
20125f5d09a5Sjsing     {
20135f5d09a5Sjsing         {
20145f5d09a5Sjsing             {12015105, 2801261, 28198131, 10151021, 24818120, -4743133,
20155f5d09a5Sjsing              -11194191, -5645734, 5150968, 7274186},
20165f5d09a5Sjsing             {2831366, -12492146, 1478975, 6122054, 23825128, -12733586,
20175f5d09a5Sjsing              31097299, 6083058, 31021603, -9793610},
20185f5d09a5Sjsing             {-2529932, -2229646, 445613, 10720828, -13849527, -11505937,
20195f5d09a5Sjsing              -23507731, 16354465, 15067285, -14147707},
20205f5d09a5Sjsing         },
20215f5d09a5Sjsing         {
20225f5d09a5Sjsing             {7840942, 14037873, -33364863, 15934016, -728213, -3642706,
20235f5d09a5Sjsing              21403988, 1057586, -19379462, -12403220},
20245f5d09a5Sjsing             {915865, -16469274, 15608285, -8789130, -24357026, 6060030,
20255f5d09a5Sjsing              -17371319, 8410997, -7220461, 16527025},
20265f5d09a5Sjsing             {32922597, -556987, 20336074, -16184568, 10903705, -5384487,
20275f5d09a5Sjsing              16957574, 52992, 23834301, 6588044},
20285f5d09a5Sjsing         },
20295f5d09a5Sjsing         {
20305f5d09a5Sjsing             {32752030, 11232950, 3381995, -8714866, 22652988, -10744103,
20315f5d09a5Sjsing              17159699, 16689107, -20314580, -1305992},
20325f5d09a5Sjsing             {-4689649, 9166776, -25710296, -10847306, 11576752, 12733943,
20335f5d09a5Sjsing              7924251, -2752281, 1976123, -7249027},
20345f5d09a5Sjsing             {21251222, 16309901, -2983015, -6783122, 30810597, 12967303, 156041,
20355f5d09a5Sjsing              -3371252, 12331345, -8237197},
20365f5d09a5Sjsing         },
20375f5d09a5Sjsing         {
20385f5d09a5Sjsing             {8651614, -4477032, -16085636, -4996994, 13002507, 2950805,
20395f5d09a5Sjsing              29054427, -5106970, 10008136, -4667901},
20405f5d09a5Sjsing             {31486080, 15114593, -14261250, 12951354, 14369431, -7387845,
20415f5d09a5Sjsing              16347321, -13662089, 8684155, -10532952},
20425f5d09a5Sjsing             {19443825, 11385320, 24468943, -9659068, -23919258, 2187569,
20435f5d09a5Sjsing              -26263207, -6086921, 31316348, 14219878},
20445f5d09a5Sjsing         },
20455f5d09a5Sjsing         {
20465f5d09a5Sjsing             {-28594490, 1193785, 32245219, 11392485, 31092169, 15722801,
20475f5d09a5Sjsing              27146014, 6992409, 29126555, 9207390},
20485f5d09a5Sjsing             {32382935, 1110093, 18477781, 11028262, -27411763, -7548111,
20495f5d09a5Sjsing              -4980517, 10843782, -7957600, -14435730},
20505f5d09a5Sjsing             {2814918, 7836403, 27519878, -7868156, -20894015, -11553689,
20515f5d09a5Sjsing              -21494559, 8550130, 28346258, 1994730},
20525f5d09a5Sjsing         },
20535f5d09a5Sjsing         {
20545f5d09a5Sjsing             {-19578299, 8085545, -14000519, -3948622, 2785838, -16231307,
20555f5d09a5Sjsing              -19516951, 7174894, 22628102, 8115180},
20565f5d09a5Sjsing             {-30405132, 955511, -11133838, -15078069, -32447087, -13278079,
20575f5d09a5Sjsing              -25651578, 3317160, -9943017, 930272},
20585f5d09a5Sjsing             {-15303681, -6833769, 28856490, 1357446, 23421993, 1057177,
20595f5d09a5Sjsing              24091212, -1388970, -22765376, -10650715},
20605f5d09a5Sjsing         },
20615f5d09a5Sjsing         {
20625f5d09a5Sjsing             {-22751231, -5303997, -12907607, -12768866, -15811511, -7797053,
20635f5d09a5Sjsing              -14839018, -16554220, -1867018, 8398970},
20645f5d09a5Sjsing             {-31969310, 2106403, -4736360, 1362501, 12813763, 16200670,
20655f5d09a5Sjsing              22981545, -6291273, 18009408, -15772772},
20665f5d09a5Sjsing             {-17220923, -9545221, -27784654, 14166835, 29815394, 7444469,
20675f5d09a5Sjsing              29551787, -3727419, 19288549, 1325865},
20685f5d09a5Sjsing         },
20695f5d09a5Sjsing         {
20705f5d09a5Sjsing             {15100157, -15835752, -23923978, -1005098, -26450192, 15509408,
20715f5d09a5Sjsing              12376730, -3479146, 33166107, -8042750},
20725f5d09a5Sjsing             {20909231, 13023121, -9209752, 16251778, -5778415, -8094914,
20735f5d09a5Sjsing              12412151, 10018715, 2213263, -13878373},
20745f5d09a5Sjsing             {32529814, -11074689, 30361439, -16689753, -9135940, 1513226,
20755f5d09a5Sjsing              22922121, 6382134, -5766928, 8371348},
20765f5d09a5Sjsing         },
20775f5d09a5Sjsing     },
20785f5d09a5Sjsing     {
20795f5d09a5Sjsing         {
20805f5d09a5Sjsing             {9923462, 11271500, 12616794, 3544722, -29998368, -1721626,
20815f5d09a5Sjsing              12891687, -8193132, -26442943, 10486144},
20825f5d09a5Sjsing             {-22597207, -7012665, 8587003, -8257861, 4084309, -12970062, 361726,
20835f5d09a5Sjsing              2610596, -23921530, -11455195},
20845f5d09a5Sjsing             {5408411, -1136691, -4969122, 10561668, 24145918, 14240566,
20855f5d09a5Sjsing              31319731, -4235541, 19985175, -3436086},
20865f5d09a5Sjsing         },
20875f5d09a5Sjsing         {
20885f5d09a5Sjsing             {-13994457, 16616821, 14549246, 3341099, 32155958, 13648976,
20895f5d09a5Sjsing              -17577068, 8849297, 65030, 8370684},
20905f5d09a5Sjsing             {-8320926, -12049626, 31204563, 5839400, -20627288, -1057277,
20915f5d09a5Sjsing              -19442942, 6922164, 12743482, -9800518},
20925f5d09a5Sjsing             {-2361371, 12678785, 28815050, 4759974, -23893047, 4884717,
20935f5d09a5Sjsing              23783145, 11038569, 18800704, 255233},
20945f5d09a5Sjsing         },
20955f5d09a5Sjsing         {
20965f5d09a5Sjsing             {-5269658, -1773886, 13957886, 7990715, 23132995, 728773, 13393847,
20975f5d09a5Sjsing              9066957, 19258688, -14753793},
20985f5d09a5Sjsing             {-2936654, -10827535, -10432089, 14516793, -3640786, 4372541,
20995f5d09a5Sjsing              -31934921, 2209390, -1524053, 2055794},
21005f5d09a5Sjsing             {580882, 16705327, 5468415, -2683018, -30926419, -14696000,
21015f5d09a5Sjsing              -7203346, -8994389, -30021019, 7394435},
21025f5d09a5Sjsing         },
21035f5d09a5Sjsing         {
21045f5d09a5Sjsing             {23838809, 1822728, -15738443, 15242727, 8318092, -3733104,
21055f5d09a5Sjsing              -21672180, -3492205, -4821741, 14799921},
21065f5d09a5Sjsing             {13345610, 9759151, 3371034, -16137791, 16353039, 8577942, 31129804,
21075f5d09a5Sjsing              13496856, -9056018, 7402518},
21085f5d09a5Sjsing             {2286874, -4435931, -20042458, -2008336, -13696227, 5038122,
21095f5d09a5Sjsing              11006906, -15760352, 8205061, 1607563},
21105f5d09a5Sjsing         },
21115f5d09a5Sjsing         {
21125f5d09a5Sjsing             {14414086, -8002132, 3331830, -3208217, 22249151, -5594188,
21135f5d09a5Sjsing              18364661, -2906958, 30019587, -9029278},
21145f5d09a5Sjsing             {-27688051, 1585953, -10775053, 931069, -29120221, -11002319,
21155f5d09a5Sjsing              -14410829, 12029093, 9944378, 8024},
21165f5d09a5Sjsing             {4368715, -3709630, 29874200, -15022983, -20230386, -11410704,
21175f5d09a5Sjsing              -16114594, -999085, -8142388, 5640030},
21185f5d09a5Sjsing         },
21195f5d09a5Sjsing         {
21205f5d09a5Sjsing             {10299610, 13746483, 11661824, 16234854, 7630238, 5998374, 9809887,
21215f5d09a5Sjsing              -16694564, 15219798, -14327783},
21225f5d09a5Sjsing             {27425505, -5719081, 3055006, 10660664, 23458024, 595578, -15398605,
21235f5d09a5Sjsing              -1173195, -18342183, 9742717},
21245f5d09a5Sjsing             {6744077, 2427284, 26042789, 2720740, -847906, 1118974, 32324614,
21255f5d09a5Sjsing              7406442, 12420155, 1994844},
21265f5d09a5Sjsing         },
21275f5d09a5Sjsing         {
21285f5d09a5Sjsing             {14012521, -5024720, -18384453, -9578469, -26485342, -3936439,
21295f5d09a5Sjsing              -13033478, -10909803, 24319929, -6446333},
21305f5d09a5Sjsing             {16412690, -4507367, 10772641, 15929391, -17068788, -4658621,
21315f5d09a5Sjsing              10555945, -10484049, -30102368, -4739048},
21325f5d09a5Sjsing             {22397382, -7767684, -9293161, -12792868, 17166287, -9755136,
21335f5d09a5Sjsing              -27333065, 6199366, 21880021, -12250760},
21345f5d09a5Sjsing         },
21355f5d09a5Sjsing         {
21365f5d09a5Sjsing             {-4283307, 5368523, -31117018, 8163389, -30323063, 3209128,
21375f5d09a5Sjsing              16557151, 8890729, 8840445, 4957760},
21385f5d09a5Sjsing             {-15447727, 709327, -6919446, -10870178, -29777922, 6522332,
21395f5d09a5Sjsing              -21720181, 12130072, -14796503, 5005757},
21405f5d09a5Sjsing             {-2114751, -14308128, 23019042, 15765735, -25269683, 6002752,
21415f5d09a5Sjsing              10183197, -13239326, -16395286, -2176112},
21425f5d09a5Sjsing         },
21435f5d09a5Sjsing     },
21445f5d09a5Sjsing     {
21455f5d09a5Sjsing         {
21465f5d09a5Sjsing             {-19025756, 1632005, 13466291, -7995100, -23640451, 16573537,
21475f5d09a5Sjsing              -32013908, -3057104, 22208662, 2000468},
21485f5d09a5Sjsing             {3065073, -1412761, -25598674, -361432, -17683065, -5703415,
21495f5d09a5Sjsing              -8164212, 11248527, -3691214, -7414184},
21505f5d09a5Sjsing             {10379208, -6045554, 8877319, 1473647, -29291284, -12507580,
21515f5d09a5Sjsing              16690915, 2553332, -3132688, 16400289},
21525f5d09a5Sjsing         },
21535f5d09a5Sjsing         {
21545f5d09a5Sjsing             {15716668, 1254266, -18472690, 7446274, -8448918, 6344164,
21555f5d09a5Sjsing              -22097271, -7285580, 26894937, 9132066},
21565f5d09a5Sjsing             {24158887, 12938817, 11085297, -8177598, -28063478, -4457083,
21575f5d09a5Sjsing              -30576463, 64452, -6817084, -2692882},
21585f5d09a5Sjsing             {13488534, 7794716, 22236231, 5989356, 25426474, -12578208, 2350710,
21595f5d09a5Sjsing              -3418511, -4688006, 2364226},
21605f5d09a5Sjsing         },
21615f5d09a5Sjsing         {
21625f5d09a5Sjsing             {16335052, 9132434, 25640582, 6678888, 1725628, 8517937, -11807024,
21635f5d09a5Sjsing              -11697457, 15445875, -7798101},
21645f5d09a5Sjsing             {29004207, -7867081, 28661402, -640412, -12794003, -7943086,
21655f5d09a5Sjsing              31863255, -4135540, -278050, -15759279},
21665f5d09a5Sjsing             {-6122061, -14866665, -28614905, 14569919, -10857999, -3591829,
21675f5d09a5Sjsing              10343412, -6976290, -29828287, -10815811},
21685f5d09a5Sjsing         },
21695f5d09a5Sjsing         {
21705f5d09a5Sjsing             {27081650, 3463984, 14099042, -4517604, 1616303, -6205604, 29542636,
21715f5d09a5Sjsing              15372179, 17293797, 960709},
21725f5d09a5Sjsing             {20263915, 11434237, -5765435, 11236810, 13505955, -10857102,
21735f5d09a5Sjsing              -16111345, 6493122, -19384511, 7639714},
21745f5d09a5Sjsing             {-2830798, -14839232, 25403038, -8215196, -8317012, -16173699,
21755f5d09a5Sjsing              18006287, -16043750, 29994677, -15808121},
21765f5d09a5Sjsing         },
21775f5d09a5Sjsing         {
21785f5d09a5Sjsing             {9769828, 5202651, -24157398, -13631392, -28051003, -11561624,
21795f5d09a5Sjsing              -24613141, -13860782, -31184575, 709464},
21805f5d09a5Sjsing             {12286395, 13076066, -21775189, -1176622, -25003198, 4057652,
21815f5d09a5Sjsing              -32018128, -8890874, 16102007, 13205847},
21825f5d09a5Sjsing             {13733362, 5599946, 10557076, 3195751, -5557991, 8536970, -25540170,
21835f5d09a5Sjsing              8525972, 10151379, 10394400},
21845f5d09a5Sjsing         },
21855f5d09a5Sjsing         {
21865f5d09a5Sjsing             {4024660, -16137551, 22436262, 12276534, -9099015, -2686099,
21875f5d09a5Sjsing              19698229, 11743039, -33302334, 8934414},
21885f5d09a5Sjsing             {-15879800, -4525240, -8580747, -2934061, 14634845, -698278,
21895f5d09a5Sjsing              -9449077, 3137094, -11536886, 11721158},
21905f5d09a5Sjsing             {17555939, -5013938, 8268606, 2331751, -22738815, 9761013, 9319229,
21915f5d09a5Sjsing              8835153, -9205489, -1280045},
21925f5d09a5Sjsing         },
21935f5d09a5Sjsing         {
21945f5d09a5Sjsing             {-461409, -7830014, 20614118, 16688288, -7514766, -4807119,
21955f5d09a5Sjsing              22300304, 505429, 6108462, -6183415},
21965f5d09a5Sjsing             {-5070281, 12367917, -30663534, 3234473, 32617080, -8422642,
21975f5d09a5Sjsing              29880583, -13483331, -26898490, -7867459},
21985f5d09a5Sjsing             {-31975283, 5726539, 26934134, 10237677, -3173717, -605053,
21995f5d09a5Sjsing              24199304, 3795095, 7592688, -14992079},
22005f5d09a5Sjsing         },
22015f5d09a5Sjsing         {
22025f5d09a5Sjsing             {21594432, -14964228, 17466408, -4077222, 32537084, 2739898,
22035f5d09a5Sjsing              6407723, 12018833, -28256052, 4298412},
22045f5d09a5Sjsing             {-20650503, -11961496, -27236275, 570498, 3767144, -1717540,
22055f5d09a5Sjsing              13891942, -1569194, 13717174, 10805743},
22065f5d09a5Sjsing             {-14676630, -15644296, 15287174, 11927123, 24177847, -8175568,
22075f5d09a5Sjsing              -796431, 14860609, -26938930, -5863836},
22085f5d09a5Sjsing         },
22095f5d09a5Sjsing     },
22105f5d09a5Sjsing     {
22115f5d09a5Sjsing         {
22125f5d09a5Sjsing             {12962541, 5311799, -10060768, 11658280, 18855286, -7954201,
22135f5d09a5Sjsing              13286263, -12808704, -4381056, 9882022},
22145f5d09a5Sjsing             {18512079, 11319350, -20123124, 15090309, 18818594, 5271736,
22155f5d09a5Sjsing              -22727904, 3666879, -23967430, -3299429},
22165f5d09a5Sjsing             {-6789020, -3146043, 16192429, 13241070, 15898607, -14206114,
22175f5d09a5Sjsing              -10084880, -6661110, -2403099, 5276065},
22185f5d09a5Sjsing         },
22195f5d09a5Sjsing         {
22205f5d09a5Sjsing             {30169808, -5317648, 26306206, -11750859, 27814964, 7069267,
22215f5d09a5Sjsing              7152851, 3684982, 1449224, 13082861},
22225f5d09a5Sjsing             {10342826, 3098505, 2119311, 193222, 25702612, 12233820, 23697382,
22235f5d09a5Sjsing              15056736, -21016438, -8202000},
22245f5d09a5Sjsing             {-33150110, 3261608, 22745853, 7948688, 19370557, -15177665,
22255f5d09a5Sjsing              -26171976, 6482814, -10300080, -11060101},
22265f5d09a5Sjsing         },
22275f5d09a5Sjsing         {
22285f5d09a5Sjsing             {32869458, -5408545, 25609743, 15678670, -10687769, -15471071,
22295f5d09a5Sjsing              26112421, 2521008, -22664288, 6904815},
22305f5d09a5Sjsing             {29506923, 4457497, 3377935, -9796444, -30510046, 12935080, 1561737,
22315f5d09a5Sjsing              3841096, -29003639, -6657642},
22325f5d09a5Sjsing             {10340844, -6630377, -18656632, -2278430, 12621151, -13339055,
22335f5d09a5Sjsing              30878497, -11824370, -25584551, 5181966},
22345f5d09a5Sjsing         },
22355f5d09a5Sjsing         {
22365f5d09a5Sjsing             {25940115, -12658025, 17324188, -10307374, -8671468, 15029094,
22375f5d09a5Sjsing              24396252, -16450922, -2322852, -12388574},
22385f5d09a5Sjsing             {-21765684, 9916823, -1300409, 4079498, -1028346, 11909559, 1782390,
22395f5d09a5Sjsing              12641087, 20603771, -6561742},
22405f5d09a5Sjsing             {-18882287, -11673380, 24849422, 11501709, 13161720, -4768874,
22415f5d09a5Sjsing              1925523, 11914390, 4662781, 7820689},
22425f5d09a5Sjsing         },
22435f5d09a5Sjsing         {
22445f5d09a5Sjsing             {12241050, -425982, 8132691, 9393934, 32846760, -1599620, 29749456,
22455f5d09a5Sjsing              12172924, 16136752, 15264020},
22465f5d09a5Sjsing             {-10349955, -14680563, -8211979, 2330220, -17662549, -14545780,
22475f5d09a5Sjsing              10658213, 6671822, 19012087, 3772772},
22485f5d09a5Sjsing             {3753511, -3421066, 10617074, 2028709, 14841030, -6721664, 28718732,
22495f5d09a5Sjsing              -15762884, 20527771, 12988982},
22505f5d09a5Sjsing         },
22515f5d09a5Sjsing         {
22525f5d09a5Sjsing             {-14822485, -5797269, -3707987, 12689773, -898983, -10914866,
22535f5d09a5Sjsing              -24183046, -10564943, 3299665, -12424953},
22545f5d09a5Sjsing             {-16777703, -15253301, -9642417, 4978983, 3308785, 8755439, 6943197,
22555f5d09a5Sjsing              6461331, -25583147, 8991218},
22565f5d09a5Sjsing             {-17226263, 1816362, -1673288, -6086439, 31783888, -8175991,
22575f5d09a5Sjsing              -32948145, 7417950, -30242287, 1507265},
22585f5d09a5Sjsing         },
22595f5d09a5Sjsing         {
22605f5d09a5Sjsing             {29692663, 6829891, -10498800, 4334896, 20945975, -11906496,
22615f5d09a5Sjsing              -28887608, 8209391, 14606362, -10647073},
22625f5d09a5Sjsing             {-3481570, 8707081, 32188102, 5672294, 22096700, 1711240, -33020695,
22635f5d09a5Sjsing              9761487, 4170404, -2085325},
22645f5d09a5Sjsing             {-11587470, 14855945, -4127778, -1531857, -26649089, 15084046,
22655f5d09a5Sjsing              22186522, 16002000, -14276837, -8400798},
22665f5d09a5Sjsing         },
22675f5d09a5Sjsing         {
22685f5d09a5Sjsing             {-4811456, 13761029, -31703877, -2483919, -3312471, 7869047,
22695f5d09a5Sjsing              -7113572, -9620092, 13240845, 10965870},
22705f5d09a5Sjsing             {-7742563, -8256762, -14768334, -13656260, -23232383, 12387166,
22715f5d09a5Sjsing              4498947, 14147411, 29514390, 4302863},
22725f5d09a5Sjsing             {-13413405, -12407859, 20757302, -13801832, 14785143, 8976368,
22735f5d09a5Sjsing              -5061276, -2144373, 17846988, -13971927},
22745f5d09a5Sjsing         },
22755f5d09a5Sjsing     },
22765f5d09a5Sjsing     {
22775f5d09a5Sjsing         {
22785f5d09a5Sjsing             {-2244452, -754728, -4597030, -1066309, -6247172, 1455299,
22795f5d09a5Sjsing              -21647728, -9214789, -5222701, 12650267},
22805f5d09a5Sjsing             {-9906797, -16070310, 21134160, 12198166, -27064575, 708126, 387813,
22815f5d09a5Sjsing              13770293, -19134326, 10958663},
22825f5d09a5Sjsing             {22470984, 12369526, 23446014, -5441109, -21520802, -9698723,
22835f5d09a5Sjsing              -11772496, -11574455, -25083830, 4271862},
22845f5d09a5Sjsing         },
22855f5d09a5Sjsing         {
22865f5d09a5Sjsing             {-25169565, -10053642, -19909332, 15361595, -5984358, 2159192,
22875f5d09a5Sjsing              75375, -4278529, -32526221, 8469673},
22885f5d09a5Sjsing             {15854970, 4148314, -8893890, 7259002, 11666551, 13824734,
22895f5d09a5Sjsing              -30531198, 2697372, 24154791, -9460943},
22905f5d09a5Sjsing             {15446137, -15806644, 29759747, 14019369, 30811221, -9610191,
22915f5d09a5Sjsing              -31582008, 12840104, 24913809, 9815020},
22925f5d09a5Sjsing         },
22935f5d09a5Sjsing         {
22945f5d09a5Sjsing             {-4709286, -5614269, -31841498, -12288893, -14443537, 10799414,
22955f5d09a5Sjsing              -9103676, 13438769, 18735128, 9466238},
22965f5d09a5Sjsing             {11933045, 9281483, 5081055, -5183824, -2628162, -4905629, -7727821,
22975f5d09a5Sjsing              -10896103, -22728655, 16199064},
22985f5d09a5Sjsing             {14576810, 379472, -26786533, -8317236, -29426508, -10812974,
22995f5d09a5Sjsing              -102766, 1876699, 30801119, 2164795},
23005f5d09a5Sjsing         },
23015f5d09a5Sjsing         {
23025f5d09a5Sjsing             {15995086, 3199873, 13672555, 13712240, -19378835, -4647646,
23035f5d09a5Sjsing              -13081610, -15496269, -13492807, 1268052},
23045f5d09a5Sjsing             {-10290614, -3659039, -3286592, 10948818, 23037027, 3794475,
23055f5d09a5Sjsing              -3470338, -12600221, -17055369, 3565904},
23065f5d09a5Sjsing             {29210088, -9419337, -5919792, -4952785, 10834811, -13327726,
23075f5d09a5Sjsing              -16512102, -10820713, -27162222, -14030531},
23085f5d09a5Sjsing         },
23095f5d09a5Sjsing         {
23105f5d09a5Sjsing             {-13161890, 15508588, 16663704, -8156150, -28349942, 9019123,
23115f5d09a5Sjsing              -29183421, -3769423, 2244111, -14001979},
23125f5d09a5Sjsing             {-5152875, -3800936, -9306475, -6071583, 16243069, 14684434,
23135f5d09a5Sjsing              -25673088, -16180800, 13491506, 4641841},
23145f5d09a5Sjsing             {10813417, 643330, -19188515, -728916, 30292062, -16600078,
23155f5d09a5Sjsing              27548447, -7721242, 14476989, -12767431},
23165f5d09a5Sjsing         },
23175f5d09a5Sjsing         {
23185f5d09a5Sjsing             {10292079, 9984945, 6481436, 8279905, -7251514, 7032743, 27282937,
23195f5d09a5Sjsing              -1644259, -27912810, 12651324},
23205f5d09a5Sjsing             {-31185513, -813383, 22271204, 11835308, 10201545, 15351028,
23215f5d09a5Sjsing              17099662, 3988035, 21721536, -3148940},
23225f5d09a5Sjsing             {10202177, -6545839, -31373232, -9574638, -32150642, -8119683,
23235f5d09a5Sjsing              -12906320, 3852694, 13216206, 14842320},
23245f5d09a5Sjsing         },
23255f5d09a5Sjsing         {
23265f5d09a5Sjsing             {-15815640, -10601066, -6538952, -7258995, -6984659, -6581778,
23275f5d09a5Sjsing              -31500847, 13765824, -27434397, 9900184},
23285f5d09a5Sjsing             {14465505, -13833331, -32133984, -14738873, -27443187, 12990492,
23295f5d09a5Sjsing              33046193, 15796406, -7051866, -8040114},
23305f5d09a5Sjsing             {30924417, -8279620, 6359016, -12816335, 16508377, 9071735,
23315f5d09a5Sjsing              -25488601, 15413635, 9524356, -7018878},
23325f5d09a5Sjsing         },
23335f5d09a5Sjsing         {
23345f5d09a5Sjsing             {12274201, -13175547, 32627641, -1785326, 6736625, 13267305,
23355f5d09a5Sjsing              5237659, -5109483, 15663516, 4035784},
23365f5d09a5Sjsing             {-2951309, 8903985, 17349946, 601635, -16432815, -4612556,
23375f5d09a5Sjsing              -13732739, -15889334, -22258478, 4659091},
23385f5d09a5Sjsing             {-16916263, -4952973, -30393711, -15158821, 20774812, 15897498,
23395f5d09a5Sjsing              5736189, 15026997, -2178256, -13455585},
23405f5d09a5Sjsing         },
23415f5d09a5Sjsing     },
23425f5d09a5Sjsing     {
23435f5d09a5Sjsing         {
23445f5d09a5Sjsing             {-8858980, -2219056, 28571666, -10155518, -474467, -10105698,
23455f5d09a5Sjsing              -3801496, 278095, 23440562, -290208},
23465f5d09a5Sjsing             {10226241, -5928702, 15139956, 120818, -14867693, 5218603, 32937275,
23475f5d09a5Sjsing              11551483, -16571960, -7442864},
23485f5d09a5Sjsing             {17932739, -12437276, -24039557, 10749060, 11316803, 7535897,
23495f5d09a5Sjsing              22503767, 5561594, -3646624, 3898661},
23505f5d09a5Sjsing         },
23515f5d09a5Sjsing         {
23525f5d09a5Sjsing             {7749907, -969567, -16339731, -16464, -25018111, 15122143, -1573531,
23535f5d09a5Sjsing              7152530, 21831162, 1245233},
23545f5d09a5Sjsing             {26958459, -14658026, 4314586, 8346991, -5677764, 11960072,
23555f5d09a5Sjsing              -32589295, -620035, -30402091, -16716212},
23565f5d09a5Sjsing             {-12165896, 9166947, 33491384, 13673479, 29787085, 13096535,
23575f5d09a5Sjsing              6280834, 14587357, -22338025, 13987525},
23585f5d09a5Sjsing         },
23595f5d09a5Sjsing         {
23605f5d09a5Sjsing             {-24349909, 7778775, 21116000, 15572597, -4833266, -5357778,
23615f5d09a5Sjsing              -4300898, -5124639, -7469781, -2858068},
23625f5d09a5Sjsing             {9681908, -6737123, -31951644, 13591838, -6883821, 386950, 31622781,
23635f5d09a5Sjsing              6439245, -14581012, 4091397},
23645f5d09a5Sjsing             {-8426427, 1470727, -28109679, -1596990, 3978627, -5123623,
23655f5d09a5Sjsing              -19622683, 12092163, 29077877, -14741988},
23665f5d09a5Sjsing         },
23675f5d09a5Sjsing         {
23685f5d09a5Sjsing             {5269168, -6859726, -13230211, -8020715, 25932563, 1763552,
23695f5d09a5Sjsing              -5606110, -5505881, -20017847, 2357889},
23705f5d09a5Sjsing             {32264008, -15407652, -5387735, -1160093, -2091322, -3946900,
23715f5d09a5Sjsing              23104804, -12869908, 5727338, 189038},
23725f5d09a5Sjsing             {14609123, -8954470, -6000566, -16622781, -14577387, -7743898,
23735f5d09a5Sjsing              -26745169, 10942115, -25888931, -14884697},
23745f5d09a5Sjsing         },
23755f5d09a5Sjsing         {
23765f5d09a5Sjsing             {20513500, 5557931, -15604613, 7829531, 26413943, -2019404,
23775f5d09a5Sjsing              -21378968, 7471781, 13913677, -5137875},
23785f5d09a5Sjsing             {-25574376, 11967826, 29233242, 12948236, -6754465, 4713227,
23795f5d09a5Sjsing              -8940970, 14059180, 12878652, 8511905},
23805f5d09a5Sjsing             {-25656801, 3393631, -2955415, -7075526, -2250709, 9366908,
23815f5d09a5Sjsing              -30223418, 6812974, 5568676, -3127656},
23825f5d09a5Sjsing         },
23835f5d09a5Sjsing         {
23845f5d09a5Sjsing             {11630004, 12144454, 2116339, 13606037, 27378885, 15676917,
23855f5d09a5Sjsing              -17408753, -13504373, -14395196, 8070818},
23865f5d09a5Sjsing             {27117696, -10007378, -31282771, -5570088, 1127282, 12772488,
23875f5d09a5Sjsing              -29845906, 10483306, -11552749, -1028714},
23885f5d09a5Sjsing             {10637467, -5688064, 5674781, 1072708, -26343588, -6982302,
23895f5d09a5Sjsing              -1683975, 9177853, -27493162, 15431203},
23905f5d09a5Sjsing         },
23915f5d09a5Sjsing         {
23925f5d09a5Sjsing             {20525145, 10892566, -12742472, 12779443, -29493034, 16150075,
23935f5d09a5Sjsing              -28240519, 14943142, -15056790, -7935931},
23945f5d09a5Sjsing             {-30024462, 5626926, -551567, -9981087, 753598, 11981191, 25244767,
23955f5d09a5Sjsing              -3239766, -3356550, 9594024},
23965f5d09a5Sjsing             {-23752644, 2636870, -5163910, -10103818, 585134, 7877383, 11345683,
23975f5d09a5Sjsing              -6492290, 13352335, -10977084},
23985f5d09a5Sjsing         },
23995f5d09a5Sjsing         {
24005f5d09a5Sjsing             {-1931799, -5407458, 3304649, -12884869, 17015806, -4877091,
24015f5d09a5Sjsing              -29783850, -7752482, -13215537, -319204},
24025f5d09a5Sjsing             {20239939, 6607058, 6203985, 3483793, -18386976, -779229, -20723742,
24035f5d09a5Sjsing              15077870, -22750759, 14523817},
24045f5d09a5Sjsing             {27406042, -6041657, 27423596, -4497394, 4996214, 10002360,
24055f5d09a5Sjsing              -28842031, -4545494, -30172742, -4805667},
24065f5d09a5Sjsing         },
24075f5d09a5Sjsing     },
24085f5d09a5Sjsing     {
24095f5d09a5Sjsing         {
24105f5d09a5Sjsing             {11374242, 12660715, 17861383, -12540833, 10935568, 1099227,
24115f5d09a5Sjsing              -13886076, -9091740, -27727044, 11358504},
24125f5d09a5Sjsing             {-12730809, 10311867, 1510375, 10778093, -2119455, -9145702,
24135f5d09a5Sjsing              32676003, 11149336, -26123651, 4985768},
24145f5d09a5Sjsing             {-19096303, 341147, -6197485, -239033, 15756973, -8796662, -983043,
24155f5d09a5Sjsing              13794114, -19414307, -15621255},
24165f5d09a5Sjsing         },
24175f5d09a5Sjsing         {
24185f5d09a5Sjsing             {6490081, 11940286, 25495923, -7726360, 8668373, -8751316, 3367603,
24195f5d09a5Sjsing              6970005, -1691065, -9004790},
24205f5d09a5Sjsing             {1656497, 13457317, 15370807, 6364910, 13605745, 8362338, -19174622,
24215f5d09a5Sjsing              -5475723, -16796596, -5031438},
24225f5d09a5Sjsing             {-22273315, -13524424, -64685, -4334223, -18605636, -10921968,
24235f5d09a5Sjsing              -20571065, -7007978, -99853, -10237333},
24245f5d09a5Sjsing         },
24255f5d09a5Sjsing         {
24265f5d09a5Sjsing             {17747465, 10039260, 19368299, -4050591, -20630635, -16041286,
24275f5d09a5Sjsing              31992683, -15857976, -29260363, -5511971},
24285f5d09a5Sjsing             {31932027, -4986141, -19612382, 16366580, 22023614, 88450, 11371999,
24295f5d09a5Sjsing              -3744247, 4882242, -10626905},
24305f5d09a5Sjsing             {29796507, 37186, 19818052, 10115756, -11829032, 3352736, 18551198,
24315f5d09a5Sjsing              3272828, -5190932, -4162409},
24325f5d09a5Sjsing         },
24335f5d09a5Sjsing         {
24345f5d09a5Sjsing             {12501286, 4044383, -8612957, -13392385, -32430052, 5136599,
24355f5d09a5Sjsing              -19230378, -3529697, 330070, -3659409},
24365f5d09a5Sjsing             {6384877, 2899513, 17807477, 7663917, -2358888, 12363165, 25366522,
24375f5d09a5Sjsing              -8573892, -271295, 12071499},
24385f5d09a5Sjsing             {-8365515, -4042521, 25133448, -4517355, -6211027, 2265927,
24395f5d09a5Sjsing              -32769618, 1936675, -5159697, 3829363},
24405f5d09a5Sjsing         },
24415f5d09a5Sjsing         {
24425f5d09a5Sjsing             {28425966, -5835433, -577090, -4697198, -14217555, 6870930, 7921550,
24435f5d09a5Sjsing              -6567787, 26333140, 14267664},
24445f5d09a5Sjsing             {-11067219, 11871231, 27385719, -10559544, -4585914, -11189312,
24455f5d09a5Sjsing              10004786, -8709488, -21761224, 8930324},
24465f5d09a5Sjsing             {-21197785, -16396035, 25654216, -1725397, 12282012, 11008919,
24475f5d09a5Sjsing              1541940, 4757911, -26491501, -16408940},
24485f5d09a5Sjsing         },
24495f5d09a5Sjsing         {
24505f5d09a5Sjsing             {13537262, -7759490, -20604840, 10961927, -5922820, -13218065,
24515f5d09a5Sjsing              -13156584, 6217254, -15943699, 13814990},
24525f5d09a5Sjsing             {-17422573, 15157790, 18705543, 29619, 24409717, -260476, 27361681,
24535f5d09a5Sjsing              9257833, -1956526, -1776914},
24545f5d09a5Sjsing             {-25045300, -10191966, 15366585, 15166509, -13105086, 8423556,
24555f5d09a5Sjsing              -29171540, 12361135, -18685978, 4578290},
24565f5d09a5Sjsing         },
24575f5d09a5Sjsing         {
24585f5d09a5Sjsing             {24579768, 3711570, 1342322, -11180126, -27005135, 14124956,
24595f5d09a5Sjsing              -22544529, 14074919, 21964432, 8235257},
24605f5d09a5Sjsing             {-6528613, -2411497, 9442966, -5925588, 12025640, -1487420,
24615f5d09a5Sjsing              -2981514, -1669206, 13006806, 2355433},
24625f5d09a5Sjsing             {-16304899, -13605259, -6632427, -5142349, 16974359, -10911083,
24635f5d09a5Sjsing              27202044, 1719366, 1141648, -12796236},
24645f5d09a5Sjsing         },
24655f5d09a5Sjsing         {
24665f5d09a5Sjsing             {-12863944, -13219986, -8318266, -11018091, -6810145, -4843894,
24675f5d09a5Sjsing              13475066, -3133972, 32674895, 13715045},
24685f5d09a5Sjsing             {11423335, -5468059, 32344216, 8962751, 24989809, 9241752,
24695f5d09a5Sjsing              -13265253, 16086212, -28740881, -15642093},
24705f5d09a5Sjsing             {-1409668, 12530728, -6368726, 10847387, 19531186, -14132160,
24715f5d09a5Sjsing              -11709148, 7791794, -27245943, 4383347},
24725f5d09a5Sjsing         },
24735f5d09a5Sjsing     },
24745f5d09a5Sjsing     {
24755f5d09a5Sjsing         {
24765f5d09a5Sjsing             {-28970898, 5271447, -1266009, -9736989, -12455236, 16732599,
24775f5d09a5Sjsing              -4862407, -4906449, 27193557, 6245191},
24785f5d09a5Sjsing             {-15193956, 5362278, -1783893, 2695834, 4960227, 12840725, 23061898,
24795f5d09a5Sjsing              3260492, 22510453, 8577507},
24805f5d09a5Sjsing             {-12632451, 11257346, -32692994, 13548177, -721004, 10879011,
24815f5d09a5Sjsing              31168030, 13952092, -29571492, -3635906},
24825f5d09a5Sjsing         },
24835f5d09a5Sjsing         {
24845f5d09a5Sjsing             {3877321, -9572739, 32416692, 5405324, -11004407, -13656635,
24855f5d09a5Sjsing              3759769, 11935320, 5611860, 8164018},
24865f5d09a5Sjsing             {-16275802, 14667797, 15906460, 12155291, -22111149, -9039718,
24875f5d09a5Sjsing              32003002, -8832289, 5773085, -8422109},
24885f5d09a5Sjsing             {-23788118, -8254300, 1950875, 8937633, 18686727, 16459170, -905725,
24895f5d09a5Sjsing              12376320, 31632953, 190926},
24905f5d09a5Sjsing         },
24915f5d09a5Sjsing         {
24925f5d09a5Sjsing             {-24593607, -16138885, -8423991, 13378746, 14162407, 6901328,
24935f5d09a5Sjsing              -8288749, 4508564, -25341555, -3627528},
24945f5d09a5Sjsing             {8884438, -5884009, 6023974, 10104341, -6881569, -4941533, 18722941,
24955f5d09a5Sjsing              -14786005, -1672488, 827625},
24965f5d09a5Sjsing             {-32720583, -16289296, -32503547, 7101210, 13354605, 2659080,
24975f5d09a5Sjsing              -1800575, -14108036, -24878478, 1541286},
24985f5d09a5Sjsing         },
24995f5d09a5Sjsing         {
25005f5d09a5Sjsing             {2901347, -1117687, 3880376, -10059388, -17620940, -3612781,
25015f5d09a5Sjsing              -21802117, -3567481, 20456845, -1885033},
25025f5d09a5Sjsing             {27019610, 12299467, -13658288, -1603234, -12861660, -4861471,
25035f5d09a5Sjsing              -19540150, -5016058, 29439641, 15138866},
25045f5d09a5Sjsing             {21536104, -6626420, -32447818, -10690208, -22408077, 5175814,
25055f5d09a5Sjsing              -5420040, -16361163, 7779328, 109896},
25065f5d09a5Sjsing         },
25075f5d09a5Sjsing         {
25085f5d09a5Sjsing             {30279744, 14648750, -8044871, 6425558, 13639621, -743509, 28698390,
25095f5d09a5Sjsing              12180118, 23177719, -554075},
25105f5d09a5Sjsing             {26572847, 3405927, -31701700, 12890905, -19265668, 5335866,
25115f5d09a5Sjsing              -6493768, 2378492, 4439158, -13279347},
25125f5d09a5Sjsing             {-22716706, 3489070, -9225266, -332753, 18875722, -1140095,
25135f5d09a5Sjsing              14819434, -12731527, -17717757, -5461437},
25145f5d09a5Sjsing         },
25155f5d09a5Sjsing         {
25165f5d09a5Sjsing             {-5056483, 16566551, 15953661, 3767752, -10436499, 15627060,
25175f5d09a5Sjsing              -820954, 2177225, 8550082, -15114165},
25185f5d09a5Sjsing             {-18473302, 16596775, -381660, 15663611, 22860960, 15585581,
25195f5d09a5Sjsing              -27844109, -3582739, -23260460, -8428588},
25205f5d09a5Sjsing             {-32480551, 15707275, -8205912, -5652081, 29464558, 2713815,
25215f5d09a5Sjsing              -22725137, 15860482, -21902570, 1494193},
25225f5d09a5Sjsing         },
25235f5d09a5Sjsing         {
25245f5d09a5Sjsing             {-19562091, -14087393, -25583872, -9299552, 13127842, 759709,
25255f5d09a5Sjsing              21923482, 16529112, 8742704, 12967017},
25265f5d09a5Sjsing             {-28464899, 1553205, 32536856, -10473729, -24691605, -406174,
25275f5d09a5Sjsing              -8914625, -2933896, -29903758, 15553883},
25285f5d09a5Sjsing             {21877909, 3230008, 9881174, 10539357, -4797115, 2841332, 11543572,
25295f5d09a5Sjsing              14513274, 19375923, -12647961},
25305f5d09a5Sjsing         },
25315f5d09a5Sjsing         {
25325f5d09a5Sjsing             {8832269, -14495485, 13253511, 5137575, 5037871, 4078777, 24880818,
25335f5d09a5Sjsing              -6222716, 2862653, 9455043},
25345f5d09a5Sjsing             {29306751, 5123106, 20245049, -14149889, 9592566, 8447059, -2077124,
25355f5d09a5Sjsing              -2990080, 15511449, 4789663},
25365f5d09a5Sjsing             {-20679756, 7004547, 8824831, -9434977, -4045704, -3750736,
25375f5d09a5Sjsing              -5754762, 108893, 23513200, 16652362},
25385f5d09a5Sjsing         },
25395f5d09a5Sjsing     },
25405f5d09a5Sjsing     {
25415f5d09a5Sjsing         {
25425f5d09a5Sjsing             {-33256173, 4144782, -4476029, -6579123, 10770039, -7155542,
25435f5d09a5Sjsing              -6650416, -12936300, -18319198, 10212860},
25445f5d09a5Sjsing             {2756081, 8598110, 7383731, -6859892, 22312759, -1105012, 21179801,
25455f5d09a5Sjsing              2600940, -9988298, -12506466},
25465f5d09a5Sjsing             {-24645692, 13317462, -30449259, -15653928, 21365574, -10869657,
25475f5d09a5Sjsing              11344424, 864440, -2499677, -16710063},
25485f5d09a5Sjsing         },
25495f5d09a5Sjsing         {
25505f5d09a5Sjsing             {-26432803, 6148329, -17184412, -14474154, 18782929, -275997,
25515f5d09a5Sjsing              -22561534, 211300, 2719757, 4940997},
25525f5d09a5Sjsing             {-1323882, 3911313, -6948744, 14759765, -30027150, 7851207,
25535f5d09a5Sjsing              21690126, 8518463, 26699843, 5276295},
25545f5d09a5Sjsing             {-13149873, -6429067, 9396249, 365013, 24703301, -10488939, 1321586,
25555f5d09a5Sjsing              149635, -15452774, 7159369},
25565f5d09a5Sjsing         },
25575f5d09a5Sjsing         {
25585f5d09a5Sjsing             {9987780, -3404759, 17507962, 9505530, 9731535, -2165514, 22356009,
25595f5d09a5Sjsing              8312176, 22477218, -8403385},
25605f5d09a5Sjsing             {18155857, -16504990, 19744716, 9006923, 15154154, -10538976,
25615f5d09a5Sjsing              24256460, -4864995, -22548173, 9334109},
25625f5d09a5Sjsing             {2986088, -4911893, 10776628, -3473844, 10620590, -7083203,
25635f5d09a5Sjsing              -21413845, 14253545, -22587149, 536906},
25645f5d09a5Sjsing         },
25655f5d09a5Sjsing         {
25665f5d09a5Sjsing             {4377756, 8115836, 24567078, 15495314, 11625074, 13064599, 7390551,
25675f5d09a5Sjsing              10589625, 10838060, -15420424},
25685f5d09a5Sjsing             {-19342404, 867880, 9277171, -3218459, -14431572, -1986443,
25695f5d09a5Sjsing              19295826, -15796950, 6378260, 699185},
25705f5d09a5Sjsing             {7895026, 4057113, -7081772, -13077756, -17886831, -323126, -716039,
25715f5d09a5Sjsing              15693155, -5045064, -13373962},
25725f5d09a5Sjsing         },
25735f5d09a5Sjsing         {
25745f5d09a5Sjsing             {-7737563, -5869402, -14566319, -7406919, 11385654, 13201616,
25755f5d09a5Sjsing              31730678, -10962840, -3918636, -9669325},
25765f5d09a5Sjsing             {10188286, -15770834, -7336361, 13427543, 22223443, 14896287,
25775f5d09a5Sjsing              30743455, 7116568, -21786507, 5427593},
25785f5d09a5Sjsing             {696102, 13206899, 27047647, -10632082, 15285305, -9853179,
25795f5d09a5Sjsing              10798490, -4578720, 19236243, 12477404},
25805f5d09a5Sjsing         },
25815f5d09a5Sjsing         {
25825f5d09a5Sjsing             {-11229439, 11243796, -17054270, -8040865, -788228, -8167967,
25835f5d09a5Sjsing              -3897669, 11180504, -23169516, 7733644},
25845f5d09a5Sjsing             {17800790, -14036179, -27000429, -11766671, 23887827, 3149671,
25855f5d09a5Sjsing              23466177, -10538171, 10322027, 15313801},
25865f5d09a5Sjsing             {26246234, 11968874, 32263343, -5468728, 6830755, -13323031,
25875f5d09a5Sjsing              -15794704, -101982, -24449242, 10890804},
25885f5d09a5Sjsing         },
25895f5d09a5Sjsing         {
25905f5d09a5Sjsing             {-31365647, 10271363, -12660625, -6267268, 16690207, -13062544,
25915f5d09a5Sjsing              -14982212, 16484931, 25180797, -5334884},
25925f5d09a5Sjsing             {-586574, 10376444, -32586414, -11286356, 19801893, 10997610,
25935f5d09a5Sjsing              2276632, 9482883, 316878, 13820577},
25945f5d09a5Sjsing             {-9882808, -4510367, -2115506, 16457136, -11100081, 11674996,
25955f5d09a5Sjsing              30756178, -7515054, 30696930, -3712849},
25965f5d09a5Sjsing         },
25975f5d09a5Sjsing         {
25985f5d09a5Sjsing             {32988917, -9603412, 12499366, 7910787, -10617257, -11931514,
25995f5d09a5Sjsing              -7342816, -9985397, -32349517, 7392473},
26005f5d09a5Sjsing             {-8855661, 15927861, 9866406, -3649411, -2396914, -16655781,
26015f5d09a5Sjsing              -30409476, -9134995, 25112947, -2926644},
26025f5d09a5Sjsing             {-2504044, -436966, 25621774, -5678772, 15085042, -5479877,
26035f5d09a5Sjsing              -24884878, -13526194, 5537438, -13914319},
26045f5d09a5Sjsing         },
26055f5d09a5Sjsing     },
26065f5d09a5Sjsing     {
26075f5d09a5Sjsing         {
26085f5d09a5Sjsing             {-11225584, 2320285, -9584280, 10149187, -33444663, 5808648,
26095f5d09a5Sjsing              -14876251, -1729667, 31234590, 6090599},
26105f5d09a5Sjsing             {-9633316, 116426, 26083934, 2897444, -6364437, -2688086, 609721,
26115f5d09a5Sjsing              15878753, -6970405, -9034768},
26125f5d09a5Sjsing             {-27757857, 247744, -15194774, -9002551, 23288161, -10011936,
26135f5d09a5Sjsing              -23869595, 6503646, 20650474, 1804084},
26145f5d09a5Sjsing         },
26155f5d09a5Sjsing         {
26165f5d09a5Sjsing             {-27589786, 15456424, 8972517, 8469608, 15640622, 4439847, 3121995,
26175f5d09a5Sjsing              -10329713, 27842616, -202328},
26185f5d09a5Sjsing             {-15306973, 2839644, 22530074, 10026331, 4602058, 5048462, 28248656,
26195f5d09a5Sjsing              5031932, -11375082, 12714369},
26205f5d09a5Sjsing             {20807691, -7270825, 29286141, 11421711, -27876523, -13868230,
26215f5d09a5Sjsing              -21227475, 1035546, -19733229, 12796920},
26225f5d09a5Sjsing         },
26235f5d09a5Sjsing         {
26245f5d09a5Sjsing             {12076899, -14301286, -8785001, -11848922, -25012791, 16400684,
26255f5d09a5Sjsing              -17591495, -12899438, 3480665, -15182815},
26265f5d09a5Sjsing             {-32361549, 5457597, 28548107, 7833186, 7303070, -11953545,
26275f5d09a5Sjsing              -24363064, -15921875, -33374054, 2771025},
26285f5d09a5Sjsing             {-21389266, 421932, 26597266, 6860826, 22486084, -6737172,
26295f5d09a5Sjsing              -17137485, -4210226, -24552282, 15673397},
26305f5d09a5Sjsing         },
26315f5d09a5Sjsing         {
26325f5d09a5Sjsing             {-20184622, 2338216, 19788685, -9620956, -4001265, -8740893,
26335f5d09a5Sjsing              -20271184, 4733254, 3727144, -12934448},
26345f5d09a5Sjsing             {6120119, 814863, -11794402, -622716, 6812205, -15747771, 2019594,
26355f5d09a5Sjsing              7975683, 31123697, -10958981},
26365f5d09a5Sjsing             {30069250, -11435332, 30434654, 2958439, 18399564, -976289,
26375f5d09a5Sjsing              12296869, 9204260, -16432438, 9648165},
26385f5d09a5Sjsing         },
26395f5d09a5Sjsing         {
26405f5d09a5Sjsing             {32705432, -1550977, 30705658, 7451065, -11805606, 9631813, 3305266,
26415f5d09a5Sjsing              5248604, -26008332, -11377501},
26425f5d09a5Sjsing             {17219865, 2375039, -31570947, -5575615, -19459679, 9219903, 294711,
26435f5d09a5Sjsing              15298639, 2662509, -16297073},
26445f5d09a5Sjsing             {-1172927, -7558695, -4366770, -4287744, -21346413, -8434326,
26455f5d09a5Sjsing              32087529, -1222777, 32247248, -14389861},
26465f5d09a5Sjsing         },
26475f5d09a5Sjsing         {
26485f5d09a5Sjsing             {14312628, 1221556, 17395390, -8700143, -4945741, -8684635,
26495f5d09a5Sjsing              -28197744, -9637817, -16027623, -13378845},
26505f5d09a5Sjsing             {-1428825, -9678990, -9235681, 6549687, -7383069, -468664, 23046502,
26515f5d09a5Sjsing              9803137, 17597934, 2346211},
26525f5d09a5Sjsing             {18510800, 15337574, 26171504, 981392, -22241552, 7827556,
26535f5d09a5Sjsing              -23491134, -11323352, 3059833, -11782870},
26545f5d09a5Sjsing         },
26555f5d09a5Sjsing         {
26565f5d09a5Sjsing             {10141598, 6082907, 17829293, -1947643, 9830092, 13613136,
26575f5d09a5Sjsing              -25556636, -5544586, -33502212, 3592096},
26585f5d09a5Sjsing             {33114168, -15889352, -26525686, -13343397, 33076705, 8716171,
26595f5d09a5Sjsing              1151462, 1521897, -982665, -6837803},
26605f5d09a5Sjsing             {-32939165, -4255815, 23947181, -324178, -33072974, -12305637,
26615f5d09a5Sjsing              -16637686, 3891704, 26353178, 693168},
26625f5d09a5Sjsing         },
26635f5d09a5Sjsing         {
26645f5d09a5Sjsing             {30374239, 1595580, -16884039, 13186931, 4600344, 406904, 9585294,
26655f5d09a5Sjsing              -400668, 31375464, 14369965},
26665f5d09a5Sjsing             {-14370654, -7772529, 1510301, 6434173, -18784789, -6262728,
26675f5d09a5Sjsing              32732230, -13108839, 17901441, 16011505},
26685f5d09a5Sjsing             {18171223, -11934626, -12500402, 15197122, -11038147, -15230035,
26695f5d09a5Sjsing              -19172240, -16046376, 8764035, 12309598},
26705f5d09a5Sjsing         },
26715f5d09a5Sjsing     },
26725f5d09a5Sjsing     {
26735f5d09a5Sjsing         {
26745f5d09a5Sjsing             {5975908, -5243188, -19459362, -9681747, -11541277, 14015782,
26755f5d09a5Sjsing              -23665757, 1228319, 17544096, -10593782},
26765f5d09a5Sjsing             {5811932, -1715293, 3442887, -2269310, -18367348, -8359541,
26775f5d09a5Sjsing              -18044043, -15410127, -5565381, 12348900},
26785f5d09a5Sjsing             {-31399660, 11407555, 25755363, 6891399, -3256938, 14872274,
26795f5d09a5Sjsing              -24849353, 8141295, -10632534, -585479},
26805f5d09a5Sjsing         },
26815f5d09a5Sjsing         {
26825f5d09a5Sjsing             {-12675304, 694026, -5076145, 13300344, 14015258, -14451394,
26835f5d09a5Sjsing              -9698672, -11329050, 30944593, 1130208},
26845f5d09a5Sjsing             {8247766, -6710942, -26562381, -7709309, -14401939, -14648910,
26855f5d09a5Sjsing              4652152, 2488540, 23550156, -271232},
26865f5d09a5Sjsing             {17294316, -3788438, 7026748, 15626851, 22990044, 113481, 2267737,
26875f5d09a5Sjsing              -5908146, -408818, -137719},
26885f5d09a5Sjsing         },
26895f5d09a5Sjsing         {
26905f5d09a5Sjsing             {16091085, -16253926, 18599252, 7340678, 2137637, -1221657,
26915f5d09a5Sjsing              -3364161, 14550936, 3260525, -7166271},
26925f5d09a5Sjsing             {-4910104, -13332887, 18550887, 10864893, -16459325, -7291596,
26935f5d09a5Sjsing              -23028869, -13204905, -12748722, 2701326},
26945f5d09a5Sjsing             {-8574695, 16099415, 4629974, -16340524, -20786213, -6005432,
26955f5d09a5Sjsing              -10018363, 9276971, 11329923, 1862132},
26965f5d09a5Sjsing         },
26975f5d09a5Sjsing         {
26985f5d09a5Sjsing             {14763076, -15903608, -30918270, 3689867, 3511892, 10313526,
26995f5d09a5Sjsing              -21951088, 12219231, -9037963, -940300},
27005f5d09a5Sjsing             {8894987, -3446094, 6150753, 3013931, 301220, 15693451, -31981216,
27015f5d09a5Sjsing              -2909717, -15438168, 11595570},
27025f5d09a5Sjsing             {15214962, 3537601, -26238722, -14058872, 4418657, -15230761,
27035f5d09a5Sjsing              13947276, 10730794, -13489462, -4363670},
27045f5d09a5Sjsing         },
27055f5d09a5Sjsing         {
27065f5d09a5Sjsing             {-2538306, 7682793, 32759013, 263109, -29984731, -7955452,
27075f5d09a5Sjsing              -22332124, -10188635, 977108, 699994},
27085f5d09a5Sjsing             {-12466472, 4195084, -9211532, 550904, -15565337, 12917920,
27095f5d09a5Sjsing              19118110, -439841, -30534533, -14337913},
27105f5d09a5Sjsing             {31788461, -14507657, 4799989, 7372237, 8808585, -14747943, 9408237,
27115f5d09a5Sjsing              -10051775, 12493932, -5409317},
27125f5d09a5Sjsing         },
27135f5d09a5Sjsing         {
27145f5d09a5Sjsing             {-25680606, 5260744, -19235809, -6284470, -3695942, 16566087,
27155f5d09a5Sjsing              27218280, 2607121, 29375955, 6024730},
27165f5d09a5Sjsing             {842132, -2794693, -4763381, -8722815, 26332018, -12405641,
27175f5d09a5Sjsing              11831880, 6985184, -9940361, 2854096},
27185f5d09a5Sjsing             {-4847262, -7969331, 2516242, -5847713, 9695691, -7221186, 16512645,
27195f5d09a5Sjsing              960770, 12121869, 16648078},
27205f5d09a5Sjsing         },
27215f5d09a5Sjsing         {
27225f5d09a5Sjsing             {-15218652, 14667096, -13336229, 2013717, 30598287, -464137,
27235f5d09a5Sjsing              -31504922, -7882064, 20237806, 2838411},
27245f5d09a5Sjsing             {-19288047, 4453152, 15298546, -16178388, 22115043, -15972604,
27255f5d09a5Sjsing              12544294, -13470457, 1068881, -12499905},
27265f5d09a5Sjsing             {-9558883, -16518835, 33238498, 13506958, 30505848, -1114596,
27275f5d09a5Sjsing              -8486907, -2630053, 12521378, 4845654},
27285f5d09a5Sjsing         },
27295f5d09a5Sjsing         {
27305f5d09a5Sjsing             {-28198521, 10744108, -2958380, 10199664, 7759311, -13088600,
27315f5d09a5Sjsing              3409348, -873400, -6482306, -12885870},
27325f5d09a5Sjsing             {-23561822, 6230156, -20382013, 10655314, -24040585, -11621172,
27335f5d09a5Sjsing              10477734, -1240216, -3113227, 13974498},
27345f5d09a5Sjsing             {12966261, 15550616, -32038948, -1615346, 21025980, -629444,
27355f5d09a5Sjsing              5642325, 7188737, 18895762, 12629579},
27365f5d09a5Sjsing         },
27375f5d09a5Sjsing     },
27385f5d09a5Sjsing     {
27395f5d09a5Sjsing         {
27405f5d09a5Sjsing             {14741879, -14946887, 22177208, -11721237, 1279741, 8058600,
27415f5d09a5Sjsing              11758140, 789443, 32195181, 3895677},
27425f5d09a5Sjsing             {10758205, 15755439, -4509950, 9243698, -4879422, 6879879, -2204575,
27435f5d09a5Sjsing              -3566119, -8982069, 4429647},
27445f5d09a5Sjsing             {-2453894, 15725973, -20436342, -10410672, -5803908, -11040220,
27455f5d09a5Sjsing              -7135870, -11642895, 18047436, -15281743},
27465f5d09a5Sjsing         },
27475f5d09a5Sjsing         {
27485f5d09a5Sjsing             {-25173001, -11307165, 29759956, 11776784, -22262383, -15820455,
27495f5d09a5Sjsing              10993114, -12850837, -17620701, -9408468},
27505f5d09a5Sjsing             {21987233, 700364, -24505048, 14972008, -7774265, -5718395,
27515f5d09a5Sjsing              32155026, 2581431, -29958985, 8773375},
27525f5d09a5Sjsing             {-25568350, 454463, -13211935, 16126715, 25240068, 8594567,
27535f5d09a5Sjsing              20656846, 12017935, -7874389, -13920155},
27545f5d09a5Sjsing         },
27555f5d09a5Sjsing         {
27565f5d09a5Sjsing             {6028182, 6263078, -31011806, -11301710, -818919, 2461772,
27575f5d09a5Sjsing              -31841174, -5468042, -1721788, -2776725},
27585f5d09a5Sjsing             {-12278994, 16624277, 987579, -5922598, 32908203, 1248608, 7719845,
27595f5d09a5Sjsing              -4166698, 28408820, 6816612},
27605f5d09a5Sjsing             {-10358094, -8237829, 19549651, -12169222, 22082623, 16147817,
27615f5d09a5Sjsing              20613181, 13982702, -10339570, 5067943},
27625f5d09a5Sjsing         },
27635f5d09a5Sjsing         {
27645f5d09a5Sjsing             {-30505967, -3821767, 12074681, 13582412, -19877972, 2443951,
27655f5d09a5Sjsing              -19719286, 12746132, 5331210, -10105944},
27665f5d09a5Sjsing             {30528811, 3601899, -1957090, 4619785, -27361822, -15436388,
27675f5d09a5Sjsing              24180793, -12570394, 27679908, -1648928},
27685f5d09a5Sjsing             {9402404, -13957065, 32834043, 10838634, -26580150, -13237195,
27695f5d09a5Sjsing              26653274, -8685565, 22611444, -12715406},
27705f5d09a5Sjsing         },
27715f5d09a5Sjsing         {
27725f5d09a5Sjsing             {22190590, 1118029, 22736441, 15130463, -30460692, -5991321,
27735f5d09a5Sjsing              19189625, -4648942, 4854859, 6622139},
27745f5d09a5Sjsing             {-8310738, -2953450, -8262579, -3388049, -10401731, -271929,
27755f5d09a5Sjsing              13424426, -3567227, 26404409, 13001963},
27765f5d09a5Sjsing             {-31241838, -15415700, -2994250, 8939346, 11562230, -12840670,
27775f5d09a5Sjsing              -26064365, -11621720, -15405155, 11020693},
27785f5d09a5Sjsing         },
27795f5d09a5Sjsing         {
27805f5d09a5Sjsing             {1866042, -7949489, -7898649, -10301010, 12483315, 13477547,
27815f5d09a5Sjsing              3175636, -12424163, 28761762, 1406734},
27825f5d09a5Sjsing             {-448555, -1777666, 13018551, 3194501, -9580420, -11161737,
27835f5d09a5Sjsing              24760585, -4347088, 25577411, -13378680},
27845f5d09a5Sjsing             {-24290378, 4759345, -690653, -1852816, 2066747, 10693769,
27855f5d09a5Sjsing              -29595790, 9884936, -9368926, 4745410},
27865f5d09a5Sjsing         },
27875f5d09a5Sjsing         {
27885f5d09a5Sjsing             {-9141284, 6049714, -19531061, -4341411, -31260798, 9944276,
27895f5d09a5Sjsing              -15462008, -11311852, 10931924, -11931931},
27905f5d09a5Sjsing             {-16561513, 14112680, -8012645, 4817318, -8040464, -11414606,
27915f5d09a5Sjsing              -22853429, 10856641, -20470770, 13434654},
27925f5d09a5Sjsing             {22759489, -10073434, -16766264, -1871422, 13637442, -10168091,
27935f5d09a5Sjsing              1765144, -12654326, 28445307, -5364710},
27945f5d09a5Sjsing         },
27955f5d09a5Sjsing         {
27965f5d09a5Sjsing             {29875063, 12493613, 2795536, -3786330, 1710620, 15181182,
27975f5d09a5Sjsing              -10195717, -8788675, 9074234, 1167180},
27985f5d09a5Sjsing             {-26205683, 11014233, -9842651, -2635485, -26908120, 7532294,
27995f5d09a5Sjsing              -18716888, -9535498, 3843903, 9367684},
28005f5d09a5Sjsing             {-10969595, -6403711, 9591134, 9582310, 11349256, 108879, 16235123,
28015f5d09a5Sjsing              8601684, -139197, 4242895},
28025f5d09a5Sjsing         },
28035f5d09a5Sjsing     },
28045f5d09a5Sjsing     {
28055f5d09a5Sjsing         {
28065f5d09a5Sjsing             {22092954, -13191123, -2042793, -11968512, 32186753, -11517388,
28075f5d09a5Sjsing              -6574341, 2470660, -27417366, 16625501},
28085f5d09a5Sjsing             {-11057722, 3042016, 13770083, -9257922, 584236, -544855, -7770857,
28095f5d09a5Sjsing              2602725, -27351616, 14247413},
28105f5d09a5Sjsing             {6314175, -10264892, -32772502, 15957557, -10157730, 168750,
28115f5d09a5Sjsing              -8618807, 14290061, 27108877, -1180880},
28125f5d09a5Sjsing         },
28135f5d09a5Sjsing         {
28145f5d09a5Sjsing             {-8586597, -7170966, 13241782, 10960156, -32991015, -13794596,
28155f5d09a5Sjsing              33547976, -11058889, -27148451, 981874},
28165f5d09a5Sjsing             {22833440, 9293594, -32649448, -13618667, -9136966, 14756819,
28175f5d09a5Sjsing              -22928859, -13970780, -10479804, -16197962},
28185f5d09a5Sjsing             {-7768587, 3326786, -28111797, 10783824, 19178761, 14905060,
28195f5d09a5Sjsing              22680049, 13906969, -15933690, 3797899},
28205f5d09a5Sjsing         },
28215f5d09a5Sjsing         {
28225f5d09a5Sjsing             {21721356, -4212746, -12206123, 9310182, -3882239, -13653110,
28235f5d09a5Sjsing              23740224, -2709232, 20491983, -8042152},
28245f5d09a5Sjsing             {9209270, -15135055, -13256557, -6167798, -731016, 15289673,
28255f5d09a5Sjsing              25947805, 15286587, 30997318, -6703063},
28265f5d09a5Sjsing             {7392032, 16618386, 23946583, -8039892, -13265164, -1533858,
28275f5d09a5Sjsing              -14197445, -2321576, 17649998, -250080},
28285f5d09a5Sjsing         },
28295f5d09a5Sjsing         {
28305f5d09a5Sjsing             {-9301088, -14193827, 30609526, -3049543, -25175069, -1283752,
28315f5d09a5Sjsing              -15241566, -9525724, -2233253, 7662146},
28325f5d09a5Sjsing             {-17558673, 1763594, -33114336, 15908610, -30040870, -12174295,
28335f5d09a5Sjsing              7335080, -8472199, -3174674, 3440183},
28345f5d09a5Sjsing             {-19889700, -5977008, -24111293, -9688870, 10799743, -16571957,
28355f5d09a5Sjsing              40450, -4431835, 4862400, 1133},
28365f5d09a5Sjsing         },
28375f5d09a5Sjsing         {
28385f5d09a5Sjsing             {-32856209, -7873957, -5422389, 14860950, -16319031, 7956142,
28395f5d09a5Sjsing              7258061, 311861, -30594991, -7379421},
28405f5d09a5Sjsing             {-3773428, -1565936, 28985340, 7499440, 24445838, 9325937, 29727763,
28415f5d09a5Sjsing              16527196, 18278453, 15405622},
28425f5d09a5Sjsing             {-4381906, 8508652, -19898366, -3674424, -5984453, 15149970,
28435f5d09a5Sjsing              -13313598, 843523, -21875062, 13626197},
28445f5d09a5Sjsing         },
28455f5d09a5Sjsing         {
28465f5d09a5Sjsing             {2281448, -13487055, -10915418, -2609910, 1879358, 16164207,
28475f5d09a5Sjsing              -10783882, 3953792, 13340839, 15928663},
28485f5d09a5Sjsing             {31727126, -7179855, -18437503, -8283652, 2875793, -16390330,
28495f5d09a5Sjsing              -25269894, -7014826, -23452306, 5964753},
28505f5d09a5Sjsing             {4100420, -5959452, -17179337, 6017714, -18705837, 12227141,
28515f5d09a5Sjsing              -26684835, 11344144, 2538215, -7570755},
28525f5d09a5Sjsing         },
28535f5d09a5Sjsing         {
28545f5d09a5Sjsing             {-9433605, 6123113, 11159803, -2156608, 30016280, 14966241,
28555f5d09a5Sjsing              -20474983, 1485421, -629256, -15958862},
28565f5d09a5Sjsing             {-26804558, 4260919, 11851389, 9658551, -32017107, 16367492,
28575f5d09a5Sjsing              -20205425, -13191288, 11659922, -11115118},
28585f5d09a5Sjsing             {26180396, 10015009, -30844224, -8581293, 5418197, 9480663, 2231568,
28595f5d09a5Sjsing              -10170080, 33100372, -1306171},
28605f5d09a5Sjsing         },
28615f5d09a5Sjsing         {
28625f5d09a5Sjsing             {15121113, -5201871, -10389905, 15427821, -27509937, -15992507,
28635f5d09a5Sjsing              21670947, 4486675, -5931810, -14466380},
28645f5d09a5Sjsing             {16166486, -9483733, -11104130, 6023908, -31926798, -1364923,
28655f5d09a5Sjsing              2340060, -16254968, -10735770, -10039824},
28665f5d09a5Sjsing             {28042865, -3557089, -12126526, 12259706, -3717498, -6945899,
28675f5d09a5Sjsing              6766453, -8689599, 18036436, 5803270},
28685f5d09a5Sjsing         },
28695f5d09a5Sjsing     },
28705f5d09a5Sjsing     {
28715f5d09a5Sjsing         {
28725f5d09a5Sjsing             {-817581, 6763912, 11803561, 1585585, 10958447, -2671165, 23855391,
28735f5d09a5Sjsing              4598332, -6159431, -14117438},
28745f5d09a5Sjsing             {-31031306, -14256194, 17332029, -2383520, 31312682, -5967183,
28755f5d09a5Sjsing              696309, 50292, -20095739, 11763584},
28765f5d09a5Sjsing             {-594563, -2514283, -32234153, 12643980, 12650761, 14811489, 665117,
28775f5d09a5Sjsing              -12613632, -19773211, -10713562},
28785f5d09a5Sjsing         },
28795f5d09a5Sjsing         {
28805f5d09a5Sjsing             {30464590, -11262872, -4127476, -12734478, 19835327, -7105613,
28815f5d09a5Sjsing              -24396175, 2075773, -17020157, 992471},
28825f5d09a5Sjsing             {18357185, -6994433, 7766382, 16342475, -29324918, 411174, 14578841,
28835f5d09a5Sjsing              8080033, -11574335, -10601610},
28845f5d09a5Sjsing             {19598397, 10334610, 12555054, 2555664, 18821899, -10339780,
28855f5d09a5Sjsing              21873263, 16014234, 26224780, 16452269},
28865f5d09a5Sjsing         },
28875f5d09a5Sjsing         {
28885f5d09a5Sjsing             {-30223925, 5145196, 5944548, 16385966, 3976735, 2009897, -11377804,
28895f5d09a5Sjsing              -7618186, -20533829, 3698650},
28905f5d09a5Sjsing             {14187449, 3448569, -10636236, -10810935, -22663880, -3433596,
28915f5d09a5Sjsing              7268410, -10890444, 27394301, 12015369},
28925f5d09a5Sjsing             {19695761, 16087646, 28032085, 12999827, 6817792, 11427614,
28935f5d09a5Sjsing              20244189, -1312777, -13259127, -3402461},
28945f5d09a5Sjsing         },
28955f5d09a5Sjsing         {
28965f5d09a5Sjsing             {30860103, 12735208, -1888245, -4699734, -16974906, 2256940,
28975f5d09a5Sjsing              -8166013, 12298312, -8550524, -10393462},
28985f5d09a5Sjsing             {-5719826, -11245325, -1910649, 15569035, 26642876, -7587760,
28995f5d09a5Sjsing              -5789354, -15118654, -4976164, 12651793},
29005f5d09a5Sjsing             {-2848395, 9953421, 11531313, -5282879, 26895123, -12697089,
29015f5d09a5Sjsing              -13118820, -16517902, 9768698, -2533218},
29025f5d09a5Sjsing         },
29035f5d09a5Sjsing         {
29045f5d09a5Sjsing             {-24719459, 1894651, -287698, -4704085, 15348719, -8156530,
29055f5d09a5Sjsing              32767513, 12765450, 4940095, 10678226},
29065f5d09a5Sjsing             {18860224, 15980149, -18987240, -1562570, -26233012, -11071856,
29075f5d09a5Sjsing              -7843882, 13944024, -24372348, 16582019},
29085f5d09a5Sjsing             {-15504260, 4970268, -29893044, 4175593, -20993212, -2199756,
29095f5d09a5Sjsing              -11704054, 15444560, -11003761, 7989037},
29105f5d09a5Sjsing         },
29115f5d09a5Sjsing         {
29125f5d09a5Sjsing             {31490452, 5568061, -2412803, 2182383, -32336847, 4531686,
29135f5d09a5Sjsing              -32078269, 6200206, -19686113, -14800171},
29145f5d09a5Sjsing             {-17308668, -15879940, -31522777, -2831, -32887382, 16375549,
29155f5d09a5Sjsing              8680158, -16371713, 28550068, -6857132},
29165f5d09a5Sjsing             {-28126887, -5688091, 16837845, -1820458, -6850681, 12700016,
29175f5d09a5Sjsing              -30039981, 4364038, 1155602, 5988841},
29185f5d09a5Sjsing         },
29195f5d09a5Sjsing         {
29205f5d09a5Sjsing             {21890435, -13272907, -12624011, 12154349, -7831873, 15300496,
29215f5d09a5Sjsing              23148983, -4470481, 24618407, 8283181},
29225f5d09a5Sjsing             {-33136107, -10512751, 9975416, 6841041, -31559793, 16356536,
29235f5d09a5Sjsing              3070187, -7025928, 1466169, 10740210},
29245f5d09a5Sjsing             {-1509399, -15488185, -13503385, -10655916, 32799044, 909394,
29255f5d09a5Sjsing              -13938903, -5779719, -32164649, -15327040},
29265f5d09a5Sjsing         },
29275f5d09a5Sjsing         {
29285f5d09a5Sjsing             {3960823, -14267803, -28026090, -15918051, -19404858, 13146868,
29295f5d09a5Sjsing              15567327, 951507, -3260321, -573935},
29305f5d09a5Sjsing             {24740841, 5052253, -30094131, 8961361, 25877428, 6165135,
29315f5d09a5Sjsing              -24368180, 14397372, -7380369, -6144105},
29325f5d09a5Sjsing             {-28888365, 3510803, -28103278, -1158478, -11238128, -10631454,
29335f5d09a5Sjsing              -15441463, -14453128, -1625486, -6494814},
29345f5d09a5Sjsing         },
29355f5d09a5Sjsing     },
29365f5d09a5Sjsing     {
29375f5d09a5Sjsing         {
29385f5d09a5Sjsing             {793299, -9230478, 8836302, -6235707, -27360908, -2369593, 33152843,
29395f5d09a5Sjsing              -4885251, -9906200, -621852},
29405f5d09a5Sjsing             {5666233, 525582, 20782575, -8038419, -24538499, 14657740, 16099374,
29415f5d09a5Sjsing              1468826, -6171428, -15186581},
29425f5d09a5Sjsing             {-4859255, -3779343, -2917758, -6748019, 7778750, 11688288,
29435f5d09a5Sjsing              -30404353, -9871238, -1558923, -9863646},
29445f5d09a5Sjsing         },
29455f5d09a5Sjsing         {
29465f5d09a5Sjsing             {10896332, -7719704, 824275, 472601, -19460308, 3009587, 25248958,
29475f5d09a5Sjsing              14783338, -30581476, -15757844},
29485f5d09a5Sjsing             {10566929, 12612572, -31944212, 11118703, -12633376, 12362879,
29495f5d09a5Sjsing              21752402, 8822496, 24003793, 14264025},
29505f5d09a5Sjsing             {27713862, -7355973, -11008240, 9227530, 27050101, 2504721,
29515f5d09a5Sjsing              23886875, -13117525, 13958495, -5732453},
29525f5d09a5Sjsing         },
29535f5d09a5Sjsing         {
29545f5d09a5Sjsing             {-23481610, 4867226, -27247128, 3900521, 29838369, -8212291,
29555f5d09a5Sjsing              -31889399, -10041781, 7340521, -15410068},
29565f5d09a5Sjsing             {4646514, -8011124, -22766023, -11532654, 23184553, 8566613,
29575f5d09a5Sjsing              31366726, -1381061, -15066784, -10375192},
29585f5d09a5Sjsing             {-17270517, 12723032, -16993061, 14878794, 21619651, -6197576,
29595f5d09a5Sjsing              27584817, 3093888, -8843694, 3849921},
29605f5d09a5Sjsing         },
29615f5d09a5Sjsing         {
29625f5d09a5Sjsing             {-9064912, 2103172, 25561640, -15125738, -5239824, 9582958,
29635f5d09a5Sjsing              32477045, -9017955, 5002294, -15550259},
29645f5d09a5Sjsing             {-12057553, -11177906, 21115585, -13365155, 8808712, -12030708,
29655f5d09a5Sjsing              16489530, 13378448, -25845716, 12741426},
29665f5d09a5Sjsing             {-5946367, 10645103, -30911586, 15390284, -3286982, -7118677,
29675f5d09a5Sjsing              24306472, 15852464, 28834118, -7646072},
29685f5d09a5Sjsing         },
29695f5d09a5Sjsing         {
29705f5d09a5Sjsing             {-17335748, -9107057, -24531279, 9434953, -8472084, -583362,
29715f5d09a5Sjsing              -13090771, 455841, 20461858, 5491305},
29725f5d09a5Sjsing             {13669248, -16095482, -12481974, -10203039, -14569770, -11893198,
29735f5d09a5Sjsing              -24995986, 11293807, -28588204, -9421832},
29745f5d09a5Sjsing             {28497928, 6272777, -33022994, 14470570, 8906179, -1225630,
29755f5d09a5Sjsing              18504674, -14165166, 29867745, -8795943},
29765f5d09a5Sjsing         },
29775f5d09a5Sjsing         {
29785f5d09a5Sjsing             {-16207023, 13517196, -27799630, -13697798, 24009064, -6373891,
29795f5d09a5Sjsing              -6367600, -13175392, 22853429, -4012011},
29805f5d09a5Sjsing             {24191378, 16712145, -13931797, 15217831, 14542237, 1646131,
29815f5d09a5Sjsing              18603514, -11037887, 12876623, -2112447},
29825f5d09a5Sjsing             {17902668, 4518229, -411702, -2829247, 26878217, 5258055, -12860753,
29835f5d09a5Sjsing              608397, 16031844, 3723494},
29845f5d09a5Sjsing         },
29855f5d09a5Sjsing         {
29865f5d09a5Sjsing             {-28632773, 12763728, -20446446, 7577504, 33001348, -13017745,
29875f5d09a5Sjsing              17558842, -7872890, 23896954, -4314245},
29885f5d09a5Sjsing             {-20005381, -12011952, 31520464, 605201, 2543521, 5991821, -2945064,
29895f5d09a5Sjsing              7229064, -9919646, -8826859},
29905f5d09a5Sjsing             {28816045, 298879, -28165016, -15920938, 19000928, -1665890,
29915f5d09a5Sjsing              -12680833, -2949325, -18051778, -2082915},
29925f5d09a5Sjsing         },
29935f5d09a5Sjsing         {
29945f5d09a5Sjsing             {16000882, -344896, 3493092, -11447198, -29504595, -13159789,
29955f5d09a5Sjsing              12577740, 16041268, -19715240, 7847707},
29965f5d09a5Sjsing             {10151868, 10572098, 27312476, 7922682, 14825339, 4723128,
29975f5d09a5Sjsing              -32855931, -6519018, -10020567, 3852848},
29985f5d09a5Sjsing             {-11430470, 15697596, -21121557, -4420647, 5386314, 15063598,
29995f5d09a5Sjsing              16514493, -15932110, 29330899, -15076224},
30005f5d09a5Sjsing         },
30015f5d09a5Sjsing     },
30025f5d09a5Sjsing     {
30035f5d09a5Sjsing         {
30045f5d09a5Sjsing             {-25499735, -4378794, -15222908, -6901211, 16615731, 2051784,
30055f5d09a5Sjsing              3303702, 15490, -27548796, 12314391},
30065f5d09a5Sjsing             {15683520, -6003043, 18109120, -9980648, 15337968, -5997823,
30075f5d09a5Sjsing              -16717435, 15921866, 16103996, -3731215},
30085f5d09a5Sjsing             {-23169824, -10781249, 13588192, -1628807, -3798557, -1074929,
30095f5d09a5Sjsing              -19273607, 5402699, -29815713, -9841101},
30105f5d09a5Sjsing         },
30115f5d09a5Sjsing         {
30125f5d09a5Sjsing             {23190676, 2384583, -32714340, 3462154, -29903655, -1529132,
30135f5d09a5Sjsing              -11266856, 8911517, -25205859, 2739713},
30145f5d09a5Sjsing             {21374101, -3554250, -33524649, 9874411, 15377179, 11831242,
30155f5d09a5Sjsing              -33529904, 6134907, 4931255, 11987849},
30165f5d09a5Sjsing             {-7732, -2978858, -16223486, 7277597, 105524, -322051, -31480539,
30175f5d09a5Sjsing              13861388, -30076310, 10117930},
30185f5d09a5Sjsing         },
30195f5d09a5Sjsing         {
30205f5d09a5Sjsing             {-29501170, -10744872, -26163768, 13051539, -25625564, 5089643,
30215f5d09a5Sjsing              -6325503, 6704079, 12890019, 15728940},
30225f5d09a5Sjsing             {-21972360, -11771379, -951059, -4418840, 14704840, 2695116, 903376,
30235f5d09a5Sjsing              -10428139, 12885167, 8311031},
30245f5d09a5Sjsing             {-17516482, 5352194, 10384213, -13811658, 7506451, 13453191,
30255f5d09a5Sjsing              26423267, 4384730, 1888765, -5435404},
30265f5d09a5Sjsing         },
30275f5d09a5Sjsing         {
30285f5d09a5Sjsing             {-25817338, -3107312, -13494599, -3182506, 30896459, -13921729,
30295f5d09a5Sjsing              -32251644, -12707869, -19464434, -3340243},
30305f5d09a5Sjsing             {-23607977, -2665774, -526091, 4651136, 5765089, 4618330, 6092245,
30315f5d09a5Sjsing              14845197, 17151279, -9854116},
30325f5d09a5Sjsing             {-24830458, -12733720, -15165978, 10367250, -29530908, -265356,
30335f5d09a5Sjsing              22825805, -7087279, -16866484, 16176525},
30345f5d09a5Sjsing         },
30355f5d09a5Sjsing         {
30365f5d09a5Sjsing             {-23583256, 6564961, 20063689, 3798228, -4740178, 7359225, 2006182,
30375f5d09a5Sjsing              -10363426, -28746253, -10197509},
30385f5d09a5Sjsing             {-10626600, -4486402, -13320562, -5125317, 3432136, -6393229,
30395f5d09a5Sjsing              23632037, -1940610, 32808310, 1099883},
30405f5d09a5Sjsing             {15030977, 5768825, -27451236, -2887299, -6427378, -15361371,
30415f5d09a5Sjsing              -15277896, -6809350, 2051441, -15225865},
30425f5d09a5Sjsing         },
30435f5d09a5Sjsing         {
30445f5d09a5Sjsing             {-3362323, -7239372, 7517890, 9824992, 23555850, 295369, 5148398,
30455f5d09a5Sjsing              -14154188, -22686354, 16633660},
30465f5d09a5Sjsing             {4577086, -16752288, 13249841, -15304328, 19958763, -14537274,
30475f5d09a5Sjsing              18559670, -10759549, 8402478, -9864273},
30485f5d09a5Sjsing             {-28406330, -1051581, -26790155, -907698, -17212414, -11030789,
30495f5d09a5Sjsing              9453451, -14980072, 17983010, 9967138},
30505f5d09a5Sjsing         },
30515f5d09a5Sjsing         {
30525f5d09a5Sjsing             {-25762494, 6524722, 26585488, 9969270, 24709298, 1220360, -1677990,
30535f5d09a5Sjsing              7806337, 17507396, 3651560},
30545f5d09a5Sjsing             {-10420457, -4118111, 14584639, 15971087, -15768321, 8861010,
30555f5d09a5Sjsing              26556809, -5574557, -18553322, -11357135},
30565f5d09a5Sjsing             {2839101, 14284142, 4029895, 3472686, 14402957, 12689363, -26642121,
30575f5d09a5Sjsing              8459447, -5605463, -7621941},
30585f5d09a5Sjsing         },
30595f5d09a5Sjsing         {
30605f5d09a5Sjsing             {-4839289, -3535444, 9744961, 2871048, 25113978, 3187018, -25110813,
30615f5d09a5Sjsing              -849066, 17258084, -7977739},
30625f5d09a5Sjsing             {18164541, -10595176, -17154882, -1542417, 19237078, -9745295,
30635f5d09a5Sjsing              23357533, -15217008, 26908270, 12150756},
30645f5d09a5Sjsing             {-30264870, -7647865, 5112249, -7036672, -1499807, -6974257, 43168,
30655f5d09a5Sjsing              -5537701, -32302074, 16215819},
30665f5d09a5Sjsing         },
30675f5d09a5Sjsing     },
30685f5d09a5Sjsing     {
30695f5d09a5Sjsing         {
30705f5d09a5Sjsing             {-6898905, 9824394, -12304779, -4401089, -31397141, -6276835,
30715f5d09a5Sjsing              32574489, 12532905, -7503072, -8675347},
30725f5d09a5Sjsing             {-27343522, -16515468, -27151524, -10722951, 946346, 16291093,
30735f5d09a5Sjsing              254968, 7168080, 21676107, -1943028},
30745f5d09a5Sjsing             {21260961, -8424752, -16831886, -11920822, -23677961, 3968121,
30755f5d09a5Sjsing              -3651949, -6215466, -3556191, -7913075},
30765f5d09a5Sjsing         },
30775f5d09a5Sjsing         {
30785f5d09a5Sjsing             {16544754, 13250366, -16804428, 15546242, -4583003, 12757258,
30795f5d09a5Sjsing              -2462308, -8680336, -18907032, -9662799},
30805f5d09a5Sjsing             {-2415239, -15577728, 18312303, 4964443, -15272530, -12653564,
30815f5d09a5Sjsing              26820651, 16690659, 25459437, -4564609},
30825f5d09a5Sjsing             {-25144690, 11425020, 28423002, -11020557, -6144921, -15826224,
30835f5d09a5Sjsing              9142795, -2391602, -6432418, -1644817},
30845f5d09a5Sjsing         },
30855f5d09a5Sjsing         {
30865f5d09a5Sjsing             {-23104652, 6253476, 16964147, -3768872, -25113972, -12296437,
30875f5d09a5Sjsing              -27457225, -16344658, 6335692, 7249989},
30885f5d09a5Sjsing             {-30333227, 13979675, 7503222, -12368314, -11956721, -4621693,
30895f5d09a5Sjsing              -30272269, 2682242, 25993170, -12478523},
30905f5d09a5Sjsing             {4364628, 5930691, 32304656, -10044554, -8054781, 15091131,
30915f5d09a5Sjsing              22857016, -10598955, 31820368, 15075278},
30925f5d09a5Sjsing         },
30935f5d09a5Sjsing         {
30945f5d09a5Sjsing             {31879134, -8918693, 17258761, 90626, -8041836, -4917709, 24162788,
30955f5d09a5Sjsing              -9650886, -17970238, 12833045},
30965f5d09a5Sjsing             {19073683, 14851414, -24403169, -11860168, 7625278, 11091125,
30975f5d09a5Sjsing              -19619190, 2074449, -9413939, 14905377},
30985f5d09a5Sjsing             {24483667, -11935567, -2518866, -11547418, -1553130, 15355506,
30995f5d09a5Sjsing              -25282080, 9253129, 27628530, -7555480},
31005f5d09a5Sjsing         },
31015f5d09a5Sjsing         {
31025f5d09a5Sjsing             {17597607, 8340603, 19355617, 552187, 26198470, -3176583, 4593324,
31035f5d09a5Sjsing              -9157582, -14110875, 15297016},
31045f5d09a5Sjsing             {510886, 14337390, -31785257, 16638632, 6328095, 2713355, -20217417,
31055f5d09a5Sjsing              -11864220, 8683221, 2921426},
31065f5d09a5Sjsing             {18606791, 11874196, 27155355, -5281482, -24031742, 6265446,
31075f5d09a5Sjsing              -25178240, -1278924, 4674690, 13890525},
31085f5d09a5Sjsing         },
31095f5d09a5Sjsing         {
31105f5d09a5Sjsing             {13609624, 13069022, -27372361, -13055908, 24360586, 9592974,
31115f5d09a5Sjsing              14977157, 9835105, 4389687, 288396},
31125f5d09a5Sjsing             {9922506, -519394, 13613107, 5883594, -18758345, -434263, -12304062,
31135f5d09a5Sjsing              8317628, 23388070, 16052080},
31145f5d09a5Sjsing             {12720016, 11937594, -31970060, -5028689, 26900120, 8561328,
31155f5d09a5Sjsing              -20155687, -11632979, -14754271, -10812892},
31165f5d09a5Sjsing         },
31175f5d09a5Sjsing         {
31185f5d09a5Sjsing             {15961858, 14150409, 26716931, -665832, -22794328, 13603569,
31195f5d09a5Sjsing              11829573, 7467844, -28822128, 929275},
31205f5d09a5Sjsing             {11038231, -11582396, -27310482, -7316562, -10498527, -16307831,
31215f5d09a5Sjsing              -23479533, -9371869, -21393143, 2465074},
31225f5d09a5Sjsing             {20017163, -4323226, 27915242, 1529148, 12396362, 15675764,
31235f5d09a5Sjsing              13817261, -9658066, 2463391, -4622140},
31245f5d09a5Sjsing         },
31255f5d09a5Sjsing         {
31265f5d09a5Sjsing             {-16358878, -12663911, -12065183, 4996454, -1256422, 1073572,
31275f5d09a5Sjsing              9583558, 12851107, 4003896, 12673717},
31285f5d09a5Sjsing             {-1731589, -15155870, -3262930, 16143082, 19294135, 13385325,
31295f5d09a5Sjsing              14741514, -9103726, 7903886, 2348101},
31305f5d09a5Sjsing             {24536016, -16515207, 12715592, -3862155, 1511293, 10047386,
31315f5d09a5Sjsing              -3842346, -7129159, -28377538, 10048127},
31325f5d09a5Sjsing         },
31335f5d09a5Sjsing     },
31345f5d09a5Sjsing     {
31355f5d09a5Sjsing         {
31365f5d09a5Sjsing             {-12622226, -6204820, 30718825, 2591312, -10617028, 12192840,
31375f5d09a5Sjsing              18873298, -7297090, -32297756, 15221632},
31385f5d09a5Sjsing             {-26478122, -11103864, 11546244, -1852483, 9180880, 7656409,
31395f5d09a5Sjsing              -21343950, 2095755, 29769758, 6593415},
31405f5d09a5Sjsing             {-31994208, -2907461, 4176912, 3264766, 12538965, -868111, 26312345,
31415f5d09a5Sjsing              -6118678, 30958054, 8292160},
31425f5d09a5Sjsing         },
31435f5d09a5Sjsing         {
31445f5d09a5Sjsing             {31429822, -13959116, 29173532, 15632448, 12174511, -2760094,
31455f5d09a5Sjsing              32808831, 3977186, 26143136, -3148876},
31465f5d09a5Sjsing             {22648901, 1402143, -22799984, 13746059, 7936347, 365344, -8668633,
31475f5d09a5Sjsing              -1674433, -3758243, -2304625},
31485f5d09a5Sjsing             {-15491917, 8012313, -2514730, -12702462, -23965846, -10254029,
31495f5d09a5Sjsing              -1612713, -1535569, -16664475, 8194478},
31505f5d09a5Sjsing         },
31515f5d09a5Sjsing         {
31525f5d09a5Sjsing             {27338066, -7507420, -7414224, 10140405, -19026427, -6589889,
31535f5d09a5Sjsing              27277191, 8855376, 28572286, 3005164},
31545f5d09a5Sjsing             {26287124, 4821776, 25476601, -4145903, -3764513, -15788984,
31555f5d09a5Sjsing              -18008582, 1182479, -26094821, -13079595},
31565f5d09a5Sjsing             {-7171154, 3178080, 23970071, 6201893, -17195577, -4489192,
31575f5d09a5Sjsing              -21876275, -13982627, 32208683, -1198248},
31585f5d09a5Sjsing         },
31595f5d09a5Sjsing         {
31605f5d09a5Sjsing             {-16657702, 2817643, -10286362, 14811298, 6024667, 13349505,
31615f5d09a5Sjsing              -27315504, -10497842, -27672585, -11539858},
31625f5d09a5Sjsing             {15941029, -9405932, -21367050, 8062055, 31876073, -238629,
31635f5d09a5Sjsing              -15278393, -1444429, 15397331, -4130193},
31645f5d09a5Sjsing             {8934485, -13485467, -23286397, -13423241, -32446090, 14047986,
31655f5d09a5Sjsing              31170398, -1441021, -27505566, 15087184},
31665f5d09a5Sjsing         },
31675f5d09a5Sjsing         {
31685f5d09a5Sjsing             {-18357243, -2156491, 24524913, -16677868, 15520427, -6360776,
31695f5d09a5Sjsing              -15502406, 11461896, 16788528, -5868942},
31705f5d09a5Sjsing             {-1947386, 16013773, 21750665, 3714552, -17401782, -16055433,
31715f5d09a5Sjsing              -3770287, -10323320, 31322514, -11615635},
31725f5d09a5Sjsing             {21426655, -5650218, -13648287, -5347537, -28812189, -4920970,
31735f5d09a5Sjsing              -18275391, -14621414, 13040862, -12112948},
31745f5d09a5Sjsing         },
31755f5d09a5Sjsing         {
31765f5d09a5Sjsing             {11293895, 12478086, -27136401, 15083750, -29307421, 14748872,
31775f5d09a5Sjsing              14555558, -13417103, 1613711, 4896935},
31785f5d09a5Sjsing             {-25894883, 15323294, -8489791, -8057900, 25967126, -13425460,
31795f5d09a5Sjsing              2825960, -4897045, -23971776, -11267415},
31805f5d09a5Sjsing             {-15924766, -5229880, -17443532, 6410664, 3622847, 10243618,
31815f5d09a5Sjsing              20615400, 12405433, -23753030, -8436416},
31825f5d09a5Sjsing         },
31835f5d09a5Sjsing         {
31845f5d09a5Sjsing             {-7091295, 12556208, -20191352, 9025187, -17072479, 4333801,
31855f5d09a5Sjsing              4378436, 2432030, 23097949, -566018},
31865f5d09a5Sjsing             {4565804, -16025654, 20084412, -7842817, 1724999, 189254, 24767264,
31875f5d09a5Sjsing              10103221, -18512313, 2424778},
31885f5d09a5Sjsing             {366633, -11976806, 8173090, -6890119, 30788634, 5745705, -7168678,
31895f5d09a5Sjsing              1344109, -3642553, 12412659},
31905f5d09a5Sjsing         },
31915f5d09a5Sjsing         {
31925f5d09a5Sjsing             {-24001791, 7690286, 14929416, -168257, -32210835, -13412986,
31935f5d09a5Sjsing              24162697, -15326504, -3141501, 11179385},
31945f5d09a5Sjsing             {18289522, -14724954, 8056945, 16430056, -21729724, 7842514,
31955f5d09a5Sjsing              -6001441, -1486897, -18684645, -11443503},
31965f5d09a5Sjsing             {476239, 6601091, -6152790, -9723375, 17503545, -4863900, 27672959,
31975f5d09a5Sjsing              13403813, 11052904, 5219329},
31985f5d09a5Sjsing         },
31995f5d09a5Sjsing     },
32005f5d09a5Sjsing     {
32015f5d09a5Sjsing         {
32025f5d09a5Sjsing             {20678546, -8375738, -32671898, 8849123, -5009758, 14574752,
32035f5d09a5Sjsing              31186971, -3973730, 9014762, -8579056},
32045f5d09a5Sjsing             {-13644050, -10350239, -15962508, 5075808, -1514661, -11534600,
32055f5d09a5Sjsing              -33102500, 9160280, 8473550, -3256838},
32065f5d09a5Sjsing             {24900749, 14435722, 17209120, -15292541, -22592275, 9878983,
32075f5d09a5Sjsing              -7689309, -16335821, -24568481, 11788948},
32085f5d09a5Sjsing         },
32095f5d09a5Sjsing         {
32105f5d09a5Sjsing             {-3118155, -11395194, -13802089, 14797441, 9652448, -6845904,
32115f5d09a5Sjsing              -20037437, 10410733, -24568470, -1458691},
32125f5d09a5Sjsing             {-15659161, 16736706, -22467150, 10215878, -9097177, 7563911,
32135f5d09a5Sjsing              11871841, -12505194, -18513325, 8464118},
32145f5d09a5Sjsing             {-23400612, 8348507, -14585951, -861714, -3950205, -6373419,
32155f5d09a5Sjsing              14325289, 8628612, 33313881, -8370517},
32165f5d09a5Sjsing         },
32175f5d09a5Sjsing         {
32185f5d09a5Sjsing             {-20186973, -4967935, 22367356, 5271547, -1097117, -4788838,
32195f5d09a5Sjsing              -24805667, -10236854, -8940735, -5818269},
32205f5d09a5Sjsing             {-6948785, -1795212, -32625683, -16021179, 32635414, -7374245,
32215f5d09a5Sjsing              15989197, -12838188, 28358192, -4253904},
32225f5d09a5Sjsing             {-23561781, -2799059, -32351682, -1661963, -9147719, 10429267,
32235f5d09a5Sjsing              -16637684, 4072016, -5351664, 5596589},
32245f5d09a5Sjsing         },
32255f5d09a5Sjsing         {
32265f5d09a5Sjsing             {-28236598, -3390048, 12312896, 6213178, 3117142, 16078565,
32275f5d09a5Sjsing              29266239, 2557221, 1768301, 15373193},
32285f5d09a5Sjsing             {-7243358, -3246960, -4593467, -7553353, -127927, -912245, -1090902,
32295f5d09a5Sjsing              -4504991, -24660491, 3442910},
32305f5d09a5Sjsing             {-30210571, 5124043, 14181784, 8197961, 18964734, -11939093,
32315f5d09a5Sjsing              22597931, 7176455, -18585478, 13365930},
32325f5d09a5Sjsing         },
32335f5d09a5Sjsing         {
32345f5d09a5Sjsing             {-7877390, -1499958, 8324673, 4690079, 6261860, 890446, 24538107,
32355f5d09a5Sjsing              -8570186, -9689599, -3031667},
32365f5d09a5Sjsing             {25008904, -10771599, -4305031, -9638010, 16265036, 15721635,
32375f5d09a5Sjsing              683793, -11823784, 15723479, -15163481},
32385f5d09a5Sjsing             {-9660625, 12374379, -27006999, -7026148, -7724114, -12314514,
32395f5d09a5Sjsing              11879682, 5400171, 519526, -1235876},
32405f5d09a5Sjsing         },
32415f5d09a5Sjsing         {
32425f5d09a5Sjsing             {22258397, -16332233, -7869817, 14613016, -22520255, -2950923,
32435f5d09a5Sjsing              -20353881, 7315967, 16648397, 7605640},
32445f5d09a5Sjsing             {-8081308, -8464597, -8223311, 9719710, 19259459, -15348212,
32455f5d09a5Sjsing              23994942, -5281555, -9468848, 4763278},
32465f5d09a5Sjsing             {-21699244, 9220969, -15730624, 1084137, -25476107, -2852390,
32475f5d09a5Sjsing              31088447, -7764523, -11356529, 728112},
32485f5d09a5Sjsing         },
32495f5d09a5Sjsing         {
32505f5d09a5Sjsing             {26047220, -11751471, -6900323, -16521798, 24092068, 9158119,
32515f5d09a5Sjsing              -4273545, -12555558, -29365436, -5498272},
32525f5d09a5Sjsing             {17510331, -322857, 5854289, 8403524, 17133918, -3112612, -28111007,
32535f5d09a5Sjsing              12327945, 10750447, 10014012},
32545f5d09a5Sjsing             {-10312768, 3936952, 9156313, -8897683, 16498692, -994647,
32555f5d09a5Sjsing              -27481051, -666732, 3424691, 7540221},
32565f5d09a5Sjsing         },
32575f5d09a5Sjsing         {
32585f5d09a5Sjsing             {30322361, -6964110, 11361005, -4143317, 7433304, 4989748, -7071422,
32595f5d09a5Sjsing              -16317219, -9244265, 15258046},
32605f5d09a5Sjsing             {13054562, -2779497, 19155474, 469045, -12482797, 4566042, 5631406,
32615f5d09a5Sjsing              2711395, 1062915, -5136345},
32625f5d09a5Sjsing             {-19240248, -11254599, -29509029, -7499965, -5835763, 13005411,
32635f5d09a5Sjsing              -6066489, 12194497, 32960380, 1459310},
32645f5d09a5Sjsing         },
32655f5d09a5Sjsing     },
32665f5d09a5Sjsing     {
32675f5d09a5Sjsing         {
32685f5d09a5Sjsing             {19852034, 7027924, 23669353, 10020366, 8586503, -6657907, 394197,
32695f5d09a5Sjsing              -6101885, 18638003, -11174937},
32705f5d09a5Sjsing             {31395534, 15098109, 26581030, 8030562, -16527914, -5007134,
32715f5d09a5Sjsing              9012486, -7584354, -6643087, -5442636},
32725f5d09a5Sjsing             {-9192165, -2347377, -1997099, 4529534, 25766844, 607986, -13222,
32735f5d09a5Sjsing              9677543, -32294889, -6456008},
32745f5d09a5Sjsing         },
32755f5d09a5Sjsing         {
32765f5d09a5Sjsing             {-2444496, -149937, 29348902, 8186665, 1873760, 12489863, -30934579,
32775f5d09a5Sjsing              -7839692, -7852844, -8138429},
32785f5d09a5Sjsing             {-15236356, -15433509, 7766470, 746860, 26346930, -10221762,
32795f5d09a5Sjsing              -27333451, 10754588, -9431476, 5203576},
32805f5d09a5Sjsing             {31834314, 14135496, -770007, 5159118, 20917671, -16768096,
32815f5d09a5Sjsing              -7467973, -7337524, 31809243, 7347066},
32825f5d09a5Sjsing         },
32835f5d09a5Sjsing         {
32845f5d09a5Sjsing             {-9606723, -11874240, 20414459, 13033986, 13716524, -11691881,
32855f5d09a5Sjsing              19797970, -12211255, 15192876, -2087490},
32865f5d09a5Sjsing             {-12663563, -2181719, 1168162, -3804809, 26747877, -14138091,
32875f5d09a5Sjsing              10609330, 12694420, 33473243, -13382104},
32885f5d09a5Sjsing             {33184999, 11180355, 15832085, -11385430, -1633671, 225884,
32895f5d09a5Sjsing              15089336, -11023903, -6135662, 14480053},
32905f5d09a5Sjsing         },
32915f5d09a5Sjsing         {
32925f5d09a5Sjsing             {31308717, -5619998, 31030840, -1897099, 15674547, -6582883,
32935f5d09a5Sjsing              5496208, 13685227, 27595050, 8737275},
32945f5d09a5Sjsing             {-20318852, -15150239, 10933843, -16178022, 8335352, -7546022,
32955f5d09a5Sjsing              -31008351, -12610604, 26498114, 66511},
32965f5d09a5Sjsing             {22644454, -8761729, -16671776, 4884562, -3105614, -13559366,
32975f5d09a5Sjsing              30540766, -4286747, -13327787, -7515095},
32985f5d09a5Sjsing         },
32995f5d09a5Sjsing         {
33005f5d09a5Sjsing             {-28017847, 9834845, 18617207, -2681312, -3401956, -13307506,
33015f5d09a5Sjsing              8205540, 13585437, -17127465, 15115439},
33025f5d09a5Sjsing             {23711543, -672915, 31206561, -8362711, 6164647, -9709987,
33035f5d09a5Sjsing              -33535882, -1426096, 8236921, 16492939},
33045f5d09a5Sjsing             {-23910559, -13515526, -26299483, -4503841, 25005590, -7687270,
33055f5d09a5Sjsing              19574902, 10071562, 6708380, -6222424},
33065f5d09a5Sjsing         },
33075f5d09a5Sjsing         {
33085f5d09a5Sjsing             {2101391, -4930054, 19702731, 2367575, -15427167, 1047675, 5301017,
33095f5d09a5Sjsing              9328700, 29955601, -11678310},
33105f5d09a5Sjsing             {3096359, 9271816, -21620864, -15521844, -14847996, -7592937,
33115f5d09a5Sjsing              -25892142, -12635595, -9917575, 6216608},
33125f5d09a5Sjsing             {-32615849, 338663, -25195611, 2510422, -29213566, -13820213,
33135f5d09a5Sjsing              24822830, -6146567, -26767480, 7525079},
33145f5d09a5Sjsing         },
33155f5d09a5Sjsing         {
33165f5d09a5Sjsing             {-23066649, -13985623, 16133487, -7896178, -3389565, 778788,
33175f5d09a5Sjsing              -910336, -2782495, -19386633, 11994101},
33185f5d09a5Sjsing             {21691500, -13624626, -641331, -14367021, 3285881, -3483596,
33195f5d09a5Sjsing              -25064666, 9718258, -7477437, 13381418},
33205f5d09a5Sjsing             {18445390, -4202236, 14979846, 11622458, -1727110, -3582980,
33215f5d09a5Sjsing              23111648, -6375247, 28535282, 15779576},
33225f5d09a5Sjsing         },
33235f5d09a5Sjsing         {
33245f5d09a5Sjsing             {30098053, 3089662, -9234387, 16662135, -21306940, 11308411,
33255f5d09a5Sjsing              -14068454, 12021730, 9955285, -16303356},
33265f5d09a5Sjsing             {9734894, -14576830, -7473633, -9138735, 2060392, 11313496,
33275f5d09a5Sjsing              -18426029, 9924399, 20194861, 13380996},
33285f5d09a5Sjsing             {-26378102, -7965207, -22167821, 15789297, -18055342, -6168792,
33295f5d09a5Sjsing              -1984914, 15707771, 26342023, 10146099},
33305f5d09a5Sjsing         },
33315f5d09a5Sjsing     },
33325f5d09a5Sjsing     {
33335f5d09a5Sjsing         {
33345f5d09a5Sjsing             {-26016874, -219943, 21339191, -41388, 19745256, -2878700,
33355f5d09a5Sjsing              -29637280, 2227040, 21612326, -545728},
33365f5d09a5Sjsing             {-13077387, 1184228, 23562814, -5970442, -20351244, -6348714,
33375f5d09a5Sjsing              25764461, 12243797, -20856566, 11649658},
33385f5d09a5Sjsing             {-10031494, 11262626, 27384172, 2271902, 26947504, -15997771, 39944,
33395f5d09a5Sjsing              6114064, 33514190, 2333242},
33405f5d09a5Sjsing         },
33415f5d09a5Sjsing         {
33425f5d09a5Sjsing             {-21433588, -12421821, 8119782, 7219913, -21830522, -9016134,
33435f5d09a5Sjsing              -6679750, -12670638, 24350578, -13450001},
33445f5d09a5Sjsing             {-4116307, -11271533, -23886186, 4843615, -30088339, 690623,
33455f5d09a5Sjsing              -31536088, -10406836, 8317860, 12352766},
33465f5d09a5Sjsing             {18200138, -14475911, -33087759, -2696619, -23702521, -9102511,
33475f5d09a5Sjsing              -23552096, -2287550, 20712163, 6719373},
33485f5d09a5Sjsing         },
33495f5d09a5Sjsing         {
33505f5d09a5Sjsing             {26656208, 6075253, -7858556, 1886072, -28344043, 4262326, 11117530,
33515f5d09a5Sjsing              -3763210, 26224235, -3297458},
33525f5d09a5Sjsing             {-17168938, -14854097, -3395676, -16369877, -19954045, 14050420,
33535f5d09a5Sjsing              21728352, 9493610, 18620611, -16428628},
33545f5d09a5Sjsing             {-13323321, 13325349, 11432106, 5964811, 18609221, 6062965,
33555f5d09a5Sjsing              -5269471, -9725556, -30701573, -16479657},
33565f5d09a5Sjsing         },
33575f5d09a5Sjsing         {
33585f5d09a5Sjsing             {-23860538, -11233159, 26961357, 1640861, -32413112, -16737940,
33595f5d09a5Sjsing              12248509, -5240639, 13735342, 1934062},
33605f5d09a5Sjsing             {25089769, 6742589, 17081145, -13406266, 21909293, -16067981,
33615f5d09a5Sjsing              -15136294, -3765346, -21277997, 5473616},
33625f5d09a5Sjsing             {31883677, -7961101, 1083432, -11572403, 22828471, 13290673,
33635f5d09a5Sjsing              -7125085, 12469656, 29111212, -5451014},
33645f5d09a5Sjsing         },
33655f5d09a5Sjsing         {
33665f5d09a5Sjsing             {24244947, -15050407, -26262976, 2791540, -14997599, 16666678,
33675f5d09a5Sjsing              24367466, 6388839, -10295587, 452383},
33685f5d09a5Sjsing             {-25640782, -3417841, 5217916, 16224624, 19987036, -4082269,
33695f5d09a5Sjsing              -24236251, -5915248, 15766062, 8407814},
33705f5d09a5Sjsing             {-20406999, 13990231, 15495425, 16395525, 5377168, 15166495,
33715f5d09a5Sjsing              -8917023, -4388953, -8067909, 2276718},
33725f5d09a5Sjsing         },
33735f5d09a5Sjsing         {
33745f5d09a5Sjsing             {30157918, 12924066, -17712050, 9245753, 19895028, 3368142,
33755f5d09a5Sjsing              -23827587, 5096219, 22740376, -7303417},
33765f5d09a5Sjsing             {2041139, -14256350, 7783687, 13876377, -25946985, -13352459,
33775f5d09a5Sjsing              24051124, 13742383, -15637599, 13295222},
33785f5d09a5Sjsing             {33338237, -8505733, 12532113, 7977527, 9106186, -1715251,
33795f5d09a5Sjsing              -17720195, -4612972, -4451357, -14669444},
33805f5d09a5Sjsing         },
33815f5d09a5Sjsing         {
33825f5d09a5Sjsing             {-20045281, 5454097, -14346548, 6447146, 28862071, 1883651,
33835f5d09a5Sjsing              -2469266, -4141880, 7770569, 9620597},
33845f5d09a5Sjsing             {23208068, 7979712, 33071466, 8149229, 1758231, -10834995, 30945528,
33855f5d09a5Sjsing              -1694323, -33502340, -14767970},
33865f5d09a5Sjsing             {1439958, -16270480, -1079989, -793782, 4625402, 10647766, -5043801,
33875f5d09a5Sjsing              1220118, 30494170, -11440799},
33885f5d09a5Sjsing         },
33895f5d09a5Sjsing         {
33905f5d09a5Sjsing             {-5037580, -13028295, -2970559, -3061767, 15640974, -6701666,
33915f5d09a5Sjsing              -26739026, 926050, -1684339, -13333647},
33925f5d09a5Sjsing             {13908495, -3549272, 30919928, -6273825, -21521863, 7989039,
33935f5d09a5Sjsing              9021034, 9078865, 3353509, 4033511},
33945f5d09a5Sjsing             {-29663431, -15113610, 32259991, -344482, 24295849, -12912123,
33955f5d09a5Sjsing              23161163, 8839127, 27485041, 7356032},
33965f5d09a5Sjsing         },
33975f5d09a5Sjsing     },
33985f5d09a5Sjsing     {
33995f5d09a5Sjsing         {
34005f5d09a5Sjsing             {9661027, 705443, 11980065, -5370154, -1628543, 14661173, -6346142,
34015f5d09a5Sjsing              2625015, 28431036, -16771834},
34025f5d09a5Sjsing             {-23839233, -8311415, -25945511, 7480958, -17681669, -8354183,
34035f5d09a5Sjsing              -22545972, 14150565, 15970762, 4099461},
34045f5d09a5Sjsing             {29262576, 16756590, 26350592, -8793563, 8529671, -11208050,
34055f5d09a5Sjsing              13617293, -9937143, 11465739, 8317062},
34065f5d09a5Sjsing         },
34075f5d09a5Sjsing         {
34085f5d09a5Sjsing             {-25493081, -6962928, 32500200, -9419051, -23038724, -2302222,
34095f5d09a5Sjsing              14898637, 3848455, 20969334, -5157516},
34105f5d09a5Sjsing             {-20384450, -14347713, -18336405, 13884722, -33039454, 2842114,
34115f5d09a5Sjsing              -21610826, -3649888, 11177095, 14989547},
34125f5d09a5Sjsing             {-24496721, -11716016, 16959896, 2278463, 12066309, 10137771,
34135f5d09a5Sjsing              13515641, 2581286, -28487508, 9930240},
34145f5d09a5Sjsing         },
34155f5d09a5Sjsing         {
34165f5d09a5Sjsing             {-17751622, -2097826, 16544300, -13009300, -15914807, -14949081,
34175f5d09a5Sjsing              18345767, -13403753, 16291481, -5314038},
34185f5d09a5Sjsing             {-33229194, 2553288, 32678213, 9875984, 8534129, 6889387, -9676774,
34195f5d09a5Sjsing              6957617, 4368891, 9788741},
34205f5d09a5Sjsing             {16660756, 7281060, -10830758, 12911820, 20108584, -8101676,
34215f5d09a5Sjsing              -21722536, -8613148, 16250552, -11111103},
34225f5d09a5Sjsing         },
34235f5d09a5Sjsing         {
34245f5d09a5Sjsing             {-19765507, 2390526, -16551031, 14161980, 1905286, 6414907, 4689584,
34255f5d09a5Sjsing              10604807, -30190403, 4782747},
34265f5d09a5Sjsing             {-1354539, 14736941, -7367442, -13292886, 7710542, -14155590,
34275f5d09a5Sjsing              -9981571, 4383045, 22546403, 437323},
34285f5d09a5Sjsing             {31665577, -12180464, -16186830, 1491339, -18368625, 3294682,
34295f5d09a5Sjsing              27343084, 2786261, -30633590, -14097016},
34305f5d09a5Sjsing         },
34315f5d09a5Sjsing         {
34325f5d09a5Sjsing             {-14467279, -683715, -33374107, 7448552, 19294360, 14334329,
34335f5d09a5Sjsing              -19690631, 2355319, -19284671, -6114373},
34345f5d09a5Sjsing             {15121312, -15796162, 6377020, -6031361, -10798111, -12957845,
34355f5d09a5Sjsing              18952177, 15496498, -29380133, 11754228},
34365f5d09a5Sjsing             {-2637277, -13483075, 8488727, -14303896, 12728761, -1622493,
34375f5d09a5Sjsing              7141596, 11724556, 22761615, -10134141},
34385f5d09a5Sjsing         },
34395f5d09a5Sjsing         {
34405f5d09a5Sjsing             {16918416, 11729663, -18083579, 3022987, -31015732, -13339659,
34415f5d09a5Sjsing              -28741185, -12227393, 32851222, 11717399},
34425f5d09a5Sjsing             {11166634, 7338049, -6722523, 4531520, -29468672, -7302055,
34435f5d09a5Sjsing              31474879, 3483633, -1193175, -4030831},
34445f5d09a5Sjsing             {-185635, 9921305, 31456609, -13536438, -12013818, 13348923,
34455f5d09a5Sjsing              33142652, 6546660, -19985279, -3948376},
34465f5d09a5Sjsing         },
34475f5d09a5Sjsing         {
34485f5d09a5Sjsing             {-32460596, 11266712, -11197107, -7899103, 31703694, 3855903,
34495f5d09a5Sjsing              -8537131, -12833048, -30772034, -15486313},
34505f5d09a5Sjsing             {-18006477, 12709068, 3991746, -6479188, -21491523, -10550425,
34515f5d09a5Sjsing              -31135347, -16049879, 10928917, 3011958},
34525f5d09a5Sjsing             {-6957757, -15594337, 31696059, 334240, 29576716, 14796075,
34535f5d09a5Sjsing              -30831056, -12805180, 18008031, 10258577},
34545f5d09a5Sjsing         },
34555f5d09a5Sjsing         {
34565f5d09a5Sjsing             {-22448644, 15655569, 7018479, -4410003, -30314266, -1201591,
34575f5d09a5Sjsing              -1853465, 1367120, 25127874, 6671743},
34585f5d09a5Sjsing             {29701166, -14373934, -10878120, 9279288, -17568, 13127210,
34595f5d09a5Sjsing              21382910, 11042292, 25838796, 4642684},
34605f5d09a5Sjsing             {-20430234, 14955537, -24126347, 8124619, -5369288, -5990470,
34615f5d09a5Sjsing              30468147, -13900640, 18423289, 4177476},
34625f5d09a5Sjsing         },
34635f5d09a5Sjsing     },
34645f5d09a5Sjsing };
34655f5d09a5Sjsing 
negative(signed char b)34665f5d09a5Sjsing static uint8_t negative(signed char b) {
34675f5d09a5Sjsing   uint32_t x = b;
34685f5d09a5Sjsing   x >>= 31; /* 1: yes; 0: no */
34695f5d09a5Sjsing   return x;
34705f5d09a5Sjsing }
34715f5d09a5Sjsing 
table_select(ge_precomp * t,int pos,signed char b)34725f5d09a5Sjsing static void table_select(ge_precomp *t, int pos, signed char b) {
34735f5d09a5Sjsing   ge_precomp minust;
34745f5d09a5Sjsing   uint8_t bnegative = negative(b);
34755f5d09a5Sjsing   uint8_t babs = b - ((uint8_t)((-bnegative) & b) << 1);
34765f5d09a5Sjsing 
34775f5d09a5Sjsing   ge_precomp_0(t);
34785f5d09a5Sjsing   cmov(t, &k25519Precomp[pos][0], equal(babs, 1));
34795f5d09a5Sjsing   cmov(t, &k25519Precomp[pos][1], equal(babs, 2));
34805f5d09a5Sjsing   cmov(t, &k25519Precomp[pos][2], equal(babs, 3));
34815f5d09a5Sjsing   cmov(t, &k25519Precomp[pos][3], equal(babs, 4));
34825f5d09a5Sjsing   cmov(t, &k25519Precomp[pos][4], equal(babs, 5));
34835f5d09a5Sjsing   cmov(t, &k25519Precomp[pos][5], equal(babs, 6));
34845f5d09a5Sjsing   cmov(t, &k25519Precomp[pos][6], equal(babs, 7));
34855f5d09a5Sjsing   cmov(t, &k25519Precomp[pos][7], equal(babs, 8));
34865f5d09a5Sjsing   fe_copy(minust.yplusx, t->yminusx);
34875f5d09a5Sjsing   fe_copy(minust.yminusx, t->yplusx);
34885f5d09a5Sjsing   fe_neg(minust.xy2d, t->xy2d);
34895f5d09a5Sjsing   cmov(t, &minust, bnegative);
34905f5d09a5Sjsing }
34915f5d09a5Sjsing 
34925f5d09a5Sjsing /* h = a * B
34935f5d09a5Sjsing  * where a = a[0]+256*a[1]+...+256^31 a[31]
34945f5d09a5Sjsing  * B is the Ed25519 base point (x,4/5) with x positive.
34955f5d09a5Sjsing  *
34965f5d09a5Sjsing  * Preconditions:
34975f5d09a5Sjsing  *   a[31] <= 127 */
x25519_ge_scalarmult_base(ge_p3 * h,const uint8_t a[32])349864ed187eStb void x25519_ge_scalarmult_base(ge_p3 *h, const uint8_t a[32]) {
34995f5d09a5Sjsing   signed char e[64];
35005f5d09a5Sjsing   signed char carry;
35015f5d09a5Sjsing   ge_p1p1 r;
35025f5d09a5Sjsing   ge_p2 s;
35035f5d09a5Sjsing   ge_precomp t;
35045f5d09a5Sjsing   int i;
35055f5d09a5Sjsing 
35065f5d09a5Sjsing   for (i = 0; i < 32; ++i) {
35075f5d09a5Sjsing     e[2 * i + 0] = (a[i] >> 0) & 15;
35085f5d09a5Sjsing     e[2 * i + 1] = (a[i] >> 4) & 15;
35095f5d09a5Sjsing   }
35105f5d09a5Sjsing   /* each e[i] is between 0 and 15 */
35115f5d09a5Sjsing   /* e[63] is between 0 and 7 */
35125f5d09a5Sjsing 
35135f5d09a5Sjsing   carry = 0;
35145f5d09a5Sjsing   for (i = 0; i < 63; ++i) {
35155f5d09a5Sjsing     e[i] += carry;
35165f5d09a5Sjsing     carry = e[i] + 8;
35175f5d09a5Sjsing     carry >>= 4;
35185f5d09a5Sjsing     e[i] -= carry << 4;
35195f5d09a5Sjsing   }
35205f5d09a5Sjsing   e[63] += carry;
35215f5d09a5Sjsing   /* each e[i] is between -8 and 8 */
35225f5d09a5Sjsing 
35235f5d09a5Sjsing   ge_p3_0(h);
35245f5d09a5Sjsing   for (i = 1; i < 64; i += 2) {
35255f5d09a5Sjsing     table_select(&t, i / 2, e[i]);
35265f5d09a5Sjsing     ge_madd(&r, h, &t);
35275f5d09a5Sjsing     x25519_ge_p1p1_to_p3(h, &r);
35285f5d09a5Sjsing   }
35295f5d09a5Sjsing 
35305f5d09a5Sjsing   ge_p3_dbl(&r, h);
35315f5d09a5Sjsing   x25519_ge_p1p1_to_p2(&s, &r);
35325f5d09a5Sjsing   ge_p2_dbl(&r, &s);
35335f5d09a5Sjsing   x25519_ge_p1p1_to_p2(&s, &r);
35345f5d09a5Sjsing   ge_p2_dbl(&r, &s);
35355f5d09a5Sjsing   x25519_ge_p1p1_to_p2(&s, &r);
35365f5d09a5Sjsing   ge_p2_dbl(&r, &s);
35375f5d09a5Sjsing   x25519_ge_p1p1_to_p3(h, &r);
35385f5d09a5Sjsing 
35395f5d09a5Sjsing   for (i = 0; i < 64; i += 2) {
35405f5d09a5Sjsing     table_select(&t, i / 2, e[i]);
35415f5d09a5Sjsing     ge_madd(&r, h, &t);
35425f5d09a5Sjsing     x25519_ge_p1p1_to_p3(h, &r);
35435f5d09a5Sjsing   }
35445f5d09a5Sjsing }
35455f5d09a5Sjsing 
35465f5d09a5Sjsing #endif
35475f5d09a5Sjsing 
cmov_cached(ge_cached * t,ge_cached * u,uint8_t b)35485f5d09a5Sjsing static void cmov_cached(ge_cached *t, ge_cached *u, uint8_t b) {
35495f5d09a5Sjsing   fe_cmov(t->YplusX, u->YplusX, b);
35505f5d09a5Sjsing   fe_cmov(t->YminusX, u->YminusX, b);
35515f5d09a5Sjsing   fe_cmov(t->Z, u->Z, b);
35525f5d09a5Sjsing   fe_cmov(t->T2d, u->T2d, b);
35535f5d09a5Sjsing }
35545f5d09a5Sjsing 
35555f5d09a5Sjsing /* r = scalar * A.
35565f5d09a5Sjsing  * where a = a[0]+256*a[1]+...+256^31 a[31]. */
x25519_ge_scalarmult(ge_p2 * r,const uint8_t * scalar,const ge_p3 * A)35575f5d09a5Sjsing void x25519_ge_scalarmult(ge_p2 *r, const uint8_t *scalar, const ge_p3 *A) {
35585f5d09a5Sjsing   ge_p2 Ai_p2[8];
35595f5d09a5Sjsing   ge_cached Ai[16];
35605f5d09a5Sjsing   ge_p1p1 t;
35615f5d09a5Sjsing 
35625f5d09a5Sjsing   ge_cached_0(&Ai[0]);
35635f5d09a5Sjsing   x25519_ge_p3_to_cached(&Ai[1], A);
35645f5d09a5Sjsing   ge_p3_to_p2(&Ai_p2[1], A);
35655f5d09a5Sjsing 
35665f5d09a5Sjsing   unsigned i;
35675f5d09a5Sjsing   for (i = 2; i < 16; i += 2) {
35685f5d09a5Sjsing     ge_p2_dbl(&t, &Ai_p2[i / 2]);
35695f5d09a5Sjsing     ge_p1p1_to_cached(&Ai[i], &t);
35705f5d09a5Sjsing     if (i < 8) {
35715f5d09a5Sjsing       x25519_ge_p1p1_to_p2(&Ai_p2[i], &t);
35725f5d09a5Sjsing     }
35735f5d09a5Sjsing     x25519_ge_add(&t, A, &Ai[i]);
35745f5d09a5Sjsing     ge_p1p1_to_cached(&Ai[i + 1], &t);
35755f5d09a5Sjsing     if (i < 7) {
35765f5d09a5Sjsing       x25519_ge_p1p1_to_p2(&Ai_p2[i + 1], &t);
35775f5d09a5Sjsing     }
35785f5d09a5Sjsing   }
35795f5d09a5Sjsing 
35805f5d09a5Sjsing   ge_p2_0(r);
35815f5d09a5Sjsing   ge_p3 u;
35825f5d09a5Sjsing 
35835f5d09a5Sjsing   for (i = 0; i < 256; i += 4) {
35845f5d09a5Sjsing     ge_p2_dbl(&t, r);
35855f5d09a5Sjsing     x25519_ge_p1p1_to_p2(r, &t);
35865f5d09a5Sjsing     ge_p2_dbl(&t, r);
35875f5d09a5Sjsing     x25519_ge_p1p1_to_p2(r, &t);
35885f5d09a5Sjsing     ge_p2_dbl(&t, r);
35895f5d09a5Sjsing     x25519_ge_p1p1_to_p2(r, &t);
35905f5d09a5Sjsing     ge_p2_dbl(&t, r);
35915f5d09a5Sjsing     x25519_ge_p1p1_to_p3(&u, &t);
35925f5d09a5Sjsing 
35935f5d09a5Sjsing     uint8_t index = scalar[31 - i/8];
35945f5d09a5Sjsing     index >>= 4 - (i & 4);
35955f5d09a5Sjsing     index &= 0xf;
35965f5d09a5Sjsing 
35975f5d09a5Sjsing     unsigned j;
35985f5d09a5Sjsing     ge_cached selected;
35995f5d09a5Sjsing     ge_cached_0(&selected);
36005f5d09a5Sjsing     for (j = 0; j < 16; j++) {
36015f5d09a5Sjsing       cmov_cached(&selected, &Ai[j], equal(j, index));
36025f5d09a5Sjsing     }
36035f5d09a5Sjsing 
36045f5d09a5Sjsing     x25519_ge_add(&t, &u, &selected);
36055f5d09a5Sjsing     x25519_ge_p1p1_to_p2(r, &t);
36065f5d09a5Sjsing   }
36075f5d09a5Sjsing }
36085f5d09a5Sjsing 
slide(signed char * r,const uint8_t * a)36095f5d09a5Sjsing static void slide(signed char *r, const uint8_t *a) {
36105f5d09a5Sjsing   int i;
36115f5d09a5Sjsing   int b;
36125f5d09a5Sjsing   int k;
36135f5d09a5Sjsing 
36145f5d09a5Sjsing   for (i = 0; i < 256; ++i) {
36155f5d09a5Sjsing     r[i] = 1 & (a[i >> 3] >> (i & 7));
36165f5d09a5Sjsing   }
36175f5d09a5Sjsing 
36185f5d09a5Sjsing   for (i = 0; i < 256; ++i) {
36195f5d09a5Sjsing     if (r[i]) {
36205f5d09a5Sjsing       for (b = 1; b <= 6 && i + b < 256; ++b) {
36215f5d09a5Sjsing         if (r[i + b]) {
36225f5d09a5Sjsing           if (r[i] + (r[i + b] << b) <= 15) {
36235f5d09a5Sjsing             r[i] += r[i + b] << b;
36245f5d09a5Sjsing             r[i + b] = 0;
36255f5d09a5Sjsing           } else if (r[i] - (r[i + b] << b) >= -15) {
36265f5d09a5Sjsing             r[i] -= r[i + b] << b;
36275f5d09a5Sjsing             for (k = i + b; k < 256; ++k) {
36285f5d09a5Sjsing               if (!r[k]) {
36295f5d09a5Sjsing                 r[k] = 1;
36305f5d09a5Sjsing                 break;
36315f5d09a5Sjsing               }
36325f5d09a5Sjsing               r[k] = 0;
36335f5d09a5Sjsing             }
36345f5d09a5Sjsing           } else {
36355f5d09a5Sjsing             break;
36365f5d09a5Sjsing           }
36375f5d09a5Sjsing         }
36385f5d09a5Sjsing       }
36395f5d09a5Sjsing     }
36405f5d09a5Sjsing   }
36415f5d09a5Sjsing }
36425f5d09a5Sjsing 
36435f5d09a5Sjsing static const ge_precomp Bi[8] = {
36445f5d09a5Sjsing     {
36455f5d09a5Sjsing         {25967493, -14356035, 29566456, 3660896, -12694345, 4014787, 27544626,
36465f5d09a5Sjsing          -11754271, -6079156, 2047605},
36475f5d09a5Sjsing         {-12545711, 934262, -2722910, 3049990, -727428, 9406986, 12720692,
36485f5d09a5Sjsing          5043384, 19500929, -15469378},
36495f5d09a5Sjsing         {-8738181, 4489570, 9688441, -14785194, 10184609, -12363380, 29287919,
36505f5d09a5Sjsing          11864899, -24514362, -4438546},
36515f5d09a5Sjsing     },
36525f5d09a5Sjsing     {
36535f5d09a5Sjsing         {15636291, -9688557, 24204773, -7912398, 616977, -16685262, 27787600,
36545f5d09a5Sjsing          -14772189, 28944400, -1550024},
36555f5d09a5Sjsing         {16568933, 4717097, -11556148, -1102322, 15682896, -11807043, 16354577,
36565f5d09a5Sjsing          -11775962, 7689662, 11199574},
36575f5d09a5Sjsing         {30464156, -5976125, -11779434, -15670865, 23220365, 15915852, 7512774,
36585f5d09a5Sjsing          10017326, -17749093, -9920357},
36595f5d09a5Sjsing     },
36605f5d09a5Sjsing     {
36615f5d09a5Sjsing         {10861363, 11473154, 27284546, 1981175, -30064349, 12577861, 32867885,
36625f5d09a5Sjsing          14515107, -15438304, 10819380},
36635f5d09a5Sjsing         {4708026, 6336745, 20377586, 9066809, -11272109, 6594696, -25653668,
36645f5d09a5Sjsing          12483688, -12668491, 5581306},
36655f5d09a5Sjsing         {19563160, 16186464, -29386857, 4097519, 10237984, -4348115, 28542350,
36665f5d09a5Sjsing          13850243, -23678021, -15815942},
36675f5d09a5Sjsing     },
36685f5d09a5Sjsing     {
36695f5d09a5Sjsing         {5153746, 9909285, 1723747, -2777874, 30523605, 5516873, 19480852,
36705f5d09a5Sjsing          5230134, -23952439, -15175766},
36715f5d09a5Sjsing         {-30269007, -3463509, 7665486, 10083793, 28475525, 1649722, 20654025,
36725f5d09a5Sjsing          16520125, 30598449, 7715701},
36735f5d09a5Sjsing         {28881845, 14381568, 9657904, 3680757, -20181635, 7843316, -31400660,
36745f5d09a5Sjsing          1370708, 29794553, -1409300},
36755f5d09a5Sjsing     },
36765f5d09a5Sjsing     {
36775f5d09a5Sjsing         {-22518993, -6692182, 14201702, -8745502, -23510406, 8844726, 18474211,
36785f5d09a5Sjsing          -1361450, -13062696, 13821877},
36795f5d09a5Sjsing         {-6455177, -7839871, 3374702, -4740862, -27098617, -10571707, 31655028,
36805f5d09a5Sjsing          -7212327, 18853322, -14220951},
36815f5d09a5Sjsing         {4566830, -12963868, -28974889, -12240689, -7602672, -2830569, -8514358,
36825f5d09a5Sjsing          -10431137, 2207753, -3209784},
36835f5d09a5Sjsing     },
36845f5d09a5Sjsing     {
36855f5d09a5Sjsing         {-25154831, -4185821, 29681144, 7868801, -6854661, -9423865, -12437364,
36865f5d09a5Sjsing          -663000, -31111463, -16132436},
36875f5d09a5Sjsing         {25576264, -2703214, 7349804, -11814844, 16472782, 9300885, 3844789,
36885f5d09a5Sjsing          15725684, 171356, 6466918},
36895f5d09a5Sjsing         {23103977, 13316479, 9739013, -16149481, 817875, -15038942, 8965339,
36905f5d09a5Sjsing          -14088058, -30714912, 16193877},
36915f5d09a5Sjsing     },
36925f5d09a5Sjsing     {
36935f5d09a5Sjsing         {-33521811, 3180713, -2394130, 14003687, -16903474, -16270840, 17238398,
36945f5d09a5Sjsing          4729455, -18074513, 9256800},
36955f5d09a5Sjsing         {-25182317, -4174131, 32336398, 5036987, -21236817, 11360617, 22616405,
36965f5d09a5Sjsing          9761698, -19827198, 630305},
36975f5d09a5Sjsing         {-13720693, 2639453, -24237460, -7406481, 9494427, -5774029, -6554551,
36985f5d09a5Sjsing          -15960994, -2449256, -14291300},
36995f5d09a5Sjsing     },
37005f5d09a5Sjsing     {
37015f5d09a5Sjsing         {-3151181, -5046075, 9282714, 6866145, -31907062, -863023, -18940575,
37025f5d09a5Sjsing          15033784, 25105118, -7894876},
37035f5d09a5Sjsing         {-24326370, 15950226, -31801215, -14592823, -11662737, -5090925,
37045f5d09a5Sjsing          1573892, -2625887, 2198790, -15804619},
37055f5d09a5Sjsing         {-3099351, 10324967, -2241613, 7453183, -5446979, -2735503, -13812022,
37065f5d09a5Sjsing          -16236442, -32461234, -12290683},
37075f5d09a5Sjsing     },
37085f5d09a5Sjsing };
37095f5d09a5Sjsing 
37105f5d09a5Sjsing /* r = a * A + b * B
37115f5d09a5Sjsing  * where a = a[0]+256*a[1]+...+256^31 a[31].
37125f5d09a5Sjsing  * and b = b[0]+256*b[1]+...+256^31 b[31].
37135f5d09a5Sjsing  * B is the Ed25519 base point (x,4/5) with x positive. */
37145f5d09a5Sjsing static void
ge_double_scalarmult_vartime(ge_p2 * r,const uint8_t * a,const ge_p3 * A,const uint8_t * b)37155f5d09a5Sjsing ge_double_scalarmult_vartime(ge_p2 *r, const uint8_t *a,
37165f5d09a5Sjsing     const ge_p3 *A, const uint8_t *b) {
37175f5d09a5Sjsing   signed char aslide[256];
37185f5d09a5Sjsing   signed char bslide[256];
37195f5d09a5Sjsing   ge_cached Ai[8]; /* A,3A,5A,7A,9A,11A,13A,15A */
37205f5d09a5Sjsing   ge_p1p1 t;
37215f5d09a5Sjsing   ge_p3 u;
37225f5d09a5Sjsing   ge_p3 A2;
37235f5d09a5Sjsing   int i;
37245f5d09a5Sjsing 
37255f5d09a5Sjsing   slide(aslide, a);
37265f5d09a5Sjsing   slide(bslide, b);
37275f5d09a5Sjsing 
37285f5d09a5Sjsing   x25519_ge_p3_to_cached(&Ai[0], A);
37295f5d09a5Sjsing   ge_p3_dbl(&t, A);
37305f5d09a5Sjsing   x25519_ge_p1p1_to_p3(&A2, &t);
37315f5d09a5Sjsing   x25519_ge_add(&t, &A2, &Ai[0]);
37325f5d09a5Sjsing   x25519_ge_p1p1_to_p3(&u, &t);
37335f5d09a5Sjsing   x25519_ge_p3_to_cached(&Ai[1], &u);
37345f5d09a5Sjsing   x25519_ge_add(&t, &A2, &Ai[1]);
37355f5d09a5Sjsing   x25519_ge_p1p1_to_p3(&u, &t);
37365f5d09a5Sjsing   x25519_ge_p3_to_cached(&Ai[2], &u);
37375f5d09a5Sjsing   x25519_ge_add(&t, &A2, &Ai[2]);
37385f5d09a5Sjsing   x25519_ge_p1p1_to_p3(&u, &t);
37395f5d09a5Sjsing   x25519_ge_p3_to_cached(&Ai[3], &u);
37405f5d09a5Sjsing   x25519_ge_add(&t, &A2, &Ai[3]);
37415f5d09a5Sjsing   x25519_ge_p1p1_to_p3(&u, &t);
37425f5d09a5Sjsing   x25519_ge_p3_to_cached(&Ai[4], &u);
37435f5d09a5Sjsing   x25519_ge_add(&t, &A2, &Ai[4]);
37445f5d09a5Sjsing   x25519_ge_p1p1_to_p3(&u, &t);
37455f5d09a5Sjsing   x25519_ge_p3_to_cached(&Ai[5], &u);
37465f5d09a5Sjsing   x25519_ge_add(&t, &A2, &Ai[5]);
37475f5d09a5Sjsing   x25519_ge_p1p1_to_p3(&u, &t);
37485f5d09a5Sjsing   x25519_ge_p3_to_cached(&Ai[6], &u);
37495f5d09a5Sjsing   x25519_ge_add(&t, &A2, &Ai[6]);
37505f5d09a5Sjsing   x25519_ge_p1p1_to_p3(&u, &t);
37515f5d09a5Sjsing   x25519_ge_p3_to_cached(&Ai[7], &u);
37525f5d09a5Sjsing 
37535f5d09a5Sjsing   ge_p2_0(r);
37545f5d09a5Sjsing 
37555f5d09a5Sjsing   for (i = 255; i >= 0; --i) {
37565f5d09a5Sjsing     if (aslide[i] || bslide[i]) {
37575f5d09a5Sjsing       break;
37585f5d09a5Sjsing     }
37595f5d09a5Sjsing   }
37605f5d09a5Sjsing 
37615f5d09a5Sjsing   for (; i >= 0; --i) {
37625f5d09a5Sjsing     ge_p2_dbl(&t, r);
37635f5d09a5Sjsing 
37645f5d09a5Sjsing     if (aslide[i] > 0) {
37655f5d09a5Sjsing       x25519_ge_p1p1_to_p3(&u, &t);
37665f5d09a5Sjsing       x25519_ge_add(&t, &u, &Ai[aslide[i] / 2]);
37675f5d09a5Sjsing     } else if (aslide[i] < 0) {
37685f5d09a5Sjsing       x25519_ge_p1p1_to_p3(&u, &t);
37695f5d09a5Sjsing       x25519_ge_sub(&t, &u, &Ai[(-aslide[i]) / 2]);
37705f5d09a5Sjsing     }
37715f5d09a5Sjsing 
37725f5d09a5Sjsing     if (bslide[i] > 0) {
37735f5d09a5Sjsing       x25519_ge_p1p1_to_p3(&u, &t);
37745f5d09a5Sjsing       ge_madd(&t, &u, &Bi[bslide[i] / 2]);
37755f5d09a5Sjsing     } else if (bslide[i] < 0) {
37765f5d09a5Sjsing       x25519_ge_p1p1_to_p3(&u, &t);
37775f5d09a5Sjsing       ge_msub(&t, &u, &Bi[(-bslide[i]) / 2]);
37785f5d09a5Sjsing     }
37795f5d09a5Sjsing 
37805f5d09a5Sjsing     x25519_ge_p1p1_to_p2(r, &t);
37815f5d09a5Sjsing   }
37825f5d09a5Sjsing }
37835f5d09a5Sjsing 
37845f5d09a5Sjsing /* The set of scalars is \Z/l
37855f5d09a5Sjsing  * where l = 2^252 + 27742317777372353535851937790883648493. */
37865f5d09a5Sjsing 
37875f5d09a5Sjsing /* Input:
37885f5d09a5Sjsing  *   s[0]+256*s[1]+...+256^63*s[63] = s
37895f5d09a5Sjsing  *
37905f5d09a5Sjsing  * Output:
37915f5d09a5Sjsing  *   s[0]+256*s[1]+...+256^31*s[31] = s mod l
37925f5d09a5Sjsing  *   where l = 2^252 + 27742317777372353535851937790883648493.
37935f5d09a5Sjsing  *   Overwrites s in place. */
37945f5d09a5Sjsing void
x25519_sc_reduce(uint8_t * s)37955f5d09a5Sjsing x25519_sc_reduce(uint8_t *s) {
37965f5d09a5Sjsing   int64_t s0 = 2097151 & load_3(s);
37975f5d09a5Sjsing   int64_t s1 = 2097151 & (load_4(s + 2) >> 5);
37985f5d09a5Sjsing   int64_t s2 = 2097151 & (load_3(s + 5) >> 2);
37995f5d09a5Sjsing   int64_t s3 = 2097151 & (load_4(s + 7) >> 7);
38005f5d09a5Sjsing   int64_t s4 = 2097151 & (load_4(s + 10) >> 4);
38015f5d09a5Sjsing   int64_t s5 = 2097151 & (load_3(s + 13) >> 1);
38025f5d09a5Sjsing   int64_t s6 = 2097151 & (load_4(s + 15) >> 6);
38035f5d09a5Sjsing   int64_t s7 = 2097151 & (load_3(s + 18) >> 3);
38045f5d09a5Sjsing   int64_t s8 = 2097151 & load_3(s + 21);
38055f5d09a5Sjsing   int64_t s9 = 2097151 & (load_4(s + 23) >> 5);
38065f5d09a5Sjsing   int64_t s10 = 2097151 & (load_3(s + 26) >> 2);
38075f5d09a5Sjsing   int64_t s11 = 2097151 & (load_4(s + 28) >> 7);
38085f5d09a5Sjsing   int64_t s12 = 2097151 & (load_4(s + 31) >> 4);
38095f5d09a5Sjsing   int64_t s13 = 2097151 & (load_3(s + 34) >> 1);
38105f5d09a5Sjsing   int64_t s14 = 2097151 & (load_4(s + 36) >> 6);
38115f5d09a5Sjsing   int64_t s15 = 2097151 & (load_3(s + 39) >> 3);
38125f5d09a5Sjsing   int64_t s16 = 2097151 & load_3(s + 42);
38135f5d09a5Sjsing   int64_t s17 = 2097151 & (load_4(s + 44) >> 5);
38145f5d09a5Sjsing   int64_t s18 = 2097151 & (load_3(s + 47) >> 2);
38155f5d09a5Sjsing   int64_t s19 = 2097151 & (load_4(s + 49) >> 7);
38165f5d09a5Sjsing   int64_t s20 = 2097151 & (load_4(s + 52) >> 4);
38175f5d09a5Sjsing   int64_t s21 = 2097151 & (load_3(s + 55) >> 1);
38185f5d09a5Sjsing   int64_t s22 = 2097151 & (load_4(s + 57) >> 6);
38195f5d09a5Sjsing   int64_t s23 = (load_4(s + 60) >> 3);
38205f5d09a5Sjsing   int64_t carry0;
38215f5d09a5Sjsing   int64_t carry1;
38225f5d09a5Sjsing   int64_t carry2;
38235f5d09a5Sjsing   int64_t carry3;
38245f5d09a5Sjsing   int64_t carry4;
38255f5d09a5Sjsing   int64_t carry5;
38265f5d09a5Sjsing   int64_t carry6;
38275f5d09a5Sjsing   int64_t carry7;
38285f5d09a5Sjsing   int64_t carry8;
38295f5d09a5Sjsing   int64_t carry9;
38305f5d09a5Sjsing   int64_t carry10;
38315f5d09a5Sjsing   int64_t carry11;
38325f5d09a5Sjsing   int64_t carry12;
38335f5d09a5Sjsing   int64_t carry13;
38345f5d09a5Sjsing   int64_t carry14;
38355f5d09a5Sjsing   int64_t carry15;
38365f5d09a5Sjsing   int64_t carry16;
38375f5d09a5Sjsing 
38385f5d09a5Sjsing   s11 += s23 * 666643;
38395f5d09a5Sjsing   s12 += s23 * 470296;
38405f5d09a5Sjsing   s13 += s23 * 654183;
38415f5d09a5Sjsing   s14 -= s23 * 997805;
38425f5d09a5Sjsing   s15 += s23 * 136657;
38435f5d09a5Sjsing   s16 -= s23 * 683901;
38445f5d09a5Sjsing   s23 = 0;
38455f5d09a5Sjsing 
38465f5d09a5Sjsing   s10 += s22 * 666643;
38475f5d09a5Sjsing   s11 += s22 * 470296;
38485f5d09a5Sjsing   s12 += s22 * 654183;
38495f5d09a5Sjsing   s13 -= s22 * 997805;
38505f5d09a5Sjsing   s14 += s22 * 136657;
38515f5d09a5Sjsing   s15 -= s22 * 683901;
38525f5d09a5Sjsing   s22 = 0;
38535f5d09a5Sjsing 
38545f5d09a5Sjsing   s9 += s21 * 666643;
38555f5d09a5Sjsing   s10 += s21 * 470296;
38565f5d09a5Sjsing   s11 += s21 * 654183;
38575f5d09a5Sjsing   s12 -= s21 * 997805;
38585f5d09a5Sjsing   s13 += s21 * 136657;
38595f5d09a5Sjsing   s14 -= s21 * 683901;
38605f5d09a5Sjsing   s21 = 0;
38615f5d09a5Sjsing 
38625f5d09a5Sjsing   s8 += s20 * 666643;
38635f5d09a5Sjsing   s9 += s20 * 470296;
38645f5d09a5Sjsing   s10 += s20 * 654183;
38655f5d09a5Sjsing   s11 -= s20 * 997805;
38665f5d09a5Sjsing   s12 += s20 * 136657;
38675f5d09a5Sjsing   s13 -= s20 * 683901;
38685f5d09a5Sjsing   s20 = 0;
38695f5d09a5Sjsing 
38705f5d09a5Sjsing   s7 += s19 * 666643;
38715f5d09a5Sjsing   s8 += s19 * 470296;
38725f5d09a5Sjsing   s9 += s19 * 654183;
38735f5d09a5Sjsing   s10 -= s19 * 997805;
38745f5d09a5Sjsing   s11 += s19 * 136657;
38755f5d09a5Sjsing   s12 -= s19 * 683901;
38765f5d09a5Sjsing   s19 = 0;
38775f5d09a5Sjsing 
38785f5d09a5Sjsing   s6 += s18 * 666643;
38795f5d09a5Sjsing   s7 += s18 * 470296;
38805f5d09a5Sjsing   s8 += s18 * 654183;
38815f5d09a5Sjsing   s9 -= s18 * 997805;
38825f5d09a5Sjsing   s10 += s18 * 136657;
38835f5d09a5Sjsing   s11 -= s18 * 683901;
38845f5d09a5Sjsing   s18 = 0;
38855f5d09a5Sjsing 
38865f5d09a5Sjsing   carry6 = (s6 + (1 << 20)) >> 21;
38875f5d09a5Sjsing   s7 += carry6;
38885f5d09a5Sjsing   s6 -= carry6 << 21;
38895f5d09a5Sjsing   carry8 = (s8 + (1 << 20)) >> 21;
38905f5d09a5Sjsing   s9 += carry8;
38915f5d09a5Sjsing   s8 -= carry8 << 21;
38925f5d09a5Sjsing   carry10 = (s10 + (1 << 20)) >> 21;
38935f5d09a5Sjsing   s11 += carry10;
38945f5d09a5Sjsing   s10 -= carry10 << 21;
38955f5d09a5Sjsing   carry12 = (s12 + (1 << 20)) >> 21;
38965f5d09a5Sjsing   s13 += carry12;
38975f5d09a5Sjsing   s12 -= carry12 << 21;
38985f5d09a5Sjsing   carry14 = (s14 + (1 << 20)) >> 21;
38995f5d09a5Sjsing   s15 += carry14;
39005f5d09a5Sjsing   s14 -= carry14 << 21;
39015f5d09a5Sjsing   carry16 = (s16 + (1 << 20)) >> 21;
39025f5d09a5Sjsing   s17 += carry16;
39035f5d09a5Sjsing   s16 -= carry16 << 21;
39045f5d09a5Sjsing 
39055f5d09a5Sjsing   carry7 = (s7 + (1 << 20)) >> 21;
39065f5d09a5Sjsing   s8 += carry7;
39075f5d09a5Sjsing   s7 -= carry7 << 21;
39085f5d09a5Sjsing   carry9 = (s9 + (1 << 20)) >> 21;
39095f5d09a5Sjsing   s10 += carry9;
39105f5d09a5Sjsing   s9 -= carry9 << 21;
39115f5d09a5Sjsing   carry11 = (s11 + (1 << 20)) >> 21;
39125f5d09a5Sjsing   s12 += carry11;
39135f5d09a5Sjsing   s11 -= carry11 << 21;
39145f5d09a5Sjsing   carry13 = (s13 + (1 << 20)) >> 21;
39155f5d09a5Sjsing   s14 += carry13;
39165f5d09a5Sjsing   s13 -= carry13 << 21;
39175f5d09a5Sjsing   carry15 = (s15 + (1 << 20)) >> 21;
39185f5d09a5Sjsing   s16 += carry15;
39195f5d09a5Sjsing   s15 -= carry15 << 21;
39205f5d09a5Sjsing 
39215f5d09a5Sjsing   s5 += s17 * 666643;
39225f5d09a5Sjsing   s6 += s17 * 470296;
39235f5d09a5Sjsing   s7 += s17 * 654183;
39245f5d09a5Sjsing   s8 -= s17 * 997805;
39255f5d09a5Sjsing   s9 += s17 * 136657;
39265f5d09a5Sjsing   s10 -= s17 * 683901;
39275f5d09a5Sjsing   s17 = 0;
39285f5d09a5Sjsing 
39295f5d09a5Sjsing   s4 += s16 * 666643;
39305f5d09a5Sjsing   s5 += s16 * 470296;
39315f5d09a5Sjsing   s6 += s16 * 654183;
39325f5d09a5Sjsing   s7 -= s16 * 997805;
39335f5d09a5Sjsing   s8 += s16 * 136657;
39345f5d09a5Sjsing   s9 -= s16 * 683901;
39355f5d09a5Sjsing   s16 = 0;
39365f5d09a5Sjsing 
39375f5d09a5Sjsing   s3 += s15 * 666643;
39385f5d09a5Sjsing   s4 += s15 * 470296;
39395f5d09a5Sjsing   s5 += s15 * 654183;
39405f5d09a5Sjsing   s6 -= s15 * 997805;
39415f5d09a5Sjsing   s7 += s15 * 136657;
39425f5d09a5Sjsing   s8 -= s15 * 683901;
39435f5d09a5Sjsing   s15 = 0;
39445f5d09a5Sjsing 
39455f5d09a5Sjsing   s2 += s14 * 666643;
39465f5d09a5Sjsing   s3 += s14 * 470296;
39475f5d09a5Sjsing   s4 += s14 * 654183;
39485f5d09a5Sjsing   s5 -= s14 * 997805;
39495f5d09a5Sjsing   s6 += s14 * 136657;
39505f5d09a5Sjsing   s7 -= s14 * 683901;
39515f5d09a5Sjsing   s14 = 0;
39525f5d09a5Sjsing 
39535f5d09a5Sjsing   s1 += s13 * 666643;
39545f5d09a5Sjsing   s2 += s13 * 470296;
39555f5d09a5Sjsing   s3 += s13 * 654183;
39565f5d09a5Sjsing   s4 -= s13 * 997805;
39575f5d09a5Sjsing   s5 += s13 * 136657;
39585f5d09a5Sjsing   s6 -= s13 * 683901;
39595f5d09a5Sjsing   s13 = 0;
39605f5d09a5Sjsing 
39615f5d09a5Sjsing   s0 += s12 * 666643;
39625f5d09a5Sjsing   s1 += s12 * 470296;
39635f5d09a5Sjsing   s2 += s12 * 654183;
39645f5d09a5Sjsing   s3 -= s12 * 997805;
39655f5d09a5Sjsing   s4 += s12 * 136657;
39665f5d09a5Sjsing   s5 -= s12 * 683901;
39675f5d09a5Sjsing   s12 = 0;
39685f5d09a5Sjsing 
39695f5d09a5Sjsing   carry0 = (s0 + (1 << 20)) >> 21;
39705f5d09a5Sjsing   s1 += carry0;
39715f5d09a5Sjsing   s0 -= carry0 << 21;
39725f5d09a5Sjsing   carry2 = (s2 + (1 << 20)) >> 21;
39735f5d09a5Sjsing   s3 += carry2;
39745f5d09a5Sjsing   s2 -= carry2 << 21;
39755f5d09a5Sjsing   carry4 = (s4 + (1 << 20)) >> 21;
39765f5d09a5Sjsing   s5 += carry4;
39775f5d09a5Sjsing   s4 -= carry4 << 21;
39785f5d09a5Sjsing   carry6 = (s6 + (1 << 20)) >> 21;
39795f5d09a5Sjsing   s7 += carry6;
39805f5d09a5Sjsing   s6 -= carry6 << 21;
39815f5d09a5Sjsing   carry8 = (s8 + (1 << 20)) >> 21;
39825f5d09a5Sjsing   s9 += carry8;
39835f5d09a5Sjsing   s8 -= carry8 << 21;
39845f5d09a5Sjsing   carry10 = (s10 + (1 << 20)) >> 21;
39855f5d09a5Sjsing   s11 += carry10;
39865f5d09a5Sjsing   s10 -= carry10 << 21;
39875f5d09a5Sjsing 
39885f5d09a5Sjsing   carry1 = (s1 + (1 << 20)) >> 21;
39895f5d09a5Sjsing   s2 += carry1;
39905f5d09a5Sjsing   s1 -= carry1 << 21;
39915f5d09a5Sjsing   carry3 = (s3 + (1 << 20)) >> 21;
39925f5d09a5Sjsing   s4 += carry3;
39935f5d09a5Sjsing   s3 -= carry3 << 21;
39945f5d09a5Sjsing   carry5 = (s5 + (1 << 20)) >> 21;
39955f5d09a5Sjsing   s6 += carry5;
39965f5d09a5Sjsing   s5 -= carry5 << 21;
39975f5d09a5Sjsing   carry7 = (s7 + (1 << 20)) >> 21;
39985f5d09a5Sjsing   s8 += carry7;
39995f5d09a5Sjsing   s7 -= carry7 << 21;
40005f5d09a5Sjsing   carry9 = (s9 + (1 << 20)) >> 21;
40015f5d09a5Sjsing   s10 += carry9;
40025f5d09a5Sjsing   s9 -= carry9 << 21;
40035f5d09a5Sjsing   carry11 = (s11 + (1 << 20)) >> 21;
40045f5d09a5Sjsing   s12 += carry11;
40055f5d09a5Sjsing   s11 -= carry11 << 21;
40065f5d09a5Sjsing 
40075f5d09a5Sjsing   s0 += s12 * 666643;
40085f5d09a5Sjsing   s1 += s12 * 470296;
40095f5d09a5Sjsing   s2 += s12 * 654183;
40105f5d09a5Sjsing   s3 -= s12 * 997805;
40115f5d09a5Sjsing   s4 += s12 * 136657;
40125f5d09a5Sjsing   s5 -= s12 * 683901;
40135f5d09a5Sjsing   s12 = 0;
40145f5d09a5Sjsing 
40155f5d09a5Sjsing   carry0 = s0 >> 21;
40165f5d09a5Sjsing   s1 += carry0;
40175f5d09a5Sjsing   s0 -= carry0 << 21;
40185f5d09a5Sjsing   carry1 = s1 >> 21;
40195f5d09a5Sjsing   s2 += carry1;
40205f5d09a5Sjsing   s1 -= carry1 << 21;
40215f5d09a5Sjsing   carry2 = s2 >> 21;
40225f5d09a5Sjsing   s3 += carry2;
40235f5d09a5Sjsing   s2 -= carry2 << 21;
40245f5d09a5Sjsing   carry3 = s3 >> 21;
40255f5d09a5Sjsing   s4 += carry3;
40265f5d09a5Sjsing   s3 -= carry3 << 21;
40275f5d09a5Sjsing   carry4 = s4 >> 21;
40285f5d09a5Sjsing   s5 += carry4;
40295f5d09a5Sjsing   s4 -= carry4 << 21;
40305f5d09a5Sjsing   carry5 = s5 >> 21;
40315f5d09a5Sjsing   s6 += carry5;
40325f5d09a5Sjsing   s5 -= carry5 << 21;
40335f5d09a5Sjsing   carry6 = s6 >> 21;
40345f5d09a5Sjsing   s7 += carry6;
40355f5d09a5Sjsing   s6 -= carry6 << 21;
40365f5d09a5Sjsing   carry7 = s7 >> 21;
40375f5d09a5Sjsing   s8 += carry7;
40385f5d09a5Sjsing   s7 -= carry7 << 21;
40395f5d09a5Sjsing   carry8 = s8 >> 21;
40405f5d09a5Sjsing   s9 += carry8;
40415f5d09a5Sjsing   s8 -= carry8 << 21;
40425f5d09a5Sjsing   carry9 = s9 >> 21;
40435f5d09a5Sjsing   s10 += carry9;
40445f5d09a5Sjsing   s9 -= carry9 << 21;
40455f5d09a5Sjsing   carry10 = s10 >> 21;
40465f5d09a5Sjsing   s11 += carry10;
40475f5d09a5Sjsing   s10 -= carry10 << 21;
40485f5d09a5Sjsing   carry11 = s11 >> 21;
40495f5d09a5Sjsing   s12 += carry11;
40505f5d09a5Sjsing   s11 -= carry11 << 21;
40515f5d09a5Sjsing 
40525f5d09a5Sjsing   s0 += s12 * 666643;
40535f5d09a5Sjsing   s1 += s12 * 470296;
40545f5d09a5Sjsing   s2 += s12 * 654183;
40555f5d09a5Sjsing   s3 -= s12 * 997805;
40565f5d09a5Sjsing   s4 += s12 * 136657;
40575f5d09a5Sjsing   s5 -= s12 * 683901;
40585f5d09a5Sjsing   s12 = 0;
40595f5d09a5Sjsing 
40605f5d09a5Sjsing   carry0 = s0 >> 21;
40615f5d09a5Sjsing   s1 += carry0;
40625f5d09a5Sjsing   s0 -= carry0 << 21;
40635f5d09a5Sjsing   carry1 = s1 >> 21;
40645f5d09a5Sjsing   s2 += carry1;
40655f5d09a5Sjsing   s1 -= carry1 << 21;
40665f5d09a5Sjsing   carry2 = s2 >> 21;
40675f5d09a5Sjsing   s3 += carry2;
40685f5d09a5Sjsing   s2 -= carry2 << 21;
40695f5d09a5Sjsing   carry3 = s3 >> 21;
40705f5d09a5Sjsing   s4 += carry3;
40715f5d09a5Sjsing   s3 -= carry3 << 21;
40725f5d09a5Sjsing   carry4 = s4 >> 21;
40735f5d09a5Sjsing   s5 += carry4;
40745f5d09a5Sjsing   s4 -= carry4 << 21;
40755f5d09a5Sjsing   carry5 = s5 >> 21;
40765f5d09a5Sjsing   s6 += carry5;
40775f5d09a5Sjsing   s5 -= carry5 << 21;
40785f5d09a5Sjsing   carry6 = s6 >> 21;
40795f5d09a5Sjsing   s7 += carry6;
40805f5d09a5Sjsing   s6 -= carry6 << 21;
40815f5d09a5Sjsing   carry7 = s7 >> 21;
40825f5d09a5Sjsing   s8 += carry7;
40835f5d09a5Sjsing   s7 -= carry7 << 21;
40845f5d09a5Sjsing   carry8 = s8 >> 21;
40855f5d09a5Sjsing   s9 += carry8;
40865f5d09a5Sjsing   s8 -= carry8 << 21;
40875f5d09a5Sjsing   carry9 = s9 >> 21;
40885f5d09a5Sjsing   s10 += carry9;
40895f5d09a5Sjsing   s9 -= carry9 << 21;
40905f5d09a5Sjsing   carry10 = s10 >> 21;
40915f5d09a5Sjsing   s11 += carry10;
40925f5d09a5Sjsing   s10 -= carry10 << 21;
40935f5d09a5Sjsing 
40945f5d09a5Sjsing   s[0] = s0 >> 0;
40955f5d09a5Sjsing   s[1] = s0 >> 8;
40965f5d09a5Sjsing   s[2] = (s0 >> 16) | (s1 << 5);
40975f5d09a5Sjsing   s[3] = s1 >> 3;
40985f5d09a5Sjsing   s[4] = s1 >> 11;
40995f5d09a5Sjsing   s[5] = (s1 >> 19) | (s2 << 2);
41005f5d09a5Sjsing   s[6] = s2 >> 6;
41015f5d09a5Sjsing   s[7] = (s2 >> 14) | (s3 << 7);
41025f5d09a5Sjsing   s[8] = s3 >> 1;
41035f5d09a5Sjsing   s[9] = s3 >> 9;
41045f5d09a5Sjsing   s[10] = (s3 >> 17) | (s4 << 4);
41055f5d09a5Sjsing   s[11] = s4 >> 4;
41065f5d09a5Sjsing   s[12] = s4 >> 12;
41075f5d09a5Sjsing   s[13] = (s4 >> 20) | (s5 << 1);
41085f5d09a5Sjsing   s[14] = s5 >> 7;
41095f5d09a5Sjsing   s[15] = (s5 >> 15) | (s6 << 6);
41105f5d09a5Sjsing   s[16] = s6 >> 2;
41115f5d09a5Sjsing   s[17] = s6 >> 10;
41125f5d09a5Sjsing   s[18] = (s6 >> 18) | (s7 << 3);
41135f5d09a5Sjsing   s[19] = s7 >> 5;
41145f5d09a5Sjsing   s[20] = s7 >> 13;
41155f5d09a5Sjsing   s[21] = s8 >> 0;
41165f5d09a5Sjsing   s[22] = s8 >> 8;
41175f5d09a5Sjsing   s[23] = (s8 >> 16) | (s9 << 5);
41185f5d09a5Sjsing   s[24] = s9 >> 3;
41195f5d09a5Sjsing   s[25] = s9 >> 11;
41205f5d09a5Sjsing   s[26] = (s9 >> 19) | (s10 << 2);
41215f5d09a5Sjsing   s[27] = s10 >> 6;
41225f5d09a5Sjsing   s[28] = (s10 >> 14) | (s11 << 7);
41235f5d09a5Sjsing   s[29] = s11 >> 1;
41245f5d09a5Sjsing   s[30] = s11 >> 9;
41255f5d09a5Sjsing   s[31] = s11 >> 17;
41265f5d09a5Sjsing }
41275f5d09a5Sjsing 
41285f5d09a5Sjsing /* Input:
41295f5d09a5Sjsing  *   a[0]+256*a[1]+...+256^31*a[31] = a
41305f5d09a5Sjsing  *   b[0]+256*b[1]+...+256^31*b[31] = b
41315f5d09a5Sjsing  *   c[0]+256*c[1]+...+256^31*c[31] = c
41325f5d09a5Sjsing  *
41335f5d09a5Sjsing  * Output:
41345f5d09a5Sjsing  *   s[0]+256*s[1]+...+256^31*s[31] = (ab+c) mod l
41355f5d09a5Sjsing  *   where l = 2^252 + 27742317777372353535851937790883648493. */
41365f5d09a5Sjsing static void
sc_muladd(uint8_t * s,const uint8_t * a,const uint8_t * b,const uint8_t * c)41375f5d09a5Sjsing sc_muladd(uint8_t *s, const uint8_t *a, const uint8_t *b,
41385f5d09a5Sjsing     const uint8_t *c)
41395f5d09a5Sjsing {
41405f5d09a5Sjsing   int64_t a0 = 2097151 & load_3(a);
41415f5d09a5Sjsing   int64_t a1 = 2097151 & (load_4(a + 2) >> 5);
41425f5d09a5Sjsing   int64_t a2 = 2097151 & (load_3(a + 5) >> 2);
41435f5d09a5Sjsing   int64_t a3 = 2097151 & (load_4(a + 7) >> 7);
41445f5d09a5Sjsing   int64_t a4 = 2097151 & (load_4(a + 10) >> 4);
41455f5d09a5Sjsing   int64_t a5 = 2097151 & (load_3(a + 13) >> 1);
41465f5d09a5Sjsing   int64_t a6 = 2097151 & (load_4(a + 15) >> 6);
41475f5d09a5Sjsing   int64_t a7 = 2097151 & (load_3(a + 18) >> 3);
41485f5d09a5Sjsing   int64_t a8 = 2097151 & load_3(a + 21);
41495f5d09a5Sjsing   int64_t a9 = 2097151 & (load_4(a + 23) >> 5);
41505f5d09a5Sjsing   int64_t a10 = 2097151 & (load_3(a + 26) >> 2);
41515f5d09a5Sjsing   int64_t a11 = (load_4(a + 28) >> 7);
41525f5d09a5Sjsing   int64_t b0 = 2097151 & load_3(b);
41535f5d09a5Sjsing   int64_t b1 = 2097151 & (load_4(b + 2) >> 5);
41545f5d09a5Sjsing   int64_t b2 = 2097151 & (load_3(b + 5) >> 2);
41555f5d09a5Sjsing   int64_t b3 = 2097151 & (load_4(b + 7) >> 7);
41565f5d09a5Sjsing   int64_t b4 = 2097151 & (load_4(b + 10) >> 4);
41575f5d09a5Sjsing   int64_t b5 = 2097151 & (load_3(b + 13) >> 1);
41585f5d09a5Sjsing   int64_t b6 = 2097151 & (load_4(b + 15) >> 6);
41595f5d09a5Sjsing   int64_t b7 = 2097151 & (load_3(b + 18) >> 3);
41605f5d09a5Sjsing   int64_t b8 = 2097151 & load_3(b + 21);
41615f5d09a5Sjsing   int64_t b9 = 2097151 & (load_4(b + 23) >> 5);
41625f5d09a5Sjsing   int64_t b10 = 2097151 & (load_3(b + 26) >> 2);
41635f5d09a5Sjsing   int64_t b11 = (load_4(b + 28) >> 7);
41645f5d09a5Sjsing   int64_t c0 = 2097151 & load_3(c);
41655f5d09a5Sjsing   int64_t c1 = 2097151 & (load_4(c + 2) >> 5);
41665f5d09a5Sjsing   int64_t c2 = 2097151 & (load_3(c + 5) >> 2);
41675f5d09a5Sjsing   int64_t c3 = 2097151 & (load_4(c + 7) >> 7);
41685f5d09a5Sjsing   int64_t c4 = 2097151 & (load_4(c + 10) >> 4);
41695f5d09a5Sjsing   int64_t c5 = 2097151 & (load_3(c + 13) >> 1);
41705f5d09a5Sjsing   int64_t c6 = 2097151 & (load_4(c + 15) >> 6);
41715f5d09a5Sjsing   int64_t c7 = 2097151 & (load_3(c + 18) >> 3);
41725f5d09a5Sjsing   int64_t c8 = 2097151 & load_3(c + 21);
41735f5d09a5Sjsing   int64_t c9 = 2097151 & (load_4(c + 23) >> 5);
41745f5d09a5Sjsing   int64_t c10 = 2097151 & (load_3(c + 26) >> 2);
41755f5d09a5Sjsing   int64_t c11 = (load_4(c + 28) >> 7);
41765f5d09a5Sjsing   int64_t s0;
41775f5d09a5Sjsing   int64_t s1;
41785f5d09a5Sjsing   int64_t s2;
41795f5d09a5Sjsing   int64_t s3;
41805f5d09a5Sjsing   int64_t s4;
41815f5d09a5Sjsing   int64_t s5;
41825f5d09a5Sjsing   int64_t s6;
41835f5d09a5Sjsing   int64_t s7;
41845f5d09a5Sjsing   int64_t s8;
41855f5d09a5Sjsing   int64_t s9;
41865f5d09a5Sjsing   int64_t s10;
41875f5d09a5Sjsing   int64_t s11;
41885f5d09a5Sjsing   int64_t s12;
41895f5d09a5Sjsing   int64_t s13;
41905f5d09a5Sjsing   int64_t s14;
41915f5d09a5Sjsing   int64_t s15;
41925f5d09a5Sjsing   int64_t s16;
41935f5d09a5Sjsing   int64_t s17;
41945f5d09a5Sjsing   int64_t s18;
41955f5d09a5Sjsing   int64_t s19;
41965f5d09a5Sjsing   int64_t s20;
41975f5d09a5Sjsing   int64_t s21;
41985f5d09a5Sjsing   int64_t s22;
41995f5d09a5Sjsing   int64_t s23;
42005f5d09a5Sjsing   int64_t carry0;
42015f5d09a5Sjsing   int64_t carry1;
42025f5d09a5Sjsing   int64_t carry2;
42035f5d09a5Sjsing   int64_t carry3;
42045f5d09a5Sjsing   int64_t carry4;
42055f5d09a5Sjsing   int64_t carry5;
42065f5d09a5Sjsing   int64_t carry6;
42075f5d09a5Sjsing   int64_t carry7;
42085f5d09a5Sjsing   int64_t carry8;
42095f5d09a5Sjsing   int64_t carry9;
42105f5d09a5Sjsing   int64_t carry10;
42115f5d09a5Sjsing   int64_t carry11;
42125f5d09a5Sjsing   int64_t carry12;
42135f5d09a5Sjsing   int64_t carry13;
42145f5d09a5Sjsing   int64_t carry14;
42155f5d09a5Sjsing   int64_t carry15;
42165f5d09a5Sjsing   int64_t carry16;
42175f5d09a5Sjsing   int64_t carry17;
42185f5d09a5Sjsing   int64_t carry18;
42195f5d09a5Sjsing   int64_t carry19;
42205f5d09a5Sjsing   int64_t carry20;
42215f5d09a5Sjsing   int64_t carry21;
42225f5d09a5Sjsing   int64_t carry22;
42235f5d09a5Sjsing 
42245f5d09a5Sjsing   s0 = c0 + a0 * b0;
42255f5d09a5Sjsing   s1 = c1 + a0 * b1 + a1 * b0;
42265f5d09a5Sjsing   s2 = c2 + a0 * b2 + a1 * b1 + a2 * b0;
42275f5d09a5Sjsing   s3 = c3 + a0 * b3 + a1 * b2 + a2 * b1 + a3 * b0;
42285f5d09a5Sjsing   s4 = c4 + a0 * b4 + a1 * b3 + a2 * b2 + a3 * b1 + a4 * b0;
42295f5d09a5Sjsing   s5 = c5 + a0 * b5 + a1 * b4 + a2 * b3 + a3 * b2 + a4 * b1 + a5 * b0;
42305f5d09a5Sjsing   s6 = c6 + a0 * b6 + a1 * b5 + a2 * b4 + a3 * b3 + a4 * b2 + a5 * b1 + a6 * b0;
42315f5d09a5Sjsing   s7 = c7 + a0 * b7 + a1 * b6 + a2 * b5 + a3 * b4 + a4 * b3 + a5 * b2 +
42325f5d09a5Sjsing        a6 * b1 + a7 * b0;
42335f5d09a5Sjsing   s8 = c8 + a0 * b8 + a1 * b7 + a2 * b6 + a3 * b5 + a4 * b4 + a5 * b3 +
42345f5d09a5Sjsing        a6 * b2 + a7 * b1 + a8 * b0;
42355f5d09a5Sjsing   s9 = c9 + a0 * b9 + a1 * b8 + a2 * b7 + a3 * b6 + a4 * b5 + a5 * b4 +
42365f5d09a5Sjsing        a6 * b3 + a7 * b2 + a8 * b1 + a9 * b0;
42375f5d09a5Sjsing   s10 = c10 + a0 * b10 + a1 * b9 + a2 * b8 + a3 * b7 + a4 * b6 + a5 * b5 +
42385f5d09a5Sjsing         a6 * b4 + a7 * b3 + a8 * b2 + a9 * b1 + a10 * b0;
42395f5d09a5Sjsing   s11 = c11 + a0 * b11 + a1 * b10 + a2 * b9 + a3 * b8 + a4 * b7 + a5 * b6 +
42405f5d09a5Sjsing         a6 * b5 + a7 * b4 + a8 * b3 + a9 * b2 + a10 * b1 + a11 * b0;
42415f5d09a5Sjsing   s12 = a1 * b11 + a2 * b10 + a3 * b9 + a4 * b8 + a5 * b7 + a6 * b6 + a7 * b5 +
42425f5d09a5Sjsing         a8 * b4 + a9 * b3 + a10 * b2 + a11 * b1;
42435f5d09a5Sjsing   s13 = a2 * b11 + a3 * b10 + a4 * b9 + a5 * b8 + a6 * b7 + a7 * b6 + a8 * b5 +
42445f5d09a5Sjsing         a9 * b4 + a10 * b3 + a11 * b2;
42455f5d09a5Sjsing   s14 = a3 * b11 + a4 * b10 + a5 * b9 + a6 * b8 + a7 * b7 + a8 * b6 + a9 * b5 +
42465f5d09a5Sjsing         a10 * b4 + a11 * b3;
42475f5d09a5Sjsing   s15 = a4 * b11 + a5 * b10 + a6 * b9 + a7 * b8 + a8 * b7 + a9 * b6 + a10 * b5 +
42485f5d09a5Sjsing         a11 * b4;
42495f5d09a5Sjsing   s16 = a5 * b11 + a6 * b10 + a7 * b9 + a8 * b8 + a9 * b7 + a10 * b6 + a11 * b5;
42505f5d09a5Sjsing   s17 = a6 * b11 + a7 * b10 + a8 * b9 + a9 * b8 + a10 * b7 + a11 * b6;
42515f5d09a5Sjsing   s18 = a7 * b11 + a8 * b10 + a9 * b9 + a10 * b8 + a11 * b7;
42525f5d09a5Sjsing   s19 = a8 * b11 + a9 * b10 + a10 * b9 + a11 * b8;
42535f5d09a5Sjsing   s20 = a9 * b11 + a10 * b10 + a11 * b9;
42545f5d09a5Sjsing   s21 = a10 * b11 + a11 * b10;
42555f5d09a5Sjsing   s22 = a11 * b11;
42565f5d09a5Sjsing   s23 = 0;
42575f5d09a5Sjsing 
42585f5d09a5Sjsing   carry0 = (s0 + (1 << 20)) >> 21;
42595f5d09a5Sjsing   s1 += carry0;
42605f5d09a5Sjsing   s0 -= carry0 << 21;
42615f5d09a5Sjsing   carry2 = (s2 + (1 << 20)) >> 21;
42625f5d09a5Sjsing   s3 += carry2;
42635f5d09a5Sjsing   s2 -= carry2 << 21;
42645f5d09a5Sjsing   carry4 = (s4 + (1 << 20)) >> 21;
42655f5d09a5Sjsing   s5 += carry4;
42665f5d09a5Sjsing   s4 -= carry4 << 21;
42675f5d09a5Sjsing   carry6 = (s6 + (1 << 20)) >> 21;
42685f5d09a5Sjsing   s7 += carry6;
42695f5d09a5Sjsing   s6 -= carry6 << 21;
42705f5d09a5Sjsing   carry8 = (s8 + (1 << 20)) >> 21;
42715f5d09a5Sjsing   s9 += carry8;
42725f5d09a5Sjsing   s8 -= carry8 << 21;
42735f5d09a5Sjsing   carry10 = (s10 + (1 << 20)) >> 21;
42745f5d09a5Sjsing   s11 += carry10;
42755f5d09a5Sjsing   s10 -= carry10 << 21;
42765f5d09a5Sjsing   carry12 = (s12 + (1 << 20)) >> 21;
42775f5d09a5Sjsing   s13 += carry12;
42785f5d09a5Sjsing   s12 -= carry12 << 21;
42795f5d09a5Sjsing   carry14 = (s14 + (1 << 20)) >> 21;
42805f5d09a5Sjsing   s15 += carry14;
42815f5d09a5Sjsing   s14 -= carry14 << 21;
42825f5d09a5Sjsing   carry16 = (s16 + (1 << 20)) >> 21;
42835f5d09a5Sjsing   s17 += carry16;
42845f5d09a5Sjsing   s16 -= carry16 << 21;
42855f5d09a5Sjsing   carry18 = (s18 + (1 << 20)) >> 21;
42865f5d09a5Sjsing   s19 += carry18;
42875f5d09a5Sjsing   s18 -= carry18 << 21;
42885f5d09a5Sjsing   carry20 = (s20 + (1 << 20)) >> 21;
42895f5d09a5Sjsing   s21 += carry20;
42905f5d09a5Sjsing   s20 -= carry20 << 21;
42915f5d09a5Sjsing   carry22 = (s22 + (1 << 20)) >> 21;
42925f5d09a5Sjsing   s23 += carry22;
42935f5d09a5Sjsing   s22 -= carry22 << 21;
42945f5d09a5Sjsing 
42955f5d09a5Sjsing   carry1 = (s1 + (1 << 20)) >> 21;
42965f5d09a5Sjsing   s2 += carry1;
42975f5d09a5Sjsing   s1 -= carry1 << 21;
42985f5d09a5Sjsing   carry3 = (s3 + (1 << 20)) >> 21;
42995f5d09a5Sjsing   s4 += carry3;
43005f5d09a5Sjsing   s3 -= carry3 << 21;
43015f5d09a5Sjsing   carry5 = (s5 + (1 << 20)) >> 21;
43025f5d09a5Sjsing   s6 += carry5;
43035f5d09a5Sjsing   s5 -= carry5 << 21;
43045f5d09a5Sjsing   carry7 = (s7 + (1 << 20)) >> 21;
43055f5d09a5Sjsing   s8 += carry7;
43065f5d09a5Sjsing   s7 -= carry7 << 21;
43075f5d09a5Sjsing   carry9 = (s9 + (1 << 20)) >> 21;
43085f5d09a5Sjsing   s10 += carry9;
43095f5d09a5Sjsing   s9 -= carry9 << 21;
43105f5d09a5Sjsing   carry11 = (s11 + (1 << 20)) >> 21;
43115f5d09a5Sjsing   s12 += carry11;
43125f5d09a5Sjsing   s11 -= carry11 << 21;
43135f5d09a5Sjsing   carry13 = (s13 + (1 << 20)) >> 21;
43145f5d09a5Sjsing   s14 += carry13;
43155f5d09a5Sjsing   s13 -= carry13 << 21;
43165f5d09a5Sjsing   carry15 = (s15 + (1 << 20)) >> 21;
43175f5d09a5Sjsing   s16 += carry15;
43185f5d09a5Sjsing   s15 -= carry15 << 21;
43195f5d09a5Sjsing   carry17 = (s17 + (1 << 20)) >> 21;
43205f5d09a5Sjsing   s18 += carry17;
43215f5d09a5Sjsing   s17 -= carry17 << 21;
43225f5d09a5Sjsing   carry19 = (s19 + (1 << 20)) >> 21;
43235f5d09a5Sjsing   s20 += carry19;
43245f5d09a5Sjsing   s19 -= carry19 << 21;
43255f5d09a5Sjsing   carry21 = (s21 + (1 << 20)) >> 21;
43265f5d09a5Sjsing   s22 += carry21;
43275f5d09a5Sjsing   s21 -= carry21 << 21;
43285f5d09a5Sjsing 
43295f5d09a5Sjsing   s11 += s23 * 666643;
43305f5d09a5Sjsing   s12 += s23 * 470296;
43315f5d09a5Sjsing   s13 += s23 * 654183;
43325f5d09a5Sjsing   s14 -= s23 * 997805;
43335f5d09a5Sjsing   s15 += s23 * 136657;
43345f5d09a5Sjsing   s16 -= s23 * 683901;
43355f5d09a5Sjsing   s23 = 0;
43365f5d09a5Sjsing 
43375f5d09a5Sjsing   s10 += s22 * 666643;
43385f5d09a5Sjsing   s11 += s22 * 470296;
43395f5d09a5Sjsing   s12 += s22 * 654183;
43405f5d09a5Sjsing   s13 -= s22 * 997805;
43415f5d09a5Sjsing   s14 += s22 * 136657;
43425f5d09a5Sjsing   s15 -= s22 * 683901;
43435f5d09a5Sjsing   s22 = 0;
43445f5d09a5Sjsing 
43455f5d09a5Sjsing   s9 += s21 * 666643;
43465f5d09a5Sjsing   s10 += s21 * 470296;
43475f5d09a5Sjsing   s11 += s21 * 654183;
43485f5d09a5Sjsing   s12 -= s21 * 997805;
43495f5d09a5Sjsing   s13 += s21 * 136657;
43505f5d09a5Sjsing   s14 -= s21 * 683901;
43515f5d09a5Sjsing   s21 = 0;
43525f5d09a5Sjsing 
43535f5d09a5Sjsing   s8 += s20 * 666643;
43545f5d09a5Sjsing   s9 += s20 * 470296;
43555f5d09a5Sjsing   s10 += s20 * 654183;
43565f5d09a5Sjsing   s11 -= s20 * 997805;
43575f5d09a5Sjsing   s12 += s20 * 136657;
43585f5d09a5Sjsing   s13 -= s20 * 683901;
43595f5d09a5Sjsing   s20 = 0;
43605f5d09a5Sjsing 
43615f5d09a5Sjsing   s7 += s19 * 666643;
43625f5d09a5Sjsing   s8 += s19 * 470296;
43635f5d09a5Sjsing   s9 += s19 * 654183;
43645f5d09a5Sjsing   s10 -= s19 * 997805;
43655f5d09a5Sjsing   s11 += s19 * 136657;
43665f5d09a5Sjsing   s12 -= s19 * 683901;
43675f5d09a5Sjsing   s19 = 0;
43685f5d09a5Sjsing 
43695f5d09a5Sjsing   s6 += s18 * 666643;
43705f5d09a5Sjsing   s7 += s18 * 470296;
43715f5d09a5Sjsing   s8 += s18 * 654183;
43725f5d09a5Sjsing   s9 -= s18 * 997805;
43735f5d09a5Sjsing   s10 += s18 * 136657;
43745f5d09a5Sjsing   s11 -= s18 * 683901;
43755f5d09a5Sjsing   s18 = 0;
43765f5d09a5Sjsing 
43775f5d09a5Sjsing   carry6 = (s6 + (1 << 20)) >> 21;
43785f5d09a5Sjsing   s7 += carry6;
43795f5d09a5Sjsing   s6 -= carry6 << 21;
43805f5d09a5Sjsing   carry8 = (s8 + (1 << 20)) >> 21;
43815f5d09a5Sjsing   s9 += carry8;
43825f5d09a5Sjsing   s8 -= carry8 << 21;
43835f5d09a5Sjsing   carry10 = (s10 + (1 << 20)) >> 21;
43845f5d09a5Sjsing   s11 += carry10;
43855f5d09a5Sjsing   s10 -= carry10 << 21;
43865f5d09a5Sjsing   carry12 = (s12 + (1 << 20)) >> 21;
43875f5d09a5Sjsing   s13 += carry12;
43885f5d09a5Sjsing   s12 -= carry12 << 21;
43895f5d09a5Sjsing   carry14 = (s14 + (1 << 20)) >> 21;
43905f5d09a5Sjsing   s15 += carry14;
43915f5d09a5Sjsing   s14 -= carry14 << 21;
43925f5d09a5Sjsing   carry16 = (s16 + (1 << 20)) >> 21;
43935f5d09a5Sjsing   s17 += carry16;
43945f5d09a5Sjsing   s16 -= carry16 << 21;
43955f5d09a5Sjsing 
43965f5d09a5Sjsing   carry7 = (s7 + (1 << 20)) >> 21;
43975f5d09a5Sjsing   s8 += carry7;
43985f5d09a5Sjsing   s7 -= carry7 << 21;
43995f5d09a5Sjsing   carry9 = (s9 + (1 << 20)) >> 21;
44005f5d09a5Sjsing   s10 += carry9;
44015f5d09a5Sjsing   s9 -= carry9 << 21;
44025f5d09a5Sjsing   carry11 = (s11 + (1 << 20)) >> 21;
44035f5d09a5Sjsing   s12 += carry11;
44045f5d09a5Sjsing   s11 -= carry11 << 21;
44055f5d09a5Sjsing   carry13 = (s13 + (1 << 20)) >> 21;
44065f5d09a5Sjsing   s14 += carry13;
44075f5d09a5Sjsing   s13 -= carry13 << 21;
44085f5d09a5Sjsing   carry15 = (s15 + (1 << 20)) >> 21;
44095f5d09a5Sjsing   s16 += carry15;
44105f5d09a5Sjsing   s15 -= carry15 << 21;
44115f5d09a5Sjsing 
44125f5d09a5Sjsing   s5 += s17 * 666643;
44135f5d09a5Sjsing   s6 += s17 * 470296;
44145f5d09a5Sjsing   s7 += s17 * 654183;
44155f5d09a5Sjsing   s8 -= s17 * 997805;
44165f5d09a5Sjsing   s9 += s17 * 136657;
44175f5d09a5Sjsing   s10 -= s17 * 683901;
44185f5d09a5Sjsing   s17 = 0;
44195f5d09a5Sjsing 
44205f5d09a5Sjsing   s4 += s16 * 666643;
44215f5d09a5Sjsing   s5 += s16 * 470296;
44225f5d09a5Sjsing   s6 += s16 * 654183;
44235f5d09a5Sjsing   s7 -= s16 * 997805;
44245f5d09a5Sjsing   s8 += s16 * 136657;
44255f5d09a5Sjsing   s9 -= s16 * 683901;
44265f5d09a5Sjsing   s16 = 0;
44275f5d09a5Sjsing 
44285f5d09a5Sjsing   s3 += s15 * 666643;
44295f5d09a5Sjsing   s4 += s15 * 470296;
44305f5d09a5Sjsing   s5 += s15 * 654183;
44315f5d09a5Sjsing   s6 -= s15 * 997805;
44325f5d09a5Sjsing   s7 += s15 * 136657;
44335f5d09a5Sjsing   s8 -= s15 * 683901;
44345f5d09a5Sjsing   s15 = 0;
44355f5d09a5Sjsing 
44365f5d09a5Sjsing   s2 += s14 * 666643;
44375f5d09a5Sjsing   s3 += s14 * 470296;
44385f5d09a5Sjsing   s4 += s14 * 654183;
44395f5d09a5Sjsing   s5 -= s14 * 997805;
44405f5d09a5Sjsing   s6 += s14 * 136657;
44415f5d09a5Sjsing   s7 -= s14 * 683901;
44425f5d09a5Sjsing   s14 = 0;
44435f5d09a5Sjsing 
44445f5d09a5Sjsing   s1 += s13 * 666643;
44455f5d09a5Sjsing   s2 += s13 * 470296;
44465f5d09a5Sjsing   s3 += s13 * 654183;
44475f5d09a5Sjsing   s4 -= s13 * 997805;
44485f5d09a5Sjsing   s5 += s13 * 136657;
44495f5d09a5Sjsing   s6 -= s13 * 683901;
44505f5d09a5Sjsing   s13 = 0;
44515f5d09a5Sjsing 
44525f5d09a5Sjsing   s0 += s12 * 666643;
44535f5d09a5Sjsing   s1 += s12 * 470296;
44545f5d09a5Sjsing   s2 += s12 * 654183;
44555f5d09a5Sjsing   s3 -= s12 * 997805;
44565f5d09a5Sjsing   s4 += s12 * 136657;
44575f5d09a5Sjsing   s5 -= s12 * 683901;
44585f5d09a5Sjsing   s12 = 0;
44595f5d09a5Sjsing 
44605f5d09a5Sjsing   carry0 = (s0 + (1 << 20)) >> 21;
44615f5d09a5Sjsing   s1 += carry0;
44625f5d09a5Sjsing   s0 -= carry0 << 21;
44635f5d09a5Sjsing   carry2 = (s2 + (1 << 20)) >> 21;
44645f5d09a5Sjsing   s3 += carry2;
44655f5d09a5Sjsing   s2 -= carry2 << 21;
44665f5d09a5Sjsing   carry4 = (s4 + (1 << 20)) >> 21;
44675f5d09a5Sjsing   s5 += carry4;
44685f5d09a5Sjsing   s4 -= carry4 << 21;
44695f5d09a5Sjsing   carry6 = (s6 + (1 << 20)) >> 21;
44705f5d09a5Sjsing   s7 += carry6;
44715f5d09a5Sjsing   s6 -= carry6 << 21;
44725f5d09a5Sjsing   carry8 = (s8 + (1 << 20)) >> 21;
44735f5d09a5Sjsing   s9 += carry8;
44745f5d09a5Sjsing   s8 -= carry8 << 21;
44755f5d09a5Sjsing   carry10 = (s10 + (1 << 20)) >> 21;
44765f5d09a5Sjsing   s11 += carry10;
44775f5d09a5Sjsing   s10 -= carry10 << 21;
44785f5d09a5Sjsing 
44795f5d09a5Sjsing   carry1 = (s1 + (1 << 20)) >> 21;
44805f5d09a5Sjsing   s2 += carry1;
44815f5d09a5Sjsing   s1 -= carry1 << 21;
44825f5d09a5Sjsing   carry3 = (s3 + (1 << 20)) >> 21;
44835f5d09a5Sjsing   s4 += carry3;
44845f5d09a5Sjsing   s3 -= carry3 << 21;
44855f5d09a5Sjsing   carry5 = (s5 + (1 << 20)) >> 21;
44865f5d09a5Sjsing   s6 += carry5;
44875f5d09a5Sjsing   s5 -= carry5 << 21;
44885f5d09a5Sjsing   carry7 = (s7 + (1 << 20)) >> 21;
44895f5d09a5Sjsing   s8 += carry7;
44905f5d09a5Sjsing   s7 -= carry7 << 21;
44915f5d09a5Sjsing   carry9 = (s9 + (1 << 20)) >> 21;
44925f5d09a5Sjsing   s10 += carry9;
44935f5d09a5Sjsing   s9 -= carry9 << 21;
44945f5d09a5Sjsing   carry11 = (s11 + (1 << 20)) >> 21;
44955f5d09a5Sjsing   s12 += carry11;
44965f5d09a5Sjsing   s11 -= carry11 << 21;
44975f5d09a5Sjsing 
44985f5d09a5Sjsing   s0 += s12 * 666643;
44995f5d09a5Sjsing   s1 += s12 * 470296;
45005f5d09a5Sjsing   s2 += s12 * 654183;
45015f5d09a5Sjsing   s3 -= s12 * 997805;
45025f5d09a5Sjsing   s4 += s12 * 136657;
45035f5d09a5Sjsing   s5 -= s12 * 683901;
45045f5d09a5Sjsing   s12 = 0;
45055f5d09a5Sjsing 
45065f5d09a5Sjsing   carry0 = s0 >> 21;
45075f5d09a5Sjsing   s1 += carry0;
45085f5d09a5Sjsing   s0 -= carry0 << 21;
45095f5d09a5Sjsing   carry1 = s1 >> 21;
45105f5d09a5Sjsing   s2 += carry1;
45115f5d09a5Sjsing   s1 -= carry1 << 21;
45125f5d09a5Sjsing   carry2 = s2 >> 21;
45135f5d09a5Sjsing   s3 += carry2;
45145f5d09a5Sjsing   s2 -= carry2 << 21;
45155f5d09a5Sjsing   carry3 = s3 >> 21;
45165f5d09a5Sjsing   s4 += carry3;
45175f5d09a5Sjsing   s3 -= carry3 << 21;
45185f5d09a5Sjsing   carry4 = s4 >> 21;
45195f5d09a5Sjsing   s5 += carry4;
45205f5d09a5Sjsing   s4 -= carry4 << 21;
45215f5d09a5Sjsing   carry5 = s5 >> 21;
45225f5d09a5Sjsing   s6 += carry5;
45235f5d09a5Sjsing   s5 -= carry5 << 21;
45245f5d09a5Sjsing   carry6 = s6 >> 21;
45255f5d09a5Sjsing   s7 += carry6;
45265f5d09a5Sjsing   s6 -= carry6 << 21;
45275f5d09a5Sjsing   carry7 = s7 >> 21;
45285f5d09a5Sjsing   s8 += carry7;
45295f5d09a5Sjsing   s7 -= carry7 << 21;
45305f5d09a5Sjsing   carry8 = s8 >> 21;
45315f5d09a5Sjsing   s9 += carry8;
45325f5d09a5Sjsing   s8 -= carry8 << 21;
45335f5d09a5Sjsing   carry9 = s9 >> 21;
45345f5d09a5Sjsing   s10 += carry9;
45355f5d09a5Sjsing   s9 -= carry9 << 21;
45365f5d09a5Sjsing   carry10 = s10 >> 21;
45375f5d09a5Sjsing   s11 += carry10;
45385f5d09a5Sjsing   s10 -= carry10 << 21;
45395f5d09a5Sjsing   carry11 = s11 >> 21;
45405f5d09a5Sjsing   s12 += carry11;
45415f5d09a5Sjsing   s11 -= carry11 << 21;
45425f5d09a5Sjsing 
45435f5d09a5Sjsing   s0 += s12 * 666643;
45445f5d09a5Sjsing   s1 += s12 * 470296;
45455f5d09a5Sjsing   s2 += s12 * 654183;
45465f5d09a5Sjsing   s3 -= s12 * 997805;
45475f5d09a5Sjsing   s4 += s12 * 136657;
45485f5d09a5Sjsing   s5 -= s12 * 683901;
45495f5d09a5Sjsing   s12 = 0;
45505f5d09a5Sjsing 
45515f5d09a5Sjsing   carry0 = s0 >> 21;
45525f5d09a5Sjsing   s1 += carry0;
45535f5d09a5Sjsing   s0 -= carry0 << 21;
45545f5d09a5Sjsing   carry1 = s1 >> 21;
45555f5d09a5Sjsing   s2 += carry1;
45565f5d09a5Sjsing   s1 -= carry1 << 21;
45575f5d09a5Sjsing   carry2 = s2 >> 21;
45585f5d09a5Sjsing   s3 += carry2;
45595f5d09a5Sjsing   s2 -= carry2 << 21;
45605f5d09a5Sjsing   carry3 = s3 >> 21;
45615f5d09a5Sjsing   s4 += carry3;
45625f5d09a5Sjsing   s3 -= carry3 << 21;
45635f5d09a5Sjsing   carry4 = s4 >> 21;
45645f5d09a5Sjsing   s5 += carry4;
45655f5d09a5Sjsing   s4 -= carry4 << 21;
45665f5d09a5Sjsing   carry5 = s5 >> 21;
45675f5d09a5Sjsing   s6 += carry5;
45685f5d09a5Sjsing   s5 -= carry5 << 21;
45695f5d09a5Sjsing   carry6 = s6 >> 21;
45705f5d09a5Sjsing   s7 += carry6;
45715f5d09a5Sjsing   s6 -= carry6 << 21;
45725f5d09a5Sjsing   carry7 = s7 >> 21;
45735f5d09a5Sjsing   s8 += carry7;
45745f5d09a5Sjsing   s7 -= carry7 << 21;
45755f5d09a5Sjsing   carry8 = s8 >> 21;
45765f5d09a5Sjsing   s9 += carry8;
45775f5d09a5Sjsing   s8 -= carry8 << 21;
45785f5d09a5Sjsing   carry9 = s9 >> 21;
45795f5d09a5Sjsing   s10 += carry9;
45805f5d09a5Sjsing   s9 -= carry9 << 21;
45815f5d09a5Sjsing   carry10 = s10 >> 21;
45825f5d09a5Sjsing   s11 += carry10;
45835f5d09a5Sjsing   s10 -= carry10 << 21;
45845f5d09a5Sjsing 
45855f5d09a5Sjsing   s[0] = s0 >> 0;
45865f5d09a5Sjsing   s[1] = s0 >> 8;
45875f5d09a5Sjsing   s[2] = (s0 >> 16) | (s1 << 5);
45885f5d09a5Sjsing   s[3] = s1 >> 3;
45895f5d09a5Sjsing   s[4] = s1 >> 11;
45905f5d09a5Sjsing   s[5] = (s1 >> 19) | (s2 << 2);
45915f5d09a5Sjsing   s[6] = s2 >> 6;
45925f5d09a5Sjsing   s[7] = (s2 >> 14) | (s3 << 7);
45935f5d09a5Sjsing   s[8] = s3 >> 1;
45945f5d09a5Sjsing   s[9] = s3 >> 9;
45955f5d09a5Sjsing   s[10] = (s3 >> 17) | (s4 << 4);
45965f5d09a5Sjsing   s[11] = s4 >> 4;
45975f5d09a5Sjsing   s[12] = s4 >> 12;
45985f5d09a5Sjsing   s[13] = (s4 >> 20) | (s5 << 1);
45995f5d09a5Sjsing   s[14] = s5 >> 7;
46005f5d09a5Sjsing   s[15] = (s5 >> 15) | (s6 << 6);
46015f5d09a5Sjsing   s[16] = s6 >> 2;
46025f5d09a5Sjsing   s[17] = s6 >> 10;
46035f5d09a5Sjsing   s[18] = (s6 >> 18) | (s7 << 3);
46045f5d09a5Sjsing   s[19] = s7 >> 5;
46055f5d09a5Sjsing   s[20] = s7 >> 13;
46065f5d09a5Sjsing   s[21] = s8 >> 0;
46075f5d09a5Sjsing   s[22] = s8 >> 8;
46085f5d09a5Sjsing   s[23] = (s8 >> 16) | (s9 << 5);
46095f5d09a5Sjsing   s[24] = s9 >> 3;
46105f5d09a5Sjsing   s[25] = s9 >> 11;
46115f5d09a5Sjsing   s[26] = (s9 >> 19) | (s10 << 2);
46125f5d09a5Sjsing   s[27] = s10 >> 6;
46135f5d09a5Sjsing   s[28] = (s10 >> 14) | (s11 << 7);
46145f5d09a5Sjsing   s[29] = s11 >> 1;
46155f5d09a5Sjsing   s[30] = s11 >> 9;
46165f5d09a5Sjsing   s[31] = s11 >> 17;
46175f5d09a5Sjsing }
46185f5d09a5Sjsing 
ED25519_public_from_private(uint8_t out_public_key[ED25519_PUBLIC_KEY_LENGTH],const uint8_t private_key[ED25519_PRIVATE_KEY_LENGTH])46195b0711d2Sjsing void ED25519_public_from_private(uint8_t out_public_key[ED25519_PUBLIC_KEY_LENGTH],
46205b0711d2Sjsing     const uint8_t private_key[ED25519_PRIVATE_KEY_LENGTH]) {
46215b0711d2Sjsing   uint8_t az[SHA512_DIGEST_LENGTH];
46225b0711d2Sjsing   SHA512(private_key, 32, az);
46235b0711d2Sjsing 
46245b0711d2Sjsing   az[0] &= 248;
46255b0711d2Sjsing   az[31] &= 63;
46265b0711d2Sjsing   az[31] |= 64;
46275b0711d2Sjsing 
46285b0711d2Sjsing   ge_p3 A;
46295b0711d2Sjsing   x25519_ge_scalarmult_base(&A, az);
46305b0711d2Sjsing   ge_p3_tobytes(out_public_key, &A);
46315b0711d2Sjsing }
46325b0711d2Sjsing 
ED25519_keypair(uint8_t out_public_key[ED25519_PUBLIC_KEY_LENGTH],uint8_t out_private_key[ED25519_PRIVATE_KEY_LENGTH])46335b0711d2Sjsing void ED25519_keypair(uint8_t out_public_key[ED25519_PUBLIC_KEY_LENGTH],
46345b0711d2Sjsing     uint8_t out_private_key[ED25519_PRIVATE_KEY_LENGTH]) {
46355b0711d2Sjsing   arc4random_buf(out_private_key, 32);
46365b0711d2Sjsing 
46375b0711d2Sjsing   ED25519_public_from_private(out_public_key, out_private_key);
46385f5d09a5Sjsing }
4639*4d1810faSbeck LCRYPTO_ALIAS(ED25519_keypair);
46405f5d09a5Sjsing 
ED25519_sign(uint8_t * out_sig,const uint8_t * message,size_t message_len,const uint8_t public_key[ED25519_PUBLIC_KEY_LENGTH],const uint8_t private_key[ED25519_PRIVATE_KEY_LENGTH])46415f5d09a5Sjsing int ED25519_sign(uint8_t *out_sig, const uint8_t *message, size_t message_len,
46425b0711d2Sjsing     const uint8_t public_key[ED25519_PUBLIC_KEY_LENGTH],
46435b0711d2Sjsing     const uint8_t private_key[ED25519_PRIVATE_KEY_LENGTH]) {
46445f5d09a5Sjsing   uint8_t az[SHA512_DIGEST_LENGTH];
46455f5d09a5Sjsing   SHA512(private_key, 32, az);
46465f5d09a5Sjsing 
46475f5d09a5Sjsing   az[0] &= 248;
46485f5d09a5Sjsing   az[31] &= 63;
46495f5d09a5Sjsing   az[31] |= 64;
46505f5d09a5Sjsing 
46515f5d09a5Sjsing   SHA512_CTX hash_ctx;
46525f5d09a5Sjsing   SHA512_Init(&hash_ctx);
46535f5d09a5Sjsing   SHA512_Update(&hash_ctx, az + 32, 32);
46545f5d09a5Sjsing   SHA512_Update(&hash_ctx, message, message_len);
46555f5d09a5Sjsing   uint8_t nonce[SHA512_DIGEST_LENGTH];
46565f5d09a5Sjsing   SHA512_Final(nonce, &hash_ctx);
46575f5d09a5Sjsing 
46585f5d09a5Sjsing   x25519_sc_reduce(nonce);
46595f5d09a5Sjsing   ge_p3 R;
46605f5d09a5Sjsing   x25519_ge_scalarmult_base(&R, nonce);
46615f5d09a5Sjsing   ge_p3_tobytes(out_sig, &R);
46625f5d09a5Sjsing 
46635f5d09a5Sjsing   SHA512_Init(&hash_ctx);
46645f5d09a5Sjsing   SHA512_Update(&hash_ctx, out_sig, 32);
46655b0711d2Sjsing   SHA512_Update(&hash_ctx, public_key, 32);
46665f5d09a5Sjsing   SHA512_Update(&hash_ctx, message, message_len);
46675f5d09a5Sjsing   uint8_t hram[SHA512_DIGEST_LENGTH];
46685f5d09a5Sjsing   SHA512_Final(hram, &hash_ctx);
46695f5d09a5Sjsing 
46705f5d09a5Sjsing   x25519_sc_reduce(hram);
46715f5d09a5Sjsing   sc_muladd(out_sig + 32, hram, az, nonce);
46725f5d09a5Sjsing 
46735f5d09a5Sjsing   return 1;
46745f5d09a5Sjsing }
4675*4d1810faSbeck LCRYPTO_ALIAS(ED25519_sign);
46765f5d09a5Sjsing 
467721b5f757Stb /*
467821b5f757Stb  * Little endian representation of the order of edwards25519,
467921b5f757Stb  * see https://www.rfc-editor.org/rfc/rfc7748#section-4.1
468021b5f757Stb  */
468121b5f757Stb static const uint8_t order[] = {
468221b5f757Stb   0xed, 0xd3, 0xf5, 0x5c, 0x1a, 0x63, 0x12, 0x58,
468321b5f757Stb   0xd6, 0x9c, 0xf7, 0xa2, 0xde, 0xf9, 0xde, 0x14,
468421b5f757Stb   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
468521b5f757Stb   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
468621b5f757Stb };
468721b5f757Stb 
ED25519_verify(const uint8_t * message,size_t message_len,const uint8_t signature[ED25519_SIGNATURE_LENGTH],const uint8_t public_key[ED25519_PUBLIC_KEY_LENGTH])46885f5d09a5Sjsing int ED25519_verify(const uint8_t *message, size_t message_len,
46895b0711d2Sjsing     const uint8_t signature[ED25519_SIGNATURE_LENGTH],
46905b0711d2Sjsing     const uint8_t public_key[ED25519_PUBLIC_KEY_LENGTH]) {
46915f5d09a5Sjsing   ge_p3 A;
469221b5f757Stb   int i;
46935f5d09a5Sjsing   if ((signature[63] & 224) != 0 ||
46945f5d09a5Sjsing       x25519_ge_frombytes_vartime(&A, public_key) != 0) {
46955f5d09a5Sjsing     return 0;
46965f5d09a5Sjsing   }
46975f5d09a5Sjsing 
46985f5d09a5Sjsing   fe_neg(A.X, A.X);
46995f5d09a5Sjsing   fe_neg(A.T, A.T);
47005f5d09a5Sjsing 
47015f5d09a5Sjsing   uint8_t pkcopy[32];
47025f5d09a5Sjsing   memcpy(pkcopy, public_key, 32);
47035f5d09a5Sjsing   uint8_t rcopy[32];
47045f5d09a5Sjsing   memcpy(rcopy, signature, 32);
47055f5d09a5Sjsing   uint8_t scopy[32];
47065f5d09a5Sjsing   memcpy(scopy, signature + 32, 32);
47075f5d09a5Sjsing 
470821b5f757Stb   /*
470921b5f757Stb    * https://tools.ietf.org/html/rfc8032#section-5.1.7 requires that scopy be
471021b5f757Stb    * in the range [0, order) to prevent signature malleability. This value is
471121b5f757Stb    * public, so there is no need to make this constant time.
471221b5f757Stb    */
471321b5f757Stb   for (i = 31; i >= 0; i--) {
471421b5f757Stb     if (scopy[i] > order[i])
471521b5f757Stb       return 0;
471621b5f757Stb     if (scopy[i] < order[i])
471721b5f757Stb       break;
471821b5f757Stb     if (i == 0)
471921b5f757Stb       return 0;
472021b5f757Stb   }
472121b5f757Stb 
47225f5d09a5Sjsing   SHA512_CTX hash_ctx;
47235f5d09a5Sjsing   SHA512_Init(&hash_ctx);
47245f5d09a5Sjsing   SHA512_Update(&hash_ctx, signature, 32);
47255f5d09a5Sjsing   SHA512_Update(&hash_ctx, public_key, 32);
47265f5d09a5Sjsing   SHA512_Update(&hash_ctx, message, message_len);
47275f5d09a5Sjsing   uint8_t h[SHA512_DIGEST_LENGTH];
47285f5d09a5Sjsing   SHA512_Final(h, &hash_ctx);
47295f5d09a5Sjsing 
47305f5d09a5Sjsing   x25519_sc_reduce(h);
47315f5d09a5Sjsing 
47325f5d09a5Sjsing   ge_p2 R;
47335f5d09a5Sjsing   ge_double_scalarmult_vartime(&R, h, &A, scopy);
47345f5d09a5Sjsing 
47355f5d09a5Sjsing   uint8_t rcheck[32];
47365f5d09a5Sjsing   x25519_ge_tobytes(rcheck, &R);
47375f5d09a5Sjsing 
47385f5d09a5Sjsing   return timingsafe_memcmp(rcheck, rcopy, sizeof(rcheck)) == 0;
47395f5d09a5Sjsing }
4740*4d1810faSbeck LCRYPTO_ALIAS(ED25519_verify);
47415f5d09a5Sjsing 
47425f5d09a5Sjsing /* Replace (f,g) with (g,f) if b == 1;
47435f5d09a5Sjsing  * replace (f,g) with (f,g) if b == 0.
47445f5d09a5Sjsing  *
47455f5d09a5Sjsing  * Preconditions: b in {0,1}. */
fe_cswap(fe f,fe g,unsigned int b)47465f5d09a5Sjsing static void fe_cswap(fe f, fe g, unsigned int b) {
47475f5d09a5Sjsing   b = 0-b;
47485f5d09a5Sjsing   unsigned i;
47495f5d09a5Sjsing   for (i = 0; i < 10; i++) {
47505f5d09a5Sjsing     int32_t x = f[i] ^ g[i];
47515f5d09a5Sjsing     x &= b;
47525f5d09a5Sjsing     f[i] ^= x;
47535f5d09a5Sjsing     g[i] ^= x;
47545f5d09a5Sjsing   }
47555f5d09a5Sjsing }
47565f5d09a5Sjsing 
47575f5d09a5Sjsing /* h = f * 121666
47585f5d09a5Sjsing  * Can overlap h with f.
47595f5d09a5Sjsing  *
47605f5d09a5Sjsing  * Preconditions:
47615f5d09a5Sjsing  *    |f| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc.
47625f5d09a5Sjsing  *
47635f5d09a5Sjsing  * Postconditions:
47645f5d09a5Sjsing  *    |h| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc. */
fe_mul121666(fe h,fe f)47655f5d09a5Sjsing static void fe_mul121666(fe h, fe f) {
47665f5d09a5Sjsing   int32_t f0 = f[0];
47675f5d09a5Sjsing   int32_t f1 = f[1];
47685f5d09a5Sjsing   int32_t f2 = f[2];
47695f5d09a5Sjsing   int32_t f3 = f[3];
47705f5d09a5Sjsing   int32_t f4 = f[4];
47715f5d09a5Sjsing   int32_t f5 = f[5];
47725f5d09a5Sjsing   int32_t f6 = f[6];
47735f5d09a5Sjsing   int32_t f7 = f[7];
47745f5d09a5Sjsing   int32_t f8 = f[8];
47755f5d09a5Sjsing   int32_t f9 = f[9];
47765f5d09a5Sjsing   int64_t h0 = f0 * (int64_t) 121666;
47775f5d09a5Sjsing   int64_t h1 = f1 * (int64_t) 121666;
47785f5d09a5Sjsing   int64_t h2 = f2 * (int64_t) 121666;
47795f5d09a5Sjsing   int64_t h3 = f3 * (int64_t) 121666;
47805f5d09a5Sjsing   int64_t h4 = f4 * (int64_t) 121666;
47815f5d09a5Sjsing   int64_t h5 = f5 * (int64_t) 121666;
47825f5d09a5Sjsing   int64_t h6 = f6 * (int64_t) 121666;
47835f5d09a5Sjsing   int64_t h7 = f7 * (int64_t) 121666;
47845f5d09a5Sjsing   int64_t h8 = f8 * (int64_t) 121666;
47855f5d09a5Sjsing   int64_t h9 = f9 * (int64_t) 121666;
47865f5d09a5Sjsing   int64_t carry0;
47875f5d09a5Sjsing   int64_t carry1;
47885f5d09a5Sjsing   int64_t carry2;
47895f5d09a5Sjsing   int64_t carry3;
47905f5d09a5Sjsing   int64_t carry4;
47915f5d09a5Sjsing   int64_t carry5;
47925f5d09a5Sjsing   int64_t carry6;
47935f5d09a5Sjsing   int64_t carry7;
47945f5d09a5Sjsing   int64_t carry8;
47955f5d09a5Sjsing   int64_t carry9;
47965f5d09a5Sjsing 
47975f5d09a5Sjsing   carry9 = h9 + (1 << 24); h0 += (carry9 >> 25) * 19; h9 -= carry9 & kTop39Bits;
47985f5d09a5Sjsing   carry1 = h1 + (1 << 24); h2 += carry1 >> 25; h1 -= carry1 & kTop39Bits;
47995f5d09a5Sjsing   carry3 = h3 + (1 << 24); h4 += carry3 >> 25; h3 -= carry3 & kTop39Bits;
48005f5d09a5Sjsing   carry5 = h5 + (1 << 24); h6 += carry5 >> 25; h5 -= carry5 & kTop39Bits;
48015f5d09a5Sjsing   carry7 = h7 + (1 << 24); h8 += carry7 >> 25; h7 -= carry7 & kTop39Bits;
48025f5d09a5Sjsing 
48035f5d09a5Sjsing   carry0 = h0 + (1 << 25); h1 += carry0 >> 26; h0 -= carry0 & kTop38Bits;
48045f5d09a5Sjsing   carry2 = h2 + (1 << 25); h3 += carry2 >> 26; h2 -= carry2 & kTop38Bits;
48055f5d09a5Sjsing   carry4 = h4 + (1 << 25); h5 += carry4 >> 26; h4 -= carry4 & kTop38Bits;
48065f5d09a5Sjsing   carry6 = h6 + (1 << 25); h7 += carry6 >> 26; h6 -= carry6 & kTop38Bits;
48075f5d09a5Sjsing   carry8 = h8 + (1 << 25); h9 += carry8 >> 26; h8 -= carry8 & kTop38Bits;
48085f5d09a5Sjsing 
48095f5d09a5Sjsing   h[0] = h0;
48105f5d09a5Sjsing   h[1] = h1;
48115f5d09a5Sjsing   h[2] = h2;
48125f5d09a5Sjsing   h[3] = h3;
48135f5d09a5Sjsing   h[4] = h4;
48145f5d09a5Sjsing   h[5] = h5;
48155f5d09a5Sjsing   h[6] = h6;
48165f5d09a5Sjsing   h[7] = h7;
48175f5d09a5Sjsing   h[8] = h8;
48185f5d09a5Sjsing   h[9] = h9;
48195f5d09a5Sjsing }
48205f5d09a5Sjsing 
48215f5d09a5Sjsing void
x25519_scalar_mult_generic(uint8_t out[32],const uint8_t scalar[32],const uint8_t point[32])48225f5d09a5Sjsing x25519_scalar_mult_generic(uint8_t out[32], const uint8_t scalar[32],
48235f5d09a5Sjsing     const uint8_t point[32]) {
48245f5d09a5Sjsing   fe x1, x2, z2, x3, z3, tmp0, tmp1;
48255f5d09a5Sjsing 
48265f5d09a5Sjsing   uint8_t e[32];
48275f5d09a5Sjsing   memcpy(e, scalar, 32);
48285f5d09a5Sjsing   e[0] &= 248;
48295f5d09a5Sjsing   e[31] &= 127;
48305f5d09a5Sjsing   e[31] |= 64;
48315f5d09a5Sjsing   fe_frombytes(x1, point);
48325f5d09a5Sjsing   fe_1(x2);
48335f5d09a5Sjsing   fe_0(z2);
48345f5d09a5Sjsing   fe_copy(x3, x1);
48355f5d09a5Sjsing   fe_1(z3);
48365f5d09a5Sjsing 
48375f5d09a5Sjsing   unsigned swap = 0;
48385f5d09a5Sjsing   int pos;
48395f5d09a5Sjsing   for (pos = 254; pos >= 0; --pos) {
48405f5d09a5Sjsing     unsigned b = 1 & (e[pos / 8] >> (pos & 7));
48415f5d09a5Sjsing     swap ^= b;
48425f5d09a5Sjsing     fe_cswap(x2, x3, swap);
48435f5d09a5Sjsing     fe_cswap(z2, z3, swap);
48445f5d09a5Sjsing     swap = b;
48455f5d09a5Sjsing     fe_sub(tmp0, x3, z3);
48465f5d09a5Sjsing     fe_sub(tmp1, x2, z2);
48475f5d09a5Sjsing     fe_add(x2, x2, z2);
48485f5d09a5Sjsing     fe_add(z2, x3, z3);
48495f5d09a5Sjsing     fe_mul(z3, tmp0, x2);
48505f5d09a5Sjsing     fe_mul(z2, z2, tmp1);
48515f5d09a5Sjsing     fe_sq(tmp0, tmp1);
48525f5d09a5Sjsing     fe_sq(tmp1, x2);
48535f5d09a5Sjsing     fe_add(x3, z3, z2);
48545f5d09a5Sjsing     fe_sub(z2, z3, z2);
48555f5d09a5Sjsing     fe_mul(x2, tmp1, tmp0);
48565f5d09a5Sjsing     fe_sub(tmp1, tmp1, tmp0);
48575f5d09a5Sjsing     fe_sq(z2, z2);
48585f5d09a5Sjsing     fe_mul121666(z3, tmp1);
48595f5d09a5Sjsing     fe_sq(x3, x3);
48605f5d09a5Sjsing     fe_add(tmp0, tmp0, z3);
48615f5d09a5Sjsing     fe_mul(z3, x1, z2);
48625f5d09a5Sjsing     fe_mul(z2, tmp1, tmp0);
48635f5d09a5Sjsing   }
48645f5d09a5Sjsing   fe_cswap(x2, x3, swap);
48655f5d09a5Sjsing   fe_cswap(z2, z3, swap);
48665f5d09a5Sjsing 
48675f5d09a5Sjsing   fe_invert(z2, z2);
48685f5d09a5Sjsing   fe_mul(x2, x2, z2);
48695f5d09a5Sjsing   fe_tobytes(out, x2);
48705f5d09a5Sjsing }
48715f5d09a5Sjsing 
4872d3465008Sjsing #ifdef unused
48735f5d09a5Sjsing void
x25519_public_from_private_generic(uint8_t out_public_key[32],const uint8_t private_key[32])4874bbbda117Sjsing x25519_public_from_private_generic(uint8_t out_public_key[32],
48755f5d09a5Sjsing     const uint8_t private_key[32])
48765f5d09a5Sjsing {
48775f5d09a5Sjsing   uint8_t e[32];
48785f5d09a5Sjsing 
48795f5d09a5Sjsing   memcpy(e, private_key, 32);
48805f5d09a5Sjsing   e[0] &= 248;
48815f5d09a5Sjsing   e[31] &= 127;
48825f5d09a5Sjsing   e[31] |= 64;
48835f5d09a5Sjsing 
48845f5d09a5Sjsing   ge_p3 A;
48855f5d09a5Sjsing   x25519_ge_scalarmult_base(&A, e);
48865f5d09a5Sjsing 
48875f5d09a5Sjsing   /* We only need the u-coordinate of the curve25519 point. The map is
48885f5d09a5Sjsing    * u=(y+1)/(1-y). Since y=Y/Z, this gives u=(Z+Y)/(Z-Y). */
48895f5d09a5Sjsing   fe zplusy, zminusy, zminusy_inv;
48905f5d09a5Sjsing   fe_add(zplusy, A.Z, A.Y);
48915f5d09a5Sjsing   fe_sub(zminusy, A.Z, A.Y);
48925f5d09a5Sjsing   fe_invert(zminusy_inv, zminusy);
48935f5d09a5Sjsing   fe_mul(zplusy, zplusy, zminusy_inv);
4894bbbda117Sjsing   fe_tobytes(out_public_key, zplusy);
48955f5d09a5Sjsing }
4896d3465008Sjsing #endif
48975f5d09a5Sjsing 
48985f5d09a5Sjsing void
X25519_public_from_private(uint8_t out_public_key[X25519_KEY_LENGTH],const uint8_t private_key[X25519_KEY_LENGTH])4899ab3ec570Sjsing X25519_public_from_private(uint8_t out_public_key[X25519_KEY_LENGTH],
4900ab3ec570Sjsing     const uint8_t private_key[X25519_KEY_LENGTH])
49015f5d09a5Sjsing {
49025f5d09a5Sjsing   static const uint8_t kMongomeryBasePoint[32] = {9};
49035f5d09a5Sjsing 
4904bbbda117Sjsing   x25519_scalar_mult(out_public_key, private_key, kMongomeryBasePoint);
49055f5d09a5Sjsing }
49065f5d09a5Sjsing 
49075f5d09a5Sjsing void
X25519_keypair(uint8_t out_public_key[X25519_KEY_LENGTH],uint8_t out_private_key[X25519_KEY_LENGTH])4908bbbda117Sjsing X25519_keypair(uint8_t out_public_key[X25519_KEY_LENGTH],
4909a878ae04Sjsing     uint8_t out_private_key[X25519_KEY_LENGTH])
49105f5d09a5Sjsing {
49115f5d09a5Sjsing   /* All X25519 implementations should decode scalars correctly (see
49125f5d09a5Sjsing    * https://tools.ietf.org/html/rfc7748#section-5). However, if an
49135f5d09a5Sjsing    * implementation doesn't then it might interoperate with random keys a
49145f5d09a5Sjsing    * fraction of the time because they'll, randomly, happen to be correctly
49155f5d09a5Sjsing    * formed.
49165f5d09a5Sjsing    *
49175f5d09a5Sjsing    * Thus we do the opposite of the masking here to make sure that our private
49185f5d09a5Sjsing    * keys are never correctly masked and so, hopefully, any incorrect
49195f5d09a5Sjsing    * implementations are deterministically broken.
49205f5d09a5Sjsing    *
49215f5d09a5Sjsing    * This does not affect security because, although we're throwing away
49225f5d09a5Sjsing    * entropy, a valid implementation of scalarmult should throw away the exact
49235f5d09a5Sjsing    * same bits anyway. */
49245f5d09a5Sjsing   arc4random_buf(out_private_key, 32);
49255f5d09a5Sjsing 
49265f5d09a5Sjsing   out_private_key[0] |= 7;
49275f5d09a5Sjsing   out_private_key[31] &= 63;
49285f5d09a5Sjsing   out_private_key[31] |= 128;
49295f5d09a5Sjsing 
4930ab3ec570Sjsing   X25519_public_from_private(out_public_key, out_private_key);
49315f5d09a5Sjsing }
4932*4d1810faSbeck LCRYPTO_ALIAS(X25519_keypair);
49335f5d09a5Sjsing 
49345f5d09a5Sjsing int
X25519(uint8_t out_shared_key[X25519_KEY_LENGTH],const uint8_t private_key[X25519_KEY_LENGTH],const uint8_t peer_public_key[X25519_KEY_LENGTH])4935a878ae04Sjsing X25519(uint8_t out_shared_key[X25519_KEY_LENGTH],
4936a878ae04Sjsing     const uint8_t private_key[X25519_KEY_LENGTH],
4937bbbda117Sjsing     const uint8_t peer_public_key[X25519_KEY_LENGTH])
49385f5d09a5Sjsing {
49395f5d09a5Sjsing   static const uint8_t kZeros[32] = {0};
49405f5d09a5Sjsing 
4941bbbda117Sjsing   x25519_scalar_mult(out_shared_key, private_key, peer_public_key);
49425f5d09a5Sjsing 
49435f5d09a5Sjsing   /* The all-zero output results when the input is a point of small order. */
49445f5d09a5Sjsing   return timingsafe_memcmp(kZeros, out_shared_key, 32) != 0;
49455f5d09a5Sjsing }
4946*4d1810faSbeck LCRYPTO_ALIAS(X25519);
4947