ed25519-ref10.c (171009B)
1 #include <stdint.h> 2 #include <stddef.h> 3 #include <string.h> 4 5 static int crypto_verify_32(const unsigned char *x,const unsigned char *y) 6 { 7 unsigned int differentbits = 0; 8 #define F(i) differentbits |= x[i] ^ y[i]; 9 F(0) 10 F(1) 11 F(2) 12 F(3) 13 F(4) 14 F(5) 15 F(6) 16 F(7) 17 F(8) 18 F(9) 19 F(10) 20 F(11) 21 F(12) 22 F(13) 23 F(14) 24 F(15) 25 F(16) 26 F(17) 27 F(18) 28 F(19) 29 F(20) 30 F(21) 31 F(22) 32 F(23) 33 F(24) 34 F(25) 35 F(26) 36 F(27) 37 F(28) 38 F(29) 39 F(30) 40 F(31) 41 return (1 & ((differentbits - 1) >> 8)) - 1; 42 } 43 44 #if defined(ED25519_REFHASH) 45 46 /* reference/slow SHA-512. really, do not use this */ 47 48 #define HASH_BLOCK_SIZE 128 49 #define HASH_DIGEST_SIZE 64 50 51 typedef struct sha512_state_t { 52 uint64_t H[8]; 53 uint64_t T[2]; 54 uint32_t leftover; 55 uint8_t buffer[HASH_BLOCK_SIZE]; 56 } sha512_state; 57 58 typedef sha512_state ed25519_hash_context; 59 60 static const uint64_t sha512_constants[80] = { 61 0x428a2f98d728ae22ull, 0x7137449123ef65cdull, 0xb5c0fbcfec4d3b2full, 0xe9b5dba58189dbbcull, 62 0x3956c25bf348b538ull, 0x59f111f1b605d019ull, 0x923f82a4af194f9bull, 0xab1c5ed5da6d8118ull, 63 0xd807aa98a3030242ull, 0x12835b0145706fbeull, 0x243185be4ee4b28cull, 0x550c7dc3d5ffb4e2ull, 64 0x72be5d74f27b896full, 0x80deb1fe3b1696b1ull, 0x9bdc06a725c71235ull, 0xc19bf174cf692694ull, 65 0xe49b69c19ef14ad2ull, 0xefbe4786384f25e3ull, 0x0fc19dc68b8cd5b5ull, 0x240ca1cc77ac9c65ull, 66 0x2de92c6f592b0275ull, 0x4a7484aa6ea6e483ull, 0x5cb0a9dcbd41fbd4ull, 0x76f988da831153b5ull, 67 0x983e5152ee66dfabull, 0xa831c66d2db43210ull, 0xb00327c898fb213full, 0xbf597fc7beef0ee4ull, 68 0xc6e00bf33da88fc2ull, 0xd5a79147930aa725ull, 0x06ca6351e003826full, 0x142929670a0e6e70ull, 69 0x27b70a8546d22ffcull, 0x2e1b21385c26c926ull, 0x4d2c6dfc5ac42aedull, 0x53380d139d95b3dfull, 70 0x650a73548baf63deull, 0x766a0abb3c77b2a8ull, 0x81c2c92e47edaee6ull, 0x92722c851482353bull, 71 0xa2bfe8a14cf10364ull, 0xa81a664bbc423001ull, 0xc24b8b70d0f89791ull, 0xc76c51a30654be30ull, 72 0xd192e819d6ef5218ull, 0xd69906245565a910ull, 0xf40e35855771202aull, 0x106aa07032bbd1b8ull, 73 0x19a4c116b8d2d0c8ull, 0x1e376c085141ab53ull, 0x2748774cdf8eeb99ull, 0x34b0bcb5e19b48a8ull, 74 0x391c0cb3c5c95a63ull, 0x4ed8aa4ae3418acbull, 0x5b9cca4f7763e373ull, 0x682e6ff3d6b2b8a3ull, 75 0x748f82ee5defb2fcull, 0x78a5636f43172f60ull, 0x84c87814a1f0ab72ull, 0x8cc702081a6439ecull, 76 0x90befffa23631e28ull, 0xa4506cebde82bde9ull, 0xbef9a3f7b2c67915ull, 0xc67178f2e372532bull, 77 0xca273eceea26619cull, 0xd186b8c721c0c207ull, 0xeada7dd6cde0eb1eull, 0xf57d4f7fee6ed178ull, 78 0x06f067aa72176fbaull, 0x0a637dc5a2c898a6ull, 0x113f9804bef90daeull, 0x1b710b35131c471bull, 79 0x28db77f523047d84ull, 0x32caab7b40c72493ull, 0x3c9ebe0a15c9bebcull, 0x431d67c49c100d4cull, 80 0x4cc5d4becb3e42b6ull, 0x597f299cfc657e2aull, 0x5fcb6fab3ad6faecull, 0x6c44198c4a475817ull 81 }; 82 83 static uint64_t 84 sha512_ROTR64(uint64_t x, int k) { 85 return (x >> k) | (x << (64 - k)); 86 } 87 88 static uint64_t 89 sha512_LOAD64_BE(const uint8_t *p) { 90 return 91 ((uint64_t)p[0] << 56) | 92 ((uint64_t)p[1] << 48) | 93 ((uint64_t)p[2] << 40) | 94 ((uint64_t)p[3] << 32) | 95 ((uint64_t)p[4] << 24) | 96 ((uint64_t)p[5] << 16) | 97 ((uint64_t)p[6] << 8) | 98 ((uint64_t)p[7] ); 99 } 100 101 static void 102 sha512_STORE64_BE(uint8_t *p, uint64_t v) { 103 p[0] = (uint8_t)(v >> 56); 104 p[1] = (uint8_t)(v >> 48); 105 p[2] = (uint8_t)(v >> 40); 106 p[3] = (uint8_t)(v >> 32); 107 p[4] = (uint8_t)(v >> 24); 108 p[5] = (uint8_t)(v >> 16); 109 p[6] = (uint8_t)(v >> 8); 110 p[7] = (uint8_t)(v ); 111 } 112 113 #define Ch(x,y,z) (z ^ (x & (y ^ z))) 114 #define Maj(x,y,z) (((x | y) & z) | (x & y)) 115 #define S0(x) (sha512_ROTR64(x, 28) ^ sha512_ROTR64(x, 34) ^ sha512_ROTR64(x, 39)) 116 #define S1(x) (sha512_ROTR64(x, 14) ^ sha512_ROTR64(x, 18) ^ sha512_ROTR64(x, 41)) 117 #define G0(x) (sha512_ROTR64(x, 1) ^ sha512_ROTR64(x, 8) ^ (x >> 7)) 118 #define G1(x) (sha512_ROTR64(x, 19) ^ sha512_ROTR64(x, 61) ^ (x >> 6)) 119 #define W0(in,i) (sha512_LOAD64_BE(&in[i * 8])) 120 #define W1(i) (G1(w[i - 2]) + w[i - 7] + G0(w[i - 15]) + w[i - 16]) 121 #define STEP(i) \ 122 t1 = S0(r[0]) + Maj(r[0], r[1], r[2]); \ 123 t0 = r[7] + S1(r[4]) + Ch(r[4], r[5], r[6]) + sha512_constants[i] + w[i]; \ 124 r[7] = r[6]; \ 125 r[6] = r[5]; \ 126 r[5] = r[4]; \ 127 r[4] = r[3] + t0; \ 128 r[3] = r[2]; \ 129 r[2] = r[1]; \ 130 r[1] = r[0]; \ 131 r[0] = t0 + t1; 132 133 static void 134 sha512_blocks(sha512_state *S, const uint8_t *in, size_t blocks) { 135 uint64_t r[8], w[80], t0, t1; 136 size_t i; 137 138 for (i = 0; i < 8; i++) r[i] = S->H[i]; 139 140 while (blocks--) { 141 for (i = 0; i < 16; i++) { w[i] = W0(in, i); } 142 for (i = 16; i < 80; i++) { w[i] = W1(i); } 143 for (i = 0; i < 80; i++) { STEP(i); } 144 for (i = 0; i < 8; i++) { r[i] += S->H[i]; S->H[i] = r[i]; } 145 S->T[0] += HASH_BLOCK_SIZE * 8; 146 S->T[1] += (!S->T[0]) ? 1 : 0; 147 in += HASH_BLOCK_SIZE; 148 } 149 } 150 151 static void 152 ed25519_hash_init(sha512_state *S) { 153 S->H[0] = 0x6a09e667f3bcc908ull; 154 S->H[1] = 0xbb67ae8584caa73bull; 155 S->H[2] = 0x3c6ef372fe94f82bull; 156 S->H[3] = 0xa54ff53a5f1d36f1ull; 157 S->H[4] = 0x510e527fade682d1ull; 158 S->H[5] = 0x9b05688c2b3e6c1full; 159 S->H[6] = 0x1f83d9abfb41bd6bull; 160 S->H[7] = 0x5be0cd19137e2179ull; 161 S->T[0] = 0; 162 S->T[1] = 0; 163 S->leftover = 0; 164 } 165 166 static void 167 ed25519_hash_update(sha512_state *S, const uint8_t *in, size_t inlen) { 168 size_t blocks, want; 169 170 /* handle the previous data */ 171 if (S->leftover) { 172 want = (HASH_BLOCK_SIZE - S->leftover); 173 want = (want < inlen) ? want : inlen; 174 memcpy(S->buffer + S->leftover, in, want); 175 S->leftover += (uint32_t)want; 176 if (S->leftover < HASH_BLOCK_SIZE) 177 return; 178 in += want; 179 inlen -= want; 180 sha512_blocks(S, S->buffer, 1); 181 } 182 183 /* handle the current data */ 184 blocks = (inlen & ~(HASH_BLOCK_SIZE - 1)); 185 S->leftover = (uint32_t)(inlen - blocks); 186 if (blocks) { 187 sha512_blocks(S, in, blocks / HASH_BLOCK_SIZE); 188 in += blocks; 189 } 190 191 /* handle leftover data */ 192 if (S->leftover) 193 memcpy(S->buffer, in, S->leftover); 194 } 195 196 static void 197 ed25519_hash_final(sha512_state *S, uint8_t *hash) { 198 uint64_t t0 = S->T[0] + (S->leftover * 8), t1 = S->T[1]; 199 200 S->buffer[S->leftover] = 0x80; 201 if (S->leftover <= 111) { 202 memset(S->buffer + S->leftover + 1, 0, 111 - S->leftover); 203 } else { 204 memset(S->buffer + S->leftover + 1, 0, 127 - S->leftover); 205 sha512_blocks(S, S->buffer, 1); 206 memset(S->buffer, 0, 112); 207 } 208 209 sha512_STORE64_BE(S->buffer + 112, t1); 210 sha512_STORE64_BE(S->buffer + 120, t0); 211 sha512_blocks(S, S->buffer, 1); 212 213 sha512_STORE64_BE(&hash[ 0], S->H[0]); 214 sha512_STORE64_BE(&hash[ 8], S->H[1]); 215 sha512_STORE64_BE(&hash[16], S->H[2]); 216 sha512_STORE64_BE(&hash[24], S->H[3]); 217 sha512_STORE64_BE(&hash[32], S->H[4]); 218 sha512_STORE64_BE(&hash[40], S->H[5]); 219 sha512_STORE64_BE(&hash[48], S->H[6]); 220 sha512_STORE64_BE(&hash[56], S->H[7]); 221 } 222 223 static void 224 crypto_hash_sha512(unsigned char *hash, const unsigned char *in, size_t inlen) { 225 ed25519_hash_context ctx; 226 ed25519_hash_init(&ctx); 227 ed25519_hash_update(&ctx, in, inlen); 228 ed25519_hash_final(&ctx, hash); 229 } 230 231 #else 232 233 #include <openssl/sha.h> 234 235 static void 236 crypto_hash_sha512(unsigned char *hash, const unsigned char *in, size_t inlen) { 237 SHA512(in, inlen, hash); 238 } 239 240 #endif 241 242 243 244 245 typedef int32_t crypto_int32; 246 typedef uint32_t crypto_uint32; 247 typedef int64_t crypto_int64; 248 typedef uint64_t crypto_uint64; 249 250 typedef crypto_int32 fe[10]; 251 252 /* 253 h = 0 254 */ 255 256 static void fe_0(fe h) 257 { 258 h[0] = 0; 259 h[1] = 0; 260 h[2] = 0; 261 h[3] = 0; 262 h[4] = 0; 263 h[5] = 0; 264 h[6] = 0; 265 h[7] = 0; 266 h[8] = 0; 267 h[9] = 0; 268 } 269 270 /* 271 h = 1 272 */ 273 274 static void fe_1(fe h) 275 { 276 h[0] = 1; 277 h[1] = 0; 278 h[2] = 0; 279 h[3] = 0; 280 h[4] = 0; 281 h[5] = 0; 282 h[6] = 0; 283 h[7] = 0; 284 h[8] = 0; 285 h[9] = 0; 286 } 287 288 /* 289 h = f + g 290 Can overlap h with f or g. 291 292 Preconditions: 293 |f| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc. 294 |g| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc. 295 296 Postconditions: 297 |h| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc. 298 */ 299 300 static void fe_add(fe h,const fe f,const fe g) 301 { 302 crypto_int32 f0 = f[0]; 303 crypto_int32 f1 = f[1]; 304 crypto_int32 f2 = f[2]; 305 crypto_int32 f3 = f[3]; 306 crypto_int32 f4 = f[4]; 307 crypto_int32 f5 = f[5]; 308 crypto_int32 f6 = f[6]; 309 crypto_int32 f7 = f[7]; 310 crypto_int32 f8 = f[8]; 311 crypto_int32 f9 = f[9]; 312 crypto_int32 g0 = g[0]; 313 crypto_int32 g1 = g[1]; 314 crypto_int32 g2 = g[2]; 315 crypto_int32 g3 = g[3]; 316 crypto_int32 g4 = g[4]; 317 crypto_int32 g5 = g[5]; 318 crypto_int32 g6 = g[6]; 319 crypto_int32 g7 = g[7]; 320 crypto_int32 g8 = g[8]; 321 crypto_int32 g9 = g[9]; 322 crypto_int32 h0 = f0 + g0; 323 crypto_int32 h1 = f1 + g1; 324 crypto_int32 h2 = f2 + g2; 325 crypto_int32 h3 = f3 + g3; 326 crypto_int32 h4 = f4 + g4; 327 crypto_int32 h5 = f5 + g5; 328 crypto_int32 h6 = f6 + g6; 329 crypto_int32 h7 = f7 + g7; 330 crypto_int32 h8 = f8 + g8; 331 crypto_int32 h9 = f9 + g9; 332 h[0] = h0; 333 h[1] = h1; 334 h[2] = h2; 335 h[3] = h3; 336 h[4] = h4; 337 h[5] = h5; 338 h[6] = h6; 339 h[7] = h7; 340 h[8] = h8; 341 h[9] = h9; 342 } 343 344 345 /* 346 Replace (f,g) with (g,g) if b == 1; 347 replace (f,g) with (f,g) if b == 0. 348 349 Preconditions: b in {0,1}. 350 */ 351 352 static void fe_cmov(fe f,const fe g,unsigned int b) 353 { 354 crypto_int32 f0 = f[0]; 355 crypto_int32 f1 = f[1]; 356 crypto_int32 f2 = f[2]; 357 crypto_int32 f3 = f[3]; 358 crypto_int32 f4 = f[4]; 359 crypto_int32 f5 = f[5]; 360 crypto_int32 f6 = f[6]; 361 crypto_int32 f7 = f[7]; 362 crypto_int32 f8 = f[8]; 363 crypto_int32 f9 = f[9]; 364 crypto_int32 g0 = g[0]; 365 crypto_int32 g1 = g[1]; 366 crypto_int32 g2 = g[2]; 367 crypto_int32 g3 = g[3]; 368 crypto_int32 g4 = g[4]; 369 crypto_int32 g5 = g[5]; 370 crypto_int32 g6 = g[6]; 371 crypto_int32 g7 = g[7]; 372 crypto_int32 g8 = g[8]; 373 crypto_int32 g9 = g[9]; 374 crypto_int32 x0 = f0 ^ g0; 375 crypto_int32 x1 = f1 ^ g1; 376 crypto_int32 x2 = f2 ^ g2; 377 crypto_int32 x3 = f3 ^ g3; 378 crypto_int32 x4 = f4 ^ g4; 379 crypto_int32 x5 = f5 ^ g5; 380 crypto_int32 x6 = f6 ^ g6; 381 crypto_int32 x7 = f7 ^ g7; 382 crypto_int32 x8 = f8 ^ g8; 383 crypto_int32 x9 = f9 ^ g9; 384 b = -b; 385 x0 &= b; 386 x1 &= b; 387 x2 &= b; 388 x3 &= b; 389 x4 &= b; 390 x5 &= b; 391 x6 &= b; 392 x7 &= b; 393 x8 &= b; 394 x9 &= b; 395 f[0] = f0 ^ x0; 396 f[1] = f1 ^ x1; 397 f[2] = f2 ^ x2; 398 f[3] = f3 ^ x3; 399 f[4] = f4 ^ x4; 400 f[5] = f5 ^ x5; 401 f[6] = f6 ^ x6; 402 f[7] = f7 ^ x7; 403 f[8] = f8 ^ x8; 404 f[9] = f9 ^ x9; 405 } 406 407 408 /* 409 h = f 410 */ 411 412 static void fe_copy(fe h,const fe f) 413 { 414 crypto_int32 f0 = f[0]; 415 crypto_int32 f1 = f[1]; 416 crypto_int32 f2 = f[2]; 417 crypto_int32 f3 = f[3]; 418 crypto_int32 f4 = f[4]; 419 crypto_int32 f5 = f[5]; 420 crypto_int32 f6 = f[6]; 421 crypto_int32 f7 = f[7]; 422 crypto_int32 f8 = f[8]; 423 crypto_int32 f9 = f[9]; 424 h[0] = f0; 425 h[1] = f1; 426 h[2] = f2; 427 h[3] = f3; 428 h[4] = f4; 429 h[5] = f5; 430 h[6] = f6; 431 h[7] = f7; 432 h[8] = f8; 433 h[9] = f9; 434 } 435 436 437 static crypto_uint64 load_3(const unsigned char *in) 438 { 439 crypto_uint64 result; 440 result = (crypto_uint64) in[0]; 441 result |= ((crypto_uint64) in[1]) << 8; 442 result |= ((crypto_uint64) in[2]) << 16; 443 return result; 444 } 445 446 static crypto_uint64 load_4(const unsigned char *in) 447 { 448 crypto_uint64 result; 449 result = (crypto_uint64) in[0]; 450 result |= ((crypto_uint64) in[1]) << 8; 451 result |= ((crypto_uint64) in[2]) << 16; 452 result |= ((crypto_uint64) in[3]) << 24; 453 return result; 454 } 455 456 /* 457 Ignores top bit of h. 458 */ 459 460 static void fe_frombytes(fe h,const unsigned char *s) 461 { 462 crypto_int64 h0 = load_4(s); 463 crypto_int64 h1 = load_3(s + 4) << 6; 464 crypto_int64 h2 = load_3(s + 7) << 5; 465 crypto_int64 h3 = load_3(s + 10) << 3; 466 crypto_int64 h4 = load_3(s + 13) << 2; 467 crypto_int64 h5 = load_4(s + 16); 468 crypto_int64 h6 = load_3(s + 20) << 7; 469 crypto_int64 h7 = load_3(s + 23) << 5; 470 crypto_int64 h8 = load_3(s + 26) << 4; 471 crypto_int64 h9 = (load_3(s + 29) & 8388607) << 2; 472 crypto_int64 carry0; 473 crypto_int64 carry1; 474 crypto_int64 carry2; 475 crypto_int64 carry3; 476 crypto_int64 carry4; 477 crypto_int64 carry5; 478 crypto_int64 carry6; 479 crypto_int64 carry7; 480 crypto_int64 carry8; 481 crypto_int64 carry9; 482 483 carry9 = (h9 + (crypto_int64) (1<<24)) >> 25; h0 += carry9 * 19; h9 -= carry9 << 25; 484 carry1 = (h1 + (crypto_int64) (1<<24)) >> 25; h2 += carry1; h1 -= carry1 << 25; 485 carry3 = (h3 + (crypto_int64) (1<<24)) >> 25; h4 += carry3; h3 -= carry3 << 25; 486 carry5 = (h5 + (crypto_int64) (1<<24)) >> 25; h6 += carry5; h5 -= carry5 << 25; 487 carry7 = (h7 + (crypto_int64) (1<<24)) >> 25; h8 += carry7; h7 -= carry7 << 25; 488 489 carry0 = (h0 + (crypto_int64) (1<<25)) >> 26; h1 += carry0; h0 -= carry0 << 26; 490 carry2 = (h2 + (crypto_int64) (1<<25)) >> 26; h3 += carry2; h2 -= carry2 << 26; 491 carry4 = (h4 + (crypto_int64) (1<<25)) >> 26; h5 += carry4; h4 -= carry4 << 26; 492 carry6 = (h6 + (crypto_int64) (1<<25)) >> 26; h7 += carry6; h6 -= carry6 << 26; 493 carry8 = (h8 + (crypto_int64) (1<<25)) >> 26; h9 += carry8; h8 -= carry8 << 26; 494 495 h[0] = h0; 496 h[1] = h1; 497 h[2] = h2; 498 h[3] = h3; 499 h[4] = h4; 500 h[5] = h5; 501 h[6] = h6; 502 h[7] = h7; 503 h[8] = h8; 504 h[9] = h9; 505 } 506 507 /* 508 Preconditions: 509 |h| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc. 510 511 Write p=2^255-19; q=floor(h/p). 512 Basic claim: q = floor(2^(-255)(h + 19 2^(-25)h9 + 2^(-1))). 513 514 Proof: 515 Have |h|<=p so |q|<=1 so |19^2 2^(-255) q|<1/4. 516 Also have |h-2^230 h9|<2^231 so |19 2^(-255)(h-2^230 h9)|<1/4. 517 518 Write y=2^(-1)-19^2 2^(-255)q-19 2^(-255)(h-2^230 h9). 519 Then 0<y<1. 520 521 Write r=h-pq. 522 Have 0<=r<=p-1=2^255-20. 523 Thus 0<=r+19(2^-255)r<r+19(2^-255)2^255<=2^255-1. 524 525 Write x=r+19(2^-255)r+y. 526 Then 0<x<2^255 so floor(2^(-255)x) = 0 so floor(q+2^(-255)x) = q. 527 528 Have q+2^(-255)x = 2^(-255)(h + 19 2^(-25) h9 + 2^(-1)) 529 so floor(2^(-255)(h + 19 2^(-25) h9 + 2^(-1))) = q. 530 */ 531 532 static void fe_tobytes(unsigned char *s,const fe h) 533 { 534 crypto_int32 h0 = h[0]; 535 crypto_int32 h1 = h[1]; 536 crypto_int32 h2 = h[2]; 537 crypto_int32 h3 = h[3]; 538 crypto_int32 h4 = h[4]; 539 crypto_int32 h5 = h[5]; 540 crypto_int32 h6 = h[6]; 541 crypto_int32 h7 = h[7]; 542 crypto_int32 h8 = h[8]; 543 crypto_int32 h9 = h[9]; 544 crypto_int32 q; 545 crypto_int32 carry0; 546 crypto_int32 carry1; 547 crypto_int32 carry2; 548 crypto_int32 carry3; 549 crypto_int32 carry4; 550 crypto_int32 carry5; 551 crypto_int32 carry6; 552 crypto_int32 carry7; 553 crypto_int32 carry8; 554 crypto_int32 carry9; 555 556 q = (19 * h9 + (((crypto_int32) 1) << 24)) >> 25; 557 q = (h0 + q) >> 26; 558 q = (h1 + q) >> 25; 559 q = (h2 + q) >> 26; 560 q = (h3 + q) >> 25; 561 q = (h4 + q) >> 26; 562 q = (h5 + q) >> 25; 563 q = (h6 + q) >> 26; 564 q = (h7 + q) >> 25; 565 q = (h8 + q) >> 26; 566 q = (h9 + q) >> 25; 567 568 /* Goal: Output h-(2^255-19)q, which is between 0 and 2^255-20. */ 569 h0 += 19 * q; 570 /* Goal: Output h-2^255 q, which is between 0 and 2^255-20. */ 571 572 carry0 = h0 >> 26; h1 += carry0; h0 -= carry0 << 26; 573 carry1 = h1 >> 25; h2 += carry1; h1 -= carry1 << 25; 574 carry2 = h2 >> 26; h3 += carry2; h2 -= carry2 << 26; 575 carry3 = h3 >> 25; h4 += carry3; h3 -= carry3 << 25; 576 carry4 = h4 >> 26; h5 += carry4; h4 -= carry4 << 26; 577 carry5 = h5 >> 25; h6 += carry5; h5 -= carry5 << 25; 578 carry6 = h6 >> 26; h7 += carry6; h6 -= carry6 << 26; 579 carry7 = h7 >> 25; h8 += carry7; h7 -= carry7 << 25; 580 carry8 = h8 >> 26; h9 += carry8; h8 -= carry8 << 26; 581 carry9 = h9 >> 25; h9 -= carry9 << 25; 582 /* h10 = carry9 */ 583 584 /* 585 Goal: Output h0+...+2^255 h10-2^255 q, which is between 0 and 2^255-20. 586 Have h0+...+2^230 h9 between 0 and 2^255-1; 587 evidently 2^255 h10-2^255 q = 0. 588 Goal: Output h0+...+2^230 h9. 589 */ 590 591 s[0] = h0 >> 0; 592 s[1] = h0 >> 8; 593 s[2] = h0 >> 16; 594 s[3] = (h0 >> 24) | (h1 << 2); 595 s[4] = h1 >> 6; 596 s[5] = h1 >> 14; 597 s[6] = (h1 >> 22) | (h2 << 3); 598 s[7] = h2 >> 5; 599 s[8] = h2 >> 13; 600 s[9] = (h2 >> 21) | (h3 << 5); 601 s[10] = h3 >> 3; 602 s[11] = h3 >> 11; 603 s[12] = (h3 >> 19) | (h4 << 6); 604 s[13] = h4 >> 2; 605 s[14] = h4 >> 10; 606 s[15] = h4 >> 18; 607 s[16] = h5 >> 0; 608 s[17] = h5 >> 8; 609 s[18] = h5 >> 16; 610 s[19] = (h5 >> 24) | (h6 << 1); 611 s[20] = h6 >> 7; 612 s[21] = h6 >> 15; 613 s[22] = (h6 >> 23) | (h7 << 3); 614 s[23] = h7 >> 5; 615 s[24] = h7 >> 13; 616 s[25] = (h7 >> 21) | (h8 << 4); 617 s[26] = h8 >> 4; 618 s[27] = h8 >> 12; 619 s[28] = (h8 >> 20) | (h9 << 6); 620 s[29] = h9 >> 2; 621 s[30] = h9 >> 10; 622 s[31] = h9 >> 18; 623 } 624 625 626 /* 627 h = f - g 628 Can overlap h with f or g. 629 630 Preconditions: 631 |f| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc. 632 |g| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc. 633 634 Postconditions: 635 |h| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc. 636 */ 637 638 static void fe_sub(fe h,const fe f,const fe g) 639 { 640 crypto_int32 f0 = f[0]; 641 crypto_int32 f1 = f[1]; 642 crypto_int32 f2 = f[2]; 643 crypto_int32 f3 = f[3]; 644 crypto_int32 f4 = f[4]; 645 crypto_int32 f5 = f[5]; 646 crypto_int32 f6 = f[6]; 647 crypto_int32 f7 = f[7]; 648 crypto_int32 f8 = f[8]; 649 crypto_int32 f9 = f[9]; 650 crypto_int32 g0 = g[0]; 651 crypto_int32 g1 = g[1]; 652 crypto_int32 g2 = g[2]; 653 crypto_int32 g3 = g[3]; 654 crypto_int32 g4 = g[4]; 655 crypto_int32 g5 = g[5]; 656 crypto_int32 g6 = g[6]; 657 crypto_int32 g7 = g[7]; 658 crypto_int32 g8 = g[8]; 659 crypto_int32 g9 = g[9]; 660 crypto_int32 h0 = f0 - g0; 661 crypto_int32 h1 = f1 - g1; 662 crypto_int32 h2 = f2 - g2; 663 crypto_int32 h3 = f3 - g3; 664 crypto_int32 h4 = f4 - g4; 665 crypto_int32 h5 = f5 - g5; 666 crypto_int32 h6 = f6 - g6; 667 crypto_int32 h7 = f7 - g7; 668 crypto_int32 h8 = f8 - g8; 669 crypto_int32 h9 = f9 - g9; 670 h[0] = h0; 671 h[1] = h1; 672 h[2] = h2; 673 h[3] = h3; 674 h[4] = h4; 675 h[5] = h5; 676 h[6] = h6; 677 h[7] = h7; 678 h[8] = h8; 679 h[9] = h9; 680 } 681 682 683 /* 684 h = f * f 685 Can overlap h with f. 686 687 Preconditions: 688 |f| bounded by 1.65*2^26,1.65*2^25,1.65*2^26,1.65*2^25,etc. 689 690 Postconditions: 691 |h| bounded by 1.01*2^25,1.01*2^24,1.01*2^25,1.01*2^24,etc. 692 */ 693 694 /* 695 See fe_mul.c for discussion of implementation strategy. 696 */ 697 698 static void fe_sq(fe h,const fe f) 699 { 700 crypto_int32 f0 = f[0]; 701 crypto_int32 f1 = f[1]; 702 crypto_int32 f2 = f[2]; 703 crypto_int32 f3 = f[3]; 704 crypto_int32 f4 = f[4]; 705 crypto_int32 f5 = f[5]; 706 crypto_int32 f6 = f[6]; 707 crypto_int32 f7 = f[7]; 708 crypto_int32 f8 = f[8]; 709 crypto_int32 f9 = f[9]; 710 crypto_int32 f0_2 = 2 * f0; 711 crypto_int32 f1_2 = 2 * f1; 712 crypto_int32 f2_2 = 2 * f2; 713 crypto_int32 f3_2 = 2 * f3; 714 crypto_int32 f4_2 = 2 * f4; 715 crypto_int32 f5_2 = 2 * f5; 716 crypto_int32 f6_2 = 2 * f6; 717 crypto_int32 f7_2 = 2 * f7; 718 crypto_int32 f5_38 = 38 * f5; /* 1.959375*2^30 */ 719 crypto_int32 f6_19 = 19 * f6; /* 1.959375*2^30 */ 720 crypto_int32 f7_38 = 38 * f7; /* 1.959375*2^30 */ 721 crypto_int32 f8_19 = 19 * f8; /* 1.959375*2^30 */ 722 crypto_int32 f9_38 = 38 * f9; /* 1.959375*2^30 */ 723 crypto_int64 f0f0 = f0 * (crypto_int64) f0; 724 crypto_int64 f0f1_2 = f0_2 * (crypto_int64) f1; 725 crypto_int64 f0f2_2 = f0_2 * (crypto_int64) f2; 726 crypto_int64 f0f3_2 = f0_2 * (crypto_int64) f3; 727 crypto_int64 f0f4_2 = f0_2 * (crypto_int64) f4; 728 crypto_int64 f0f5_2 = f0_2 * (crypto_int64) f5; 729 crypto_int64 f0f6_2 = f0_2 * (crypto_int64) f6; 730 crypto_int64 f0f7_2 = f0_2 * (crypto_int64) f7; 731 crypto_int64 f0f8_2 = f0_2 * (crypto_int64) f8; 732 crypto_int64 f0f9_2 = f0_2 * (crypto_int64) f9; 733 crypto_int64 f1f1_2 = f1_2 * (crypto_int64) f1; 734 crypto_int64 f1f2_2 = f1_2 * (crypto_int64) f2; 735 crypto_int64 f1f3_4 = f1_2 * (crypto_int64) f3_2; 736 crypto_int64 f1f4_2 = f1_2 * (crypto_int64) f4; 737 crypto_int64 f1f5_4 = f1_2 * (crypto_int64) f5_2; 738 crypto_int64 f1f6_2 = f1_2 * (crypto_int64) f6; 739 crypto_int64 f1f7_4 = f1_2 * (crypto_int64) f7_2; 740 crypto_int64 f1f8_2 = f1_2 * (crypto_int64) f8; 741 crypto_int64 f1f9_76 = f1_2 * (crypto_int64) f9_38; 742 crypto_int64 f2f2 = f2 * (crypto_int64) f2; 743 crypto_int64 f2f3_2 = f2_2 * (crypto_int64) f3; 744 crypto_int64 f2f4_2 = f2_2 * (crypto_int64) f4; 745 crypto_int64 f2f5_2 = f2_2 * (crypto_int64) f5; 746 crypto_int64 f2f6_2 = f2_2 * (crypto_int64) f6; 747 crypto_int64 f2f7_2 = f2_2 * (crypto_int64) f7; 748 crypto_int64 f2f8_38 = f2_2 * (crypto_int64) f8_19; 749 crypto_int64 f2f9_38 = f2 * (crypto_int64) f9_38; 750 crypto_int64 f3f3_2 = f3_2 * (crypto_int64) f3; 751 crypto_int64 f3f4_2 = f3_2 * (crypto_int64) f4; 752 crypto_int64 f3f5_4 = f3_2 * (crypto_int64) f5_2; 753 crypto_int64 f3f6_2 = f3_2 * (crypto_int64) f6; 754 crypto_int64 f3f7_76 = f3_2 * (crypto_int64) f7_38; 755 crypto_int64 f3f8_38 = f3_2 * (crypto_int64) f8_19; 756 crypto_int64 f3f9_76 = f3_2 * (crypto_int64) f9_38; 757 crypto_int64 f4f4 = f4 * (crypto_int64) f4; 758 crypto_int64 f4f5_2 = f4_2 * (crypto_int64) f5; 759 crypto_int64 f4f6_38 = f4_2 * (crypto_int64) f6_19; 760 crypto_int64 f4f7_38 = f4 * (crypto_int64) f7_38; 761 crypto_int64 f4f8_38 = f4_2 * (crypto_int64) f8_19; 762 crypto_int64 f4f9_38 = f4 * (crypto_int64) f9_38; 763 crypto_int64 f5f5_38 = f5 * (crypto_int64) f5_38; 764 crypto_int64 f5f6_38 = f5_2 * (crypto_int64) f6_19; 765 crypto_int64 f5f7_76 = f5_2 * (crypto_int64) f7_38; 766 crypto_int64 f5f8_38 = f5_2 * (crypto_int64) f8_19; 767 crypto_int64 f5f9_76 = f5_2 * (crypto_int64) f9_38; 768 crypto_int64 f6f6_19 = f6 * (crypto_int64) f6_19; 769 crypto_int64 f6f7_38 = f6 * (crypto_int64) f7_38; 770 crypto_int64 f6f8_38 = f6_2 * (crypto_int64) f8_19; 771 crypto_int64 f6f9_38 = f6 * (crypto_int64) f9_38; 772 crypto_int64 f7f7_38 = f7 * (crypto_int64) f7_38; 773 crypto_int64 f7f8_38 = f7_2 * (crypto_int64) f8_19; 774 crypto_int64 f7f9_76 = f7_2 * (crypto_int64) f9_38; 775 crypto_int64 f8f8_19 = f8 * (crypto_int64) f8_19; 776 crypto_int64 f8f9_38 = f8 * (crypto_int64) f9_38; 777 crypto_int64 f9f9_38 = f9 * (crypto_int64) f9_38; 778 crypto_int64 h0 = f0f0 +f1f9_76+f2f8_38+f3f7_76+f4f6_38+f5f5_38; 779 crypto_int64 h1 = f0f1_2+f2f9_38+f3f8_38+f4f7_38+f5f6_38; 780 crypto_int64 h2 = f0f2_2+f1f1_2 +f3f9_76+f4f8_38+f5f7_76+f6f6_19; 781 crypto_int64 h3 = f0f3_2+f1f2_2 +f4f9_38+f5f8_38+f6f7_38; 782 crypto_int64 h4 = f0f4_2+f1f3_4 +f2f2 +f5f9_76+f6f8_38+f7f7_38; 783 crypto_int64 h5 = f0f5_2+f1f4_2 +f2f3_2 +f6f9_38+f7f8_38; 784 crypto_int64 h6 = f0f6_2+f1f5_4 +f2f4_2 +f3f3_2 +f7f9_76+f8f8_19; 785 crypto_int64 h7 = f0f7_2+f1f6_2 +f2f5_2 +f3f4_2 +f8f9_38; 786 crypto_int64 h8 = f0f8_2+f1f7_4 +f2f6_2 +f3f5_4 +f4f4 +f9f9_38; 787 crypto_int64 h9 = f0f9_2+f1f8_2 +f2f7_2 +f3f6_2 +f4f5_2; 788 crypto_int64 carry0; 789 crypto_int64 carry1; 790 crypto_int64 carry2; 791 crypto_int64 carry3; 792 crypto_int64 carry4; 793 crypto_int64 carry5; 794 crypto_int64 carry6; 795 crypto_int64 carry7; 796 crypto_int64 carry8; 797 crypto_int64 carry9; 798 799 carry0 = (h0 + (crypto_int64) (1<<25)) >> 26; h1 += carry0; h0 -= carry0 << 26; 800 carry4 = (h4 + (crypto_int64) (1<<25)) >> 26; h5 += carry4; h4 -= carry4 << 26; 801 802 carry1 = (h1 + (crypto_int64) (1<<24)) >> 25; h2 += carry1; h1 -= carry1 << 25; 803 carry5 = (h5 + (crypto_int64) (1<<24)) >> 25; h6 += carry5; h5 -= carry5 << 25; 804 805 carry2 = (h2 + (crypto_int64) (1<<25)) >> 26; h3 += carry2; h2 -= carry2 << 26; 806 carry6 = (h6 + (crypto_int64) (1<<25)) >> 26; h7 += carry6; h6 -= carry6 << 26; 807 808 carry3 = (h3 + (crypto_int64) (1<<24)) >> 25; h4 += carry3; h3 -= carry3 << 25; 809 carry7 = (h7 + (crypto_int64) (1<<24)) >> 25; h8 += carry7; h7 -= carry7 << 25; 810 811 carry4 = (h4 + (crypto_int64) (1<<25)) >> 26; h5 += carry4; h4 -= carry4 << 26; 812 carry8 = (h8 + (crypto_int64) (1<<25)) >> 26; h9 += carry8; h8 -= carry8 << 26; 813 814 carry9 = (h9 + (crypto_int64) (1<<24)) >> 25; h0 += carry9 * 19; h9 -= carry9 << 25; 815 816 carry0 = (h0 + (crypto_int64) (1<<25)) >> 26; h1 += carry0; h0 -= carry0 << 26; 817 818 h[0] = h0; 819 h[1] = h1; 820 h[2] = h2; 821 h[3] = h3; 822 h[4] = h4; 823 h[5] = h5; 824 h[6] = h6; 825 h[7] = h7; 826 h[8] = h8; 827 h[9] = h9; 828 } 829 830 /* 831 h = 2 * f * f 832 Can overlap h with f. 833 834 Preconditions: 835 |f| bounded by 1.65*2^26,1.65*2^25,1.65*2^26,1.65*2^25,etc. 836 837 Postconditions: 838 |h| bounded by 1.01*2^25,1.01*2^24,1.01*2^25,1.01*2^24,etc. 839 */ 840 841 /* 842 See fe_mul.c for discussion of implementation strategy. 843 */ 844 845 static void fe_sq2(fe h,const fe f) 846 { 847 crypto_int32 f0 = f[0]; 848 crypto_int32 f1 = f[1]; 849 crypto_int32 f2 = f[2]; 850 crypto_int32 f3 = f[3]; 851 crypto_int32 f4 = f[4]; 852 crypto_int32 f5 = f[5]; 853 crypto_int32 f6 = f[6]; 854 crypto_int32 f7 = f[7]; 855 crypto_int32 f8 = f[8]; 856 crypto_int32 f9 = f[9]; 857 crypto_int32 f0_2 = 2 * f0; 858 crypto_int32 f1_2 = 2 * f1; 859 crypto_int32 f2_2 = 2 * f2; 860 crypto_int32 f3_2 = 2 * f3; 861 crypto_int32 f4_2 = 2 * f4; 862 crypto_int32 f5_2 = 2 * f5; 863 crypto_int32 f6_2 = 2 * f6; 864 crypto_int32 f7_2 = 2 * f7; 865 crypto_int32 f5_38 = 38 * f5; /* 1.959375*2^30 */ 866 crypto_int32 f6_19 = 19 * f6; /* 1.959375*2^30 */ 867 crypto_int32 f7_38 = 38 * f7; /* 1.959375*2^30 */ 868 crypto_int32 f8_19 = 19 * f8; /* 1.959375*2^30 */ 869 crypto_int32 f9_38 = 38 * f9; /* 1.959375*2^30 */ 870 crypto_int64 f0f0 = f0 * (crypto_int64) f0; 871 crypto_int64 f0f1_2 = f0_2 * (crypto_int64) f1; 872 crypto_int64 f0f2_2 = f0_2 * (crypto_int64) f2; 873 crypto_int64 f0f3_2 = f0_2 * (crypto_int64) f3; 874 crypto_int64 f0f4_2 = f0_2 * (crypto_int64) f4; 875 crypto_int64 f0f5_2 = f0_2 * (crypto_int64) f5; 876 crypto_int64 f0f6_2 = f0_2 * (crypto_int64) f6; 877 crypto_int64 f0f7_2 = f0_2 * (crypto_int64) f7; 878 crypto_int64 f0f8_2 = f0_2 * (crypto_int64) f8; 879 crypto_int64 f0f9_2 = f0_2 * (crypto_int64) f9; 880 crypto_int64 f1f1_2 = f1_2 * (crypto_int64) f1; 881 crypto_int64 f1f2_2 = f1_2 * (crypto_int64) f2; 882 crypto_int64 f1f3_4 = f1_2 * (crypto_int64) f3_2; 883 crypto_int64 f1f4_2 = f1_2 * (crypto_int64) f4; 884 crypto_int64 f1f5_4 = f1_2 * (crypto_int64) f5_2; 885 crypto_int64 f1f6_2 = f1_2 * (crypto_int64) f6; 886 crypto_int64 f1f7_4 = f1_2 * (crypto_int64) f7_2; 887 crypto_int64 f1f8_2 = f1_2 * (crypto_int64) f8; 888 crypto_int64 f1f9_76 = f1_2 * (crypto_int64) f9_38; 889 crypto_int64 f2f2 = f2 * (crypto_int64) f2; 890 crypto_int64 f2f3_2 = f2_2 * (crypto_int64) f3; 891 crypto_int64 f2f4_2 = f2_2 * (crypto_int64) f4; 892 crypto_int64 f2f5_2 = f2_2 * (crypto_int64) f5; 893 crypto_int64 f2f6_2 = f2_2 * (crypto_int64) f6; 894 crypto_int64 f2f7_2 = f2_2 * (crypto_int64) f7; 895 crypto_int64 f2f8_38 = f2_2 * (crypto_int64) f8_19; 896 crypto_int64 f2f9_38 = f2 * (crypto_int64) f9_38; 897 crypto_int64 f3f3_2 = f3_2 * (crypto_int64) f3; 898 crypto_int64 f3f4_2 = f3_2 * (crypto_int64) f4; 899 crypto_int64 f3f5_4 = f3_2 * (crypto_int64) f5_2; 900 crypto_int64 f3f6_2 = f3_2 * (crypto_int64) f6; 901 crypto_int64 f3f7_76 = f3_2 * (crypto_int64) f7_38; 902 crypto_int64 f3f8_38 = f3_2 * (crypto_int64) f8_19; 903 crypto_int64 f3f9_76 = f3_2 * (crypto_int64) f9_38; 904 crypto_int64 f4f4 = f4 * (crypto_int64) f4; 905 crypto_int64 f4f5_2 = f4_2 * (crypto_int64) f5; 906 crypto_int64 f4f6_38 = f4_2 * (crypto_int64) f6_19; 907 crypto_int64 f4f7_38 = f4 * (crypto_int64) f7_38; 908 crypto_int64 f4f8_38 = f4_2 * (crypto_int64) f8_19; 909 crypto_int64 f4f9_38 = f4 * (crypto_int64) f9_38; 910 crypto_int64 f5f5_38 = f5 * (crypto_int64) f5_38; 911 crypto_int64 f5f6_38 = f5_2 * (crypto_int64) f6_19; 912 crypto_int64 f5f7_76 = f5_2 * (crypto_int64) f7_38; 913 crypto_int64 f5f8_38 = f5_2 * (crypto_int64) f8_19; 914 crypto_int64 f5f9_76 = f5_2 * (crypto_int64) f9_38; 915 crypto_int64 f6f6_19 = f6 * (crypto_int64) f6_19; 916 crypto_int64 f6f7_38 = f6 * (crypto_int64) f7_38; 917 crypto_int64 f6f8_38 = f6_2 * (crypto_int64) f8_19; 918 crypto_int64 f6f9_38 = f6 * (crypto_int64) f9_38; 919 crypto_int64 f7f7_38 = f7 * (crypto_int64) f7_38; 920 crypto_int64 f7f8_38 = f7_2 * (crypto_int64) f8_19; 921 crypto_int64 f7f9_76 = f7_2 * (crypto_int64) f9_38; 922 crypto_int64 f8f8_19 = f8 * (crypto_int64) f8_19; 923 crypto_int64 f8f9_38 = f8 * (crypto_int64) f9_38; 924 crypto_int64 f9f9_38 = f9 * (crypto_int64) f9_38; 925 crypto_int64 h0 = f0f0 +f1f9_76+f2f8_38+f3f7_76+f4f6_38+f5f5_38; 926 crypto_int64 h1 = f0f1_2+f2f9_38+f3f8_38+f4f7_38+f5f6_38; 927 crypto_int64 h2 = f0f2_2+f1f1_2 +f3f9_76+f4f8_38+f5f7_76+f6f6_19; 928 crypto_int64 h3 = f0f3_2+f1f2_2 +f4f9_38+f5f8_38+f6f7_38; 929 crypto_int64 h4 = f0f4_2+f1f3_4 +f2f2 +f5f9_76+f6f8_38+f7f7_38; 930 crypto_int64 h5 = f0f5_2+f1f4_2 +f2f3_2 +f6f9_38+f7f8_38; 931 crypto_int64 h6 = f0f6_2+f1f5_4 +f2f4_2 +f3f3_2 +f7f9_76+f8f8_19; 932 crypto_int64 h7 = f0f7_2+f1f6_2 +f2f5_2 +f3f4_2 +f8f9_38; 933 crypto_int64 h8 = f0f8_2+f1f7_4 +f2f6_2 +f3f5_4 +f4f4 +f9f9_38; 934 crypto_int64 h9 = f0f9_2+f1f8_2 +f2f7_2 +f3f6_2 +f4f5_2; 935 crypto_int64 carry0; 936 crypto_int64 carry1; 937 crypto_int64 carry2; 938 crypto_int64 carry3; 939 crypto_int64 carry4; 940 crypto_int64 carry5; 941 crypto_int64 carry6; 942 crypto_int64 carry7; 943 crypto_int64 carry8; 944 crypto_int64 carry9; 945 946 h0 += h0; 947 h1 += h1; 948 h2 += h2; 949 h3 += h3; 950 h4 += h4; 951 h5 += h5; 952 h6 += h6; 953 h7 += h7; 954 h8 += h8; 955 h9 += h9; 956 957 carry0 = (h0 + (crypto_int64) (1<<25)) >> 26; h1 += carry0; h0 -= carry0 << 26; 958 carry4 = (h4 + (crypto_int64) (1<<25)) >> 26; h5 += carry4; h4 -= carry4 << 26; 959 960 carry1 = (h1 + (crypto_int64) (1<<24)) >> 25; h2 += carry1; h1 -= carry1 << 25; 961 carry5 = (h5 + (crypto_int64) (1<<24)) >> 25; h6 += carry5; h5 -= carry5 << 25; 962 963 carry2 = (h2 + (crypto_int64) (1<<25)) >> 26; h3 += carry2; h2 -= carry2 << 26; 964 carry6 = (h6 + (crypto_int64) (1<<25)) >> 26; h7 += carry6; h6 -= carry6 << 26; 965 966 carry3 = (h3 + (crypto_int64) (1<<24)) >> 25; h4 += carry3; h3 -= carry3 << 25; 967 carry7 = (h7 + (crypto_int64) (1<<24)) >> 25; h8 += carry7; h7 -= carry7 << 25; 968 969 carry4 = (h4 + (crypto_int64) (1<<25)) >> 26; h5 += carry4; h4 -= carry4 << 26; 970 carry8 = (h8 + (crypto_int64) (1<<25)) >> 26; h9 += carry8; h8 -= carry8 << 26; 971 972 carry9 = (h9 + (crypto_int64) (1<<24)) >> 25; h0 += carry9 * 19; h9 -= carry9 << 25; 973 974 carry0 = (h0 + (crypto_int64) (1<<25)) >> 26; h1 += carry0; h0 -= carry0 << 26; 975 976 h[0] = h0; 977 h[1] = h1; 978 h[2] = h2; 979 h[3] = h3; 980 h[4] = h4; 981 h[5] = h5; 982 h[6] = h6; 983 h[7] = h7; 984 h[8] = h8; 985 h[9] = h9; 986 } 987 988 /* 989 h = f * g 990 Can overlap h with f or g. 991 992 Preconditions: 993 |f| bounded by 1.65*2^26,1.65*2^25,1.65*2^26,1.65*2^25,etc. 994 |g| bounded by 1.65*2^26,1.65*2^25,1.65*2^26,1.65*2^25,etc. 995 996 Postconditions: 997 |h| bounded by 1.01*2^25,1.01*2^24,1.01*2^25,1.01*2^24,etc. 998 */ 999 1000 /* 1001 Notes on implementation strategy: 1002 1003 Using schoolbook multiplication. 1004 Karatsuba would save a little in some cost models. 1005 1006 Most multiplications by 2 and 19 are 32-bit precomputations; 1007 cheaper than 64-bit postcomputations. 1008 1009 There is one remaining multiplication by 19 in the carry chain; 1010 one *19 precomputation can be merged into this, 1011 but the resulting data flow is considerably less clean. 1012 1013 There are 12 carries below. 1014 10 of them are 2-way parallelizable and vectorizable. 1015 Can get away with 11 carries, but then data flow is much deeper. 1016 1017 With tighter constraints on inputs can squeeze carries into int32. 1018 */ 1019 1020 static void fe_mul(fe h,const fe f,const fe g) 1021 { 1022 crypto_int32 f0 = f[0]; 1023 crypto_int32 f1 = f[1]; 1024 crypto_int32 f2 = f[2]; 1025 crypto_int32 f3 = f[3]; 1026 crypto_int32 f4 = f[4]; 1027 crypto_int32 f5 = f[5]; 1028 crypto_int32 f6 = f[6]; 1029 crypto_int32 f7 = f[7]; 1030 crypto_int32 f8 = f[8]; 1031 crypto_int32 f9 = f[9]; 1032 crypto_int32 g0 = g[0]; 1033 crypto_int32 g1 = g[1]; 1034 crypto_int32 g2 = g[2]; 1035 crypto_int32 g3 = g[3]; 1036 crypto_int32 g4 = g[4]; 1037 crypto_int32 g5 = g[5]; 1038 crypto_int32 g6 = g[6]; 1039 crypto_int32 g7 = g[7]; 1040 crypto_int32 g8 = g[8]; 1041 crypto_int32 g9 = g[9]; 1042 crypto_int32 g1_19 = 19 * g1; /* 1.959375*2^29 */ 1043 crypto_int32 g2_19 = 19 * g2; /* 1.959375*2^30; still ok */ 1044 crypto_int32 g3_19 = 19 * g3; 1045 crypto_int32 g4_19 = 19 * g4; 1046 crypto_int32 g5_19 = 19 * g5; 1047 crypto_int32 g6_19 = 19 * g6; 1048 crypto_int32 g7_19 = 19 * g7; 1049 crypto_int32 g8_19 = 19 * g8; 1050 crypto_int32 g9_19 = 19 * g9; 1051 crypto_int32 f1_2 = 2 * f1; 1052 crypto_int32 f3_2 = 2 * f3; 1053 crypto_int32 f5_2 = 2 * f5; 1054 crypto_int32 f7_2 = 2 * f7; 1055 crypto_int32 f9_2 = 2 * f9; 1056 crypto_int64 f0g0 = f0 * (crypto_int64) g0; 1057 crypto_int64 f0g1 = f0 * (crypto_int64) g1; 1058 crypto_int64 f0g2 = f0 * (crypto_int64) g2; 1059 crypto_int64 f0g3 = f0 * (crypto_int64) g3; 1060 crypto_int64 f0g4 = f0 * (crypto_int64) g4; 1061 crypto_int64 f0g5 = f0 * (crypto_int64) g5; 1062 crypto_int64 f0g6 = f0 * (crypto_int64) g6; 1063 crypto_int64 f0g7 = f0 * (crypto_int64) g7; 1064 crypto_int64 f0g8 = f0 * (crypto_int64) g8; 1065 crypto_int64 f0g9 = f0 * (crypto_int64) g9; 1066 crypto_int64 f1g0 = f1 * (crypto_int64) g0; 1067 crypto_int64 f1g1_2 = f1_2 * (crypto_int64) g1; 1068 crypto_int64 f1g2 = f1 * (crypto_int64) g2; 1069 crypto_int64 f1g3_2 = f1_2 * (crypto_int64) g3; 1070 crypto_int64 f1g4 = f1 * (crypto_int64) g4; 1071 crypto_int64 f1g5_2 = f1_2 * (crypto_int64) g5; 1072 crypto_int64 f1g6 = f1 * (crypto_int64) g6; 1073 crypto_int64 f1g7_2 = f1_2 * (crypto_int64) g7; 1074 crypto_int64 f1g8 = f1 * (crypto_int64) g8; 1075 crypto_int64 f1g9_38 = f1_2 * (crypto_int64) g9_19; 1076 crypto_int64 f2g0 = f2 * (crypto_int64) g0; 1077 crypto_int64 f2g1 = f2 * (crypto_int64) g1; 1078 crypto_int64 f2g2 = f2 * (crypto_int64) g2; 1079 crypto_int64 f2g3 = f2 * (crypto_int64) g3; 1080 crypto_int64 f2g4 = f2 * (crypto_int64) g4; 1081 crypto_int64 f2g5 = f2 * (crypto_int64) g5; 1082 crypto_int64 f2g6 = f2 * (crypto_int64) g6; 1083 crypto_int64 f2g7 = f2 * (crypto_int64) g7; 1084 crypto_int64 f2g8_19 = f2 * (crypto_int64) g8_19; 1085 crypto_int64 f2g9_19 = f2 * (crypto_int64) g9_19; 1086 crypto_int64 f3g0 = f3 * (crypto_int64) g0; 1087 crypto_int64 f3g1_2 = f3_2 * (crypto_int64) g1; 1088 crypto_int64 f3g2 = f3 * (crypto_int64) g2; 1089 crypto_int64 f3g3_2 = f3_2 * (crypto_int64) g3; 1090 crypto_int64 f3g4 = f3 * (crypto_int64) g4; 1091 crypto_int64 f3g5_2 = f3_2 * (crypto_int64) g5; 1092 crypto_int64 f3g6 = f3 * (crypto_int64) g6; 1093 crypto_int64 f3g7_38 = f3_2 * (crypto_int64) g7_19; 1094 crypto_int64 f3g8_19 = f3 * (crypto_int64) g8_19; 1095 crypto_int64 f3g9_38 = f3_2 * (crypto_int64) g9_19; 1096 crypto_int64 f4g0 = f4 * (crypto_int64) g0; 1097 crypto_int64 f4g1 = f4 * (crypto_int64) g1; 1098 crypto_int64 f4g2 = f4 * (crypto_int64) g2; 1099 crypto_int64 f4g3 = f4 * (crypto_int64) g3; 1100 crypto_int64 f4g4 = f4 * (crypto_int64) g4; 1101 crypto_int64 f4g5 = f4 * (crypto_int64) g5; 1102 crypto_int64 f4g6_19 = f4 * (crypto_int64) g6_19; 1103 crypto_int64 f4g7_19 = f4 * (crypto_int64) g7_19; 1104 crypto_int64 f4g8_19 = f4 * (crypto_int64) g8_19; 1105 crypto_int64 f4g9_19 = f4 * (crypto_int64) g9_19; 1106 crypto_int64 f5g0 = f5 * (crypto_int64) g0; 1107 crypto_int64 f5g1_2 = f5_2 * (crypto_int64) g1; 1108 crypto_int64 f5g2 = f5 * (crypto_int64) g2; 1109 crypto_int64 f5g3_2 = f5_2 * (crypto_int64) g3; 1110 crypto_int64 f5g4 = f5 * (crypto_int64) g4; 1111 crypto_int64 f5g5_38 = f5_2 * (crypto_int64) g5_19; 1112 crypto_int64 f5g6_19 = f5 * (crypto_int64) g6_19; 1113 crypto_int64 f5g7_38 = f5_2 * (crypto_int64) g7_19; 1114 crypto_int64 f5g8_19 = f5 * (crypto_int64) g8_19; 1115 crypto_int64 f5g9_38 = f5_2 * (crypto_int64) g9_19; 1116 crypto_int64 f6g0 = f6 * (crypto_int64) g0; 1117 crypto_int64 f6g1 = f6 * (crypto_int64) g1; 1118 crypto_int64 f6g2 = f6 * (crypto_int64) g2; 1119 crypto_int64 f6g3 = f6 * (crypto_int64) g3; 1120 crypto_int64 f6g4_19 = f6 * (crypto_int64) g4_19; 1121 crypto_int64 f6g5_19 = f6 * (crypto_int64) g5_19; 1122 crypto_int64 f6g6_19 = f6 * (crypto_int64) g6_19; 1123 crypto_int64 f6g7_19 = f6 * (crypto_int64) g7_19; 1124 crypto_int64 f6g8_19 = f6 * (crypto_int64) g8_19; 1125 crypto_int64 f6g9_19 = f6 * (crypto_int64) g9_19; 1126 crypto_int64 f7g0 = f7 * (crypto_int64) g0; 1127 crypto_int64 f7g1_2 = f7_2 * (crypto_int64) g1; 1128 crypto_int64 f7g2 = f7 * (crypto_int64) g2; 1129 crypto_int64 f7g3_38 = f7_2 * (crypto_int64) g3_19; 1130 crypto_int64 f7g4_19 = f7 * (crypto_int64) g4_19; 1131 crypto_int64 f7g5_38 = f7_2 * (crypto_int64) g5_19; 1132 crypto_int64 f7g6_19 = f7 * (crypto_int64) g6_19; 1133 crypto_int64 f7g7_38 = f7_2 * (crypto_int64) g7_19; 1134 crypto_int64 f7g8_19 = f7 * (crypto_int64) g8_19; 1135 crypto_int64 f7g9_38 = f7_2 * (crypto_int64) g9_19; 1136 crypto_int64 f8g0 = f8 * (crypto_int64) g0; 1137 crypto_int64 f8g1 = f8 * (crypto_int64) g1; 1138 crypto_int64 f8g2_19 = f8 * (crypto_int64) g2_19; 1139 crypto_int64 f8g3_19 = f8 * (crypto_int64) g3_19; 1140 crypto_int64 f8g4_19 = f8 * (crypto_int64) g4_19; 1141 crypto_int64 f8g5_19 = f8 * (crypto_int64) g5_19; 1142 crypto_int64 f8g6_19 = f8 * (crypto_int64) g6_19; 1143 crypto_int64 f8g7_19 = f8 * (crypto_int64) g7_19; 1144 crypto_int64 f8g8_19 = f8 * (crypto_int64) g8_19; 1145 crypto_int64 f8g9_19 = f8 * (crypto_int64) g9_19; 1146 crypto_int64 f9g0 = f9 * (crypto_int64) g0; 1147 crypto_int64 f9g1_38 = f9_2 * (crypto_int64) g1_19; 1148 crypto_int64 f9g2_19 = f9 * (crypto_int64) g2_19; 1149 crypto_int64 f9g3_38 = f9_2 * (crypto_int64) g3_19; 1150 crypto_int64 f9g4_19 = f9 * (crypto_int64) g4_19; 1151 crypto_int64 f9g5_38 = f9_2 * (crypto_int64) g5_19; 1152 crypto_int64 f9g6_19 = f9 * (crypto_int64) g6_19; 1153 crypto_int64 f9g7_38 = f9_2 * (crypto_int64) g7_19; 1154 crypto_int64 f9g8_19 = f9 * (crypto_int64) g8_19; 1155 crypto_int64 f9g9_38 = f9_2 * (crypto_int64) g9_19; 1156 crypto_int64 h0 = f0g0+f1g9_38+f2g8_19+f3g7_38+f4g6_19+f5g5_38+f6g4_19+f7g3_38+f8g2_19+f9g1_38; 1157 crypto_int64 h1 = f0g1+f1g0 +f2g9_19+f3g8_19+f4g7_19+f5g6_19+f6g5_19+f7g4_19+f8g3_19+f9g2_19; 1158 crypto_int64 h2 = f0g2+f1g1_2 +f2g0 +f3g9_38+f4g8_19+f5g7_38+f6g6_19+f7g5_38+f8g4_19+f9g3_38; 1159 crypto_int64 h3 = f0g3+f1g2 +f2g1 +f3g0 +f4g9_19+f5g8_19+f6g7_19+f7g6_19+f8g5_19+f9g4_19; 1160 crypto_int64 h4 = f0g4+f1g3_2 +f2g2 +f3g1_2 +f4g0 +f5g9_38+f6g8_19+f7g7_38+f8g6_19+f9g5_38; 1161 crypto_int64 h5 = f0g5+f1g4 +f2g3 +f3g2 +f4g1 +f5g0 +f6g9_19+f7g8_19+f8g7_19+f9g6_19; 1162 crypto_int64 h6 = f0g6+f1g5_2 +f2g4 +f3g3_2 +f4g2 +f5g1_2 +f6g0 +f7g9_38+f8g8_19+f9g7_38; 1163 crypto_int64 h7 = f0g7+f1g6 +f2g5 +f3g4 +f4g3 +f5g2 +f6g1 +f7g0 +f8g9_19+f9g8_19; 1164 crypto_int64 h8 = f0g8+f1g7_2 +f2g6 +f3g5_2 +f4g4 +f5g3_2 +f6g2 +f7g1_2 +f8g0 +f9g9_38; 1165 crypto_int64 h9 = f0g9+f1g8 +f2g7 +f3g6 +f4g5 +f5g4 +f6g3 +f7g2 +f8g1 +f9g0 ; 1166 crypto_int64 carry0; 1167 crypto_int64 carry1; 1168 crypto_int64 carry2; 1169 crypto_int64 carry3; 1170 crypto_int64 carry4; 1171 crypto_int64 carry5; 1172 crypto_int64 carry6; 1173 crypto_int64 carry7; 1174 crypto_int64 carry8; 1175 crypto_int64 carry9; 1176 1177 /* 1178 |h0| <= (1.65*1.65*2^52*(1+19+19+19+19)+1.65*1.65*2^50*(38+38+38+38+38)) 1179 i.e. |h0| <= 1.4*2^60; narrower ranges for h2, h4, h6, h8 1180 |h1| <= (1.65*1.65*2^51*(1+1+19+19+19+19+19+19+19+19)) 1181 i.e. |h1| <= 1.7*2^59; narrower ranges for h3, h5, h7, h9 1182 */ 1183 1184 carry0 = (h0 + (crypto_int64) (1<<25)) >> 26; h1 += carry0; h0 -= carry0 << 26; 1185 carry4 = (h4 + (crypto_int64) (1<<25)) >> 26; h5 += carry4; h4 -= carry4 << 26; 1186 /* |h0| <= 2^25 */ 1187 /* |h4| <= 2^25 */ 1188 /* |h1| <= 1.71*2^59 */ 1189 /* |h5| <= 1.71*2^59 */ 1190 1191 carry1 = (h1 + (crypto_int64) (1<<24)) >> 25; h2 += carry1; h1 -= carry1 << 25; 1192 carry5 = (h5 + (crypto_int64) (1<<24)) >> 25; h6 += carry5; h5 -= carry5 << 25; 1193 /* |h1| <= 2^24; from now on fits into int32 */ 1194 /* |h5| <= 2^24; from now on fits into int32 */ 1195 /* |h2| <= 1.41*2^60 */ 1196 /* |h6| <= 1.41*2^60 */ 1197 1198 carry2 = (h2 + (crypto_int64) (1<<25)) >> 26; h3 += carry2; h2 -= carry2 << 26; 1199 carry6 = (h6 + (crypto_int64) (1<<25)) >> 26; h7 += carry6; h6 -= carry6 << 26; 1200 /* |h2| <= 2^25; from now on fits into int32 unchanged */ 1201 /* |h6| <= 2^25; from now on fits into int32 unchanged */ 1202 /* |h3| <= 1.71*2^59 */ 1203 /* |h7| <= 1.71*2^59 */ 1204 1205 carry3 = (h3 + (crypto_int64) (1<<24)) >> 25; h4 += carry3; h3 -= carry3 << 25; 1206 carry7 = (h7 + (crypto_int64) (1<<24)) >> 25; h8 += carry7; h7 -= carry7 << 25; 1207 /* |h3| <= 2^24; from now on fits into int32 unchanged */ 1208 /* |h7| <= 2^24; from now on fits into int32 unchanged */ 1209 /* |h4| <= 1.72*2^34 */ 1210 /* |h8| <= 1.41*2^60 */ 1211 1212 carry4 = (h4 + (crypto_int64) (1<<25)) >> 26; h5 += carry4; h4 -= carry4 << 26; 1213 carry8 = (h8 + (crypto_int64) (1<<25)) >> 26; h9 += carry8; h8 -= carry8 << 26; 1214 /* |h4| <= 2^25; from now on fits into int32 unchanged */ 1215 /* |h8| <= 2^25; from now on fits into int32 unchanged */ 1216 /* |h5| <= 1.01*2^24 */ 1217 /* |h9| <= 1.71*2^59 */ 1218 1219 carry9 = (h9 + (crypto_int64) (1<<24)) >> 25; h0 += carry9 * 19; h9 -= carry9 << 25; 1220 /* |h9| <= 2^24; from now on fits into int32 unchanged */ 1221 /* |h0| <= 1.1*2^39 */ 1222 1223 carry0 = (h0 + (crypto_int64) (1<<25)) >> 26; h1 += carry0; h0 -= carry0 << 26; 1224 /* |h0| <= 2^25; from now on fits into int32 unchanged */ 1225 /* |h1| <= 1.01*2^24 */ 1226 1227 h[0] = h0; 1228 h[1] = h1; 1229 h[2] = h2; 1230 h[3] = h3; 1231 h[4] = h4; 1232 h[5] = h5; 1233 h[6] = h6; 1234 h[7] = h7; 1235 h[8] = h8; 1236 h[9] = h9; 1237 } 1238 1239 1240 /* 1241 return 1 if f is in {1,3,5,...,q-2} 1242 return 0 if f is in {0,2,4,...,q-1} 1243 1244 Preconditions: 1245 |f| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc. 1246 */ 1247 1248 static int fe_isnegative(const fe f) 1249 { 1250 unsigned char s[32]; 1251 fe_tobytes(s,f); 1252 return s[0] & 1; 1253 } 1254 1255 1256 /* 1257 return 1 if f == 0 1258 return 0 if f != 0 1259 1260 Preconditions: 1261 |f| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc. 1262 */ 1263 1264 static const unsigned char zero[32] = {0}; 1265 1266 static int fe_isnonzero(const fe f) 1267 { 1268 unsigned char s[32]; 1269 fe_tobytes(s,f); 1270 return crypto_verify_32(s,zero); 1271 } 1272 1273 /* 1274 h = -f 1275 1276 Preconditions: 1277 |f| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc. 1278 1279 Postconditions: 1280 |h| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc. 1281 */ 1282 1283 static void fe_neg(fe h,const fe f) 1284 { 1285 crypto_int32 f0 = f[0]; 1286 crypto_int32 f1 = f[1]; 1287 crypto_int32 f2 = f[2]; 1288 crypto_int32 f3 = f[3]; 1289 crypto_int32 f4 = f[4]; 1290 crypto_int32 f5 = f[5]; 1291 crypto_int32 f6 = f[6]; 1292 crypto_int32 f7 = f[7]; 1293 crypto_int32 f8 = f[8]; 1294 crypto_int32 f9 = f[9]; 1295 crypto_int32 h0 = -f0; 1296 crypto_int32 h1 = -f1; 1297 crypto_int32 h2 = -f2; 1298 crypto_int32 h3 = -f3; 1299 crypto_int32 h4 = -f4; 1300 crypto_int32 h5 = -f5; 1301 crypto_int32 h6 = -f6; 1302 crypto_int32 h7 = -f7; 1303 crypto_int32 h8 = -f8; 1304 crypto_int32 h9 = -f9; 1305 h[0] = h0; 1306 h[1] = h1; 1307 h[2] = h2; 1308 h[3] = h3; 1309 h[4] = h4; 1310 h[5] = h5; 1311 h[6] = h6; 1312 h[7] = h7; 1313 h[8] = h8; 1314 h[9] = h9; 1315 } 1316 1317 static void fe_invert(fe out,const fe z) 1318 { 1319 fe t0; 1320 fe t1; 1321 fe t2; 1322 fe t3; 1323 int i; 1324 1325 1326 /* qhasm: fe z1 */ 1327 1328 /* qhasm: fe z2 */ 1329 1330 /* qhasm: fe z8 */ 1331 1332 /* qhasm: fe z9 */ 1333 1334 /* qhasm: fe z11 */ 1335 1336 /* qhasm: fe z22 */ 1337 1338 /* qhasm: fe z_5_0 */ 1339 1340 /* qhasm: fe z_10_5 */ 1341 1342 /* qhasm: fe z_10_0 */ 1343 1344 /* qhasm: fe z_20_10 */ 1345 1346 /* qhasm: fe z_20_0 */ 1347 1348 /* qhasm: fe z_40_20 */ 1349 1350 /* qhasm: fe z_40_0 */ 1351 1352 /* qhasm: fe z_50_10 */ 1353 1354 /* qhasm: fe z_50_0 */ 1355 1356 /* qhasm: fe z_100_50 */ 1357 1358 /* qhasm: fe z_100_0 */ 1359 1360 /* qhasm: fe z_200_100 */ 1361 1362 /* qhasm: fe z_200_0 */ 1363 1364 /* qhasm: fe z_250_50 */ 1365 1366 /* qhasm: fe z_250_0 */ 1367 1368 /* qhasm: fe z_255_5 */ 1369 1370 /* qhasm: fe z_255_21 */ 1371 1372 /* qhasm: enter pow225521 */ 1373 1374 /* qhasm: z2 = z1^2^1 */ 1375 /* asm 1: fe_sq(>z2=fe#1,<z1=fe#11); for (i = 1;i < 1;++i) fe_sq(>z2=fe#1,>z2=fe#1); */ 1376 /* asm 2: fe_sq(>z2=t0,<z1=z); for (i = 1;i < 1;++i) fe_sq(>z2=t0,>z2=t0); */ 1377 fe_sq(t0,z); for (i = 1;i < 1;++i) fe_sq(t0,t0); 1378 1379 /* qhasm: z8 = z2^2^2 */ 1380 /* asm 1: fe_sq(>z8=fe#2,<z2=fe#1); for (i = 1;i < 2;++i) fe_sq(>z8=fe#2,>z8=fe#2); */ 1381 /* asm 2: fe_sq(>z8=t1,<z2=t0); for (i = 1;i < 2;++i) fe_sq(>z8=t1,>z8=t1); */ 1382 fe_sq(t1,t0); for (i = 1;i < 2;++i) fe_sq(t1,t1); 1383 1384 /* qhasm: z9 = z1*z8 */ 1385 /* asm 1: fe_mul(>z9=fe#2,<z1=fe#11,<z8=fe#2); */ 1386 /* asm 2: fe_mul(>z9=t1,<z1=z,<z8=t1); */ 1387 fe_mul(t1,z,t1); 1388 1389 /* qhasm: z11 = z2*z9 */ 1390 /* asm 1: fe_mul(>z11=fe#1,<z2=fe#1,<z9=fe#2); */ 1391 /* asm 2: fe_mul(>z11=t0,<z2=t0,<z9=t1); */ 1392 fe_mul(t0,t0,t1); 1393 1394 /* qhasm: z22 = z11^2^1 */ 1395 /* asm 1: fe_sq(>z22=fe#3,<z11=fe#1); for (i = 1;i < 1;++i) fe_sq(>z22=fe#3,>z22=fe#3); */ 1396 /* asm 2: fe_sq(>z22=t2,<z11=t0); for (i = 1;i < 1;++i) fe_sq(>z22=t2,>z22=t2); */ 1397 fe_sq(t2,t0); for (i = 1;i < 1;++i) fe_sq(t2,t2); 1398 1399 /* qhasm: z_5_0 = z9*z22 */ 1400 /* asm 1: fe_mul(>z_5_0=fe#2,<z9=fe#2,<z22=fe#3); */ 1401 /* asm 2: fe_mul(>z_5_0=t1,<z9=t1,<z22=t2); */ 1402 fe_mul(t1,t1,t2); 1403 1404 /* qhasm: z_10_5 = z_5_0^2^5 */ 1405 /* asm 1: fe_sq(>z_10_5=fe#3,<z_5_0=fe#2); for (i = 1;i < 5;++i) fe_sq(>z_10_5=fe#3,>z_10_5=fe#3); */ 1406 /* asm 2: fe_sq(>z_10_5=t2,<z_5_0=t1); for (i = 1;i < 5;++i) fe_sq(>z_10_5=t2,>z_10_5=t2); */ 1407 fe_sq(t2,t1); for (i = 1;i < 5;++i) fe_sq(t2,t2); 1408 1409 /* qhasm: z_10_0 = z_10_5*z_5_0 */ 1410 /* asm 1: fe_mul(>z_10_0=fe#2,<z_10_5=fe#3,<z_5_0=fe#2); */ 1411 /* asm 2: fe_mul(>z_10_0=t1,<z_10_5=t2,<z_5_0=t1); */ 1412 fe_mul(t1,t2,t1); 1413 1414 /* qhasm: z_20_10 = z_10_0^2^10 */ 1415 /* asm 1: fe_sq(>z_20_10=fe#3,<z_10_0=fe#2); for (i = 1;i < 10;++i) fe_sq(>z_20_10=fe#3,>z_20_10=fe#3); */ 1416 /* asm 2: fe_sq(>z_20_10=t2,<z_10_0=t1); for (i = 1;i < 10;++i) fe_sq(>z_20_10=t2,>z_20_10=t2); */ 1417 fe_sq(t2,t1); for (i = 1;i < 10;++i) fe_sq(t2,t2); 1418 1419 /* qhasm: z_20_0 = z_20_10*z_10_0 */ 1420 /* asm 1: fe_mul(>z_20_0=fe#3,<z_20_10=fe#3,<z_10_0=fe#2); */ 1421 /* asm 2: fe_mul(>z_20_0=t2,<z_20_10=t2,<z_10_0=t1); */ 1422 fe_mul(t2,t2,t1); 1423 1424 /* qhasm: z_40_20 = z_20_0^2^20 */ 1425 /* asm 1: fe_sq(>z_40_20=fe#4,<z_20_0=fe#3); for (i = 1;i < 20;++i) fe_sq(>z_40_20=fe#4,>z_40_20=fe#4); */ 1426 /* asm 2: fe_sq(>z_40_20=t3,<z_20_0=t2); for (i = 1;i < 20;++i) fe_sq(>z_40_20=t3,>z_40_20=t3); */ 1427 fe_sq(t3,t2); for (i = 1;i < 20;++i) fe_sq(t3,t3); 1428 1429 /* qhasm: z_40_0 = z_40_20*z_20_0 */ 1430 /* asm 1: fe_mul(>z_40_0=fe#3,<z_40_20=fe#4,<z_20_0=fe#3); */ 1431 /* asm 2: fe_mul(>z_40_0=t2,<z_40_20=t3,<z_20_0=t2); */ 1432 fe_mul(t2,t3,t2); 1433 1434 /* qhasm: z_50_10 = z_40_0^2^10 */ 1435 /* asm 1: fe_sq(>z_50_10=fe#3,<z_40_0=fe#3); for (i = 1;i < 10;++i) fe_sq(>z_50_10=fe#3,>z_50_10=fe#3); */ 1436 /* asm 2: fe_sq(>z_50_10=t2,<z_40_0=t2); for (i = 1;i < 10;++i) fe_sq(>z_50_10=t2,>z_50_10=t2); */ 1437 fe_sq(t2,t2); for (i = 1;i < 10;++i) fe_sq(t2,t2); 1438 1439 /* qhasm: z_50_0 = z_50_10*z_10_0 */ 1440 /* asm 1: fe_mul(>z_50_0=fe#2,<z_50_10=fe#3,<z_10_0=fe#2); */ 1441 /* asm 2: fe_mul(>z_50_0=t1,<z_50_10=t2,<z_10_0=t1); */ 1442 fe_mul(t1,t2,t1); 1443 1444 /* qhasm: z_100_50 = z_50_0^2^50 */ 1445 /* asm 1: fe_sq(>z_100_50=fe#3,<z_50_0=fe#2); for (i = 1;i < 50;++i) fe_sq(>z_100_50=fe#3,>z_100_50=fe#3); */ 1446 /* asm 2: fe_sq(>z_100_50=t2,<z_50_0=t1); for (i = 1;i < 50;++i) fe_sq(>z_100_50=t2,>z_100_50=t2); */ 1447 fe_sq(t2,t1); for (i = 1;i < 50;++i) fe_sq(t2,t2); 1448 1449 /* qhasm: z_100_0 = z_100_50*z_50_0 */ 1450 /* asm 1: fe_mul(>z_100_0=fe#3,<z_100_50=fe#3,<z_50_0=fe#2); */ 1451 /* asm 2: fe_mul(>z_100_0=t2,<z_100_50=t2,<z_50_0=t1); */ 1452 fe_mul(t2,t2,t1); 1453 1454 /* qhasm: z_200_100 = z_100_0^2^100 */ 1455 /* asm 1: fe_sq(>z_200_100=fe#4,<z_100_0=fe#3); for (i = 1;i < 100;++i) fe_sq(>z_200_100=fe#4,>z_200_100=fe#4); */ 1456 /* asm 2: fe_sq(>z_200_100=t3,<z_100_0=t2); for (i = 1;i < 100;++i) fe_sq(>z_200_100=t3,>z_200_100=t3); */ 1457 fe_sq(t3,t2); for (i = 1;i < 100;++i) fe_sq(t3,t3); 1458 1459 /* qhasm: z_200_0 = z_200_100*z_100_0 */ 1460 /* asm 1: fe_mul(>z_200_0=fe#3,<z_200_100=fe#4,<z_100_0=fe#3); */ 1461 /* asm 2: fe_mul(>z_200_0=t2,<z_200_100=t3,<z_100_0=t2); */ 1462 fe_mul(t2,t3,t2); 1463 1464 /* qhasm: z_250_50 = z_200_0^2^50 */ 1465 /* asm 1: fe_sq(>z_250_50=fe#3,<z_200_0=fe#3); for (i = 1;i < 50;++i) fe_sq(>z_250_50=fe#3,>z_250_50=fe#3); */ 1466 /* asm 2: fe_sq(>z_250_50=t2,<z_200_0=t2); for (i = 1;i < 50;++i) fe_sq(>z_250_50=t2,>z_250_50=t2); */ 1467 fe_sq(t2,t2); for (i = 1;i < 50;++i) fe_sq(t2,t2); 1468 1469 /* qhasm: z_250_0 = z_250_50*z_50_0 */ 1470 /* asm 1: fe_mul(>z_250_0=fe#2,<z_250_50=fe#3,<z_50_0=fe#2); */ 1471 /* asm 2: fe_mul(>z_250_0=t1,<z_250_50=t2,<z_50_0=t1); */ 1472 fe_mul(t1,t2,t1); 1473 1474 /* qhasm: z_255_5 = z_250_0^2^5 */ 1475 /* asm 1: fe_sq(>z_255_5=fe#2,<z_250_0=fe#2); for (i = 1;i < 5;++i) fe_sq(>z_255_5=fe#2,>z_255_5=fe#2); */ 1476 /* asm 2: fe_sq(>z_255_5=t1,<z_250_0=t1); for (i = 1;i < 5;++i) fe_sq(>z_255_5=t1,>z_255_5=t1); */ 1477 fe_sq(t1,t1); for (i = 1;i < 5;++i) fe_sq(t1,t1); 1478 1479 /* qhasm: z_255_21 = z_255_5*z11 */ 1480 /* asm 1: fe_mul(>z_255_21=fe#12,<z_255_5=fe#2,<z11=fe#1); */ 1481 /* asm 2: fe_mul(>z_255_21=out,<z_255_5=t1,<z11=t0); */ 1482 fe_mul(out,t1,t0); 1483 1484 /* qhasm: return */ 1485 1486 return; 1487 } 1488 1489 1490 static void fe_pow22523(fe out,const fe z) 1491 { 1492 fe t0; 1493 fe t1; 1494 fe t2; 1495 int i; 1496 1497 1498 /* qhasm: fe z1 */ 1499 1500 /* qhasm: fe z2 */ 1501 1502 /* qhasm: fe z8 */ 1503 1504 /* qhasm: fe z9 */ 1505 1506 /* qhasm: fe z11 */ 1507 1508 /* qhasm: fe z22 */ 1509 1510 /* qhasm: fe z_5_0 */ 1511 1512 /* qhasm: fe z_10_5 */ 1513 1514 /* qhasm: fe z_10_0 */ 1515 1516 /* qhasm: fe z_20_10 */ 1517 1518 /* qhasm: fe z_20_0 */ 1519 1520 /* qhasm: fe z_40_20 */ 1521 1522 /* qhasm: fe z_40_0 */ 1523 1524 /* qhasm: fe z_50_10 */ 1525 1526 /* qhasm: fe z_50_0 */ 1527 1528 /* qhasm: fe z_100_50 */ 1529 1530 /* qhasm: fe z_100_0 */ 1531 1532 /* qhasm: fe z_200_100 */ 1533 1534 /* qhasm: fe z_200_0 */ 1535 1536 /* qhasm: fe z_250_50 */ 1537 1538 /* qhasm: fe z_250_0 */ 1539 1540 /* qhasm: fe z_252_2 */ 1541 1542 /* qhasm: fe z_252_3 */ 1543 1544 /* qhasm: enter pow22523 */ 1545 1546 /* qhasm: z2 = z1^2^1 */ 1547 /* asm 1: fe_sq(>z2=fe#1,<z1=fe#11); for (i = 1;i < 1;++i) fe_sq(>z2=fe#1,>z2=fe#1); */ 1548 /* asm 2: fe_sq(>z2=t0,<z1=z); for (i = 1;i < 1;++i) fe_sq(>z2=t0,>z2=t0); */ 1549 fe_sq(t0,z); for (i = 1;i < 1;++i) fe_sq(t0,t0); 1550 1551 /* qhasm: z8 = z2^2^2 */ 1552 /* asm 1: fe_sq(>z8=fe#2,<z2=fe#1); for (i = 1;i < 2;++i) fe_sq(>z8=fe#2,>z8=fe#2); */ 1553 /* asm 2: fe_sq(>z8=t1,<z2=t0); for (i = 1;i < 2;++i) fe_sq(>z8=t1,>z8=t1); */ 1554 fe_sq(t1,t0); for (i = 1;i < 2;++i) fe_sq(t1,t1); 1555 1556 /* qhasm: z9 = z1*z8 */ 1557 /* asm 1: fe_mul(>z9=fe#2,<z1=fe#11,<z8=fe#2); */ 1558 /* asm 2: fe_mul(>z9=t1,<z1=z,<z8=t1); */ 1559 fe_mul(t1,z,t1); 1560 1561 /* qhasm: z11 = z2*z9 */ 1562 /* asm 1: fe_mul(>z11=fe#1,<z2=fe#1,<z9=fe#2); */ 1563 /* asm 2: fe_mul(>z11=t0,<z2=t0,<z9=t1); */ 1564 fe_mul(t0,t0,t1); 1565 1566 /* qhasm: z22 = z11^2^1 */ 1567 /* asm 1: fe_sq(>z22=fe#1,<z11=fe#1); for (i = 1;i < 1;++i) fe_sq(>z22=fe#1,>z22=fe#1); */ 1568 /* asm 2: fe_sq(>z22=t0,<z11=t0); for (i = 1;i < 1;++i) fe_sq(>z22=t0,>z22=t0); */ 1569 fe_sq(t0,t0); for (i = 1;i < 1;++i) fe_sq(t0,t0); 1570 1571 /* qhasm: z_5_0 = z9*z22 */ 1572 /* asm 1: fe_mul(>z_5_0=fe#1,<z9=fe#2,<z22=fe#1); */ 1573 /* asm 2: fe_mul(>z_5_0=t0,<z9=t1,<z22=t0); */ 1574 fe_mul(t0,t1,t0); 1575 1576 /* qhasm: z_10_5 = z_5_0^2^5 */ 1577 /* asm 1: fe_sq(>z_10_5=fe#2,<z_5_0=fe#1); for (i = 1;i < 5;++i) fe_sq(>z_10_5=fe#2,>z_10_5=fe#2); */ 1578 /* asm 2: fe_sq(>z_10_5=t1,<z_5_0=t0); for (i = 1;i < 5;++i) fe_sq(>z_10_5=t1,>z_10_5=t1); */ 1579 fe_sq(t1,t0); for (i = 1;i < 5;++i) fe_sq(t1,t1); 1580 1581 /* qhasm: z_10_0 = z_10_5*z_5_0 */ 1582 /* asm 1: fe_mul(>z_10_0=fe#1,<z_10_5=fe#2,<z_5_0=fe#1); */ 1583 /* asm 2: fe_mul(>z_10_0=t0,<z_10_5=t1,<z_5_0=t0); */ 1584 fe_mul(t0,t1,t0); 1585 1586 /* qhasm: z_20_10 = z_10_0^2^10 */ 1587 /* asm 1: fe_sq(>z_20_10=fe#2,<z_10_0=fe#1); for (i = 1;i < 10;++i) fe_sq(>z_20_10=fe#2,>z_20_10=fe#2); */ 1588 /* asm 2: fe_sq(>z_20_10=t1,<z_10_0=t0); for (i = 1;i < 10;++i) fe_sq(>z_20_10=t1,>z_20_10=t1); */ 1589 fe_sq(t1,t0); for (i = 1;i < 10;++i) fe_sq(t1,t1); 1590 1591 /* qhasm: z_20_0 = z_20_10*z_10_0 */ 1592 /* asm 1: fe_mul(>z_20_0=fe#2,<z_20_10=fe#2,<z_10_0=fe#1); */ 1593 /* asm 2: fe_mul(>z_20_0=t1,<z_20_10=t1,<z_10_0=t0); */ 1594 fe_mul(t1,t1,t0); 1595 1596 /* qhasm: z_40_20 = z_20_0^2^20 */ 1597 /* asm 1: fe_sq(>z_40_20=fe#3,<z_20_0=fe#2); for (i = 1;i < 20;++i) fe_sq(>z_40_20=fe#3,>z_40_20=fe#3); */ 1598 /* asm 2: fe_sq(>z_40_20=t2,<z_20_0=t1); for (i = 1;i < 20;++i) fe_sq(>z_40_20=t2,>z_40_20=t2); */ 1599 fe_sq(t2,t1); for (i = 1;i < 20;++i) fe_sq(t2,t2); 1600 1601 /* qhasm: z_40_0 = z_40_20*z_20_0 */ 1602 /* asm 1: fe_mul(>z_40_0=fe#2,<z_40_20=fe#3,<z_20_0=fe#2); */ 1603 /* asm 2: fe_mul(>z_40_0=t1,<z_40_20=t2,<z_20_0=t1); */ 1604 fe_mul(t1,t2,t1); 1605 1606 /* qhasm: z_50_10 = z_40_0^2^10 */ 1607 /* asm 1: fe_sq(>z_50_10=fe#2,<z_40_0=fe#2); for (i = 1;i < 10;++i) fe_sq(>z_50_10=fe#2,>z_50_10=fe#2); */ 1608 /* asm 2: fe_sq(>z_50_10=t1,<z_40_0=t1); for (i = 1;i < 10;++i) fe_sq(>z_50_10=t1,>z_50_10=t1); */ 1609 fe_sq(t1,t1); for (i = 1;i < 10;++i) fe_sq(t1,t1); 1610 1611 /* qhasm: z_50_0 = z_50_10*z_10_0 */ 1612 /* asm 1: fe_mul(>z_50_0=fe#1,<z_50_10=fe#2,<z_10_0=fe#1); */ 1613 /* asm 2: fe_mul(>z_50_0=t0,<z_50_10=t1,<z_10_0=t0); */ 1614 fe_mul(t0,t1,t0); 1615 1616 /* qhasm: z_100_50 = z_50_0^2^50 */ 1617 /* asm 1: fe_sq(>z_100_50=fe#2,<z_50_0=fe#1); for (i = 1;i < 50;++i) fe_sq(>z_100_50=fe#2,>z_100_50=fe#2); */ 1618 /* asm 2: fe_sq(>z_100_50=t1,<z_50_0=t0); for (i = 1;i < 50;++i) fe_sq(>z_100_50=t1,>z_100_50=t1); */ 1619 fe_sq(t1,t0); for (i = 1;i < 50;++i) fe_sq(t1,t1); 1620 1621 /* qhasm: z_100_0 = z_100_50*z_50_0 */ 1622 /* asm 1: fe_mul(>z_100_0=fe#2,<z_100_50=fe#2,<z_50_0=fe#1); */ 1623 /* asm 2: fe_mul(>z_100_0=t1,<z_100_50=t1,<z_50_0=t0); */ 1624 fe_mul(t1,t1,t0); 1625 1626 /* qhasm: z_200_100 = z_100_0^2^100 */ 1627 /* asm 1: fe_sq(>z_200_100=fe#3,<z_100_0=fe#2); for (i = 1;i < 100;++i) fe_sq(>z_200_100=fe#3,>z_200_100=fe#3); */ 1628 /* asm 2: fe_sq(>z_200_100=t2,<z_100_0=t1); for (i = 1;i < 100;++i) fe_sq(>z_200_100=t2,>z_200_100=t2); */ 1629 fe_sq(t2,t1); for (i = 1;i < 100;++i) fe_sq(t2,t2); 1630 1631 /* qhasm: z_200_0 = z_200_100*z_100_0 */ 1632 /* asm 1: fe_mul(>z_200_0=fe#2,<z_200_100=fe#3,<z_100_0=fe#2); */ 1633 /* asm 2: fe_mul(>z_200_0=t1,<z_200_100=t2,<z_100_0=t1); */ 1634 fe_mul(t1,t2,t1); 1635 1636 /* qhasm: z_250_50 = z_200_0^2^50 */ 1637 /* asm 1: fe_sq(>z_250_50=fe#2,<z_200_0=fe#2); for (i = 1;i < 50;++i) fe_sq(>z_250_50=fe#2,>z_250_50=fe#2); */ 1638 /* asm 2: fe_sq(>z_250_50=t1,<z_200_0=t1); for (i = 1;i < 50;++i) fe_sq(>z_250_50=t1,>z_250_50=t1); */ 1639 fe_sq(t1,t1); for (i = 1;i < 50;++i) fe_sq(t1,t1); 1640 1641 /* qhasm: z_250_0 = z_250_50*z_50_0 */ 1642 /* asm 1: fe_mul(>z_250_0=fe#1,<z_250_50=fe#2,<z_50_0=fe#1); */ 1643 /* asm 2: fe_mul(>z_250_0=t0,<z_250_50=t1,<z_50_0=t0); */ 1644 fe_mul(t0,t1,t0); 1645 1646 /* qhasm: z_252_2 = z_250_0^2^2 */ 1647 /* asm 1: fe_sq(>z_252_2=fe#1,<z_250_0=fe#1); for (i = 1;i < 2;++i) fe_sq(>z_252_2=fe#1,>z_252_2=fe#1); */ 1648 /* asm 2: fe_sq(>z_252_2=t0,<z_250_0=t0); for (i = 1;i < 2;++i) fe_sq(>z_252_2=t0,>z_252_2=t0); */ 1649 fe_sq(t0,t0); for (i = 1;i < 2;++i) fe_sq(t0,t0); 1650 1651 /* qhasm: z_252_3 = z_252_2*z1 */ 1652 /* asm 1: fe_mul(>z_252_3=fe#12,<z_252_2=fe#1,<z1=fe#11); */ 1653 /* asm 2: fe_mul(>z_252_3=out,<z_252_2=t0,<z1=z); */ 1654 fe_mul(out,t0,z); 1655 1656 /* qhasm: return */ 1657 1658 1659 return; 1660 } 1661 1662 1663 /* 1664 ge means group element. 1665 1666 Here the group is the set of pairs (x,y) of field elements (see fe.h) 1667 satisfying -x^2 + y^2 = 1 + d x^2y^2 1668 where d = -121665/121666. 1669 1670 Representations: 1671 ge_p2 (projective): (X:Y:Z) satisfying x=X/Z, y=Y/Z 1672 ge_p3 (extended): (X:Y:Z:T) satisfying x=X/Z, y=Y/Z, XY=ZT 1673 ge_p1p1 (completed): ((X:Z),(Y:T)) satisfying x=X/Z, y=Y/T 1674 ge_precomp (Duif): (y+x,y-x,2dxy) 1675 */ 1676 1677 typedef struct { 1678 fe X; 1679 fe Y; 1680 fe Z; 1681 } ge_p2; 1682 1683 typedef struct { 1684 fe X; 1685 fe Y; 1686 fe Z; 1687 fe T; 1688 } ge_p3; 1689 1690 typedef struct { 1691 fe X; 1692 fe Y; 1693 fe Z; 1694 fe T; 1695 } ge_p1p1; 1696 1697 typedef struct { 1698 fe yplusx; 1699 fe yminusx; 1700 fe xy2d; 1701 } ge_precomp; 1702 1703 typedef struct { 1704 fe YplusX; 1705 fe YminusX; 1706 fe Z; 1707 fe T2d; 1708 } ge_cached; 1709 1710 static const fe d = { 1711 -10913610,13857413,-15372611,6949391,114729,-8787816,-6275908,-3247719,-18696448,-12055116 1712 } ; 1713 1714 static const fe sqrtm1 = { 1715 -32595792,-7943725,9377950,3500415,12389472,-272473,-25146209,-2005654,326686,11406482 1716 } ; 1717 1718 static const fe d2 = { 1719 -21827239,-5839606,-30745221,13898782,229458,15978800,-12551817,-6495438,29715968,9444199 1720 } ; 1721 1722 static ge_precomp Bi[8] = { 1723 { 1724 { 25967493,-14356035,29566456,3660896,-12694345,4014787,27544626,-11754271,-6079156,2047605 }, 1725 { -12545711,934262,-2722910,3049990,-727428,9406986,12720692,5043384,19500929,-15469378 }, 1726 { -8738181,4489570,9688441,-14785194,10184609,-12363380,29287919,11864899,-24514362,-4438546 }, 1727 }, 1728 { 1729 { 15636291,-9688557,24204773,-7912398,616977,-16685262,27787600,-14772189,28944400,-1550024 }, 1730 { 16568933,4717097,-11556148,-1102322,15682896,-11807043,16354577,-11775962,7689662,11199574 }, 1731 { 30464156,-5976125,-11779434,-15670865,23220365,15915852,7512774,10017326,-17749093,-9920357 }, 1732 }, 1733 { 1734 { 10861363,11473154,27284546,1981175,-30064349,12577861,32867885,14515107,-15438304,10819380 }, 1735 { 4708026,6336745,20377586,9066809,-11272109,6594696,-25653668,12483688,-12668491,5581306 }, 1736 { 19563160,16186464,-29386857,4097519,10237984,-4348115,28542350,13850243,-23678021,-15815942 }, 1737 }, 1738 { 1739 { 5153746,9909285,1723747,-2777874,30523605,5516873,19480852,5230134,-23952439,-15175766 }, 1740 { -30269007,-3463509,7665486,10083793,28475525,1649722,20654025,16520125,30598449,7715701 }, 1741 { 28881845,14381568,9657904,3680757,-20181635,7843316,-31400660,1370708,29794553,-1409300 }, 1742 }, 1743 { 1744 { -22518993,-6692182,14201702,-8745502,-23510406,8844726,18474211,-1361450,-13062696,13821877 }, 1745 { -6455177,-7839871,3374702,-4740862,-27098617,-10571707,31655028,-7212327,18853322,-14220951 }, 1746 { 4566830,-12963868,-28974889,-12240689,-7602672,-2830569,-8514358,-10431137,2207753,-3209784 }, 1747 }, 1748 { 1749 { -25154831,-4185821,29681144,7868801,-6854661,-9423865,-12437364,-663000,-31111463,-16132436 }, 1750 { 25576264,-2703214,7349804,-11814844,16472782,9300885,3844789,15725684,171356,6466918 }, 1751 { 23103977,13316479,9739013,-16149481,817875,-15038942,8965339,-14088058,-30714912,16193877 }, 1752 }, 1753 { 1754 { -33521811,3180713,-2394130,14003687,-16903474,-16270840,17238398,4729455,-18074513,9256800 }, 1755 { -25182317,-4174131,32336398,5036987,-21236817,11360617,22616405,9761698,-19827198,630305 }, 1756 { -13720693,2639453,-24237460,-7406481,9494427,-5774029,-6554551,-15960994,-2449256,-14291300 }, 1757 }, 1758 { 1759 { -3151181,-5046075,9282714,6866145,-31907062,-863023,-18940575,15033784,25105118,-7894876 }, 1760 { -24326370,15950226,-31801215,-14592823,-11662737,-5090925,1573892,-2625887,2198790,-15804619 }, 1761 { -3099351,10324967,-2241613,7453183,-5446979,-2735503,-13812022,-16236442,-32461234,-12290683 }, 1762 }, 1763 } ; 1764 1765 1766 /* base[i][j] = (j+1)*256^i*B */ 1767 static ge_precomp base[32][8] = { 1768 { 1769 { 1770 { 25967493,-14356035,29566456,3660896,-12694345,4014787,27544626,-11754271,-6079156,2047605 }, 1771 { -12545711,934262,-2722910,3049990,-727428,9406986,12720692,5043384,19500929,-15469378 }, 1772 { -8738181,4489570,9688441,-14785194,10184609,-12363380,29287919,11864899,-24514362,-4438546 }, 1773 }, 1774 { 1775 { -12815894,-12976347,-21581243,11784320,-25355658,-2750717,-11717903,-3814571,-358445,-10211303 }, 1776 { -21703237,6903825,27185491,6451973,-29577724,-9554005,-15616551,11189268,-26829678,-5319081 }, 1777 { 26966642,11152617,32442495,15396054,14353839,-12752335,-3128826,-9541118,-15472047,-4166697 }, 1778 }, 1779 { 1780 { 15636291,-9688557,24204773,-7912398,616977,-16685262,27787600,-14772189,28944400,-1550024 }, 1781 { 16568933,4717097,-11556148,-1102322,15682896,-11807043,16354577,-11775962,7689662,11199574 }, 1782 { 30464156,-5976125,-11779434,-15670865,23220365,15915852,7512774,10017326,-17749093,-9920357 }, 1783 }, 1784 { 1785 { -17036878,13921892,10945806,-6033431,27105052,-16084379,-28926210,15006023,3284568,-6276540 }, 1786 { 23599295,-8306047,-11193664,-7687416,13236774,10506355,7464579,9656445,13059162,10374397 }, 1787 { 7798556,16710257,3033922,2874086,28997861,2835604,32406664,-3839045,-641708,-101325 }, 1788 }, 1789 { 1790 { 10861363,11473154,27284546,1981175,-30064349,12577861,32867885,14515107,-15438304,10819380 }, 1791 { 4708026,6336745,20377586,9066809,-11272109,6594696,-25653668,12483688,-12668491,5581306 }, 1792 { 19563160,16186464,-29386857,4097519,10237984,-4348115,28542350,13850243,-23678021,-15815942 }, 1793 }, 1794 { 1795 { -15371964,-12862754,32573250,4720197,-26436522,5875511,-19188627,-15224819,-9818940,-12085777 }, 1796 { -8549212,109983,15149363,2178705,22900618,4543417,3044240,-15689887,1762328,14866737 }, 1797 { -18199695,-15951423,-10473290,1707278,-17185920,3916101,-28236412,3959421,27914454,4383652 }, 1798 }, 1799 { 1800 { 5153746,9909285,1723747,-2777874,30523605,5516873,19480852,5230134,-23952439,-15175766 }, 1801 { -30269007,-3463509,7665486,10083793,28475525,1649722,20654025,16520125,30598449,7715701 }, 1802 { 28881845,14381568,9657904,3680757,-20181635,7843316,-31400660,1370708,29794553,-1409300 }, 1803 }, 1804 { 1805 { 14499471,-2729599,-33191113,-4254652,28494862,14271267,30290735,10876454,-33154098,2381726 }, 1806 { -7195431,-2655363,-14730155,462251,-27724326,3941372,-6236617,3696005,-32300832,15351955 }, 1807 { 27431194,8222322,16448760,-3907995,-18707002,11938355,-32961401,-2970515,29551813,10109425 }, 1808 }, 1809 }, 1810 { 1811 { 1812 { -13657040,-13155431,-31283750,11777098,21447386,6519384,-2378284,-1627556,10092783,-4764171 }, 1813 { 27939166,14210322,4677035,16277044,-22964462,-12398139,-32508754,12005538,-17810127,12803510 }, 1814 { 17228999,-15661624,-1233527,300140,-1224870,-11714777,30364213,-9038194,18016357,4397660 }, 1815 }, 1816 { 1817 { -10958843,-7690207,4776341,-14954238,27850028,-15602212,-26619106,14544525,-17477504,982639 }, 1818 { 29253598,15796703,-2863982,-9908884,10057023,3163536,7332899,-4120128,-21047696,9934963 }, 1819 { 5793303,16271923,-24131614,-10116404,29188560,1206517,-14747930,4559895,-30123922,-10897950 }, 1820 }, 1821 { 1822 { -27643952,-11493006,16282657,-11036493,28414021,-15012264,24191034,4541697,-13338309,5500568 }, 1823 { 12650548,-1497113,9052871,11355358,-17680037,-8400164,-17430592,12264343,10874051,13524335 }, 1824 { 25556948,-3045990,714651,2510400,23394682,-10415330,33119038,5080568,-22528059,5376628 }, 1825 }, 1826 { 1827 { -26088264,-4011052,-17013699,-3537628,-6726793,1920897,-22321305,-9447443,4535768,1569007 }, 1828 { -2255422,14606630,-21692440,-8039818,28430649,8775819,-30494562,3044290,31848280,12543772 }, 1829 { -22028579,2943893,-31857513,6777306,13784462,-4292203,-27377195,-2062731,7718482,14474653 }, 1830 }, 1831 { 1832 { 2385315,2454213,-22631320,46603,-4437935,-15680415,656965,-7236665,24316168,-5253567 }, 1833 { 13741529,10911568,-33233417,-8603737,-20177830,-1033297,33040651,-13424532,-20729456,8321686 }, 1834 { 21060490,-2212744,15712757,-4336099,1639040,10656336,23845965,-11874838,-9984458,608372 }, 1835 }, 1836 { 1837 { -13672732,-15087586,-10889693,-7557059,-6036909,11305547,1123968,-6780577,27229399,23887 }, 1838 { -23244140,-294205,-11744728,14712571,-29465699,-2029617,12797024,-6440308,-1633405,16678954 }, 1839 { -29500620,4770662,-16054387,14001338,7830047,9564805,-1508144,-4795045,-17169265,4904953 }, 1840 }, 1841 { 1842 { 24059557,14617003,19037157,-15039908,19766093,-14906429,5169211,16191880,2128236,-4326833 }, 1843 { -16981152,4124966,-8540610,-10653797,30336522,-14105247,-29806336,916033,-6882542,-2986532 }, 1844 { -22630907,12419372,-7134229,-7473371,-16478904,16739175,285431,2763829,15736322,4143876 }, 1845 }, 1846 { 1847 { 2379352,11839345,-4110402,-5988665,11274298,794957,212801,-14594663,23527084,-16458268 }, 1848 { 33431127,-11130478,-17838966,-15626900,8909499,8376530,-32625340,4087881,-15188911,-14416214 }, 1849 { 1767683,7197987,-13205226,-2022635,-13091350,448826,5799055,4357868,-4774191,-16323038 }, 1850 }, 1851 }, 1852 { 1853 { 1854 { 6721966,13833823,-23523388,-1551314,26354293,-11863321,23365147,-3949732,7390890,2759800 }, 1855 { 4409041,2052381,23373853,10530217,7676779,-12885954,21302353,-4264057,1244380,-12919645 }, 1856 { -4421239,7169619,4982368,-2957590,30256825,-2777540,14086413,9208236,15886429,16489664 }, 1857 }, 1858 { 1859 { 1996075,10375649,14346367,13311202,-6874135,-16438411,-13693198,398369,-30606455,-712933 }, 1860 { -25307465,9795880,-2777414,14878809,-33531835,14780363,13348553,12076947,-30836462,5113182 }, 1861 { -17770784,11797796,31950843,13929123,-25888302,12288344,-30341101,-7336386,13847711,5387222 }, 1862 }, 1863 { 1864 { -18582163,-3416217,17824843,-2340966,22744343,-10442611,8763061,3617786,-19600662,10370991 }, 1865 { 20246567,-14369378,22358229,-543712,18507283,-10413996,14554437,-8746092,32232924,16763880 }, 1866 { 9648505,10094563,26416693,14745928,-30374318,-6472621,11094161,15689506,3140038,-16510092 }, 1867 }, 1868 { 1869 { -16160072,5472695,31895588,4744994,8823515,10365685,-27224800,9448613,-28774454,366295 }, 1870 { 19153450,11523972,-11096490,-6503142,-24647631,5420647,28344573,8041113,719605,11671788 }, 1871 { 8678025,2694440,-6808014,2517372,4964326,11152271,-15432916,-15266516,27000813,-10195553 }, 1872 }, 1873 { 1874 { -15157904,7134312,8639287,-2814877,-7235688,10421742,564065,5336097,6750977,-14521026 }, 1875 { 11836410,-3979488,26297894,16080799,23455045,15735944,1695823,-8819122,8169720,16220347 }, 1876 { -18115838,8653647,17578566,-6092619,-8025777,-16012763,-11144307,-2627664,-5990708,-14166033 }, 1877 }, 1878 { 1879 { -23308498,-10968312,15213228,-10081214,-30853605,-11050004,27884329,2847284,2655861,1738395 }, 1880 { -27537433,-14253021,-25336301,-8002780,-9370762,8129821,21651608,-3239336,-19087449,-11005278 }, 1881 { 1533110,3437855,23735889,459276,29970501,11335377,26030092,5821408,10478196,8544890 }, 1882 }, 1883 { 1884 { 32173121,-16129311,24896207,3921497,22579056,-3410854,19270449,12217473,17789017,-3395995 }, 1885 { -30552961,-2228401,-15578829,-10147201,13243889,517024,15479401,-3853233,30460520,1052596 }, 1886 { -11614875,13323618,32618793,8175907,-15230173,12596687,27491595,-4612359,3179268,-9478891 }, 1887 }, 1888 { 1889 { 31947069,-14366651,-4640583,-15339921,-15125977,-6039709,-14756777,-16411740,19072640,-9511060 }, 1890 { 11685058,11822410,3158003,-13952594,33402194,-4165066,5977896,-5215017,473099,5040608 }, 1891 { -20290863,8198642,-27410132,11602123,1290375,-2799760,28326862,1721092,-19558642,-3131606 }, 1892 }, 1893 }, 1894 { 1895 { 1896 { 7881532,10687937,7578723,7738378,-18951012,-2553952,21820786,8076149,-27868496,11538389 }, 1897 { -19935666,3899861,18283497,-6801568,-15728660,-11249211,8754525,7446702,-5676054,5797016 }, 1898 { -11295600,-3793569,-15782110,-7964573,12708869,-8456199,2014099,-9050574,-2369172,-5877341 }, 1899 }, 1900 { 1901 { -22472376,-11568741,-27682020,1146375,18956691,16640559,1192730,-3714199,15123619,10811505 }, 1902 { 14352098,-3419715,-18942044,10822655,32750596,4699007,-70363,15776356,-28886779,-11974553 }, 1903 { -28241164,-8072475,-4978962,-5315317,29416931,1847569,-20654173,-16484855,4714547,-9600655 }, 1904 }, 1905 { 1906 { 15200332,8368572,19679101,15970074,-31872674,1959451,24611599,-4543832,-11745876,12340220 }, 1907 { 12876937,-10480056,33134381,6590940,-6307776,14872440,9613953,8241152,15370987,9608631 }, 1908 { -4143277,-12014408,8446281,-391603,4407738,13629032,-7724868,15866074,-28210621,-8814099 }, 1909 }, 1910 { 1911 { 26660628,-15677655,8393734,358047,-7401291,992988,-23904233,858697,20571223,8420556 }, 1912 { 14620715,13067227,-15447274,8264467,14106269,15080814,33531827,12516406,-21574435,-12476749 }, 1913 { 236881,10476226,57258,-14677024,6472998,2466984,17258519,7256740,8791136,15069930 }, 1914 }, 1915 { 1916 { 1276410,-9371918,22949635,-16322807,-23493039,-5702186,14711875,4874229,-30663140,-2331391 }, 1917 { 5855666,4990204,-13711848,7294284,-7804282,1924647,-1423175,-7912378,-33069337,9234253 }, 1918 { 20590503,-9018988,31529744,-7352666,-2706834,10650548,31559055,-11609587,18979186,13396066 }, 1919 }, 1920 { 1921 { 24474287,4968103,22267082,4407354,24063882,-8325180,-18816887,13594782,33514650,7021958 }, 1922 { -11566906,-6565505,-21365085,15928892,-26158305,4315421,-25948728,-3916677,-21480480,12868082 }, 1923 { -28635013,13504661,19988037,-2132761,21078225,6443208,-21446107,2244500,-12455797,-8089383 }, 1924 }, 1925 { 1926 { -30595528,13793479,-5852820,319136,-25723172,-6263899,33086546,8957937,-15233648,5540521 }, 1927 { -11630176,-11503902,-8119500,-7643073,2620056,1022908,-23710744,-1568984,-16128528,-14962807 }, 1928 { 23152971,775386,27395463,14006635,-9701118,4649512,1689819,892185,-11513277,-15205948 }, 1929 }, 1930 { 1931 { 9770129,9586738,26496094,4324120,1556511,-3550024,27453819,4763127,-19179614,5867134 }, 1932 { -32765025,1927590,31726409,-4753295,23962434,-16019500,27846559,5931263,-29749703,-16108455 }, 1933 { 27461885,-2977536,22380810,1815854,-23033753,-3031938,7283490,-15148073,-19526700,7734629 }, 1934 }, 1935 }, 1936 { 1937 { 1938 { -8010264,-9590817,-11120403,6196038,29344158,-13430885,7585295,-3176626,18549497,15302069 }, 1939 { -32658337,-6171222,-7672793,-11051681,6258878,13504381,10458790,-6418461,-8872242,8424746 }, 1940 { 24687205,8613276,-30667046,-3233545,1863892,-1830544,19206234,7134917,-11284482,-828919 }, 1941 }, 1942 { 1943 { 11334899,-9218022,8025293,12707519,17523892,-10476071,10243738,-14685461,-5066034,16498837 }, 1944 { 8911542,6887158,-9584260,-6958590,11145641,-9543680,17303925,-14124238,6536641,10543906 }, 1945 { -28946384,15479763,-17466835,568876,-1497683,11223454,-2669190,-16625574,-27235709,8876771 }, 1946 }, 1947 { 1948 { -25742899,-12566864,-15649966,-846607,-33026686,-796288,-33481822,15824474,-604426,-9039817 }, 1949 { 10330056,70051,7957388,-9002667,9764902,15609756,27698697,-4890037,1657394,3084098 }, 1950 { 10477963,-7470260,12119566,-13250805,29016247,-5365589,31280319,14396151,-30233575,15272409 }, 1951 }, 1952 { 1953 { -12288309,3169463,28813183,16658753,25116432,-5630466,-25173957,-12636138,-25014757,1950504 }, 1954 { -26180358,9489187,11053416,-14746161,-31053720,5825630,-8384306,-8767532,15341279,8373727 }, 1955 { 28685821,7759505,-14378516,-12002860,-31971820,4079242,298136,-10232602,-2878207,15190420 }, 1956 }, 1957 { 1958 { -32932876,13806336,-14337485,-15794431,-24004620,10940928,8669718,2742393,-26033313,-6875003 }, 1959 { -1580388,-11729417,-25979658,-11445023,-17411874,-10912854,9291594,-16247779,-12154742,6048605 }, 1960 { -30305315,14843444,1539301,11864366,20201677,1900163,13934231,5128323,11213262,9168384 }, 1961 }, 1962 { 1963 { -26280513,11007847,19408960,-940758,-18592965,-4328580,-5088060,-11105150,20470157,-16398701 }, 1964 { -23136053,9282192,14855179,-15390078,-7362815,-14408560,-22783952,14461608,14042978,5230683 }, 1965 { 29969567,-2741594,-16711867,-8552442,9175486,-2468974,21556951,3506042,-5933891,-12449708 }, 1966 }, 1967 { 1968 { -3144746,8744661,19704003,4581278,-20430686,6830683,-21284170,8971513,-28539189,15326563 }, 1969 { -19464629,10110288,-17262528,-3503892,-23500387,1355669,-15523050,15300988,-20514118,9168260 }, 1970 { -5353335,4488613,-23803248,16314347,7780487,-15638939,-28948358,9601605,33087103,-9011387 }, 1971 }, 1972 { 1973 { -19443170,-15512900,-20797467,-12445323,-29824447,10229461,-27444329,-15000531,-5996870,15664672 }, 1974 { 23294591,-16632613,-22650781,-8470978,27844204,11461195,13099750,-2460356,18151676,13417686 }, 1975 { -24722913,-4176517,-31150679,5988919,-26858785,6685065,1661597,-12551441,15271676,-15452665 }, 1976 }, 1977 }, 1978 { 1979 { 1980 { 11433042,-13228665,8239631,-5279517,-1985436,-725718,-18698764,2167544,-6921301,-13440182 }, 1981 { -31436171,15575146,30436815,12192228,-22463353,9395379,-9917708,-8638997,12215110,12028277 }, 1982 { 14098400,6555944,23007258,5757252,-15427832,-12950502,30123440,4617780,-16900089,-655628 }, 1983 }, 1984 { 1985 { -4026201,-15240835,11893168,13718664,-14809462,1847385,-15819999,10154009,23973261,-12684474 }, 1986 { -26531820,-3695990,-1908898,2534301,-31870557,-16550355,18341390,-11419951,32013174,-10103539 }, 1987 { -25479301,10876443,-11771086,-14625140,-12369567,1838104,21911214,6354752,4425632,-837822 }, 1988 }, 1989 { 1990 { -10433389,-14612966,22229858,-3091047,-13191166,776729,-17415375,-12020462,4725005,14044970 }, 1991 { 19268650,-7304421,1555349,8692754,-21474059,-9910664,6347390,-1411784,-19522291,-16109756 }, 1992 { -24864089,12986008,-10898878,-5558584,-11312371,-148526,19541418,8180106,9282262,10282508 }, 1993 }, 1994 { 1995 { -26205082,4428547,-8661196,-13194263,4098402,-14165257,15522535,8372215,5542595,-10702683 }, 1996 { -10562541,14895633,26814552,-16673850,-17480754,-2489360,-2781891,6993761,-18093885,10114655 }, 1997 { -20107055,-929418,31422704,10427861,-7110749,6150669,-29091755,-11529146,25953725,-106158 }, 1998 }, 1999 { 2000 { -4234397,-8039292,-9119125,3046000,2101609,-12607294,19390020,6094296,-3315279,12831125 }, 2001 { -15998678,7578152,5310217,14408357,-33548620,-224739,31575954,6326196,7381791,-2421839 }, 2002 { -20902779,3296811,24736065,-16328389,18374254,7318640,6295303,8082724,-15362489,12339664 }, 2003 }, 2004 { 2005 { 27724736,2291157,6088201,-14184798,1792727,5857634,13848414,15768922,25091167,14856294 }, 2006 { -18866652,8331043,24373479,8541013,-701998,-9269457,12927300,-12695493,-22182473,-9012899 }, 2007 { -11423429,-5421590,11632845,3405020,30536730,-11674039,-27260765,13866390,30146206,9142070 }, 2008 }, 2009 { 2010 { 3924129,-15307516,-13817122,-10054960,12291820,-668366,-27702774,9326384,-8237858,4171294 }, 2011 { -15921940,16037937,6713787,16606682,-21612135,2790944,26396185,3731949,345228,-5462949 }, 2012 { -21327538,13448259,25284571,1143661,20614966,-8849387,2031539,-12391231,-16253183,-13582083 }, 2013 }, 2014 { 2015 { 31016211,-16722429,26371392,-14451233,-5027349,14854137,17477601,3842657,28012650,-16405420 }, 2016 { -5075835,9368966,-8562079,-4600902,-15249953,6970560,-9189873,16292057,-8867157,3507940 }, 2017 { 29439664,3537914,23333589,6997794,-17555561,-11018068,-15209202,-15051267,-9164929,6580396 }, 2018 }, 2019 }, 2020 { 2021 { 2022 { -12185861,-7679788,16438269,10826160,-8696817,-6235611,17860444,-9273846,-2095802,9304567 }, 2023 { 20714564,-4336911,29088195,7406487,11426967,-5095705,14792667,-14608617,5289421,-477127 }, 2024 { -16665533,-10650790,-6160345,-13305760,9192020,-1802462,17271490,12349094,26939669,-3752294 }, 2025 }, 2026 { 2027 { -12889898,9373458,31595848,16374215,21471720,13221525,-27283495,-12348559,-3698806,117887 }, 2028 { 22263325,-6560050,3984570,-11174646,-15114008,-566785,28311253,5358056,-23319780,541964 }, 2029 { 16259219,3261970,2309254,-15534474,-16885711,-4581916,24134070,-16705829,-13337066,-13552195 }, 2030 }, 2031 { 2032 { 9378160,-13140186,-22845982,-12745264,28198281,-7244098,-2399684,-717351,690426,14876244 }, 2033 { 24977353,-314384,-8223969,-13465086,28432343,-1176353,-13068804,-12297348,-22380984,6618999 }, 2034 { -1538174,11685646,12944378,13682314,-24389511,-14413193,8044829,-13817328,32239829,-5652762 }, 2035 }, 2036 { 2037 { -18603066,4762990,-926250,8885304,-28412480,-3187315,9781647,-10350059,32779359,5095274 }, 2038 { -33008130,-5214506,-32264887,-3685216,9460461,-9327423,-24601656,14506724,21639561,-2630236 }, 2039 { -16400943,-13112215,25239338,15531969,3987758,-4499318,-1289502,-6863535,17874574,558605 }, 2040 }, 2041 { 2042 { -13600129,10240081,9171883,16131053,-20869254,9599700,33499487,5080151,2085892,5119761 }, 2043 { -22205145,-2519528,-16381601,414691,-25019550,2170430,30634760,-8363614,-31999993,-5759884 }, 2044 { -6845704,15791202,8550074,-1312654,29928809,-12092256,27534430,-7192145,-22351378,12961482 }, 2045 }, 2046 { 2047 { -24492060,-9570771,10368194,11582341,-23397293,-2245287,16533930,8206996,-30194652,-5159638 }, 2048 { -11121496,-3382234,2307366,6362031,-135455,8868177,-16835630,7031275,7589640,8945490 }, 2049 { -32152748,8917967,6661220,-11677616,-1192060,-15793393,7251489,-11182180,24099109,-14456170 }, 2050 }, 2051 { 2052 { 5019558,-7907470,4244127,-14714356,-26933272,6453165,-19118182,-13289025,-6231896,-10280736 }, 2053 { 10853594,10721687,26480089,5861829,-22995819,1972175,-1866647,-10557898,-3363451,-6441124 }, 2054 { -17002408,5906790,221599,-6563147,7828208,-13248918,24362661,-2008168,-13866408,7421392 }, 2055 }, 2056 { 2057 { 8139927,-6546497,32257646,-5890546,30375719,1886181,-21175108,15441252,28826358,-4123029 }, 2058 { 6267086,9695052,7709135,-16603597,-32869068,-1886135,14795160,-7840124,13746021,-1742048 }, 2059 { 28584902,7787108,-6732942,-15050729,22846041,-7571236,-3181936,-363524,4771362,-8419958 }, 2060 }, 2061 }, 2062 { 2063 { 2064 { 24949256,6376279,-27466481,-8174608,-18646154,-9930606,33543569,-12141695,3569627,11342593 }, 2065 { 26514989,4740088,27912651,3697550,19331575,-11472339,6809886,4608608,7325975,-14801071 }, 2066 { -11618399,-14554430,-24321212,7655128,-1369274,5214312,-27400540,10258390,-17646694,-8186692 }, 2067 }, 2068 { 2069 { 11431204,15823007,26570245,14329124,18029990,4796082,-31446179,15580664,9280358,-3973687 }, 2070 { -160783,-10326257,-22855316,-4304997,-20861367,-13621002,-32810901,-11181622,-15545091,4387441 }, 2071 { -20799378,12194512,3937617,-5805892,-27154820,9340370,-24513992,8548137,20617071,-7482001 }, 2072 }, 2073 { 2074 { -938825,-3930586,-8714311,16124718,24603125,-6225393,-13775352,-11875822,24345683,10325460 }, 2075 { -19855277,-1568885,-22202708,8714034,14007766,6928528,16318175,-1010689,4766743,3552007 }, 2076 { -21751364,-16730916,1351763,-803421,-4009670,3950935,3217514,14481909,10988822,-3994762 }, 2077 }, 2078 { 2079 { 15564307,-14311570,3101243,5684148,30446780,-8051356,12677127,-6505343,-8295852,13296005 }, 2080 { -9442290,6624296,-30298964,-11913677,-4670981,-2057379,31521204,9614054,-30000824,12074674 }, 2081 { 4771191,-135239,14290749,-13089852,27992298,14998318,-1413936,-1556716,29832613,-16391035 }, 2082 }, 2083 { 2084 { 7064884,-7541174,-19161962,-5067537,-18891269,-2912736,25825242,5293297,-27122660,13101590 }, 2085 { -2298563,2439670,-7466610,1719965,-27267541,-16328445,32512469,-5317593,-30356070,-4190957 }, 2086 { -30006540,10162316,-33180176,3981723,-16482138,-13070044,14413974,9515896,19568978,9628812 }, 2087 }, 2088 { 2089 { 33053803,199357,15894591,1583059,27380243,-4580435,-17838894,-6106839,-6291786,3437740 }, 2090 { -18978877,3884493,19469877,12726490,15913552,13614290,-22961733,70104,7463304,4176122 }, 2091 { -27124001,10659917,11482427,-16070381,12771467,-6635117,-32719404,-5322751,24216882,5944158 }, 2092 }, 2093 { 2094 { 8894125,7450974,-2664149,-9765752,-28080517,-12389115,19345746,14680796,11632993,5847885 }, 2095 { 26942781,-2315317,9129564,-4906607,26024105,11769399,-11518837,6367194,-9727230,4782140 }, 2096 { 19916461,-4828410,-22910704,-11414391,25606324,-5972441,33253853,8220911,6358847,-1873857 }, 2097 }, 2098 { 2099 { 801428,-2081702,16569428,11065167,29875704,96627,7908388,-4480480,-13538503,1387155 }, 2100 { 19646058,5720633,-11416706,12814209,11607948,12749789,14147075,15156355,-21866831,11835260 }, 2101 { 19299512,1155910,28703737,14890794,2925026,7269399,26121523,15467869,-26560550,5052483 }, 2102 }, 2103 }, 2104 { 2105 { 2106 { -3017432,10058206,1980837,3964243,22160966,12322533,-6431123,-12618185,12228557,-7003677 }, 2107 { 32944382,14922211,-22844894,5188528,21913450,-8719943,4001465,13238564,-6114803,8653815 }, 2108 { 22865569,-4652735,27603668,-12545395,14348958,8234005,24808405,5719875,28483275,2841751 }, 2109 }, 2110 { 2111 { -16420968,-1113305,-327719,-12107856,21886282,-15552774,-1887966,-315658,19932058,-12739203 }, 2112 { -11656086,10087521,-8864888,-5536143,-19278573,-3055912,3999228,13239134,-4777469,-13910208 }, 2113 { 1382174,-11694719,17266790,9194690,-13324356,9720081,20403944,11284705,-14013818,3093230 }, 2114 }, 2115 { 2116 { 16650921,-11037932,-1064178,1570629,-8329746,7352753,-302424,16271225,-24049421,-6691850 }, 2117 { -21911077,-5927941,-4611316,-5560156,-31744103,-10785293,24123614,15193618,-21652117,-16739389 }, 2118 { -9935934,-4289447,-25279823,4372842,2087473,10399484,31870908,14690798,17361620,11864968 }, 2119 }, 2120 { 2121 { -11307610,6210372,13206574,5806320,-29017692,-13967200,-12331205,-7486601,-25578460,-16240689 }, 2122 { 14668462,-12270235,26039039,15305210,25515617,4542480,10453892,6577524,9145645,-6443880 }, 2123 { 5974874,3053895,-9433049,-10385191,-31865124,3225009,-7972642,3936128,-5652273,-3050304 }, 2124 }, 2125 { 2126 { 30625386,-4729400,-25555961,-12792866,-20484575,7695099,17097188,-16303496,-27999779,1803632 }, 2127 { -3553091,9865099,-5228566,4272701,-5673832,-16689700,14911344,12196514,-21405489,7047412 }, 2128 { 20093277,9920966,-11138194,-5343857,13161587,12044805,-32856851,4124601,-32343828,-10257566 }, 2129 }, 2130 { 2131 { -20788824,14084654,-13531713,7842147,19119038,-13822605,4752377,-8714640,-21679658,2288038 }, 2132 { -26819236,-3283715,29965059,3039786,-14473765,2540457,29457502,14625692,-24819617,12570232 }, 2133 { -1063558,-11551823,16920318,12494842,1278292,-5869109,-21159943,-3498680,-11974704,4724943 }, 2134 }, 2135 { 2136 { 17960970,-11775534,-4140968,-9702530,-8876562,-1410617,-12907383,-8659932,-29576300,1903856 }, 2137 { 23134274,-14279132,-10681997,-1611936,20684485,15770816,-12989750,3190296,26955097,14109738 }, 2138 { 15308788,5320727,-30113809,-14318877,22902008,7767164,29425325,-11277562,31960942,11934971 }, 2139 }, 2140 { 2141 { -27395711,8435796,4109644,12222639,-24627868,14818669,20638173,4875028,10491392,1379718 }, 2142 { -13159415,9197841,3875503,-8936108,-1383712,-5879801,33518459,16176658,21432314,12180697 }, 2143 { -11787308,11500838,13787581,-13832590,-22430679,10140205,1465425,12689540,-10301319,-13872883 }, 2144 }, 2145 }, 2146 { 2147 { 2148 { 5414091,-15386041,-21007664,9643570,12834970,1186149,-2622916,-1342231,26128231,6032912 }, 2149 { -26337395,-13766162,32496025,-13653919,17847801,-12669156,3604025,8316894,-25875034,-10437358 }, 2150 { 3296484,6223048,24680646,-12246460,-23052020,5903205,-8862297,-4639164,12376617,3188849 }, 2151 }, 2152 { 2153 { 29190488,-14659046,27549113,-1183516,3520066,-10697301,32049515,-7309113,-16109234,-9852307 }, 2154 { -14744486,-9309156,735818,-598978,-20407687,-5057904,25246078,-15795669,18640741,-960977 }, 2155 { -6928835,-16430795,10361374,5642961,4910474,12345252,-31638386,-494430,10530747,1053335 }, 2156 }, 2157 { 2158 { -29265967,-14186805,-13538216,-12117373,-19457059,-10655384,-31462369,-2948985,24018831,15026644 }, 2159 { -22592535,-3145277,-2289276,5953843,-13440189,9425631,25310643,13003497,-2314791,-15145616 }, 2160 { -27419985,-603321,-8043984,-1669117,-26092265,13987819,-27297622,187899,-23166419,-2531735 }, 2161 }, 2162 { 2163 { -21744398,-13810475,1844840,5021428,-10434399,-15911473,9716667,16266922,-5070217,726099 }, 2164 { 29370922,-6053998,7334071,-15342259,9385287,2247707,-13661962,-4839461,30007388,-15823341 }, 2165 { -936379,16086691,23751945,-543318,-1167538,-5189036,9137109,730663,9835848,4555336 }, 2166 }, 2167 { 2168 { -23376435,1410446,-22253753,-12899614,30867635,15826977,17693930,544696,-11985298,12422646 }, 2169 { 31117226,-12215734,-13502838,6561947,-9876867,-12757670,-5118685,-4096706,29120153,13924425 }, 2170 { -17400879,-14233209,19675799,-2734756,-11006962,-5858820,-9383939,-11317700,7240931,-237388 }, 2171 }, 2172 { 2173 { -31361739,-11346780,-15007447,-5856218,-22453340,-12152771,1222336,4389483,3293637,-15551743 }, 2174 { -16684801,-14444245,11038544,11054958,-13801175,-3338533,-24319580,7733547,12796905,-6335822 }, 2175 { -8759414,-10817836,-25418864,10783769,-30615557,-9746811,-28253339,3647836,3222231,-11160462 }, 2176 }, 2177 { 2178 { 18606113,1693100,-25448386,-15170272,4112353,10045021,23603893,-2048234,-7550776,2484985 }, 2179 { 9255317,-3131197,-12156162,-1004256,13098013,-9214866,16377220,-2102812,-19802075,-3034702 }, 2180 { -22729289,7496160,-5742199,11329249,19991973,-3347502,-31718148,9936966,-30097688,-10618797 }, 2181 }, 2182 { 2183 { 21878590,-5001297,4338336,13643897,-3036865,13160960,19708896,5415497,-7360503,-4109293 }, 2184 { 27736861,10103576,12500508,8502413,-3413016,-9633558,10436918,-1550276,-23659143,-8132100 }, 2185 { 19492550,-12104365,-29681976,-852630,-3208171,12403437,30066266,8367329,13243957,8709688 }, 2186 }, 2187 }, 2188 { 2189 { 2190 { 12015105,2801261,28198131,10151021,24818120,-4743133,-11194191,-5645734,5150968,7274186 }, 2191 { 2831366,-12492146,1478975,6122054,23825128,-12733586,31097299,6083058,31021603,-9793610 }, 2192 { -2529932,-2229646,445613,10720828,-13849527,-11505937,-23507731,16354465,15067285,-14147707 }, 2193 }, 2194 { 2195 { 7840942,14037873,-33364863,15934016,-728213,-3642706,21403988,1057586,-19379462,-12403220 }, 2196 { 915865,-16469274,15608285,-8789130,-24357026,6060030,-17371319,8410997,-7220461,16527025 }, 2197 { 32922597,-556987,20336074,-16184568,10903705,-5384487,16957574,52992,23834301,6588044 }, 2198 }, 2199 { 2200 { 32752030,11232950,3381995,-8714866,22652988,-10744103,17159699,16689107,-20314580,-1305992 }, 2201 { -4689649,9166776,-25710296,-10847306,11576752,12733943,7924251,-2752281,1976123,-7249027 }, 2202 { 21251222,16309901,-2983015,-6783122,30810597,12967303,156041,-3371252,12331345,-8237197 }, 2203 }, 2204 { 2205 { 8651614,-4477032,-16085636,-4996994,13002507,2950805,29054427,-5106970,10008136,-4667901 }, 2206 { 31486080,15114593,-14261250,12951354,14369431,-7387845,16347321,-13662089,8684155,-10532952 }, 2207 { 19443825,11385320,24468943,-9659068,-23919258,2187569,-26263207,-6086921,31316348,14219878 }, 2208 }, 2209 { 2210 { -28594490,1193785,32245219,11392485,31092169,15722801,27146014,6992409,29126555,9207390 }, 2211 { 32382935,1110093,18477781,11028262,-27411763,-7548111,-4980517,10843782,-7957600,-14435730 }, 2212 { 2814918,7836403,27519878,-7868156,-20894015,-11553689,-21494559,8550130,28346258,1994730 }, 2213 }, 2214 { 2215 { -19578299,8085545,-14000519,-3948622,2785838,-16231307,-19516951,7174894,22628102,8115180 }, 2216 { -30405132,955511,-11133838,-15078069,-32447087,-13278079,-25651578,3317160,-9943017,930272 }, 2217 { -15303681,-6833769,28856490,1357446,23421993,1057177,24091212,-1388970,-22765376,-10650715 }, 2218 }, 2219 { 2220 { -22751231,-5303997,-12907607,-12768866,-15811511,-7797053,-14839018,-16554220,-1867018,8398970 }, 2221 { -31969310,2106403,-4736360,1362501,12813763,16200670,22981545,-6291273,18009408,-15772772 }, 2222 { -17220923,-9545221,-27784654,14166835,29815394,7444469,29551787,-3727419,19288549,1325865 }, 2223 }, 2224 { 2225 { 15100157,-15835752,-23923978,-1005098,-26450192,15509408,12376730,-3479146,33166107,-8042750 }, 2226 { 20909231,13023121,-9209752,16251778,-5778415,-8094914,12412151,10018715,2213263,-13878373 }, 2227 { 32529814,-11074689,30361439,-16689753,-9135940,1513226,22922121,6382134,-5766928,8371348 }, 2228 }, 2229 }, 2230 { 2231 { 2232 { 9923462,11271500,12616794,3544722,-29998368,-1721626,12891687,-8193132,-26442943,10486144 }, 2233 { -22597207,-7012665,8587003,-8257861,4084309,-12970062,361726,2610596,-23921530,-11455195 }, 2234 { 5408411,-1136691,-4969122,10561668,24145918,14240566,31319731,-4235541,19985175,-3436086 }, 2235 }, 2236 { 2237 { -13994457,16616821,14549246,3341099,32155958,13648976,-17577068,8849297,65030,8370684 }, 2238 { -8320926,-12049626,31204563,5839400,-20627288,-1057277,-19442942,6922164,12743482,-9800518 }, 2239 { -2361371,12678785,28815050,4759974,-23893047,4884717,23783145,11038569,18800704,255233 }, 2240 }, 2241 { 2242 { -5269658,-1773886,13957886,7990715,23132995,728773,13393847,9066957,19258688,-14753793 }, 2243 { -2936654,-10827535,-10432089,14516793,-3640786,4372541,-31934921,2209390,-1524053,2055794 }, 2244 { 580882,16705327,5468415,-2683018,-30926419,-14696000,-7203346,-8994389,-30021019,7394435 }, 2245 }, 2246 { 2247 { 23838809,1822728,-15738443,15242727,8318092,-3733104,-21672180,-3492205,-4821741,14799921 }, 2248 { 13345610,9759151,3371034,-16137791,16353039,8577942,31129804,13496856,-9056018,7402518 }, 2249 { 2286874,-4435931,-20042458,-2008336,-13696227,5038122,11006906,-15760352,8205061,1607563 }, 2250 }, 2251 { 2252 { 14414086,-8002132,3331830,-3208217,22249151,-5594188,18364661,-2906958,30019587,-9029278 }, 2253 { -27688051,1585953,-10775053,931069,-29120221,-11002319,-14410829,12029093,9944378,8024 }, 2254 { 4368715,-3709630,29874200,-15022983,-20230386,-11410704,-16114594,-999085,-8142388,5640030 }, 2255 }, 2256 { 2257 { 10299610,13746483,11661824,16234854,7630238,5998374,9809887,-16694564,15219798,-14327783 }, 2258 { 27425505,-5719081,3055006,10660664,23458024,595578,-15398605,-1173195,-18342183,9742717 }, 2259 { 6744077,2427284,26042789,2720740,-847906,1118974,32324614,7406442,12420155,1994844 }, 2260 }, 2261 { 2262 { 14012521,-5024720,-18384453,-9578469,-26485342,-3936439,-13033478,-10909803,24319929,-6446333 }, 2263 { 16412690,-4507367,10772641,15929391,-17068788,-4658621,10555945,-10484049,-30102368,-4739048 }, 2264 { 22397382,-7767684,-9293161,-12792868,17166287,-9755136,-27333065,6199366,21880021,-12250760 }, 2265 }, 2266 { 2267 { -4283307,5368523,-31117018,8163389,-30323063,3209128,16557151,8890729,8840445,4957760 }, 2268 { -15447727,709327,-6919446,-10870178,-29777922,6522332,-21720181,12130072,-14796503,5005757 }, 2269 { -2114751,-14308128,23019042,15765735,-25269683,6002752,10183197,-13239326,-16395286,-2176112 }, 2270 }, 2271 }, 2272 { 2273 { 2274 { -19025756,1632005,13466291,-7995100,-23640451,16573537,-32013908,-3057104,22208662,2000468 }, 2275 { 3065073,-1412761,-25598674,-361432,-17683065,-5703415,-8164212,11248527,-3691214,-7414184 }, 2276 { 10379208,-6045554,8877319,1473647,-29291284,-12507580,16690915,2553332,-3132688,16400289 }, 2277 }, 2278 { 2279 { 15716668,1254266,-18472690,7446274,-8448918,6344164,-22097271,-7285580,26894937,9132066 }, 2280 { 24158887,12938817,11085297,-8177598,-28063478,-4457083,-30576463,64452,-6817084,-2692882 }, 2281 { 13488534,7794716,22236231,5989356,25426474,-12578208,2350710,-3418511,-4688006,2364226 }, 2282 }, 2283 { 2284 { 16335052,9132434,25640582,6678888,1725628,8517937,-11807024,-11697457,15445875,-7798101 }, 2285 { 29004207,-7867081,28661402,-640412,-12794003,-7943086,31863255,-4135540,-278050,-15759279 }, 2286 { -6122061,-14866665,-28614905,14569919,-10857999,-3591829,10343412,-6976290,-29828287,-10815811 }, 2287 }, 2288 { 2289 { 27081650,3463984,14099042,-4517604,1616303,-6205604,29542636,15372179,17293797,960709 }, 2290 { 20263915,11434237,-5765435,11236810,13505955,-10857102,-16111345,6493122,-19384511,7639714 }, 2291 { -2830798,-14839232,25403038,-8215196,-8317012,-16173699,18006287,-16043750,29994677,-15808121 }, 2292 }, 2293 { 2294 { 9769828,5202651,-24157398,-13631392,-28051003,-11561624,-24613141,-13860782,-31184575,709464 }, 2295 { 12286395,13076066,-21775189,-1176622,-25003198,4057652,-32018128,-8890874,16102007,13205847 }, 2296 { 13733362,5599946,10557076,3195751,-5557991,8536970,-25540170,8525972,10151379,10394400 }, 2297 }, 2298 { 2299 { 4024660,-16137551,22436262,12276534,-9099015,-2686099,19698229,11743039,-33302334,8934414 }, 2300 { -15879800,-4525240,-8580747,-2934061,14634845,-698278,-9449077,3137094,-11536886,11721158 }, 2301 { 17555939,-5013938,8268606,2331751,-22738815,9761013,9319229,8835153,-9205489,-1280045 }, 2302 }, 2303 { 2304 { -461409,-7830014,20614118,16688288,-7514766,-4807119,22300304,505429,6108462,-6183415 }, 2305 { -5070281,12367917,-30663534,3234473,32617080,-8422642,29880583,-13483331,-26898490,-7867459 }, 2306 { -31975283,5726539,26934134,10237677,-3173717,-605053,24199304,3795095,7592688,-14992079 }, 2307 }, 2308 { 2309 { 21594432,-14964228,17466408,-4077222,32537084,2739898,6407723,12018833,-28256052,4298412 }, 2310 { -20650503,-11961496,-27236275,570498,3767144,-1717540,13891942,-1569194,13717174,10805743 }, 2311 { -14676630,-15644296,15287174,11927123,24177847,-8175568,-796431,14860609,-26938930,-5863836 }, 2312 }, 2313 }, 2314 { 2315 { 2316 { 12962541,5311799,-10060768,11658280,18855286,-7954201,13286263,-12808704,-4381056,9882022 }, 2317 { 18512079,11319350,-20123124,15090309,18818594,5271736,-22727904,3666879,-23967430,-3299429 }, 2318 { -6789020,-3146043,16192429,13241070,15898607,-14206114,-10084880,-6661110,-2403099,5276065 }, 2319 }, 2320 { 2321 { 30169808,-5317648,26306206,-11750859,27814964,7069267,7152851,3684982,1449224,13082861 }, 2322 { 10342826,3098505,2119311,193222,25702612,12233820,23697382,15056736,-21016438,-8202000 }, 2323 { -33150110,3261608,22745853,7948688,19370557,-15177665,-26171976,6482814,-10300080,-11060101 }, 2324 }, 2325 { 2326 { 32869458,-5408545,25609743,15678670,-10687769,-15471071,26112421,2521008,-22664288,6904815 }, 2327 { 29506923,4457497,3377935,-9796444,-30510046,12935080,1561737,3841096,-29003639,-6657642 }, 2328 { 10340844,-6630377,-18656632,-2278430,12621151,-13339055,30878497,-11824370,-25584551,5181966 }, 2329 }, 2330 { 2331 { 25940115,-12658025,17324188,-10307374,-8671468,15029094,24396252,-16450922,-2322852,-12388574 }, 2332 { -21765684,9916823,-1300409,4079498,-1028346,11909559,1782390,12641087,20603771,-6561742 }, 2333 { -18882287,-11673380,24849422,11501709,13161720,-4768874,1925523,11914390,4662781,7820689 }, 2334 }, 2335 { 2336 { 12241050,-425982,8132691,9393934,32846760,-1599620,29749456,12172924,16136752,15264020 }, 2337 { -10349955,-14680563,-8211979,2330220,-17662549,-14545780,10658213,6671822,19012087,3772772 }, 2338 { 3753511,-3421066,10617074,2028709,14841030,-6721664,28718732,-15762884,20527771,12988982 }, 2339 }, 2340 { 2341 { -14822485,-5797269,-3707987,12689773,-898983,-10914866,-24183046,-10564943,3299665,-12424953 }, 2342 { -16777703,-15253301,-9642417,4978983,3308785,8755439,6943197,6461331,-25583147,8991218 }, 2343 { -17226263,1816362,-1673288,-6086439,31783888,-8175991,-32948145,7417950,-30242287,1507265 }, 2344 }, 2345 { 2346 { 29692663,6829891,-10498800,4334896,20945975,-11906496,-28887608,8209391,14606362,-10647073 }, 2347 { -3481570,8707081,32188102,5672294,22096700,1711240,-33020695,9761487,4170404,-2085325 }, 2348 { -11587470,14855945,-4127778,-1531857,-26649089,15084046,22186522,16002000,-14276837,-8400798 }, 2349 }, 2350 { 2351 { -4811456,13761029,-31703877,-2483919,-3312471,7869047,-7113572,-9620092,13240845,10965870 }, 2352 { -7742563,-8256762,-14768334,-13656260,-23232383,12387166,4498947,14147411,29514390,4302863 }, 2353 { -13413405,-12407859,20757302,-13801832,14785143,8976368,-5061276,-2144373,17846988,-13971927 }, 2354 }, 2355 }, 2356 { 2357 { 2358 { -2244452,-754728,-4597030,-1066309,-6247172,1455299,-21647728,-9214789,-5222701,12650267 }, 2359 { -9906797,-16070310,21134160,12198166,-27064575,708126,387813,13770293,-19134326,10958663 }, 2360 { 22470984,12369526,23446014,-5441109,-21520802,-9698723,-11772496,-11574455,-25083830,4271862 }, 2361 }, 2362 { 2363 { -25169565,-10053642,-19909332,15361595,-5984358,2159192,75375,-4278529,-32526221,8469673 }, 2364 { 15854970,4148314,-8893890,7259002,11666551,13824734,-30531198,2697372,24154791,-9460943 }, 2365 { 15446137,-15806644,29759747,14019369,30811221,-9610191,-31582008,12840104,24913809,9815020 }, 2366 }, 2367 { 2368 { -4709286,-5614269,-31841498,-12288893,-14443537,10799414,-9103676,13438769,18735128,9466238 }, 2369 { 11933045,9281483,5081055,-5183824,-2628162,-4905629,-7727821,-10896103,-22728655,16199064 }, 2370 { 14576810,379472,-26786533,-8317236,-29426508,-10812974,-102766,1876699,30801119,2164795 }, 2371 }, 2372 { 2373 { 15995086,3199873,13672555,13712240,-19378835,-4647646,-13081610,-15496269,-13492807,1268052 }, 2374 { -10290614,-3659039,-3286592,10948818,23037027,3794475,-3470338,-12600221,-17055369,3565904 }, 2375 { 29210088,-9419337,-5919792,-4952785,10834811,-13327726,-16512102,-10820713,-27162222,-14030531 }, 2376 }, 2377 { 2378 { -13161890,15508588,16663704,-8156150,-28349942,9019123,-29183421,-3769423,2244111,-14001979 }, 2379 { -5152875,-3800936,-9306475,-6071583,16243069,14684434,-25673088,-16180800,13491506,4641841 }, 2380 { 10813417,643330,-19188515,-728916,30292062,-16600078,27548447,-7721242,14476989,-12767431 }, 2381 }, 2382 { 2383 { 10292079,9984945,6481436,8279905,-7251514,7032743,27282937,-1644259,-27912810,12651324 }, 2384 { -31185513,-813383,22271204,11835308,10201545,15351028,17099662,3988035,21721536,-3148940 }, 2385 { 10202177,-6545839,-31373232,-9574638,-32150642,-8119683,-12906320,3852694,13216206,14842320 }, 2386 }, 2387 { 2388 { -15815640,-10601066,-6538952,-7258995,-6984659,-6581778,-31500847,13765824,-27434397,9900184 }, 2389 { 14465505,-13833331,-32133984,-14738873,-27443187,12990492,33046193,15796406,-7051866,-8040114 }, 2390 { 30924417,-8279620,6359016,-12816335,16508377,9071735,-25488601,15413635,9524356,-7018878 }, 2391 }, 2392 { 2393 { 12274201,-13175547,32627641,-1785326,6736625,13267305,5237659,-5109483,15663516,4035784 }, 2394 { -2951309,8903985,17349946,601635,-16432815,-4612556,-13732739,-15889334,-22258478,4659091 }, 2395 { -16916263,-4952973,-30393711,-15158821,20774812,15897498,5736189,15026997,-2178256,-13455585 }, 2396 }, 2397 }, 2398 { 2399 { 2400 { -8858980,-2219056,28571666,-10155518,-474467,-10105698,-3801496,278095,23440562,-290208 }, 2401 { 10226241,-5928702,15139956,120818,-14867693,5218603,32937275,11551483,-16571960,-7442864 }, 2402 { 17932739,-12437276,-24039557,10749060,11316803,7535897,22503767,5561594,-3646624,3898661 }, 2403 }, 2404 { 2405 { 7749907,-969567,-16339731,-16464,-25018111,15122143,-1573531,7152530,21831162,1245233 }, 2406 { 26958459,-14658026,4314586,8346991,-5677764,11960072,-32589295,-620035,-30402091,-16716212 }, 2407 { -12165896,9166947,33491384,13673479,29787085,13096535,6280834,14587357,-22338025,13987525 }, 2408 }, 2409 { 2410 { -24349909,7778775,21116000,15572597,-4833266,-5357778,-4300898,-5124639,-7469781,-2858068 }, 2411 { 9681908,-6737123,-31951644,13591838,-6883821,386950,31622781,6439245,-14581012,4091397 }, 2412 { -8426427,1470727,-28109679,-1596990,3978627,-5123623,-19622683,12092163,29077877,-14741988 }, 2413 }, 2414 { 2415 { 5269168,-6859726,-13230211,-8020715,25932563,1763552,-5606110,-5505881,-20017847,2357889 }, 2416 { 32264008,-15407652,-5387735,-1160093,-2091322,-3946900,23104804,-12869908,5727338,189038 }, 2417 { 14609123,-8954470,-6000566,-16622781,-14577387,-7743898,-26745169,10942115,-25888931,-14884697 }, 2418 }, 2419 { 2420 { 20513500,5557931,-15604613,7829531,26413943,-2019404,-21378968,7471781,13913677,-5137875 }, 2421 { -25574376,11967826,29233242,12948236,-6754465,4713227,-8940970,14059180,12878652,8511905 }, 2422 { -25656801,3393631,-2955415,-7075526,-2250709,9366908,-30223418,6812974,5568676,-3127656 }, 2423 }, 2424 { 2425 { 11630004,12144454,2116339,13606037,27378885,15676917,-17408753,-13504373,-14395196,8070818 }, 2426 { 27117696,-10007378,-31282771,-5570088,1127282,12772488,-29845906,10483306,-11552749,-1028714 }, 2427 { 10637467,-5688064,5674781,1072708,-26343588,-6982302,-1683975,9177853,-27493162,15431203 }, 2428 }, 2429 { 2430 { 20525145,10892566,-12742472,12779443,-29493034,16150075,-28240519,14943142,-15056790,-7935931 }, 2431 { -30024462,5626926,-551567,-9981087,753598,11981191,25244767,-3239766,-3356550,9594024 }, 2432 { -23752644,2636870,-5163910,-10103818,585134,7877383,11345683,-6492290,13352335,-10977084 }, 2433 }, 2434 { 2435 { -1931799,-5407458,3304649,-12884869,17015806,-4877091,-29783850,-7752482,-13215537,-319204 }, 2436 { 20239939,6607058,6203985,3483793,-18386976,-779229,-20723742,15077870,-22750759,14523817 }, 2437 { 27406042,-6041657,27423596,-4497394,4996214,10002360,-28842031,-4545494,-30172742,-4805667 }, 2438 }, 2439 }, 2440 { 2441 { 2442 { 11374242,12660715,17861383,-12540833,10935568,1099227,-13886076,-9091740,-27727044,11358504 }, 2443 { -12730809,10311867,1510375,10778093,-2119455,-9145702,32676003,11149336,-26123651,4985768 }, 2444 { -19096303,341147,-6197485,-239033,15756973,-8796662,-983043,13794114,-19414307,-15621255 }, 2445 }, 2446 { 2447 { 6490081,11940286,25495923,-7726360,8668373,-8751316,3367603,6970005,-1691065,-9004790 }, 2448 { 1656497,13457317,15370807,6364910,13605745,8362338,-19174622,-5475723,-16796596,-5031438 }, 2449 { -22273315,-13524424,-64685,-4334223,-18605636,-10921968,-20571065,-7007978,-99853,-10237333 }, 2450 }, 2451 { 2452 { 17747465,10039260,19368299,-4050591,-20630635,-16041286,31992683,-15857976,-29260363,-5511971 }, 2453 { 31932027,-4986141,-19612382,16366580,22023614,88450,11371999,-3744247,4882242,-10626905 }, 2454 { 29796507,37186,19818052,10115756,-11829032,3352736,18551198,3272828,-5190932,-4162409 }, 2455 }, 2456 { 2457 { 12501286,4044383,-8612957,-13392385,-32430052,5136599,-19230378,-3529697,330070,-3659409 }, 2458 { 6384877,2899513,17807477,7663917,-2358888,12363165,25366522,-8573892,-271295,12071499 }, 2459 { -8365515,-4042521,25133448,-4517355,-6211027,2265927,-32769618,1936675,-5159697,3829363 }, 2460 }, 2461 { 2462 { 28425966,-5835433,-577090,-4697198,-14217555,6870930,7921550,-6567787,26333140,14267664 }, 2463 { -11067219,11871231,27385719,-10559544,-4585914,-11189312,10004786,-8709488,-21761224,8930324 }, 2464 { -21197785,-16396035,25654216,-1725397,12282012,11008919,1541940,4757911,-26491501,-16408940 }, 2465 }, 2466 { 2467 { 13537262,-7759490,-20604840,10961927,-5922820,-13218065,-13156584,6217254,-15943699,13814990 }, 2468 { -17422573,15157790,18705543,29619,24409717,-260476,27361681,9257833,-1956526,-1776914 }, 2469 { -25045300,-10191966,15366585,15166509,-13105086,8423556,-29171540,12361135,-18685978,4578290 }, 2470 }, 2471 { 2472 { 24579768,3711570,1342322,-11180126,-27005135,14124956,-22544529,14074919,21964432,8235257 }, 2473 { -6528613,-2411497,9442966,-5925588,12025640,-1487420,-2981514,-1669206,13006806,2355433 }, 2474 { -16304899,-13605259,-6632427,-5142349,16974359,-10911083,27202044,1719366,1141648,-12796236 }, 2475 }, 2476 { 2477 { -12863944,-13219986,-8318266,-11018091,-6810145,-4843894,13475066,-3133972,32674895,13715045 }, 2478 { 11423335,-5468059,32344216,8962751,24989809,9241752,-13265253,16086212,-28740881,-15642093 }, 2479 { -1409668,12530728,-6368726,10847387,19531186,-14132160,-11709148,7791794,-27245943,4383347 }, 2480 }, 2481 }, 2482 { 2483 { 2484 { -28970898,5271447,-1266009,-9736989,-12455236,16732599,-4862407,-4906449,27193557,6245191 }, 2485 { -15193956,5362278,-1783893,2695834,4960227,12840725,23061898,3260492,22510453,8577507 }, 2486 { -12632451,11257346,-32692994,13548177,-721004,10879011,31168030,13952092,-29571492,-3635906 }, 2487 }, 2488 { 2489 { 3877321,-9572739,32416692,5405324,-11004407,-13656635,3759769,11935320,5611860,8164018 }, 2490 { -16275802,14667797,15906460,12155291,-22111149,-9039718,32003002,-8832289,5773085,-8422109 }, 2491 { -23788118,-8254300,1950875,8937633,18686727,16459170,-905725,12376320,31632953,190926 }, 2492 }, 2493 { 2494 { -24593607,-16138885,-8423991,13378746,14162407,6901328,-8288749,4508564,-25341555,-3627528 }, 2495 { 8884438,-5884009,6023974,10104341,-6881569,-4941533,18722941,-14786005,-1672488,827625 }, 2496 { -32720583,-16289296,-32503547,7101210,13354605,2659080,-1800575,-14108036,-24878478,1541286 }, 2497 }, 2498 { 2499 { 2901347,-1117687,3880376,-10059388,-17620940,-3612781,-21802117,-3567481,20456845,-1885033 }, 2500 { 27019610,12299467,-13658288,-1603234,-12861660,-4861471,-19540150,-5016058,29439641,15138866 }, 2501 { 21536104,-6626420,-32447818,-10690208,-22408077,5175814,-5420040,-16361163,7779328,109896 }, 2502 }, 2503 { 2504 { 30279744,14648750,-8044871,6425558,13639621,-743509,28698390,12180118,23177719,-554075 }, 2505 { 26572847,3405927,-31701700,12890905,-19265668,5335866,-6493768,2378492,4439158,-13279347 }, 2506 { -22716706,3489070,-9225266,-332753,18875722,-1140095,14819434,-12731527,-17717757,-5461437 }, 2507 }, 2508 { 2509 { -5056483,16566551,15953661,3767752,-10436499,15627060,-820954,2177225,8550082,-15114165 }, 2510 { -18473302,16596775,-381660,15663611,22860960,15585581,-27844109,-3582739,-23260460,-8428588 }, 2511 { -32480551,15707275,-8205912,-5652081,29464558,2713815,-22725137,15860482,-21902570,1494193 }, 2512 }, 2513 { 2514 { -19562091,-14087393,-25583872,-9299552,13127842,759709,21923482,16529112,8742704,12967017 }, 2515 { -28464899,1553205,32536856,-10473729,-24691605,-406174,-8914625,-2933896,-29903758,15553883 }, 2516 { 21877909,3230008,9881174,10539357,-4797115,2841332,11543572,14513274,19375923,-12647961 }, 2517 }, 2518 { 2519 { 8832269,-14495485,13253511,5137575,5037871,4078777,24880818,-6222716,2862653,9455043 }, 2520 { 29306751,5123106,20245049,-14149889,9592566,8447059,-2077124,-2990080,15511449,4789663 }, 2521 { -20679756,7004547,8824831,-9434977,-4045704,-3750736,-5754762,108893,23513200,16652362 }, 2522 }, 2523 }, 2524 { 2525 { 2526 { -33256173,4144782,-4476029,-6579123,10770039,-7155542,-6650416,-12936300,-18319198,10212860 }, 2527 { 2756081,8598110,7383731,-6859892,22312759,-1105012,21179801,2600940,-9988298,-12506466 }, 2528 { -24645692,13317462,-30449259,-15653928,21365574,-10869657,11344424,864440,-2499677,-16710063 }, 2529 }, 2530 { 2531 { -26432803,6148329,-17184412,-14474154,18782929,-275997,-22561534,211300,2719757,4940997 }, 2532 { -1323882,3911313,-6948744,14759765,-30027150,7851207,21690126,8518463,26699843,5276295 }, 2533 { -13149873,-6429067,9396249,365013,24703301,-10488939,1321586,149635,-15452774,7159369 }, 2534 }, 2535 { 2536 { 9987780,-3404759,17507962,9505530,9731535,-2165514,22356009,8312176,22477218,-8403385 }, 2537 { 18155857,-16504990,19744716,9006923,15154154,-10538976,24256460,-4864995,-22548173,9334109 }, 2538 { 2986088,-4911893,10776628,-3473844,10620590,-7083203,-21413845,14253545,-22587149,536906 }, 2539 }, 2540 { 2541 { 4377756,8115836,24567078,15495314,11625074,13064599,7390551,10589625,10838060,-15420424 }, 2542 { -19342404,867880,9277171,-3218459,-14431572,-1986443,19295826,-15796950,6378260,699185 }, 2543 { 7895026,4057113,-7081772,-13077756,-17886831,-323126,-716039,15693155,-5045064,-13373962 }, 2544 }, 2545 { 2546 { -7737563,-5869402,-14566319,-7406919,11385654,13201616,31730678,-10962840,-3918636,-9669325 }, 2547 { 10188286,-15770834,-7336361,13427543,22223443,14896287,30743455,7116568,-21786507,5427593 }, 2548 { 696102,13206899,27047647,-10632082,15285305,-9853179,10798490,-4578720,19236243,12477404 }, 2549 }, 2550 { 2551 { -11229439,11243796,-17054270,-8040865,-788228,-8167967,-3897669,11180504,-23169516,7733644 }, 2552 { 17800790,-14036179,-27000429,-11766671,23887827,3149671,23466177,-10538171,10322027,15313801 }, 2553 { 26246234,11968874,32263343,-5468728,6830755,-13323031,-15794704,-101982,-24449242,10890804 }, 2554 }, 2555 { 2556 { -31365647,10271363,-12660625,-6267268,16690207,-13062544,-14982212,16484931,25180797,-5334884 }, 2557 { -586574,10376444,-32586414,-11286356,19801893,10997610,2276632,9482883,316878,13820577 }, 2558 { -9882808,-4510367,-2115506,16457136,-11100081,11674996,30756178,-7515054,30696930,-3712849 }, 2559 }, 2560 { 2561 { 32988917,-9603412,12499366,7910787,-10617257,-11931514,-7342816,-9985397,-32349517,7392473 }, 2562 { -8855661,15927861,9866406,-3649411,-2396914,-16655781,-30409476,-9134995,25112947,-2926644 }, 2563 { -2504044,-436966,25621774,-5678772,15085042,-5479877,-24884878,-13526194,5537438,-13914319 }, 2564 }, 2565 }, 2566 { 2567 { 2568 { -11225584,2320285,-9584280,10149187,-33444663,5808648,-14876251,-1729667,31234590,6090599 }, 2569 { -9633316,116426,26083934,2897444,-6364437,-2688086,609721,15878753,-6970405,-9034768 }, 2570 { -27757857,247744,-15194774,-9002551,23288161,-10011936,-23869595,6503646,20650474,1804084 }, 2571 }, 2572 { 2573 { -27589786,15456424,8972517,8469608,15640622,4439847,3121995,-10329713,27842616,-202328 }, 2574 { -15306973,2839644,22530074,10026331,4602058,5048462,28248656,5031932,-11375082,12714369 }, 2575 { 20807691,-7270825,29286141,11421711,-27876523,-13868230,-21227475,1035546,-19733229,12796920 }, 2576 }, 2577 { 2578 { 12076899,-14301286,-8785001,-11848922,-25012791,16400684,-17591495,-12899438,3480665,-15182815 }, 2579 { -32361549,5457597,28548107,7833186,7303070,-11953545,-24363064,-15921875,-33374054,2771025 }, 2580 { -21389266,421932,26597266,6860826,22486084,-6737172,-17137485,-4210226,-24552282,15673397 }, 2581 }, 2582 { 2583 { -20184622,2338216,19788685,-9620956,-4001265,-8740893,-20271184,4733254,3727144,-12934448 }, 2584 { 6120119,814863,-11794402,-622716,6812205,-15747771,2019594,7975683,31123697,-10958981 }, 2585 { 30069250,-11435332,30434654,2958439,18399564,-976289,12296869,9204260,-16432438,9648165 }, 2586 }, 2587 { 2588 { 32705432,-1550977,30705658,7451065,-11805606,9631813,3305266,5248604,-26008332,-11377501 }, 2589 { 17219865,2375039,-31570947,-5575615,-19459679,9219903,294711,15298639,2662509,-16297073 }, 2590 { -1172927,-7558695,-4366770,-4287744,-21346413,-8434326,32087529,-1222777,32247248,-14389861 }, 2591 }, 2592 { 2593 { 14312628,1221556,17395390,-8700143,-4945741,-8684635,-28197744,-9637817,-16027623,-13378845 }, 2594 { -1428825,-9678990,-9235681,6549687,-7383069,-468664,23046502,9803137,17597934,2346211 }, 2595 { 18510800,15337574,26171504,981392,-22241552,7827556,-23491134,-11323352,3059833,-11782870 }, 2596 }, 2597 { 2598 { 10141598,6082907,17829293,-1947643,9830092,13613136,-25556636,-5544586,-33502212,3592096 }, 2599 { 33114168,-15889352,-26525686,-13343397,33076705,8716171,1151462,1521897,-982665,-6837803 }, 2600 { -32939165,-4255815,23947181,-324178,-33072974,-12305637,-16637686,3891704,26353178,693168 }, 2601 }, 2602 { 2603 { 30374239,1595580,-16884039,13186931,4600344,406904,9585294,-400668,31375464,14369965 }, 2604 { -14370654,-7772529,1510301,6434173,-18784789,-6262728,32732230,-13108839,17901441,16011505 }, 2605 { 18171223,-11934626,-12500402,15197122,-11038147,-15230035,-19172240,-16046376,8764035,12309598 }, 2606 }, 2607 }, 2608 { 2609 { 2610 { 5975908,-5243188,-19459362,-9681747,-11541277,14015782,-23665757,1228319,17544096,-10593782 }, 2611 { 5811932,-1715293,3442887,-2269310,-18367348,-8359541,-18044043,-15410127,-5565381,12348900 }, 2612 { -31399660,11407555,25755363,6891399,-3256938,14872274,-24849353,8141295,-10632534,-585479 }, 2613 }, 2614 { 2615 { -12675304,694026,-5076145,13300344,14015258,-14451394,-9698672,-11329050,30944593,1130208 }, 2616 { 8247766,-6710942,-26562381,-7709309,-14401939,-14648910,4652152,2488540,23550156,-271232 }, 2617 { 17294316,-3788438,7026748,15626851,22990044,113481,2267737,-5908146,-408818,-137719 }, 2618 }, 2619 { 2620 { 16091085,-16253926,18599252,7340678,2137637,-1221657,-3364161,14550936,3260525,-7166271 }, 2621 { -4910104,-13332887,18550887,10864893,-16459325,-7291596,-23028869,-13204905,-12748722,2701326 }, 2622 { -8574695,16099415,4629974,-16340524,-20786213,-6005432,-10018363,9276971,11329923,1862132 }, 2623 }, 2624 { 2625 { 14763076,-15903608,-30918270,3689867,3511892,10313526,-21951088,12219231,-9037963,-940300 }, 2626 { 8894987,-3446094,6150753,3013931,301220,15693451,-31981216,-2909717,-15438168,11595570 }, 2627 { 15214962,3537601,-26238722,-14058872,4418657,-15230761,13947276,10730794,-13489462,-4363670 }, 2628 }, 2629 { 2630 { -2538306,7682793,32759013,263109,-29984731,-7955452,-22332124,-10188635,977108,699994 }, 2631 { -12466472,4195084,-9211532,550904,-15565337,12917920,19118110,-439841,-30534533,-14337913 }, 2632 { 31788461,-14507657,4799989,7372237,8808585,-14747943,9408237,-10051775,12493932,-5409317 }, 2633 }, 2634 { 2635 { -25680606,5260744,-19235809,-6284470,-3695942,16566087,27218280,2607121,29375955,6024730 }, 2636 { 842132,-2794693,-4763381,-8722815,26332018,-12405641,11831880,6985184,-9940361,2854096 }, 2637 { -4847262,-7969331,2516242,-5847713,9695691,-7221186,16512645,960770,12121869,16648078 }, 2638 }, 2639 { 2640 { -15218652,14667096,-13336229,2013717,30598287,-464137,-31504922,-7882064,20237806,2838411 }, 2641 { -19288047,4453152,15298546,-16178388,22115043,-15972604,12544294,-13470457,1068881,-12499905 }, 2642 { -9558883,-16518835,33238498,13506958,30505848,-1114596,-8486907,-2630053,12521378,4845654 }, 2643 }, 2644 { 2645 { -28198521,10744108,-2958380,10199664,7759311,-13088600,3409348,-873400,-6482306,-12885870 }, 2646 { -23561822,6230156,-20382013,10655314,-24040585,-11621172,10477734,-1240216,-3113227,13974498 }, 2647 { 12966261,15550616,-32038948,-1615346,21025980,-629444,5642325,7188737,18895762,12629579 }, 2648 }, 2649 }, 2650 { 2651 { 2652 { 14741879,-14946887,22177208,-11721237,1279741,8058600,11758140,789443,32195181,3895677 }, 2653 { 10758205,15755439,-4509950,9243698,-4879422,6879879,-2204575,-3566119,-8982069,4429647 }, 2654 { -2453894,15725973,-20436342,-10410672,-5803908,-11040220,-7135870,-11642895,18047436,-15281743 }, 2655 }, 2656 { 2657 { -25173001,-11307165,29759956,11776784,-22262383,-15820455,10993114,-12850837,-17620701,-9408468 }, 2658 { 21987233,700364,-24505048,14972008,-7774265,-5718395,32155026,2581431,-29958985,8773375 }, 2659 { -25568350,454463,-13211935,16126715,25240068,8594567,20656846,12017935,-7874389,-13920155 }, 2660 }, 2661 { 2662 { 6028182,6263078,-31011806,-11301710,-818919,2461772,-31841174,-5468042,-1721788,-2776725 }, 2663 { -12278994,16624277,987579,-5922598,32908203,1248608,7719845,-4166698,28408820,6816612 }, 2664 { -10358094,-8237829,19549651,-12169222,22082623,16147817,20613181,13982702,-10339570,5067943 }, 2665 }, 2666 { 2667 { -30505967,-3821767,12074681,13582412,-19877972,2443951,-19719286,12746132,5331210,-10105944 }, 2668 { 30528811,3601899,-1957090,4619785,-27361822,-15436388,24180793,-12570394,27679908,-1648928 }, 2669 { 9402404,-13957065,32834043,10838634,-26580150,-13237195,26653274,-8685565,22611444,-12715406 }, 2670 }, 2671 { 2672 { 22190590,1118029,22736441,15130463,-30460692,-5991321,19189625,-4648942,4854859,6622139 }, 2673 { -8310738,-2953450,-8262579,-3388049,-10401731,-271929,13424426,-3567227,26404409,13001963 }, 2674 { -31241838,-15415700,-2994250,8939346,11562230,-12840670,-26064365,-11621720,-15405155,11020693 }, 2675 }, 2676 { 2677 { 1866042,-7949489,-7898649,-10301010,12483315,13477547,3175636,-12424163,28761762,1406734 }, 2678 { -448555,-1777666,13018551,3194501,-9580420,-11161737,24760585,-4347088,25577411,-13378680 }, 2679 { -24290378,4759345,-690653,-1852816,2066747,10693769,-29595790,9884936,-9368926,4745410 }, 2680 }, 2681 { 2682 { -9141284,6049714,-19531061,-4341411,-31260798,9944276,-15462008,-11311852,10931924,-11931931 }, 2683 { -16561513,14112680,-8012645,4817318,-8040464,-11414606,-22853429,10856641,-20470770,13434654 }, 2684 { 22759489,-10073434,-16766264,-1871422,13637442,-10168091,1765144,-12654326,28445307,-5364710 }, 2685 }, 2686 { 2687 { 29875063,12493613,2795536,-3786330,1710620,15181182,-10195717,-8788675,9074234,1167180 }, 2688 { -26205683,11014233,-9842651,-2635485,-26908120,7532294,-18716888,-9535498,3843903,9367684 }, 2689 { -10969595,-6403711,9591134,9582310,11349256,108879,16235123,8601684,-139197,4242895 }, 2690 }, 2691 }, 2692 { 2693 { 2694 { 22092954,-13191123,-2042793,-11968512,32186753,-11517388,-6574341,2470660,-27417366,16625501 }, 2695 { -11057722,3042016,13770083,-9257922,584236,-544855,-7770857,2602725,-27351616,14247413 }, 2696 { 6314175,-10264892,-32772502,15957557,-10157730,168750,-8618807,14290061,27108877,-1180880 }, 2697 }, 2698 { 2699 { -8586597,-7170966,13241782,10960156,-32991015,-13794596,33547976,-11058889,-27148451,981874 }, 2700 { 22833440,9293594,-32649448,-13618667,-9136966,14756819,-22928859,-13970780,-10479804,-16197962 }, 2701 { -7768587,3326786,-28111797,10783824,19178761,14905060,22680049,13906969,-15933690,3797899 }, 2702 }, 2703 { 2704 { 21721356,-4212746,-12206123,9310182,-3882239,-13653110,23740224,-2709232,20491983,-8042152 }, 2705 { 9209270,-15135055,-13256557,-6167798,-731016,15289673,25947805,15286587,30997318,-6703063 }, 2706 { 7392032,16618386,23946583,-8039892,-13265164,-1533858,-14197445,-2321576,17649998,-250080 }, 2707 }, 2708 { 2709 { -9301088,-14193827,30609526,-3049543,-25175069,-1283752,-15241566,-9525724,-2233253,7662146 }, 2710 { -17558673,1763594,-33114336,15908610,-30040870,-12174295,7335080,-8472199,-3174674,3440183 }, 2711 { -19889700,-5977008,-24111293,-9688870,10799743,-16571957,40450,-4431835,4862400,1133 }, 2712 }, 2713 { 2714 { -32856209,-7873957,-5422389,14860950,-16319031,7956142,7258061,311861,-30594991,-7379421 }, 2715 { -3773428,-1565936,28985340,7499440,24445838,9325937,29727763,16527196,18278453,15405622 }, 2716 { -4381906,8508652,-19898366,-3674424,-5984453,15149970,-13313598,843523,-21875062,13626197 }, 2717 }, 2718 { 2719 { 2281448,-13487055,-10915418,-2609910,1879358,16164207,-10783882,3953792,13340839,15928663 }, 2720 { 31727126,-7179855,-18437503,-8283652,2875793,-16390330,-25269894,-7014826,-23452306,5964753 }, 2721 { 4100420,-5959452,-17179337,6017714,-18705837,12227141,-26684835,11344144,2538215,-7570755 }, 2722 }, 2723 { 2724 { -9433605,6123113,11159803,-2156608,30016280,14966241,-20474983,1485421,-629256,-15958862 }, 2725 { -26804558,4260919,11851389,9658551,-32017107,16367492,-20205425,-13191288,11659922,-11115118 }, 2726 { 26180396,10015009,-30844224,-8581293,5418197,9480663,2231568,-10170080,33100372,-1306171 }, 2727 }, 2728 { 2729 { 15121113,-5201871,-10389905,15427821,-27509937,-15992507,21670947,4486675,-5931810,-14466380 }, 2730 { 16166486,-9483733,-11104130,6023908,-31926798,-1364923,2340060,-16254968,-10735770,-10039824 }, 2731 { 28042865,-3557089,-12126526,12259706,-3717498,-6945899,6766453,-8689599,18036436,5803270 }, 2732 }, 2733 }, 2734 { 2735 { 2736 { -817581,6763912,11803561,1585585,10958447,-2671165,23855391,4598332,-6159431,-14117438 }, 2737 { -31031306,-14256194,17332029,-2383520,31312682,-5967183,696309,50292,-20095739,11763584 }, 2738 { -594563,-2514283,-32234153,12643980,12650761,14811489,665117,-12613632,-19773211,-10713562 }, 2739 }, 2740 { 2741 { 30464590,-11262872,-4127476,-12734478,19835327,-7105613,-24396175,2075773,-17020157,992471 }, 2742 { 18357185,-6994433,7766382,16342475,-29324918,411174,14578841,8080033,-11574335,-10601610 }, 2743 { 19598397,10334610,12555054,2555664,18821899,-10339780,21873263,16014234,26224780,16452269 }, 2744 }, 2745 { 2746 { -30223925,5145196,5944548,16385966,3976735,2009897,-11377804,-7618186,-20533829,3698650 }, 2747 { 14187449,3448569,-10636236,-10810935,-22663880,-3433596,7268410,-10890444,27394301,12015369 }, 2748 { 19695761,16087646,28032085,12999827,6817792,11427614,20244189,-1312777,-13259127,-3402461 }, 2749 }, 2750 { 2751 { 30860103,12735208,-1888245,-4699734,-16974906,2256940,-8166013,12298312,-8550524,-10393462 }, 2752 { -5719826,-11245325,-1910649,15569035,26642876,-7587760,-5789354,-15118654,-4976164,12651793 }, 2753 { -2848395,9953421,11531313,-5282879,26895123,-12697089,-13118820,-16517902,9768698,-2533218 }, 2754 }, 2755 { 2756 { -24719459,1894651,-287698,-4704085,15348719,-8156530,32767513,12765450,4940095,10678226 }, 2757 { 18860224,15980149,-18987240,-1562570,-26233012,-11071856,-7843882,13944024,-24372348,16582019 }, 2758 { -15504260,4970268,-29893044,4175593,-20993212,-2199756,-11704054,15444560,-11003761,7989037 }, 2759 }, 2760 { 2761 { 31490452,5568061,-2412803,2182383,-32336847,4531686,-32078269,6200206,-19686113,-14800171 }, 2762 { -17308668,-15879940,-31522777,-2831,-32887382,16375549,8680158,-16371713,28550068,-6857132 }, 2763 { -28126887,-5688091,16837845,-1820458,-6850681,12700016,-30039981,4364038,1155602,5988841 }, 2764 }, 2765 { 2766 { 21890435,-13272907,-12624011,12154349,-7831873,15300496,23148983,-4470481,24618407,8283181 }, 2767 { -33136107,-10512751,9975416,6841041,-31559793,16356536,3070187,-7025928,1466169,10740210 }, 2768 { -1509399,-15488185,-13503385,-10655916,32799044,909394,-13938903,-5779719,-32164649,-15327040 }, 2769 }, 2770 { 2771 { 3960823,-14267803,-28026090,-15918051,-19404858,13146868,15567327,951507,-3260321,-573935 }, 2772 { 24740841,5052253,-30094131,8961361,25877428,6165135,-24368180,14397372,-7380369,-6144105 }, 2773 { -28888365,3510803,-28103278,-1158478,-11238128,-10631454,-15441463,-14453128,-1625486,-6494814 }, 2774 }, 2775 }, 2776 { 2777 { 2778 { 793299,-9230478,8836302,-6235707,-27360908,-2369593,33152843,-4885251,-9906200,-621852 }, 2779 { 5666233,525582,20782575,-8038419,-24538499,14657740,16099374,1468826,-6171428,-15186581 }, 2780 { -4859255,-3779343,-2917758,-6748019,7778750,11688288,-30404353,-9871238,-1558923,-9863646 }, 2781 }, 2782 { 2783 { 10896332,-7719704,824275,472601,-19460308,3009587,25248958,14783338,-30581476,-15757844 }, 2784 { 10566929,12612572,-31944212,11118703,-12633376,12362879,21752402,8822496,24003793,14264025 }, 2785 { 27713862,-7355973,-11008240,9227530,27050101,2504721,23886875,-13117525,13958495,-5732453 }, 2786 }, 2787 { 2788 { -23481610,4867226,-27247128,3900521,29838369,-8212291,-31889399,-10041781,7340521,-15410068 }, 2789 { 4646514,-8011124,-22766023,-11532654,23184553,8566613,31366726,-1381061,-15066784,-10375192 }, 2790 { -17270517,12723032,-16993061,14878794,21619651,-6197576,27584817,3093888,-8843694,3849921 }, 2791 }, 2792 { 2793 { -9064912,2103172,25561640,-15125738,-5239824,9582958,32477045,-9017955,5002294,-15550259 }, 2794 { -12057553,-11177906,21115585,-13365155,8808712,-12030708,16489530,13378448,-25845716,12741426 }, 2795 { -5946367,10645103,-30911586,15390284,-3286982,-7118677,24306472,15852464,28834118,-7646072 }, 2796 }, 2797 { 2798 { -17335748,-9107057,-24531279,9434953,-8472084,-583362,-13090771,455841,20461858,5491305 }, 2799 { 13669248,-16095482,-12481974,-10203039,-14569770,-11893198,-24995986,11293807,-28588204,-9421832 }, 2800 { 28497928,6272777,-33022994,14470570,8906179,-1225630,18504674,-14165166,29867745,-8795943 }, 2801 }, 2802 { 2803 { -16207023,13517196,-27799630,-13697798,24009064,-6373891,-6367600,-13175392,22853429,-4012011 }, 2804 { 24191378,16712145,-13931797,15217831,14542237,1646131,18603514,-11037887,12876623,-2112447 }, 2805 { 17902668,4518229,-411702,-2829247,26878217,5258055,-12860753,608397,16031844,3723494 }, 2806 }, 2807 { 2808 { -28632773,12763728,-20446446,7577504,33001348,-13017745,17558842,-7872890,23896954,-4314245 }, 2809 { -20005381,-12011952,31520464,605201,2543521,5991821,-2945064,7229064,-9919646,-8826859 }, 2810 { 28816045,298879,-28165016,-15920938,19000928,-1665890,-12680833,-2949325,-18051778,-2082915 }, 2811 }, 2812 { 2813 { 16000882,-344896,3493092,-11447198,-29504595,-13159789,12577740,16041268,-19715240,7847707 }, 2814 { 10151868,10572098,27312476,7922682,14825339,4723128,-32855931,-6519018,-10020567,3852848 }, 2815 { -11430470,15697596,-21121557,-4420647,5386314,15063598,16514493,-15932110,29330899,-15076224 }, 2816 }, 2817 }, 2818 { 2819 { 2820 { -25499735,-4378794,-15222908,-6901211,16615731,2051784,3303702,15490,-27548796,12314391 }, 2821 { 15683520,-6003043,18109120,-9980648,15337968,-5997823,-16717435,15921866,16103996,-3731215 }, 2822 { -23169824,-10781249,13588192,-1628807,-3798557,-1074929,-19273607,5402699,-29815713,-9841101 }, 2823 }, 2824 { 2825 { 23190676,2384583,-32714340,3462154,-29903655,-1529132,-11266856,8911517,-25205859,2739713 }, 2826 { 21374101,-3554250,-33524649,9874411,15377179,11831242,-33529904,6134907,4931255,11987849 }, 2827 { -7732,-2978858,-16223486,7277597,105524,-322051,-31480539,13861388,-30076310,10117930 }, 2828 }, 2829 { 2830 { -29501170,-10744872,-26163768,13051539,-25625564,5089643,-6325503,6704079,12890019,15728940 }, 2831 { -21972360,-11771379,-951059,-4418840,14704840,2695116,903376,-10428139,12885167,8311031 }, 2832 { -17516482,5352194,10384213,-13811658,7506451,13453191,26423267,4384730,1888765,-5435404 }, 2833 }, 2834 { 2835 { -25817338,-3107312,-13494599,-3182506,30896459,-13921729,-32251644,-12707869,-19464434,-3340243 }, 2836 { -23607977,-2665774,-526091,4651136,5765089,4618330,6092245,14845197,17151279,-9854116 }, 2837 { -24830458,-12733720,-15165978,10367250,-29530908,-265356,22825805,-7087279,-16866484,16176525 }, 2838 }, 2839 { 2840 { -23583256,6564961,20063689,3798228,-4740178,7359225,2006182,-10363426,-28746253,-10197509 }, 2841 { -10626600,-4486402,-13320562,-5125317,3432136,-6393229,23632037,-1940610,32808310,1099883 }, 2842 { 15030977,5768825,-27451236,-2887299,-6427378,-15361371,-15277896,-6809350,2051441,-15225865 }, 2843 }, 2844 { 2845 { -3362323,-7239372,7517890,9824992,23555850,295369,5148398,-14154188,-22686354,16633660 }, 2846 { 4577086,-16752288,13249841,-15304328,19958763,-14537274,18559670,-10759549,8402478,-9864273 }, 2847 { -28406330,-1051581,-26790155,-907698,-17212414,-11030789,9453451,-14980072,17983010,9967138 }, 2848 }, 2849 { 2850 { -25762494,6524722,26585488,9969270,24709298,1220360,-1677990,7806337,17507396,3651560 }, 2851 { -10420457,-4118111,14584639,15971087,-15768321,8861010,26556809,-5574557,-18553322,-11357135 }, 2852 { 2839101,14284142,4029895,3472686,14402957,12689363,-26642121,8459447,-5605463,-7621941 }, 2853 }, 2854 { 2855 { -4839289,-3535444,9744961,2871048,25113978,3187018,-25110813,-849066,17258084,-7977739 }, 2856 { 18164541,-10595176,-17154882,-1542417,19237078,-9745295,23357533,-15217008,26908270,12150756 }, 2857 { -30264870,-7647865,5112249,-7036672,-1499807,-6974257,43168,-5537701,-32302074,16215819 }, 2858 }, 2859 }, 2860 { 2861 { 2862 { -6898905,9824394,-12304779,-4401089,-31397141,-6276835,32574489,12532905,-7503072,-8675347 }, 2863 { -27343522,-16515468,-27151524,-10722951,946346,16291093,254968,7168080,21676107,-1943028 }, 2864 { 21260961,-8424752,-16831886,-11920822,-23677961,3968121,-3651949,-6215466,-3556191,-7913075 }, 2865 }, 2866 { 2867 { 16544754,13250366,-16804428,15546242,-4583003,12757258,-2462308,-8680336,-18907032,-9662799 }, 2868 { -2415239,-15577728,18312303,4964443,-15272530,-12653564,26820651,16690659,25459437,-4564609 }, 2869 { -25144690,11425020,28423002,-11020557,-6144921,-15826224,9142795,-2391602,-6432418,-1644817 }, 2870 }, 2871 { 2872 { -23104652,6253476,16964147,-3768872,-25113972,-12296437,-27457225,-16344658,6335692,7249989 }, 2873 { -30333227,13979675,7503222,-12368314,-11956721,-4621693,-30272269,2682242,25993170,-12478523 }, 2874 { 4364628,5930691,32304656,-10044554,-8054781,15091131,22857016,-10598955,31820368,15075278 }, 2875 }, 2876 { 2877 { 31879134,-8918693,17258761,90626,-8041836,-4917709,24162788,-9650886,-17970238,12833045 }, 2878 { 19073683,14851414,-24403169,-11860168,7625278,11091125,-19619190,2074449,-9413939,14905377 }, 2879 { 24483667,-11935567,-2518866,-11547418,-1553130,15355506,-25282080,9253129,27628530,-7555480 }, 2880 }, 2881 { 2882 { 17597607,8340603,19355617,552187,26198470,-3176583,4593324,-9157582,-14110875,15297016 }, 2883 { 510886,14337390,-31785257,16638632,6328095,2713355,-20217417,-11864220,8683221,2921426 }, 2884 { 18606791,11874196,27155355,-5281482,-24031742,6265446,-25178240,-1278924,4674690,13890525 }, 2885 }, 2886 { 2887 { 13609624,13069022,-27372361,-13055908,24360586,9592974,14977157,9835105,4389687,288396 }, 2888 { 9922506,-519394,13613107,5883594,-18758345,-434263,-12304062,8317628,23388070,16052080 }, 2889 { 12720016,11937594,-31970060,-5028689,26900120,8561328,-20155687,-11632979,-14754271,-10812892 }, 2890 }, 2891 { 2892 { 15961858,14150409,26716931,-665832,-22794328,13603569,11829573,7467844,-28822128,929275 }, 2893 { 11038231,-11582396,-27310482,-7316562,-10498527,-16307831,-23479533,-9371869,-21393143,2465074 }, 2894 { 20017163,-4323226,27915242,1529148,12396362,15675764,13817261,-9658066,2463391,-4622140 }, 2895 }, 2896 { 2897 { -16358878,-12663911,-12065183,4996454,-1256422,1073572,9583558,12851107,4003896,12673717 }, 2898 { -1731589,-15155870,-3262930,16143082,19294135,13385325,14741514,-9103726,7903886,2348101 }, 2899 { 24536016,-16515207,12715592,-3862155,1511293,10047386,-3842346,-7129159,-28377538,10048127 }, 2900 }, 2901 }, 2902 { 2903 { 2904 { -12622226,-6204820,30718825,2591312,-10617028,12192840,18873298,-7297090,-32297756,15221632 }, 2905 { -26478122,-11103864,11546244,-1852483,9180880,7656409,-21343950,2095755,29769758,6593415 }, 2906 { -31994208,-2907461,4176912,3264766,12538965,-868111,26312345,-6118678,30958054,8292160 }, 2907 }, 2908 { 2909 { 31429822,-13959116,29173532,15632448,12174511,-2760094,32808831,3977186,26143136,-3148876 }, 2910 { 22648901,1402143,-22799984,13746059,7936347,365344,-8668633,-1674433,-3758243,-2304625 }, 2911 { -15491917,8012313,-2514730,-12702462,-23965846,-10254029,-1612713,-1535569,-16664475,8194478 }, 2912 }, 2913 { 2914 { 27338066,-7507420,-7414224,10140405,-19026427,-6589889,27277191,8855376,28572286,3005164 }, 2915 { 26287124,4821776,25476601,-4145903,-3764513,-15788984,-18008582,1182479,-26094821,-13079595 }, 2916 { -7171154,3178080,23970071,6201893,-17195577,-4489192,-21876275,-13982627,32208683,-1198248 }, 2917 }, 2918 { 2919 { -16657702,2817643,-10286362,14811298,6024667,13349505,-27315504,-10497842,-27672585,-11539858 }, 2920 { 15941029,-9405932,-21367050,8062055,31876073,-238629,-15278393,-1444429,15397331,-4130193 }, 2921 { 8934485,-13485467,-23286397,-13423241,-32446090,14047986,31170398,-1441021,-27505566,15087184 }, 2922 }, 2923 { 2924 { -18357243,-2156491,24524913,-16677868,15520427,-6360776,-15502406,11461896,16788528,-5868942 }, 2925 { -1947386,16013773,21750665,3714552,-17401782,-16055433,-3770287,-10323320,31322514,-11615635 }, 2926 { 21426655,-5650218,-13648287,-5347537,-28812189,-4920970,-18275391,-14621414,13040862,-12112948 }, 2927 }, 2928 { 2929 { 11293895,12478086,-27136401,15083750,-29307421,14748872,14555558,-13417103,1613711,4896935 }, 2930 { -25894883,15323294,-8489791,-8057900,25967126,-13425460,2825960,-4897045,-23971776,-11267415 }, 2931 { -15924766,-5229880,-17443532,6410664,3622847,10243618,20615400,12405433,-23753030,-8436416 }, 2932 }, 2933 { 2934 { -7091295,12556208,-20191352,9025187,-17072479,4333801,4378436,2432030,23097949,-566018 }, 2935 { 4565804,-16025654,20084412,-7842817,1724999,189254,24767264,10103221,-18512313,2424778 }, 2936 { 366633,-11976806,8173090,-6890119,30788634,5745705,-7168678,1344109,-3642553,12412659 }, 2937 }, 2938 { 2939 { -24001791,7690286,14929416,-168257,-32210835,-13412986,24162697,-15326504,-3141501,11179385 }, 2940 { 18289522,-14724954,8056945,16430056,-21729724,7842514,-6001441,-1486897,-18684645,-11443503 }, 2941 { 476239,6601091,-6152790,-9723375,17503545,-4863900,27672959,13403813,11052904,5219329 }, 2942 }, 2943 }, 2944 { 2945 { 2946 { 20678546,-8375738,-32671898,8849123,-5009758,14574752,31186971,-3973730,9014762,-8579056 }, 2947 { -13644050,-10350239,-15962508,5075808,-1514661,-11534600,-33102500,9160280,8473550,-3256838 }, 2948 { 24900749,14435722,17209120,-15292541,-22592275,9878983,-7689309,-16335821,-24568481,11788948 }, 2949 }, 2950 { 2951 { -3118155,-11395194,-13802089,14797441,9652448,-6845904,-20037437,10410733,-24568470,-1458691 }, 2952 { -15659161,16736706,-22467150,10215878,-9097177,7563911,11871841,-12505194,-18513325,8464118 }, 2953 { -23400612,8348507,-14585951,-861714,-3950205,-6373419,14325289,8628612,33313881,-8370517 }, 2954 }, 2955 { 2956 { -20186973,-4967935,22367356,5271547,-1097117,-4788838,-24805667,-10236854,-8940735,-5818269 }, 2957 { -6948785,-1795212,-32625683,-16021179,32635414,-7374245,15989197,-12838188,28358192,-4253904 }, 2958 { -23561781,-2799059,-32351682,-1661963,-9147719,10429267,-16637684,4072016,-5351664,5596589 }, 2959 }, 2960 { 2961 { -28236598,-3390048,12312896,6213178,3117142,16078565,29266239,2557221,1768301,15373193 }, 2962 { -7243358,-3246960,-4593467,-7553353,-127927,-912245,-1090902,-4504991,-24660491,3442910 }, 2963 { -30210571,5124043,14181784,8197961,18964734,-11939093,22597931,7176455,-18585478,13365930 }, 2964 }, 2965 { 2966 { -7877390,-1499958,8324673,4690079,6261860,890446,24538107,-8570186,-9689599,-3031667 }, 2967 { 25008904,-10771599,-4305031,-9638010,16265036,15721635,683793,-11823784,15723479,-15163481 }, 2968 { -9660625,12374379,-27006999,-7026148,-7724114,-12314514,11879682,5400171,519526,-1235876 }, 2969 }, 2970 { 2971 { 22258397,-16332233,-7869817,14613016,-22520255,-2950923,-20353881,7315967,16648397,7605640 }, 2972 { -8081308,-8464597,-8223311,9719710,19259459,-15348212,23994942,-5281555,-9468848,4763278 }, 2973 { -21699244,9220969,-15730624,1084137,-25476107,-2852390,31088447,-7764523,-11356529,728112 }, 2974 }, 2975 { 2976 { 26047220,-11751471,-6900323,-16521798,24092068,9158119,-4273545,-12555558,-29365436,-5498272 }, 2977 { 17510331,-322857,5854289,8403524,17133918,-3112612,-28111007,12327945,10750447,10014012 }, 2978 { -10312768,3936952,9156313,-8897683,16498692,-994647,-27481051,-666732,3424691,7540221 }, 2979 }, 2980 { 2981 { 30322361,-6964110,11361005,-4143317,7433304,4989748,-7071422,-16317219,-9244265,15258046 }, 2982 { 13054562,-2779497,19155474,469045,-12482797,4566042,5631406,2711395,1062915,-5136345 }, 2983 { -19240248,-11254599,-29509029,-7499965,-5835763,13005411,-6066489,12194497,32960380,1459310 }, 2984 }, 2985 }, 2986 { 2987 { 2988 { 19852034,7027924,23669353,10020366,8586503,-6657907,394197,-6101885,18638003,-11174937 }, 2989 { 31395534,15098109,26581030,8030562,-16527914,-5007134,9012486,-7584354,-6643087,-5442636 }, 2990 { -9192165,-2347377,-1997099,4529534,25766844,607986,-13222,9677543,-32294889,-6456008 }, 2991 }, 2992 { 2993 { -2444496,-149937,29348902,8186665,1873760,12489863,-30934579,-7839692,-7852844,-8138429 }, 2994 { -15236356,-15433509,7766470,746860,26346930,-10221762,-27333451,10754588,-9431476,5203576 }, 2995 { 31834314,14135496,-770007,5159118,20917671,-16768096,-7467973,-7337524,31809243,7347066 }, 2996 }, 2997 { 2998 { -9606723,-11874240,20414459,13033986,13716524,-11691881,19797970,-12211255,15192876,-2087490 }, 2999 { -12663563,-2181719,1168162,-3804809,26747877,-14138091,10609330,12694420,33473243,-13382104 }, 3000 { 33184999,11180355,15832085,-11385430,-1633671,225884,15089336,-11023903,-6135662,14480053 }, 3001 }, 3002 { 3003 { 31308717,-5619998,31030840,-1897099,15674547,-6582883,5496208,13685227,27595050,8737275 }, 3004 { -20318852,-15150239,10933843,-16178022,8335352,-7546022,-31008351,-12610604,26498114,66511 }, 3005 { 22644454,-8761729,-16671776,4884562,-3105614,-13559366,30540766,-4286747,-13327787,-7515095 }, 3006 }, 3007 { 3008 { -28017847,9834845,18617207,-2681312,-3401956,-13307506,8205540,13585437,-17127465,15115439 }, 3009 { 23711543,-672915,31206561,-8362711,6164647,-9709987,-33535882,-1426096,8236921,16492939 }, 3010 { -23910559,-13515526,-26299483,-4503841,25005590,-7687270,19574902,10071562,6708380,-6222424 }, 3011 }, 3012 { 3013 { 2101391,-4930054,19702731,2367575,-15427167,1047675,5301017,9328700,29955601,-11678310 }, 3014 { 3096359,9271816,-21620864,-15521844,-14847996,-7592937,-25892142,-12635595,-9917575,6216608 }, 3015 { -32615849,338663,-25195611,2510422,-29213566,-13820213,24822830,-6146567,-26767480,7525079 }, 3016 }, 3017 { 3018 { -23066649,-13985623,16133487,-7896178,-3389565,778788,-910336,-2782495,-19386633,11994101 }, 3019 { 21691500,-13624626,-641331,-14367021,3285881,-3483596,-25064666,9718258,-7477437,13381418 }, 3020 { 18445390,-4202236,14979846,11622458,-1727110,-3582980,23111648,-6375247,28535282,15779576 }, 3021 }, 3022 { 3023 { 30098053,3089662,-9234387,16662135,-21306940,11308411,-14068454,12021730,9955285,-16303356 }, 3024 { 9734894,-14576830,-7473633,-9138735,2060392,11313496,-18426029,9924399,20194861,13380996 }, 3025 { -26378102,-7965207,-22167821,15789297,-18055342,-6168792,-1984914,15707771,26342023,10146099 }, 3026 }, 3027 }, 3028 { 3029 { 3030 { -26016874,-219943,21339191,-41388,19745256,-2878700,-29637280,2227040,21612326,-545728 }, 3031 { -13077387,1184228,23562814,-5970442,-20351244,-6348714,25764461,12243797,-20856566,11649658 }, 3032 { -10031494,11262626,27384172,2271902,26947504,-15997771,39944,6114064,33514190,2333242 }, 3033 }, 3034 { 3035 { -21433588,-12421821,8119782,7219913,-21830522,-9016134,-6679750,-12670638,24350578,-13450001 }, 3036 { -4116307,-11271533,-23886186,4843615,-30088339,690623,-31536088,-10406836,8317860,12352766 }, 3037 { 18200138,-14475911,-33087759,-2696619,-23702521,-9102511,-23552096,-2287550,20712163,6719373 }, 3038 }, 3039 { 3040 { 26656208,6075253,-7858556,1886072,-28344043,4262326,11117530,-3763210,26224235,-3297458 }, 3041 { -17168938,-14854097,-3395676,-16369877,-19954045,14050420,21728352,9493610,18620611,-16428628 }, 3042 { -13323321,13325349,11432106,5964811,18609221,6062965,-5269471,-9725556,-30701573,-16479657 }, 3043 }, 3044 { 3045 { -23860538,-11233159,26961357,1640861,-32413112,-16737940,12248509,-5240639,13735342,1934062 }, 3046 { 25089769,6742589,17081145,-13406266,21909293,-16067981,-15136294,-3765346,-21277997,5473616 }, 3047 { 31883677,-7961101,1083432,-11572403,22828471,13290673,-7125085,12469656,29111212,-5451014 }, 3048 }, 3049 { 3050 { 24244947,-15050407,-26262976,2791540,-14997599,16666678,24367466,6388839,-10295587,452383 }, 3051 { -25640782,-3417841,5217916,16224624,19987036,-4082269,-24236251,-5915248,15766062,8407814 }, 3052 { -20406999,13990231,15495425,16395525,5377168,15166495,-8917023,-4388953,-8067909,2276718 }, 3053 }, 3054 { 3055 { 30157918,12924066,-17712050,9245753,19895028,3368142,-23827587,5096219,22740376,-7303417 }, 3056 { 2041139,-14256350,7783687,13876377,-25946985,-13352459,24051124,13742383,-15637599,13295222 }, 3057 { 33338237,-8505733,12532113,7977527,9106186,-1715251,-17720195,-4612972,-4451357,-14669444 }, 3058 }, 3059 { 3060 { -20045281,5454097,-14346548,6447146,28862071,1883651,-2469266,-4141880,7770569,9620597 }, 3061 { 23208068,7979712,33071466,8149229,1758231,-10834995,30945528,-1694323,-33502340,-14767970 }, 3062 { 1439958,-16270480,-1079989,-793782,4625402,10647766,-5043801,1220118,30494170,-11440799 }, 3063 }, 3064 { 3065 { -5037580,-13028295,-2970559,-3061767,15640974,-6701666,-26739026,926050,-1684339,-13333647 }, 3066 { 13908495,-3549272,30919928,-6273825,-21521863,7989039,9021034,9078865,3353509,4033511 }, 3067 { -29663431,-15113610,32259991,-344482,24295849,-12912123,23161163,8839127,27485041,7356032 }, 3068 }, 3069 }, 3070 { 3071 { 3072 { 9661027,705443,11980065,-5370154,-1628543,14661173,-6346142,2625015,28431036,-16771834 }, 3073 { -23839233,-8311415,-25945511,7480958,-17681669,-8354183,-22545972,14150565,15970762,4099461 }, 3074 { 29262576,16756590,26350592,-8793563,8529671,-11208050,13617293,-9937143,11465739,8317062 }, 3075 }, 3076 { 3077 { -25493081,-6962928,32500200,-9419051,-23038724,-2302222,14898637,3848455,20969334,-5157516 }, 3078 { -20384450,-14347713,-18336405,13884722,-33039454,2842114,-21610826,-3649888,11177095,14989547 }, 3079 { -24496721,-11716016,16959896,2278463,12066309,10137771,13515641,2581286,-28487508,9930240 }, 3080 }, 3081 { 3082 { -17751622,-2097826,16544300,-13009300,-15914807,-14949081,18345767,-13403753,16291481,-5314038 }, 3083 { -33229194,2553288,32678213,9875984,8534129,6889387,-9676774,6957617,4368891,9788741 }, 3084 { 16660756,7281060,-10830758,12911820,20108584,-8101676,-21722536,-8613148,16250552,-11111103 }, 3085 }, 3086 { 3087 { -19765507,2390526,-16551031,14161980,1905286,6414907,4689584,10604807,-30190403,4782747 }, 3088 { -1354539,14736941,-7367442,-13292886,7710542,-14155590,-9981571,4383045,22546403,437323 }, 3089 { 31665577,-12180464,-16186830,1491339,-18368625,3294682,27343084,2786261,-30633590,-14097016 }, 3090 }, 3091 { 3092 { -14467279,-683715,-33374107,7448552,19294360,14334329,-19690631,2355319,-19284671,-6114373 }, 3093 { 15121312,-15796162,6377020,-6031361,-10798111,-12957845,18952177,15496498,-29380133,11754228 }, 3094 { -2637277,-13483075,8488727,-14303896,12728761,-1622493,7141596,11724556,22761615,-10134141 }, 3095 }, 3096 { 3097 { 16918416,11729663,-18083579,3022987,-31015732,-13339659,-28741185,-12227393,32851222,11717399 }, 3098 { 11166634,7338049,-6722523,4531520,-29468672,-7302055,31474879,3483633,-1193175,-4030831 }, 3099 { -185635,9921305,31456609,-13536438,-12013818,13348923,33142652,6546660,-19985279,-3948376 }, 3100 }, 3101 { 3102 { -32460596,11266712,-11197107,-7899103,31703694,3855903,-8537131,-12833048,-30772034,-15486313 }, 3103 { -18006477,12709068,3991746,-6479188,-21491523,-10550425,-31135347,-16049879,10928917,3011958 }, 3104 { -6957757,-15594337,31696059,334240,29576716,14796075,-30831056,-12805180,18008031,10258577 }, 3105 }, 3106 { 3107 { -22448644,15655569,7018479,-4410003,-30314266,-1201591,-1853465,1367120,25127874,6671743 }, 3108 { 29701166,-14373934,-10878120,9279288,-17568,13127210,21382910,11042292,25838796,4642684 }, 3109 { -20430234,14955537,-24126347,8124619,-5369288,-5990470,30468147,-13900640,18423289,4177476 }, 3110 }, 3111 }, 3112 } ; 3113 3114 static void ge_p2_0(ge_p2 *h) 3115 { 3116 fe_0(h->X); 3117 fe_1(h->Y); 3118 fe_1(h->Z); 3119 } 3120 3121 static void ge_p3_0(ge_p3 *h) 3122 { 3123 fe_0(h->X); 3124 fe_1(h->Y); 3125 fe_1(h->Z); 3126 fe_0(h->T); 3127 } 3128 3129 static void ge_precomp_0(ge_precomp *h) 3130 { 3131 fe_1(h->yplusx); 3132 fe_1(h->yminusx); 3133 fe_0(h->xy2d); 3134 } 3135 3136 /* 3137 r = p 3138 */ 3139 3140 static void ge_p1p1_to_p2(ge_p2 *r,const ge_p1p1 *p) 3141 { 3142 fe_mul(r->X,p->X,p->T); 3143 fe_mul(r->Y,p->Y,p->Z); 3144 fe_mul(r->Z,p->Z,p->T); 3145 } 3146 3147 /* 3148 r = p 3149 */ 3150 3151 static void ge_p1p1_to_p3(ge_p3 *r,const ge_p1p1 *p) 3152 { 3153 fe_mul(r->X,p->X,p->T); 3154 fe_mul(r->Y,p->Y,p->Z); 3155 fe_mul(r->Z,p->Z,p->T); 3156 fe_mul(r->T,p->X,p->Y); 3157 } 3158 3159 /* 3160 r = p 3161 */ 3162 3163 static void ge_p3_to_p2(ge_p2 *r,const ge_p3 *p) 3164 { 3165 fe_copy(r->X,p->X); 3166 fe_copy(r->Y,p->Y); 3167 fe_copy(r->Z,p->Z); 3168 } 3169 3170 3171 /* 3172 r = 2 * p 3173 */ 3174 3175 static void ge_p2_dbl(ge_p1p1 *r,const ge_p2 *p) 3176 { 3177 fe t0; 3178 /* qhasm: enter ge_p2_dbl */ 3179 3180 /* qhasm: fe X1 */ 3181 3182 /* qhasm: fe Y1 */ 3183 3184 /* qhasm: fe Z1 */ 3185 3186 /* qhasm: fe A */ 3187 3188 /* qhasm: fe AA */ 3189 3190 /* qhasm: fe XX */ 3191 3192 /* qhasm: fe YY */ 3193 3194 /* qhasm: fe B */ 3195 3196 /* qhasm: fe X3 */ 3197 3198 /* qhasm: fe Y3 */ 3199 3200 /* qhasm: fe Z3 */ 3201 3202 /* qhasm: fe T3 */ 3203 3204 /* qhasm: XX=X1^2 */ 3205 /* asm 1: fe_sq(>XX=fe#1,<X1=fe#11); */ 3206 /* asm 2: fe_sq(>XX=r->X,<X1=p->X); */ 3207 fe_sq(r->X,p->X); 3208 3209 /* qhasm: YY=Y1^2 */ 3210 /* asm 1: fe_sq(>YY=fe#3,<Y1=fe#12); */ 3211 /* asm 2: fe_sq(>YY=r->Z,<Y1=p->Y); */ 3212 fe_sq(r->Z,p->Y); 3213 3214 /* qhasm: B=2*Z1^2 */ 3215 /* asm 1: fe_sq2(>B=fe#4,<Z1=fe#13); */ 3216 /* asm 2: fe_sq2(>B=r->T,<Z1=p->Z); */ 3217 fe_sq2(r->T,p->Z); 3218 3219 /* qhasm: A=X1+Y1 */ 3220 /* asm 1: fe_add(>A=fe#2,<X1=fe#11,<Y1=fe#12); */ 3221 /* asm 2: fe_add(>A=r->Y,<X1=p->X,<Y1=p->Y); */ 3222 fe_add(r->Y,p->X,p->Y); 3223 3224 /* qhasm: AA=A^2 */ 3225 /* asm 1: fe_sq(>AA=fe#5,<A=fe#2); */ 3226 /* asm 2: fe_sq(>AA=t0,<A=r->Y); */ 3227 fe_sq(t0,r->Y); 3228 3229 /* qhasm: Y3=YY+XX */ 3230 /* asm 1: fe_add(>Y3=fe#2,<YY=fe#3,<XX=fe#1); */ 3231 /* asm 2: fe_add(>Y3=r->Y,<YY=r->Z,<XX=r->X); */ 3232 fe_add(r->Y,r->Z,r->X); 3233 3234 /* qhasm: Z3=YY-XX */ 3235 /* asm 1: fe_sub(>Z3=fe#3,<YY=fe#3,<XX=fe#1); */ 3236 /* asm 2: fe_sub(>Z3=r->Z,<YY=r->Z,<XX=r->X); */ 3237 fe_sub(r->Z,r->Z,r->X); 3238 3239 /* qhasm: X3=AA-Y3 */ 3240 /* asm 1: fe_sub(>X3=fe#1,<AA=fe#5,<Y3=fe#2); */ 3241 /* asm 2: fe_sub(>X3=r->X,<AA=t0,<Y3=r->Y); */ 3242 fe_sub(r->X,t0,r->Y); 3243 3244 /* qhasm: T3=B-Z3 */ 3245 /* asm 1: fe_sub(>T3=fe#4,<B=fe#4,<Z3=fe#3); */ 3246 /* asm 2: fe_sub(>T3=r->T,<B=r->T,<Z3=r->Z); */ 3247 fe_sub(r->T,r->T,r->Z); 3248 3249 /* qhasm: return */ 3250 } 3251 3252 3253 /* 3254 r = 2 * p 3255 */ 3256 3257 static void ge_p3_dbl(ge_p1p1 *r,const ge_p3 *p) 3258 { 3259 ge_p2 q; 3260 ge_p3_to_p2(&q,p); 3261 ge_p2_dbl(r,&q); 3262 } 3263 3264 3265 /* 3266 r = p 3267 */ 3268 3269 static void ge_p3_to_cached(ge_cached *r,const ge_p3 *p) 3270 { 3271 fe_add(r->YplusX,p->Y,p->X); 3272 fe_sub(r->YminusX,p->Y,p->X); 3273 fe_copy(r->Z,p->Z); 3274 fe_mul(r->T2d,p->T,d2); 3275 } 3276 3277 /* 3278 r = p + q 3279 */ 3280 3281 static void ge_add(ge_p1p1 *r,const ge_p3 *p,const ge_cached *q) 3282 { 3283 fe t0; 3284 /* qhasm: enter ge_add */ 3285 3286 /* qhasm: fe X1 */ 3287 3288 /* qhasm: fe Y1 */ 3289 3290 /* qhasm: fe Z1 */ 3291 3292 /* qhasm: fe Z2 */ 3293 3294 /* qhasm: fe T1 */ 3295 3296 /* qhasm: fe ZZ */ 3297 3298 /* qhasm: fe YpX2 */ 3299 3300 /* qhasm: fe YmX2 */ 3301 3302 /* qhasm: fe T2d2 */ 3303 3304 /* qhasm: fe X3 */ 3305 3306 /* qhasm: fe Y3 */ 3307 3308 /* qhasm: fe Z3 */ 3309 3310 /* qhasm: fe T3 */ 3311 3312 /* qhasm: fe YpX1 */ 3313 3314 /* qhasm: fe YmX1 */ 3315 3316 /* qhasm: fe A */ 3317 3318 /* qhasm: fe B */ 3319 3320 /* qhasm: fe C */ 3321 3322 /* qhasm: fe D */ 3323 3324 /* qhasm: YpX1 = Y1+X1 */ 3325 /* asm 1: fe_add(>YpX1=fe#1,<Y1=fe#12,<X1=fe#11); */ 3326 /* asm 2: fe_add(>YpX1=r->X,<Y1=p->Y,<X1=p->X); */ 3327 fe_add(r->X,p->Y,p->X); 3328 3329 /* qhasm: YmX1 = Y1-X1 */ 3330 /* asm 1: fe_sub(>YmX1=fe#2,<Y1=fe#12,<X1=fe#11); */ 3331 /* asm 2: fe_sub(>YmX1=r->Y,<Y1=p->Y,<X1=p->X); */ 3332 fe_sub(r->Y,p->Y,p->X); 3333 3334 /* qhasm: A = YpX1*YpX2 */ 3335 /* asm 1: fe_mul(>A=fe#3,<YpX1=fe#1,<YpX2=fe#15); */ 3336 /* asm 2: fe_mul(>A=r->Z,<YpX1=r->X,<YpX2=q->YplusX); */ 3337 fe_mul(r->Z,r->X,q->YplusX); 3338 3339 /* qhasm: B = YmX1*YmX2 */ 3340 /* asm 1: fe_mul(>B=fe#2,<YmX1=fe#2,<YmX2=fe#16); */ 3341 /* asm 2: fe_mul(>B=r->Y,<YmX1=r->Y,<YmX2=q->YminusX); */ 3342 fe_mul(r->Y,r->Y,q->YminusX); 3343 3344 /* qhasm: C = T2d2*T1 */ 3345 /* asm 1: fe_mul(>C=fe#4,<T2d2=fe#18,<T1=fe#14); */ 3346 /* asm 2: fe_mul(>C=r->T,<T2d2=q->T2d,<T1=p->T); */ 3347 fe_mul(r->T,q->T2d,p->T); 3348 3349 /* qhasm: ZZ = Z1*Z2 */ 3350 /* asm 1: fe_mul(>ZZ=fe#1,<Z1=fe#13,<Z2=fe#17); */ 3351 /* asm 2: fe_mul(>ZZ=r->X,<Z1=p->Z,<Z2=q->Z); */ 3352 fe_mul(r->X,p->Z,q->Z); 3353 3354 /* qhasm: D = 2*ZZ */ 3355 /* asm 1: fe_add(>D=fe#5,<ZZ=fe#1,<ZZ=fe#1); */ 3356 /* asm 2: fe_add(>D=t0,<ZZ=r->X,<ZZ=r->X); */ 3357 fe_add(t0,r->X,r->X); 3358 3359 /* qhasm: X3 = A-B */ 3360 /* asm 1: fe_sub(>X3=fe#1,<A=fe#3,<B=fe#2); */ 3361 /* asm 2: fe_sub(>X3=r->X,<A=r->Z,<B=r->Y); */ 3362 fe_sub(r->X,r->Z,r->Y); 3363 3364 /* qhasm: Y3 = A+B */ 3365 /* asm 1: fe_add(>Y3=fe#2,<A=fe#3,<B=fe#2); */ 3366 /* asm 2: fe_add(>Y3=r->Y,<A=r->Z,<B=r->Y); */ 3367 fe_add(r->Y,r->Z,r->Y); 3368 3369 /* qhasm: Z3 = D+C */ 3370 /* asm 1: fe_add(>Z3=fe#3,<D=fe#5,<C=fe#4); */ 3371 /* asm 2: fe_add(>Z3=r->Z,<D=t0,<C=r->T); */ 3372 fe_add(r->Z,t0,r->T); 3373 3374 /* qhasm: T3 = D-C */ 3375 /* asm 1: fe_sub(>T3=fe#4,<D=fe#5,<C=fe#4); */ 3376 /* asm 2: fe_sub(>T3=r->T,<D=t0,<C=r->T); */ 3377 fe_sub(r->T,t0,r->T); 3378 3379 /* qhasm: return */ 3380 } 3381 3382 3383 /* 3384 r = p - q 3385 */ 3386 3387 static void ge_sub(ge_p1p1 *r,const ge_p3 *p,const ge_cached *q) 3388 { 3389 fe t0; 3390 /* qhasm: enter ge_sub */ 3391 3392 /* qhasm: fe X1 */ 3393 3394 /* qhasm: fe Y1 */ 3395 3396 /* qhasm: fe Z1 */ 3397 3398 /* qhasm: fe Z2 */ 3399 3400 /* qhasm: fe T1 */ 3401 3402 /* qhasm: fe ZZ */ 3403 3404 /* qhasm: fe YpX2 */ 3405 3406 /* qhasm: fe YmX2 */ 3407 3408 /* qhasm: fe T2d2 */ 3409 3410 /* qhasm: fe X3 */ 3411 3412 /* qhasm: fe Y3 */ 3413 3414 /* qhasm: fe Z3 */ 3415 3416 /* qhasm: fe T3 */ 3417 3418 /* qhasm: fe YpX1 */ 3419 3420 /* qhasm: fe YmX1 */ 3421 3422 /* qhasm: fe A */ 3423 3424 /* qhasm: fe B */ 3425 3426 /* qhasm: fe C */ 3427 3428 /* qhasm: fe D */ 3429 3430 /* qhasm: YpX1 = Y1+X1 */ 3431 /* asm 1: fe_add(>YpX1=fe#1,<Y1=fe#12,<X1=fe#11); */ 3432 /* asm 2: fe_add(>YpX1=r->X,<Y1=p->Y,<X1=p->X); */ 3433 fe_add(r->X,p->Y,p->X); 3434 3435 /* qhasm: YmX1 = Y1-X1 */ 3436 /* asm 1: fe_sub(>YmX1=fe#2,<Y1=fe#12,<X1=fe#11); */ 3437 /* asm 2: fe_sub(>YmX1=r->Y,<Y1=p->Y,<X1=p->X); */ 3438 fe_sub(r->Y,p->Y,p->X); 3439 3440 /* qhasm: A = YpX1*YmX2 */ 3441 /* asm 1: fe_mul(>A=fe#3,<YpX1=fe#1,<YmX2=fe#16); */ 3442 /* asm 2: fe_mul(>A=r->Z,<YpX1=r->X,<YmX2=q->YminusX); */ 3443 fe_mul(r->Z,r->X,q->YminusX); 3444 3445 /* qhasm: B = YmX1*YpX2 */ 3446 /* asm 1: fe_mul(>B=fe#2,<YmX1=fe#2,<YpX2=fe#15); */ 3447 /* asm 2: fe_mul(>B=r->Y,<YmX1=r->Y,<YpX2=q->YplusX); */ 3448 fe_mul(r->Y,r->Y,q->YplusX); 3449 3450 /* qhasm: C = T2d2*T1 */ 3451 /* asm 1: fe_mul(>C=fe#4,<T2d2=fe#18,<T1=fe#14); */ 3452 /* asm 2: fe_mul(>C=r->T,<T2d2=q->T2d,<T1=p->T); */ 3453 fe_mul(r->T,q->T2d,p->T); 3454 3455 /* qhasm: ZZ = Z1*Z2 */ 3456 /* asm 1: fe_mul(>ZZ=fe#1,<Z1=fe#13,<Z2=fe#17); */ 3457 /* asm 2: fe_mul(>ZZ=r->X,<Z1=p->Z,<Z2=q->Z); */ 3458 fe_mul(r->X,p->Z,q->Z); 3459 3460 /* qhasm: D = 2*ZZ */ 3461 /* asm 1: fe_add(>D=fe#5,<ZZ=fe#1,<ZZ=fe#1); */ 3462 /* asm 2: fe_add(>D=t0,<ZZ=r->X,<ZZ=r->X); */ 3463 fe_add(t0,r->X,r->X); 3464 3465 /* qhasm: X3 = A-B */ 3466 /* asm 1: fe_sub(>X3=fe#1,<A=fe#3,<B=fe#2); */ 3467 /* asm 2: fe_sub(>X3=r->X,<A=r->Z,<B=r->Y); */ 3468 fe_sub(r->X,r->Z,r->Y); 3469 3470 /* qhasm: Y3 = A+B */ 3471 /* asm 1: fe_add(>Y3=fe#2,<A=fe#3,<B=fe#2); */ 3472 /* asm 2: fe_add(>Y3=r->Y,<A=r->Z,<B=r->Y); */ 3473 fe_add(r->Y,r->Z,r->Y); 3474 3475 /* qhasm: Z3 = D-C */ 3476 /* asm 1: fe_sub(>Z3=fe#3,<D=fe#5,<C=fe#4); */ 3477 /* asm 2: fe_sub(>Z3=r->Z,<D=t0,<C=r->T); */ 3478 fe_sub(r->Z,t0,r->T); 3479 3480 /* qhasm: T3 = D+C */ 3481 /* asm 1: fe_add(>T3=fe#4,<D=fe#5,<C=fe#4); */ 3482 /* asm 2: fe_add(>T3=r->T,<D=t0,<C=r->T); */ 3483 fe_add(r->T,t0,r->T); 3484 3485 /* qhasm: return */ 3486 } 3487 3488 3489 /* 3490 r = p + q 3491 */ 3492 3493 static void ge_madd(ge_p1p1 *r,const ge_p3 *p,const ge_precomp *q) 3494 { 3495 fe t0; 3496 /* qhasm: enter ge_madd */ 3497 3498 /* qhasm: fe X1 */ 3499 3500 /* qhasm: fe Y1 */ 3501 3502 /* qhasm: fe Z1 */ 3503 3504 /* qhasm: fe T1 */ 3505 3506 /* qhasm: fe ypx2 */ 3507 3508 /* qhasm: fe ymx2 */ 3509 3510 /* qhasm: fe xy2d2 */ 3511 3512 /* qhasm: fe X3 */ 3513 3514 /* qhasm: fe Y3 */ 3515 3516 /* qhasm: fe Z3 */ 3517 3518 /* qhasm: fe T3 */ 3519 3520 /* qhasm: fe YpX1 */ 3521 3522 /* qhasm: fe YmX1 */ 3523 3524 /* qhasm: fe A */ 3525 3526 /* qhasm: fe B */ 3527 3528 /* qhasm: fe C */ 3529 3530 /* qhasm: fe D */ 3531 3532 /* qhasm: YpX1 = Y1+X1 */ 3533 /* asm 1: fe_add(>YpX1=fe#1,<Y1=fe#12,<X1=fe#11); */ 3534 /* asm 2: fe_add(>YpX1=r->X,<Y1=p->Y,<X1=p->X); */ 3535 fe_add(r->X,p->Y,p->X); 3536 3537 /* qhasm: YmX1 = Y1-X1 */ 3538 /* asm 1: fe_sub(>YmX1=fe#2,<Y1=fe#12,<X1=fe#11); */ 3539 /* asm 2: fe_sub(>YmX1=r->Y,<Y1=p->Y,<X1=p->X); */ 3540 fe_sub(r->Y,p->Y,p->X); 3541 3542 /* qhasm: A = YpX1*ypx2 */ 3543 /* asm 1: fe_mul(>A=fe#3,<YpX1=fe#1,<ypx2=fe#15); */ 3544 /* asm 2: fe_mul(>A=r->Z,<YpX1=r->X,<ypx2=q->yplusx); */ 3545 fe_mul(r->Z,r->X,q->yplusx); 3546 3547 /* qhasm: B = YmX1*ymx2 */ 3548 /* asm 1: fe_mul(>B=fe#2,<YmX1=fe#2,<ymx2=fe#16); */ 3549 /* asm 2: fe_mul(>B=r->Y,<YmX1=r->Y,<ymx2=q->yminusx); */ 3550 fe_mul(r->Y,r->Y,q->yminusx); 3551 3552 /* qhasm: C = xy2d2*T1 */ 3553 /* asm 1: fe_mul(>C=fe#4,<xy2d2=fe#17,<T1=fe#14); */ 3554 /* asm 2: fe_mul(>C=r->T,<xy2d2=q->xy2d,<T1=p->T); */ 3555 fe_mul(r->T,q->xy2d,p->T); 3556 3557 /* qhasm: D = 2*Z1 */ 3558 /* asm 1: fe_add(>D=fe#5,<Z1=fe#13,<Z1=fe#13); */ 3559 /* asm 2: fe_add(>D=t0,<Z1=p->Z,<Z1=p->Z); */ 3560 fe_add(t0,p->Z,p->Z); 3561 3562 /* qhasm: X3 = A-B */ 3563 /* asm 1: fe_sub(>X3=fe#1,<A=fe#3,<B=fe#2); */ 3564 /* asm 2: fe_sub(>X3=r->X,<A=r->Z,<B=r->Y); */ 3565 fe_sub(r->X,r->Z,r->Y); 3566 3567 /* qhasm: Y3 = A+B */ 3568 /* asm 1: fe_add(>Y3=fe#2,<A=fe#3,<B=fe#2); */ 3569 /* asm 2: fe_add(>Y3=r->Y,<A=r->Z,<B=r->Y); */ 3570 fe_add(r->Y,r->Z,r->Y); 3571 3572 /* qhasm: Z3 = D+C */ 3573 /* asm 1: fe_add(>Z3=fe#3,<D=fe#5,<C=fe#4); */ 3574 /* asm 2: fe_add(>Z3=r->Z,<D=t0,<C=r->T); */ 3575 fe_add(r->Z,t0,r->T); 3576 3577 /* qhasm: T3 = D-C */ 3578 /* asm 1: fe_sub(>T3=fe#4,<D=fe#5,<C=fe#4); */ 3579 /* asm 2: fe_sub(>T3=r->T,<D=t0,<C=r->T); */ 3580 fe_sub(r->T,t0,r->T); 3581 3582 /* qhasm: return */ 3583 } 3584 3585 3586 /* 3587 r = p - q 3588 */ 3589 3590 static void ge_msub(ge_p1p1 *r,const ge_p3 *p,const ge_precomp *q) 3591 { 3592 fe t0; 3593 /* qhasm: enter ge_msub */ 3594 3595 /* qhasm: fe X1 */ 3596 3597 /* qhasm: fe Y1 */ 3598 3599 /* qhasm: fe Z1 */ 3600 3601 /* qhasm: fe T1 */ 3602 3603 /* qhasm: fe ypx2 */ 3604 3605 /* qhasm: fe ymx2 */ 3606 3607 /* qhasm: fe xy2d2 */ 3608 3609 /* qhasm: fe X3 */ 3610 3611 /* qhasm: fe Y3 */ 3612 3613 /* qhasm: fe Z3 */ 3614 3615 /* qhasm: fe T3 */ 3616 3617 /* qhasm: fe YpX1 */ 3618 3619 /* qhasm: fe YmX1 */ 3620 3621 /* qhasm: fe A */ 3622 3623 /* qhasm: fe B */ 3624 3625 /* qhasm: fe C */ 3626 3627 /* qhasm: fe D */ 3628 3629 /* qhasm: YpX1 = Y1+X1 */ 3630 /* asm 1: fe_add(>YpX1=fe#1,<Y1=fe#12,<X1=fe#11); */ 3631 /* asm 2: fe_add(>YpX1=r->X,<Y1=p->Y,<X1=p->X); */ 3632 fe_add(r->X,p->Y,p->X); 3633 3634 /* qhasm: YmX1 = Y1-X1 */ 3635 /* asm 1: fe_sub(>YmX1=fe#2,<Y1=fe#12,<X1=fe#11); */ 3636 /* asm 2: fe_sub(>YmX1=r->Y,<Y1=p->Y,<X1=p->X); */ 3637 fe_sub(r->Y,p->Y,p->X); 3638 3639 /* qhasm: A = YpX1*ymx2 */ 3640 /* asm 1: fe_mul(>A=fe#3,<YpX1=fe#1,<ymx2=fe#16); */ 3641 /* asm 2: fe_mul(>A=r->Z,<YpX1=r->X,<ymx2=q->yminusx); */ 3642 fe_mul(r->Z,r->X,q->yminusx); 3643 3644 /* qhasm: B = YmX1*ypx2 */ 3645 /* asm 1: fe_mul(>B=fe#2,<YmX1=fe#2,<ypx2=fe#15); */ 3646 /* asm 2: fe_mul(>B=r->Y,<YmX1=r->Y,<ypx2=q->yplusx); */ 3647 fe_mul(r->Y,r->Y,q->yplusx); 3648 3649 /* qhasm: C = xy2d2*T1 */ 3650 /* asm 1: fe_mul(>C=fe#4,<xy2d2=fe#17,<T1=fe#14); */ 3651 /* asm 2: fe_mul(>C=r->T,<xy2d2=q->xy2d,<T1=p->T); */ 3652 fe_mul(r->T,q->xy2d,p->T); 3653 3654 /* qhasm: D = 2*Z1 */ 3655 /* asm 1: fe_add(>D=fe#5,<Z1=fe#13,<Z1=fe#13); */ 3656 /* asm 2: fe_add(>D=t0,<Z1=p->Z,<Z1=p->Z); */ 3657 fe_add(t0,p->Z,p->Z); 3658 3659 /* qhasm: X3 = A-B */ 3660 /* asm 1: fe_sub(>X3=fe#1,<A=fe#3,<B=fe#2); */ 3661 /* asm 2: fe_sub(>X3=r->X,<A=r->Z,<B=r->Y); */ 3662 fe_sub(r->X,r->Z,r->Y); 3663 3664 /* qhasm: Y3 = A+B */ 3665 /* asm 1: fe_add(>Y3=fe#2,<A=fe#3,<B=fe#2); */ 3666 /* asm 2: fe_add(>Y3=r->Y,<A=r->Z,<B=r->Y); */ 3667 fe_add(r->Y,r->Z,r->Y); 3668 3669 /* qhasm: Z3 = D-C */ 3670 /* asm 1: fe_sub(>Z3=fe#3,<D=fe#5,<C=fe#4); */ 3671 /* asm 2: fe_sub(>Z3=r->Z,<D=t0,<C=r->T); */ 3672 fe_sub(r->Z,t0,r->T); 3673 3674 /* qhasm: T3 = D+C */ 3675 /* asm 1: fe_add(>T3=fe#4,<D=fe#5,<C=fe#4); */ 3676 /* asm 2: fe_add(>T3=r->T,<D=t0,<C=r->T); */ 3677 fe_add(r->T,t0,r->T); 3678 3679 /* qhasm: return */ 3680 } 3681 3682 3683 static void ge_p3_tobytes(unsigned char *s,const ge_p3 *h) 3684 { 3685 fe recip; 3686 fe x; 3687 fe y; 3688 3689 fe_invert(recip,h->Z); 3690 fe_mul(x,h->X,recip); 3691 fe_mul(y,h->Y,recip); 3692 fe_tobytes(s,y); 3693 s[31] ^= fe_isnegative(x) << 7; 3694 } 3695 3696 static void ge_tobytes(unsigned char *s,const ge_p2 *h) 3697 { 3698 fe recip; 3699 fe x; 3700 fe y; 3701 3702 fe_invert(recip,h->Z); 3703 fe_mul(x,h->X,recip); 3704 fe_mul(y,h->Y,recip); 3705 fe_tobytes(s,y); 3706 s[31] ^= fe_isnegative(x) << 7; 3707 } 3708 3709 static int ge_frombytes_negate_vartime(ge_p3 *h,const unsigned char *s) 3710 { 3711 fe u; 3712 fe v; 3713 fe v3; 3714 fe vxx; 3715 fe check; 3716 3717 fe_frombytes(h->Y,s); 3718 fe_1(h->Z); 3719 fe_sq(u,h->Y); 3720 fe_mul(v,u,d); 3721 fe_sub(u,u,h->Z); /* u = y^2-1 */ 3722 fe_add(v,v,h->Z); /* v = dy^2+1 */ 3723 3724 fe_sq(v3,v); 3725 fe_mul(v3,v3,v); /* v3 = v^3 */ 3726 fe_sq(h->X,v3); 3727 fe_mul(h->X,h->X,v); 3728 fe_mul(h->X,h->X,u); /* x = uv^7 */ 3729 3730 fe_pow22523(h->X,h->X); /* x = (uv^7)^((q-5)/8) */ 3731 fe_mul(h->X,h->X,v3); 3732 fe_mul(h->X,h->X,u); /* x = uv^3(uv^7)^((q-5)/8) */ 3733 3734 fe_sq(vxx,h->X); 3735 fe_mul(vxx,vxx,v); 3736 fe_sub(check,vxx,u); /* vx^2-u */ 3737 if (fe_isnonzero(check)) { 3738 fe_add(check,vxx,u); /* vx^2+u */ 3739 if (fe_isnonzero(check)) return -1; 3740 fe_mul(h->X,h->X,sqrtm1); 3741 } 3742 3743 if (fe_isnegative(h->X) == (s[31] >> 7)) 3744 fe_neg(h->X,h->X); 3745 3746 fe_mul(h->T,h->X,h->Y); 3747 return 0; 3748 } 3749 3750 3751 static void slide(signed char *r,const unsigned char *a) 3752 { 3753 int i; 3754 int b; 3755 int k; 3756 3757 for (i = 0;i < 256;++i) 3758 r[i] = 1 & (a[i >> 3] >> (i & 7)); 3759 3760 for (i = 0;i < 256;++i) 3761 if (r[i]) { 3762 for (b = 1;b <= 6 && i + b < 256;++b) { 3763 if (r[i + b]) { 3764 if (r[i] + (r[i + b] << b) <= 15) { 3765 r[i] += r[i + b] << b; r[i + b] = 0; 3766 } else if (r[i] - (r[i + b] << b) >= -15) { 3767 r[i] -= r[i + b] << b; 3768 for (k = i + b;k < 256;++k) { 3769 if (!r[k]) { 3770 r[k] = 1; 3771 break; 3772 } 3773 r[k] = 0; 3774 } 3775 } else 3776 break; 3777 } 3778 } 3779 } 3780 3781 } 3782 3783 3784 /* 3785 r = a * A + b * B 3786 where a = a[0]+256*a[1]+...+256^31 a[31]. 3787 and b = b[0]+256*b[1]+...+256^31 b[31]. 3788 B is the Ed25519 base point (x,4/5) with x positive. 3789 */ 3790 3791 static void ge_double_scalarmult_vartime(ge_p2 *r,const unsigned char *a,const ge_p3 *A,const unsigned char *b) 3792 { 3793 signed char aslide[256]; 3794 signed char bslide[256]; 3795 ge_cached Ai[8]; /* A,3A,5A,7A,9A,11A,13A,15A */ 3796 ge_p1p1 t; 3797 ge_p3 u; 3798 ge_p3 A2; 3799 int i; 3800 3801 slide(aslide,a); 3802 slide(bslide,b); 3803 3804 ge_p3_to_cached(&Ai[0],A); 3805 ge_p3_dbl(&t,A); ge_p1p1_to_p3(&A2,&t); 3806 ge_add(&t,&A2,&Ai[0]); ge_p1p1_to_p3(&u,&t); ge_p3_to_cached(&Ai[1],&u); 3807 ge_add(&t,&A2,&Ai[1]); ge_p1p1_to_p3(&u,&t); ge_p3_to_cached(&Ai[2],&u); 3808 ge_add(&t,&A2,&Ai[2]); ge_p1p1_to_p3(&u,&t); ge_p3_to_cached(&Ai[3],&u); 3809 ge_add(&t,&A2,&Ai[3]); ge_p1p1_to_p3(&u,&t); ge_p3_to_cached(&Ai[4],&u); 3810 ge_add(&t,&A2,&Ai[4]); ge_p1p1_to_p3(&u,&t); ge_p3_to_cached(&Ai[5],&u); 3811 ge_add(&t,&A2,&Ai[5]); ge_p1p1_to_p3(&u,&t); ge_p3_to_cached(&Ai[6],&u); 3812 ge_add(&t,&A2,&Ai[6]); ge_p1p1_to_p3(&u,&t); ge_p3_to_cached(&Ai[7],&u); 3813 3814 ge_p2_0(r); 3815 3816 for (i = 255;i >= 0;--i) { 3817 if (aslide[i] || bslide[i]) break; 3818 } 3819 3820 for (;i >= 0;--i) { 3821 ge_p2_dbl(&t,r); 3822 3823 if (aslide[i] > 0) { 3824 ge_p1p1_to_p3(&u,&t); 3825 ge_add(&t,&u,&Ai[aslide[i]/2]); 3826 } else if (aslide[i] < 0) { 3827 ge_p1p1_to_p3(&u,&t); 3828 ge_sub(&t,&u,&Ai[(-aslide[i])/2]); 3829 } 3830 3831 if (bslide[i] > 0) { 3832 ge_p1p1_to_p3(&u,&t); 3833 ge_madd(&t,&u,&Bi[bslide[i]/2]); 3834 } else if (bslide[i] < 0) { 3835 ge_p1p1_to_p3(&u,&t); 3836 ge_msub(&t,&u,&Bi[(-bslide[i])/2]); 3837 } 3838 3839 ge_p1p1_to_p2(r,&t); 3840 } 3841 } 3842 3843 static unsigned char equal(signed char b,signed char c) 3844 { 3845 unsigned char ub = b; 3846 unsigned char uc = c; 3847 unsigned char x = ub ^ uc; /* 0: yes; 1..255: no */ 3848 crypto_uint32 y = x; /* 0: yes; 1..255: no */ 3849 y -= 1; /* 4294967295: yes; 0..254: no */ 3850 y >>= 31; /* 1: yes; 0: no */ 3851 return y; 3852 } 3853 3854 static unsigned char negative(signed char b) 3855 { 3856 unsigned long long x = b; /* 18446744073709551361..18446744073709551615: yes; 0..255: no */ 3857 x >>= 63; /* 1: yes; 0: no */ 3858 return x; 3859 } 3860 3861 static void cmov(ge_precomp *t,ge_precomp *u,unsigned char b) 3862 { 3863 fe_cmov(t->yplusx,u->yplusx,b); 3864 fe_cmov(t->yminusx,u->yminusx,b); 3865 fe_cmov(t->xy2d,u->xy2d,b); 3866 } 3867 3868 3869 3870 static void select(ge_precomp *t,int pos,signed char b) 3871 { 3872 ge_precomp minust; 3873 unsigned char bnegative = negative(b); 3874 unsigned char babs = b - (((-bnegative) & b) << 1); 3875 3876 ge_precomp_0(t); 3877 cmov(t,&base[pos][0],equal(babs,1)); 3878 cmov(t,&base[pos][1],equal(babs,2)); 3879 cmov(t,&base[pos][2],equal(babs,3)); 3880 cmov(t,&base[pos][3],equal(babs,4)); 3881 cmov(t,&base[pos][4],equal(babs,5)); 3882 cmov(t,&base[pos][5],equal(babs,6)); 3883 cmov(t,&base[pos][6],equal(babs,7)); 3884 cmov(t,&base[pos][7],equal(babs,8)); 3885 fe_copy(minust.yplusx,t->yminusx); 3886 fe_copy(minust.yminusx,t->yplusx); 3887 fe_neg(minust.xy2d,t->xy2d); 3888 cmov(t,&minust,bnegative); 3889 } 3890 3891 /* 3892 h = a * B 3893 where a = a[0]+256*a[1]+...+256^31 a[31] 3894 B is the Ed25519 base point (x,4/5) with x positive. 3895 3896 Preconditions: 3897 a[31] <= 127 3898 */ 3899 3900 static void ge_scalarmult_base(ge_p3 *h,const unsigned char *a) 3901 { 3902 signed char e[64]; 3903 signed char carry; 3904 ge_p1p1 r; 3905 ge_p2 s; 3906 ge_precomp t; 3907 int i; 3908 3909 for (i = 0;i < 32;++i) { 3910 e[2 * i + 0] = (a[i] >> 0) & 15; 3911 e[2 * i + 1] = (a[i] >> 4) & 15; 3912 } 3913 /* each e[i] is between 0 and 15 */ 3914 /* e[63] is between 0 and 7 */ 3915 3916 carry = 0; 3917 for (i = 0;i < 63;++i) { 3918 e[i] += carry; 3919 carry = e[i] + 8; 3920 carry >>= 4; 3921 e[i] -= carry << 4; 3922 } 3923 e[63] += carry; 3924 /* each e[i] is between -8 and 8 */ 3925 3926 ge_p3_0(h); 3927 for (i = 1;i < 64;i += 2) { 3928 select(&t,i / 2,e[i]); 3929 ge_madd(&r,h,&t); ge_p1p1_to_p3(h,&r); 3930 } 3931 3932 ge_p3_dbl(&r,h); ge_p1p1_to_p2(&s,&r); 3933 ge_p2_dbl(&r,&s); ge_p1p1_to_p2(&s,&r); 3934 ge_p2_dbl(&r,&s); ge_p1p1_to_p2(&s,&r); 3935 ge_p2_dbl(&r,&s); ge_p1p1_to_p3(h,&r); 3936 3937 for (i = 0;i < 64;i += 2) { 3938 select(&t,i / 2,e[i]); 3939 ge_madd(&r,h,&t); ge_p1p1_to_p3(h,&r); 3940 } 3941 } 3942 3943 /* 3944 Input: 3945 s[0]+256*s[1]+...+256^63*s[63] = s 3946 3947 Output: 3948 s[0]+256*s[1]+...+256^31*s[31] = s mod l 3949 where l = 2^252 + 27742317777372353535851937790883648493. 3950 Overwrites s in place. 3951 */ 3952 3953 static void sc_reduce(unsigned char *s) 3954 { 3955 crypto_int64 s0 = 2097151 & load_3(s); 3956 crypto_int64 s1 = 2097151 & (load_4(s + 2) >> 5); 3957 crypto_int64 s2 = 2097151 & (load_3(s + 5) >> 2); 3958 crypto_int64 s3 = 2097151 & (load_4(s + 7) >> 7); 3959 crypto_int64 s4 = 2097151 & (load_4(s + 10) >> 4); 3960 crypto_int64 s5 = 2097151 & (load_3(s + 13) >> 1); 3961 crypto_int64 s6 = 2097151 & (load_4(s + 15) >> 6); 3962 crypto_int64 s7 = 2097151 & (load_3(s + 18) >> 3); 3963 crypto_int64 s8 = 2097151 & load_3(s + 21); 3964 crypto_int64 s9 = 2097151 & (load_4(s + 23) >> 5); 3965 crypto_int64 s10 = 2097151 & (load_3(s + 26) >> 2); 3966 crypto_int64 s11 = 2097151 & (load_4(s + 28) >> 7); 3967 crypto_int64 s12 = 2097151 & (load_4(s + 31) >> 4); 3968 crypto_int64 s13 = 2097151 & (load_3(s + 34) >> 1); 3969 crypto_int64 s14 = 2097151 & (load_4(s + 36) >> 6); 3970 crypto_int64 s15 = 2097151 & (load_3(s + 39) >> 3); 3971 crypto_int64 s16 = 2097151 & load_3(s + 42); 3972 crypto_int64 s17 = 2097151 & (load_4(s + 44) >> 5); 3973 crypto_int64 s18 = 2097151 & (load_3(s + 47) >> 2); 3974 crypto_int64 s19 = 2097151 & (load_4(s + 49) >> 7); 3975 crypto_int64 s20 = 2097151 & (load_4(s + 52) >> 4); 3976 crypto_int64 s21 = 2097151 & (load_3(s + 55) >> 1); 3977 crypto_int64 s22 = 2097151 & (load_4(s + 57) >> 6); 3978 crypto_int64 s23 = (load_4(s + 60) >> 3); 3979 crypto_int64 carry0; 3980 crypto_int64 carry1; 3981 crypto_int64 carry2; 3982 crypto_int64 carry3; 3983 crypto_int64 carry4; 3984 crypto_int64 carry5; 3985 crypto_int64 carry6; 3986 crypto_int64 carry7; 3987 crypto_int64 carry8; 3988 crypto_int64 carry9; 3989 crypto_int64 carry10; 3990 crypto_int64 carry11; 3991 crypto_int64 carry12; 3992 crypto_int64 carry13; 3993 crypto_int64 carry14; 3994 crypto_int64 carry15; 3995 crypto_int64 carry16; 3996 3997 s11 += s23 * 666643; 3998 s12 += s23 * 470296; 3999 s13 += s23 * 654183; 4000 s14 -= s23 * 997805; 4001 s15 += s23 * 136657; 4002 s16 -= s23 * 683901; 4003 s23 = 0; 4004 4005 s10 += s22 * 666643; 4006 s11 += s22 * 470296; 4007 s12 += s22 * 654183; 4008 s13 -= s22 * 997805; 4009 s14 += s22 * 136657; 4010 s15 -= s22 * 683901; 4011 s22 = 0; 4012 4013 s9 += s21 * 666643; 4014 s10 += s21 * 470296; 4015 s11 += s21 * 654183; 4016 s12 -= s21 * 997805; 4017 s13 += s21 * 136657; 4018 s14 -= s21 * 683901; 4019 s21 = 0; 4020 4021 s8 += s20 * 666643; 4022 s9 += s20 * 470296; 4023 s10 += s20 * 654183; 4024 s11 -= s20 * 997805; 4025 s12 += s20 * 136657; 4026 s13 -= s20 * 683901; 4027 s20 = 0; 4028 4029 s7 += s19 * 666643; 4030 s8 += s19 * 470296; 4031 s9 += s19 * 654183; 4032 s10 -= s19 * 997805; 4033 s11 += s19 * 136657; 4034 s12 -= s19 * 683901; 4035 s19 = 0; 4036 4037 s6 += s18 * 666643; 4038 s7 += s18 * 470296; 4039 s8 += s18 * 654183; 4040 s9 -= s18 * 997805; 4041 s10 += s18 * 136657; 4042 s11 -= s18 * 683901; 4043 s18 = 0; 4044 4045 carry6 = (s6 + (1<<20)) >> 21; s7 += carry6; s6 -= carry6 << 21; 4046 carry8 = (s8 + (1<<20)) >> 21; s9 += carry8; s8 -= carry8 << 21; 4047 carry10 = (s10 + (1<<20)) >> 21; s11 += carry10; s10 -= carry10 << 21; 4048 carry12 = (s12 + (1<<20)) >> 21; s13 += carry12; s12 -= carry12 << 21; 4049 carry14 = (s14 + (1<<20)) >> 21; s15 += carry14; s14 -= carry14 << 21; 4050 carry16 = (s16 + (1<<20)) >> 21; s17 += carry16; s16 -= carry16 << 21; 4051 4052 carry7 = (s7 + (1<<20)) >> 21; s8 += carry7; s7 -= carry7 << 21; 4053 carry9 = (s9 + (1<<20)) >> 21; s10 += carry9; s9 -= carry9 << 21; 4054 carry11 = (s11 + (1<<20)) >> 21; s12 += carry11; s11 -= carry11 << 21; 4055 carry13 = (s13 + (1<<20)) >> 21; s14 += carry13; s13 -= carry13 << 21; 4056 carry15 = (s15 + (1<<20)) >> 21; s16 += carry15; s15 -= carry15 << 21; 4057 4058 s5 += s17 * 666643; 4059 s6 += s17 * 470296; 4060 s7 += s17 * 654183; 4061 s8 -= s17 * 997805; 4062 s9 += s17 * 136657; 4063 s10 -= s17 * 683901; 4064 s17 = 0; 4065 4066 s4 += s16 * 666643; 4067 s5 += s16 * 470296; 4068 s6 += s16 * 654183; 4069 s7 -= s16 * 997805; 4070 s8 += s16 * 136657; 4071 s9 -= s16 * 683901; 4072 s16 = 0; 4073 4074 s3 += s15 * 666643; 4075 s4 += s15 * 470296; 4076 s5 += s15 * 654183; 4077 s6 -= s15 * 997805; 4078 s7 += s15 * 136657; 4079 s8 -= s15 * 683901; 4080 s15 = 0; 4081 4082 s2 += s14 * 666643; 4083 s3 += s14 * 470296; 4084 s4 += s14 * 654183; 4085 s5 -= s14 * 997805; 4086 s6 += s14 * 136657; 4087 s7 -= s14 * 683901; 4088 s14 = 0; 4089 4090 s1 += s13 * 666643; 4091 s2 += s13 * 470296; 4092 s3 += s13 * 654183; 4093 s4 -= s13 * 997805; 4094 s5 += s13 * 136657; 4095 s6 -= s13 * 683901; 4096 s13 = 0; 4097 4098 s0 += s12 * 666643; 4099 s1 += s12 * 470296; 4100 s2 += s12 * 654183; 4101 s3 -= s12 * 997805; 4102 s4 += s12 * 136657; 4103 s5 -= s12 * 683901; 4104 s12 = 0; 4105 4106 carry0 = (s0 + (1<<20)) >> 21; s1 += carry0; s0 -= carry0 << 21; 4107 carry2 = (s2 + (1<<20)) >> 21; s3 += carry2; s2 -= carry2 << 21; 4108 carry4 = (s4 + (1<<20)) >> 21; s5 += carry4; s4 -= carry4 << 21; 4109 carry6 = (s6 + (1<<20)) >> 21; s7 += carry6; s6 -= carry6 << 21; 4110 carry8 = (s8 + (1<<20)) >> 21; s9 += carry8; s8 -= carry8 << 21; 4111 carry10 = (s10 + (1<<20)) >> 21; s11 += carry10; s10 -= carry10 << 21; 4112 4113 carry1 = (s1 + (1<<20)) >> 21; s2 += carry1; s1 -= carry1 << 21; 4114 carry3 = (s3 + (1<<20)) >> 21; s4 += carry3; s3 -= carry3 << 21; 4115 carry5 = (s5 + (1<<20)) >> 21; s6 += carry5; s5 -= carry5 << 21; 4116 carry7 = (s7 + (1<<20)) >> 21; s8 += carry7; s7 -= carry7 << 21; 4117 carry9 = (s9 + (1<<20)) >> 21; s10 += carry9; s9 -= carry9 << 21; 4118 carry11 = (s11 + (1<<20)) >> 21; s12 += carry11; s11 -= carry11 << 21; 4119 4120 s0 += s12 * 666643; 4121 s1 += s12 * 470296; 4122 s2 += s12 * 654183; 4123 s3 -= s12 * 997805; 4124 s4 += s12 * 136657; 4125 s5 -= s12 * 683901; 4126 s12 = 0; 4127 4128 carry0 = s0 >> 21; s1 += carry0; s0 -= carry0 << 21; 4129 carry1 = s1 >> 21; s2 += carry1; s1 -= carry1 << 21; 4130 carry2 = s2 >> 21; s3 += carry2; s2 -= carry2 << 21; 4131 carry3 = s3 >> 21; s4 += carry3; s3 -= carry3 << 21; 4132 carry4 = s4 >> 21; s5 += carry4; s4 -= carry4 << 21; 4133 carry5 = s5 >> 21; s6 += carry5; s5 -= carry5 << 21; 4134 carry6 = s6 >> 21; s7 += carry6; s6 -= carry6 << 21; 4135 carry7 = s7 >> 21; s8 += carry7; s7 -= carry7 << 21; 4136 carry8 = s8 >> 21; s9 += carry8; s8 -= carry8 << 21; 4137 carry9 = s9 >> 21; s10 += carry9; s9 -= carry9 << 21; 4138 carry10 = s10 >> 21; s11 += carry10; s10 -= carry10 << 21; 4139 carry11 = s11 >> 21; s12 += carry11; s11 -= carry11 << 21; 4140 4141 s0 += s12 * 666643; 4142 s1 += s12 * 470296; 4143 s2 += s12 * 654183; 4144 s3 -= s12 * 997805; 4145 s4 += s12 * 136657; 4146 s5 -= s12 * 683901; 4147 s12 = 0; 4148 4149 carry0 = s0 >> 21; s1 += carry0; s0 -= carry0 << 21; 4150 carry1 = s1 >> 21; s2 += carry1; s1 -= carry1 << 21; 4151 carry2 = s2 >> 21; s3 += carry2; s2 -= carry2 << 21; 4152 carry3 = s3 >> 21; s4 += carry3; s3 -= carry3 << 21; 4153 carry4 = s4 >> 21; s5 += carry4; s4 -= carry4 << 21; 4154 carry5 = s5 >> 21; s6 += carry5; s5 -= carry5 << 21; 4155 carry6 = s6 >> 21; s7 += carry6; s6 -= carry6 << 21; 4156 carry7 = s7 >> 21; s8 += carry7; s7 -= carry7 << 21; 4157 carry8 = s8 >> 21; s9 += carry8; s8 -= carry8 << 21; 4158 carry9 = s9 >> 21; s10 += carry9; s9 -= carry9 << 21; 4159 carry10 = s10 >> 21; s11 += carry10; s10 -= carry10 << 21; 4160 4161 s[0] = s0 >> 0; 4162 s[1] = s0 >> 8; 4163 s[2] = (s0 >> 16) | (s1 << 5); 4164 s[3] = s1 >> 3; 4165 s[4] = s1 >> 11; 4166 s[5] = (s1 >> 19) | (s2 << 2); 4167 s[6] = s2 >> 6; 4168 s[7] = (s2 >> 14) | (s3 << 7); 4169 s[8] = s3 >> 1; 4170 s[9] = s3 >> 9; 4171 s[10] = (s3 >> 17) | (s4 << 4); 4172 s[11] = s4 >> 4; 4173 s[12] = s4 >> 12; 4174 s[13] = (s4 >> 20) | (s5 << 1); 4175 s[14] = s5 >> 7; 4176 s[15] = (s5 >> 15) | (s6 << 6); 4177 s[16] = s6 >> 2; 4178 s[17] = s6 >> 10; 4179 s[18] = (s6 >> 18) | (s7 << 3); 4180 s[19] = s7 >> 5; 4181 s[20] = s7 >> 13; 4182 s[21] = s8 >> 0; 4183 s[22] = s8 >> 8; 4184 s[23] = (s8 >> 16) | (s9 << 5); 4185 s[24] = s9 >> 3; 4186 s[25] = s9 >> 11; 4187 s[26] = (s9 >> 19) | (s10 << 2); 4188 s[27] = s10 >> 6; 4189 s[28] = (s10 >> 14) | (s11 << 7); 4190 s[29] = s11 >> 1; 4191 s[30] = s11 >> 9; 4192 s[31] = s11 >> 17; 4193 } 4194 4195 /* 4196 Input: 4197 a[0]+256*a[1]+...+256^31*a[31] = a 4198 b[0]+256*b[1]+...+256^31*b[31] = b 4199 c[0]+256*c[1]+...+256^31*c[31] = c 4200 4201 Output: 4202 s[0]+256*s[1]+...+256^31*s[31] = (ab+c) mod l 4203 where l = 2^252 + 27742317777372353535851937790883648493. 4204 */ 4205 4206 static void sc_muladd(unsigned char *s,const unsigned char *a,const unsigned char *b,const unsigned char *c) 4207 { 4208 crypto_int64 a0 = 2097151 & load_3(a); 4209 crypto_int64 a1 = 2097151 & (load_4(a + 2) >> 5); 4210 crypto_int64 a2 = 2097151 & (load_3(a + 5) >> 2); 4211 crypto_int64 a3 = 2097151 & (load_4(a + 7) >> 7); 4212 crypto_int64 a4 = 2097151 & (load_4(a + 10) >> 4); 4213 crypto_int64 a5 = 2097151 & (load_3(a + 13) >> 1); 4214 crypto_int64 a6 = 2097151 & (load_4(a + 15) >> 6); 4215 crypto_int64 a7 = 2097151 & (load_3(a + 18) >> 3); 4216 crypto_int64 a8 = 2097151 & load_3(a + 21); 4217 crypto_int64 a9 = 2097151 & (load_4(a + 23) >> 5); 4218 crypto_int64 a10 = 2097151 & (load_3(a + 26) >> 2); 4219 crypto_int64 a11 = (load_4(a + 28) >> 7); 4220 crypto_int64 b0 = 2097151 & load_3(b); 4221 crypto_int64 b1 = 2097151 & (load_4(b + 2) >> 5); 4222 crypto_int64 b2 = 2097151 & (load_3(b + 5) >> 2); 4223 crypto_int64 b3 = 2097151 & (load_4(b + 7) >> 7); 4224 crypto_int64 b4 = 2097151 & (load_4(b + 10) >> 4); 4225 crypto_int64 b5 = 2097151 & (load_3(b + 13) >> 1); 4226 crypto_int64 b6 = 2097151 & (load_4(b + 15) >> 6); 4227 crypto_int64 b7 = 2097151 & (load_3(b + 18) >> 3); 4228 crypto_int64 b8 = 2097151 & load_3(b + 21); 4229 crypto_int64 b9 = 2097151 & (load_4(b + 23) >> 5); 4230 crypto_int64 b10 = 2097151 & (load_3(b + 26) >> 2); 4231 crypto_int64 b11 = (load_4(b + 28) >> 7); 4232 crypto_int64 c0 = 2097151 & load_3(c); 4233 crypto_int64 c1 = 2097151 & (load_4(c + 2) >> 5); 4234 crypto_int64 c2 = 2097151 & (load_3(c + 5) >> 2); 4235 crypto_int64 c3 = 2097151 & (load_4(c + 7) >> 7); 4236 crypto_int64 c4 = 2097151 & (load_4(c + 10) >> 4); 4237 crypto_int64 c5 = 2097151 & (load_3(c + 13) >> 1); 4238 crypto_int64 c6 = 2097151 & (load_4(c + 15) >> 6); 4239 crypto_int64 c7 = 2097151 & (load_3(c + 18) >> 3); 4240 crypto_int64 c8 = 2097151 & load_3(c + 21); 4241 crypto_int64 c9 = 2097151 & (load_4(c + 23) >> 5); 4242 crypto_int64 c10 = 2097151 & (load_3(c + 26) >> 2); 4243 crypto_int64 c11 = (load_4(c + 28) >> 7); 4244 crypto_int64 s0; 4245 crypto_int64 s1; 4246 crypto_int64 s2; 4247 crypto_int64 s3; 4248 crypto_int64 s4; 4249 crypto_int64 s5; 4250 crypto_int64 s6; 4251 crypto_int64 s7; 4252 crypto_int64 s8; 4253 crypto_int64 s9; 4254 crypto_int64 s10; 4255 crypto_int64 s11; 4256 crypto_int64 s12; 4257 crypto_int64 s13; 4258 crypto_int64 s14; 4259 crypto_int64 s15; 4260 crypto_int64 s16; 4261 crypto_int64 s17; 4262 crypto_int64 s18; 4263 crypto_int64 s19; 4264 crypto_int64 s20; 4265 crypto_int64 s21; 4266 crypto_int64 s22; 4267 crypto_int64 s23; 4268 crypto_int64 carry0; 4269 crypto_int64 carry1; 4270 crypto_int64 carry2; 4271 crypto_int64 carry3; 4272 crypto_int64 carry4; 4273 crypto_int64 carry5; 4274 crypto_int64 carry6; 4275 crypto_int64 carry7; 4276 crypto_int64 carry8; 4277 crypto_int64 carry9; 4278 crypto_int64 carry10; 4279 crypto_int64 carry11; 4280 crypto_int64 carry12; 4281 crypto_int64 carry13; 4282 crypto_int64 carry14; 4283 crypto_int64 carry15; 4284 crypto_int64 carry16; 4285 crypto_int64 carry17; 4286 crypto_int64 carry18; 4287 crypto_int64 carry19; 4288 crypto_int64 carry20; 4289 crypto_int64 carry21; 4290 crypto_int64 carry22; 4291 4292 s0 = c0 + a0*b0; 4293 s1 = c1 + a0*b1 + a1*b0; 4294 s2 = c2 + a0*b2 + a1*b1 + a2*b0; 4295 s3 = c3 + a0*b3 + a1*b2 + a2*b1 + a3*b0; 4296 s4 = c4 + a0*b4 + a1*b3 + a2*b2 + a3*b1 + a4*b0; 4297 s5 = c5 + a0*b5 + a1*b4 + a2*b3 + a3*b2 + a4*b1 + a5*b0; 4298 s6 = c6 + a0*b6 + a1*b5 + a2*b4 + a3*b3 + a4*b2 + a5*b1 + a6*b0; 4299 s7 = c7 + a0*b7 + a1*b6 + a2*b5 + a3*b4 + a4*b3 + a5*b2 + a6*b1 + a7*b0; 4300 s8 = c8 + a0*b8 + a1*b7 + a2*b6 + a3*b5 + a4*b4 + a5*b3 + a6*b2 + a7*b1 + a8*b0; 4301 s9 = c9 + a0*b9 + a1*b8 + a2*b7 + a3*b6 + a4*b5 + a5*b4 + a6*b3 + a7*b2 + a8*b1 + a9*b0; 4302 s10 = c10 + a0*b10 + a1*b9 + a2*b8 + a3*b7 + a4*b6 + a5*b5 + a6*b4 + a7*b3 + a8*b2 + a9*b1 + a10*b0; 4303 s11 = c11 + a0*b11 + a1*b10 + a2*b9 + a3*b8 + a4*b7 + a5*b6 + a6*b5 + a7*b4 + a8*b3 + a9*b2 + a10*b1 + a11*b0; 4304 s12 = a1*b11 + a2*b10 + a3*b9 + a4*b8 + a5*b7 + a6*b6 + a7*b5 + a8*b4 + a9*b3 + a10*b2 + a11*b1; 4305 s13 = a2*b11 + a3*b10 + a4*b9 + a5*b8 + a6*b7 + a7*b6 + a8*b5 + a9*b4 + a10*b3 + a11*b2; 4306 s14 = a3*b11 + a4*b10 + a5*b9 + a6*b8 + a7*b7 + a8*b6 + a9*b5 + a10*b4 + a11*b3; 4307 s15 = a4*b11 + a5*b10 + a6*b9 + a7*b8 + a8*b7 + a9*b6 + a10*b5 + a11*b4; 4308 s16 = a5*b11 + a6*b10 + a7*b9 + a8*b8 + a9*b7 + a10*b6 + a11*b5; 4309 s17 = a6*b11 + a7*b10 + a8*b9 + a9*b8 + a10*b7 + a11*b6; 4310 s18 = a7*b11 + a8*b10 + a9*b9 + a10*b8 + a11*b7; 4311 s19 = a8*b11 + a9*b10 + a10*b9 + a11*b8; 4312 s20 = a9*b11 + a10*b10 + a11*b9; 4313 s21 = a10*b11 + a11*b10; 4314 s22 = a11*b11; 4315 s23 = 0; 4316 4317 carry0 = (s0 + (1<<20)) >> 21; s1 += carry0; s0 -= carry0 << 21; 4318 carry2 = (s2 + (1<<20)) >> 21; s3 += carry2; s2 -= carry2 << 21; 4319 carry4 = (s4 + (1<<20)) >> 21; s5 += carry4; s4 -= carry4 << 21; 4320 carry6 = (s6 + (1<<20)) >> 21; s7 += carry6; s6 -= carry6 << 21; 4321 carry8 = (s8 + (1<<20)) >> 21; s9 += carry8; s8 -= carry8 << 21; 4322 carry10 = (s10 + (1<<20)) >> 21; s11 += carry10; s10 -= carry10 << 21; 4323 carry12 = (s12 + (1<<20)) >> 21; s13 += carry12; s12 -= carry12 << 21; 4324 carry14 = (s14 + (1<<20)) >> 21; s15 += carry14; s14 -= carry14 << 21; 4325 carry16 = (s16 + (1<<20)) >> 21; s17 += carry16; s16 -= carry16 << 21; 4326 carry18 = (s18 + (1<<20)) >> 21; s19 += carry18; s18 -= carry18 << 21; 4327 carry20 = (s20 + (1<<20)) >> 21; s21 += carry20; s20 -= carry20 << 21; 4328 carry22 = (s22 + (1<<20)) >> 21; s23 += carry22; s22 -= carry22 << 21; 4329 4330 carry1 = (s1 + (1<<20)) >> 21; s2 += carry1; s1 -= carry1 << 21; 4331 carry3 = (s3 + (1<<20)) >> 21; s4 += carry3; s3 -= carry3 << 21; 4332 carry5 = (s5 + (1<<20)) >> 21; s6 += carry5; s5 -= carry5 << 21; 4333 carry7 = (s7 + (1<<20)) >> 21; s8 += carry7; s7 -= carry7 << 21; 4334 carry9 = (s9 + (1<<20)) >> 21; s10 += carry9; s9 -= carry9 << 21; 4335 carry11 = (s11 + (1<<20)) >> 21; s12 += carry11; s11 -= carry11 << 21; 4336 carry13 = (s13 + (1<<20)) >> 21; s14 += carry13; s13 -= carry13 << 21; 4337 carry15 = (s15 + (1<<20)) >> 21; s16 += carry15; s15 -= carry15 << 21; 4338 carry17 = (s17 + (1<<20)) >> 21; s18 += carry17; s17 -= carry17 << 21; 4339 carry19 = (s19 + (1<<20)) >> 21; s20 += carry19; s19 -= carry19 << 21; 4340 carry21 = (s21 + (1<<20)) >> 21; s22 += carry21; s21 -= carry21 << 21; 4341 4342 s11 += s23 * 666643; 4343 s12 += s23 * 470296; 4344 s13 += s23 * 654183; 4345 s14 -= s23 * 997805; 4346 s15 += s23 * 136657; 4347 s16 -= s23 * 683901; 4348 s23 = 0; 4349 4350 s10 += s22 * 666643; 4351 s11 += s22 * 470296; 4352 s12 += s22 * 654183; 4353 s13 -= s22 * 997805; 4354 s14 += s22 * 136657; 4355 s15 -= s22 * 683901; 4356 s22 = 0; 4357 4358 s9 += s21 * 666643; 4359 s10 += s21 * 470296; 4360 s11 += s21 * 654183; 4361 s12 -= s21 * 997805; 4362 s13 += s21 * 136657; 4363 s14 -= s21 * 683901; 4364 s21 = 0; 4365 4366 s8 += s20 * 666643; 4367 s9 += s20 * 470296; 4368 s10 += s20 * 654183; 4369 s11 -= s20 * 997805; 4370 s12 += s20 * 136657; 4371 s13 -= s20 * 683901; 4372 s20 = 0; 4373 4374 s7 += s19 * 666643; 4375 s8 += s19 * 470296; 4376 s9 += s19 * 654183; 4377 s10 -= s19 * 997805; 4378 s11 += s19 * 136657; 4379 s12 -= s19 * 683901; 4380 s19 = 0; 4381 4382 s6 += s18 * 666643; 4383 s7 += s18 * 470296; 4384 s8 += s18 * 654183; 4385 s9 -= s18 * 997805; 4386 s10 += s18 * 136657; 4387 s11 -= s18 * 683901; 4388 s18 = 0; 4389 4390 carry6 = (s6 + (1<<20)) >> 21; s7 += carry6; s6 -= carry6 << 21; 4391 carry8 = (s8 + (1<<20)) >> 21; s9 += carry8; s8 -= carry8 << 21; 4392 carry10 = (s10 + (1<<20)) >> 21; s11 += carry10; s10 -= carry10 << 21; 4393 carry12 = (s12 + (1<<20)) >> 21; s13 += carry12; s12 -= carry12 << 21; 4394 carry14 = (s14 + (1<<20)) >> 21; s15 += carry14; s14 -= carry14 << 21; 4395 carry16 = (s16 + (1<<20)) >> 21; s17 += carry16; s16 -= carry16 << 21; 4396 4397 carry7 = (s7 + (1<<20)) >> 21; s8 += carry7; s7 -= carry7 << 21; 4398 carry9 = (s9 + (1<<20)) >> 21; s10 += carry9; s9 -= carry9 << 21; 4399 carry11 = (s11 + (1<<20)) >> 21; s12 += carry11; s11 -= carry11 << 21; 4400 carry13 = (s13 + (1<<20)) >> 21; s14 += carry13; s13 -= carry13 << 21; 4401 carry15 = (s15 + (1<<20)) >> 21; s16 += carry15; s15 -= carry15 << 21; 4402 4403 s5 += s17 * 666643; 4404 s6 += s17 * 470296; 4405 s7 += s17 * 654183; 4406 s8 -= s17 * 997805; 4407 s9 += s17 * 136657; 4408 s10 -= s17 * 683901; 4409 s17 = 0; 4410 4411 s4 += s16 * 666643; 4412 s5 += s16 * 470296; 4413 s6 += s16 * 654183; 4414 s7 -= s16 * 997805; 4415 s8 += s16 * 136657; 4416 s9 -= s16 * 683901; 4417 s16 = 0; 4418 4419 s3 += s15 * 666643; 4420 s4 += s15 * 470296; 4421 s5 += s15 * 654183; 4422 s6 -= s15 * 997805; 4423 s7 += s15 * 136657; 4424 s8 -= s15 * 683901; 4425 s15 = 0; 4426 4427 s2 += s14 * 666643; 4428 s3 += s14 * 470296; 4429 s4 += s14 * 654183; 4430 s5 -= s14 * 997805; 4431 s6 += s14 * 136657; 4432 s7 -= s14 * 683901; 4433 s14 = 0; 4434 4435 s1 += s13 * 666643; 4436 s2 += s13 * 470296; 4437 s3 += s13 * 654183; 4438 s4 -= s13 * 997805; 4439 s5 += s13 * 136657; 4440 s6 -= s13 * 683901; 4441 s13 = 0; 4442 4443 s0 += s12 * 666643; 4444 s1 += s12 * 470296; 4445 s2 += s12 * 654183; 4446 s3 -= s12 * 997805; 4447 s4 += s12 * 136657; 4448 s5 -= s12 * 683901; 4449 s12 = 0; 4450 4451 carry0 = (s0 + (1<<20)) >> 21; s1 += carry0; s0 -= carry0 << 21; 4452 carry2 = (s2 + (1<<20)) >> 21; s3 += carry2; s2 -= carry2 << 21; 4453 carry4 = (s4 + (1<<20)) >> 21; s5 += carry4; s4 -= carry4 << 21; 4454 carry6 = (s6 + (1<<20)) >> 21; s7 += carry6; s6 -= carry6 << 21; 4455 carry8 = (s8 + (1<<20)) >> 21; s9 += carry8; s8 -= carry8 << 21; 4456 carry10 = (s10 + (1<<20)) >> 21; s11 += carry10; s10 -= carry10 << 21; 4457 4458 carry1 = (s1 + (1<<20)) >> 21; s2 += carry1; s1 -= carry1 << 21; 4459 carry3 = (s3 + (1<<20)) >> 21; s4 += carry3; s3 -= carry3 << 21; 4460 carry5 = (s5 + (1<<20)) >> 21; s6 += carry5; s5 -= carry5 << 21; 4461 carry7 = (s7 + (1<<20)) >> 21; s8 += carry7; s7 -= carry7 << 21; 4462 carry9 = (s9 + (1<<20)) >> 21; s10 += carry9; s9 -= carry9 << 21; 4463 carry11 = (s11 + (1<<20)) >> 21; s12 += carry11; s11 -= carry11 << 21; 4464 4465 s0 += s12 * 666643; 4466 s1 += s12 * 470296; 4467 s2 += s12 * 654183; 4468 s3 -= s12 * 997805; 4469 s4 += s12 * 136657; 4470 s5 -= s12 * 683901; 4471 s12 = 0; 4472 4473 carry0 = s0 >> 21; s1 += carry0; s0 -= carry0 << 21; 4474 carry1 = s1 >> 21; s2 += carry1; s1 -= carry1 << 21; 4475 carry2 = s2 >> 21; s3 += carry2; s2 -= carry2 << 21; 4476 carry3 = s3 >> 21; s4 += carry3; s3 -= carry3 << 21; 4477 carry4 = s4 >> 21; s5 += carry4; s4 -= carry4 << 21; 4478 carry5 = s5 >> 21; s6 += carry5; s5 -= carry5 << 21; 4479 carry6 = s6 >> 21; s7 += carry6; s6 -= carry6 << 21; 4480 carry7 = s7 >> 21; s8 += carry7; s7 -= carry7 << 21; 4481 carry8 = s8 >> 21; s9 += carry8; s8 -= carry8 << 21; 4482 carry9 = s9 >> 21; s10 += carry9; s9 -= carry9 << 21; 4483 carry10 = s10 >> 21; s11 += carry10; s10 -= carry10 << 21; 4484 carry11 = s11 >> 21; s12 += carry11; s11 -= carry11 << 21; 4485 4486 s0 += s12 * 666643; 4487 s1 += s12 * 470296; 4488 s2 += s12 * 654183; 4489 s3 -= s12 * 997805; 4490 s4 += s12 * 136657; 4491 s5 -= s12 * 683901; 4492 s12 = 0; 4493 4494 carry0 = s0 >> 21; s1 += carry0; s0 -= carry0 << 21; 4495 carry1 = s1 >> 21; s2 += carry1; s1 -= carry1 << 21; 4496 carry2 = s2 >> 21; s3 += carry2; s2 -= carry2 << 21; 4497 carry3 = s3 >> 21; s4 += carry3; s3 -= carry3 << 21; 4498 carry4 = s4 >> 21; s5 += carry4; s4 -= carry4 << 21; 4499 carry5 = s5 >> 21; s6 += carry5; s5 -= carry5 << 21; 4500 carry6 = s6 >> 21; s7 += carry6; s6 -= carry6 << 21; 4501 carry7 = s7 >> 21; s8 += carry7; s7 -= carry7 << 21; 4502 carry8 = s8 >> 21; s9 += carry8; s8 -= carry8 << 21; 4503 carry9 = s9 >> 21; s10 += carry9; s9 -= carry9 << 21; 4504 carry10 = s10 >> 21; s11 += carry10; s10 -= carry10 << 21; 4505 4506 s[0] = s0 >> 0; 4507 s[1] = s0 >> 8; 4508 s[2] = (s0 >> 16) | (s1 << 5); 4509 s[3] = s1 >> 3; 4510 s[4] = s1 >> 11; 4511 s[5] = (s1 >> 19) | (s2 << 2); 4512 s[6] = s2 >> 6; 4513 s[7] = (s2 >> 14) | (s3 << 7); 4514 s[8] = s3 >> 1; 4515 s[9] = s3 >> 9; 4516 s[10] = (s3 >> 17) | (s4 << 4); 4517 s[11] = s4 >> 4; 4518 s[12] = s4 >> 12; 4519 s[13] = (s4 >> 20) | (s5 << 1); 4520 s[14] = s5 >> 7; 4521 s[15] = (s5 >> 15) | (s6 << 6); 4522 s[16] = s6 >> 2; 4523 s[17] = s6 >> 10; 4524 s[18] = (s6 >> 18) | (s7 << 3); 4525 s[19] = s7 >> 5; 4526 s[20] = s7 >> 13; 4527 s[21] = s8 >> 0; 4528 s[22] = s8 >> 8; 4529 s[23] = (s8 >> 16) | (s9 << 5); 4530 s[24] = s9 >> 3; 4531 s[25] = s9 >> 11; 4532 s[26] = (s9 >> 19) | (s10 << 2); 4533 s[27] = s10 >> 6; 4534 s[28] = (s10 >> 14) | (s11 << 7); 4535 s[29] = s11 >> 1; 4536 s[30] = s11 >> 9; 4537 s[31] = s11 >> 17; 4538 } 4539 4540 /* 4541 int crypto_sign_keypair(unsigned char *pk,unsigned char *sk) 4542 { 4543 unsigned char h[64]; 4544 ge_p3 A; 4545 int i; 4546 4547 randombytes(sk,32); 4548 crypto_hash_sha512(h,sk,32); 4549 h[0] &= 248; 4550 h[31] &= 63; 4551 h[31] |= 64; 4552 4553 ge_scalarmult_base(&A,h); 4554 ge_p3_tobytes(pk,&A); 4555 4556 for (i = 0;i < 32;++i) sk[32 + i] = pk[i]; 4557 return 0; 4558 } 4559 */ 4560 4561 int crypto_sign_pk_ref10(unsigned char *pk,unsigned char *sk) 4562 { 4563 unsigned char h[64]; 4564 ge_p3 A; 4565 int i; 4566 4567 crypto_hash_sha512(h,sk,32); 4568 h[0] &= 248; 4569 h[31] &= 63; 4570 h[31] |= 64; 4571 4572 ge_scalarmult_base(&A,h); 4573 ge_p3_tobytes(pk,&A); 4574 4575 for (i = 0;i < 32;++i) sk[32 + i] = pk[i]; 4576 return 0; 4577 } 4578 4579 int crypto_sign_ref10( 4580 unsigned char *sm,unsigned long long *smlen, 4581 const unsigned char *m,unsigned long long mlen, 4582 const unsigned char *sk 4583 ) 4584 { 4585 unsigned char az[64]; 4586 unsigned char r[64]; 4587 unsigned char hram[64]; 4588 ge_p3 R; 4589 unsigned long long i; 4590 4591 crypto_hash_sha512(az,sk,32); 4592 az[0] &= 248; 4593 az[31] &= 63; 4594 az[31] |= 64; 4595 4596 *smlen = mlen + 64; 4597 for (i = 0;i < mlen;++i) sm[64 + i] = m[i]; 4598 for (i = 0;i < 32;++i) sm[32 + i] = az[32 + i]; 4599 crypto_hash_sha512(r,sm + 32,mlen + 32); 4600 for (i = 0;i < 32;++i) sm[32 + i] = sk[32 + i]; 4601 4602 sc_reduce(r); 4603 ge_scalarmult_base(&R,r); 4604 ge_p3_tobytes(sm,&R); 4605 4606 crypto_hash_sha512(hram,sm,mlen + 64); 4607 sc_reduce(hram); 4608 sc_muladd(sm + 32,hram,az,r); 4609 4610 return 0; 4611 } 4612 4613 int crypto_sign_open_ref10( 4614 unsigned char *m,unsigned long long *mlen, 4615 const unsigned char *sm,unsigned long long smlen, 4616 const unsigned char *pk 4617 ) 4618 { 4619 unsigned char h[64]; 4620 unsigned char checkr[32]; 4621 ge_p3 A; 4622 ge_p2 R; 4623 unsigned long long i; 4624 4625 *mlen = -1; 4626 if (smlen < 64) return -1; 4627 if (sm[63] & 224) return -1; 4628 if (ge_frombytes_negate_vartime(&A,pk) != 0) return -1; 4629 4630 for (i = 0;i < smlen;++i) m[i] = sm[i]; 4631 for (i = 0;i < 32;++i) m[32 + i] = pk[i]; 4632 crypto_hash_sha512(h,m,smlen); 4633 sc_reduce(h); 4634 4635 ge_double_scalarmult_vartime(&R,h,&A,sm + 32); 4636 ge_tobytes(checkr,&R); 4637 if (crypto_verify_32(checkr,sm) != 0) { 4638 for (i = 0;i < smlen;++i) m[i] = 0; 4639 return -1; 4640 } 4641 4642 for (i = 0;i < smlen - 64;++i) m[i] = sm[64 + i]; 4643 for (i = smlen - 64;i < smlen;++i) m[i] = 0; 4644 *mlen = smlen - 64; 4645 return 0; 4646 }