diff --git a/cipher/md4.c b/cipher/md4.c index 09838080..997dbe0c 100644 --- a/cipher/md4.c +++ b/cipher/md4.c @@ -1,292 +1,298 @@ /* md4.c - MD4 Message-Digest Algorithm * Copyright (C) 2002, 2003 Free Software Foundation, Inc. * * This file is part of Libgcrypt. * * Libgcrypt is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * Libgcrypt is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * * Based on md5.c in libgcrypt, but rewritten to compute md4 checksums * using a public domain md4 implementation with the following comments: * * Modified by Wei Dai from Andrew M. Kuchling's md4.c * The original code and all modifications are in the public domain. * * This is the original introductory comment: * * md4.c : MD4 hash algorithm. * * Part of the Python Cryptography Toolkit, version 1.1 * * Distribute and use freely; there are no restrictions on further * dissemination and usage except those imposed by the laws of your * country of residence. * */ /* MD4 test suite: * MD4 ("") = 31d6cfe0d16ae931b73c59d7e0c089c0 * MD4 ("a") = bde52cb31de33e46245e05fbdbd6fb24 * MD4 ("abc") = a448017aaf21d8525fc10ae87aa6729d * MD4 ("message digest") = d9130a8164549fe818874806e1c7014b * MD4 ("abcdefghijklmnopqrstuvwxyz") = d79e1c308aa5bbcdeea8ed63df412da9 * MD4 ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789") = * 043f8582f241db351ce627e153e7f0e4 * MD4 ("123456789012345678901234567890123456789012345678901234567890123456 * 78901234567890") = e33b4ddc9c38f2199c3e7b164fcc0536 */ #include #include #include #include #include "g10lib.h" #include "cipher.h" #include "bithelp.h" #include "bufhelp.h" #include "hash-common.h" typedef struct { gcry_md_block_ctx_t bctx; u32 A,B,C,D; /* chaining variables */ } MD4_CONTEXT; static unsigned int transform ( void *c, const unsigned char *data, size_t nblks ); static void md4_init (void *context, unsigned int flags) { MD4_CONTEXT *ctx = context; (void)flags; ctx->A = 0x67452301; ctx->B = 0xefcdab89; ctx->C = 0x98badcfe; ctx->D = 0x10325476; ctx->bctx.nblocks = 0; ctx->bctx.nblocks_high = 0; ctx->bctx.count = 0; ctx->bctx.blocksize = 64; ctx->bctx.bwrite = transform; } #define F(x, y, z) ((z) ^ ((x) & ((y) ^ (z)))) #define G(x, y, z) (((x) & (y)) | ((x) & (z)) | ((y) & (z))) #define H(x, y, z) ((x) ^ (y) ^ (z)) /**************** * transform 64 bytes */ static unsigned int transform_blk ( void *c, const unsigned char *data ) { MD4_CONTEXT *ctx = c; u32 in[16]; register u32 A = ctx->A; register u32 B = ctx->B; register u32 C = ctx->C; register u32 D = ctx->D; int i; for ( i = 0; i < 16; i++ ) in[i] = buf_get_le32(data + i * 4); /* Round 1. */ #define function(a,b,c,d,k,s) a=rol(a+F(b,c,d)+in[k],s); function(A,B,C,D, 0, 3); function(D,A,B,C, 1, 7); function(C,D,A,B, 2,11); function(B,C,D,A, 3,19); function(A,B,C,D, 4, 3); function(D,A,B,C, 5, 7); function(C,D,A,B, 6,11); function(B,C,D,A, 7,19); function(A,B,C,D, 8, 3); function(D,A,B,C, 9, 7); function(C,D,A,B,10,11); function(B,C,D,A,11,19); function(A,B,C,D,12, 3); function(D,A,B,C,13, 7); function(C,D,A,B,14,11); function(B,C,D,A,15,19); #undef function /* Round 2. */ #define function(a,b,c,d,k,s) a=rol(a+G(b,c,d)+in[k]+0x5a827999,s); function(A,B,C,D, 0, 3); function(D,A,B,C, 4, 5); function(C,D,A,B, 8, 9); function(B,C,D,A,12,13); function(A,B,C,D, 1, 3); function(D,A,B,C, 5, 5); function(C,D,A,B, 9, 9); function(B,C,D,A,13,13); function(A,B,C,D, 2, 3); function(D,A,B,C, 6, 5); function(C,D,A,B,10, 9); function(B,C,D,A,14,13); function(A,B,C,D, 3, 3); function(D,A,B,C, 7, 5); function(C,D,A,B,11, 9); function(B,C,D,A,15,13); #undef function /* Round 3. */ #define function(a,b,c,d,k,s) a=rol(a+H(b,c,d)+in[k]+0x6ed9eba1,s); function(A,B,C,D, 0, 3); function(D,A,B,C, 8, 9); function(C,D,A,B, 4,11); function(B,C,D,A,12,15); function(A,B,C,D, 2, 3); function(D,A,B,C,10, 9); function(C,D,A,B, 6,11); function(B,C,D,A,14,15); function(A,B,C,D, 1, 3); function(D,A,B,C, 9, 9); function(C,D,A,B, 5,11); function(B,C,D,A,13,15); function(A,B,C,D, 3, 3); function(D,A,B,C,11, 9); function(C,D,A,B, 7,11); function(B,C,D,A,15,15); /* Put checksum in context given as argument. */ ctx->A += A; ctx->B += B; ctx->C += C; ctx->D += D; return /*burn_stack*/ 80+6*sizeof(void*); } static unsigned int transform ( void *c, const unsigned char *data, size_t nblks ) { unsigned int burn; do { burn = transform_blk (c, data); data += 64; } while (--nblks); return burn; } /* The routine final terminates the message-digest computation and * ends with the desired message digest in mdContext->digest[0...15]. * The handle is prepared for a new MD4 cycle. * Returns 16 bytes representing the digest. */ static void md4_final( void *context ) { MD4_CONTEXT *hd = context; u32 t, th, msb, lsb; byte *p; unsigned int burn; _gcry_md_block_write(hd, NULL, 0); /* flush */; t = hd->bctx.nblocks; if (sizeof t == sizeof hd->bctx.nblocks) th = hd->bctx.nblocks_high; else th = hd->bctx.nblocks >> 32; /* multiply by 64 to make a byte count */ lsb = t << 6; msb = (th << 6) | (t >> 26); /* add the count */ t = lsb; if( (lsb += hd->bctx.count) < t ) msb++; /* multiply by 8 to make a bit count */ t = lsb; lsb <<= 3; msb <<= 3; msb |= t >> 29; - if( hd->bctx.count < 56 ) /* enough room */ + if (hd->bctx.count < 56) /* enough room */ { hd->bctx.buf[hd->bctx.count++] = 0x80; /* pad */ - while( hd->bctx.count < 56 ) - hd->bctx.buf[hd->bctx.count++] = 0; /* pad */ + if (hd->bctx.count < 56) + memset (&hd->bctx.buf[hd->bctx.count], 0, 56 - hd->bctx.count); + hd->bctx.count = 56; + + /* append the 64 bit count */ + buf_put_le32(hd->bctx.buf + 56, lsb); + buf_put_le32(hd->bctx.buf + 60, msb); + burn = transform (hd, hd->bctx.buf, 1); } else /* need one extra block */ { hd->bctx.buf[hd->bctx.count++] = 0x80; /* pad character */ - while( hd->bctx.count < 64 ) - hd->bctx.buf[hd->bctx.count++] = 0; - _gcry_md_block_write(hd, NULL, 0); /* flush */; - memset(hd->bctx.buf, 0, 56 ); /* fill next block with zeroes */ + /* fill pad and next block with zeroes */ + memset (&hd->bctx.buf[hd->bctx.count], 0, 64 - hd->bctx.count + 56); + hd->bctx.count = 64 + 56; + + /* append the 64 bit count */ + buf_put_le32(hd->bctx.buf + 56, lsb); + buf_put_le32(hd->bctx.buf + 60, msb); + burn = transform (hd, hd->bctx.buf, 2); } - /* append the 64 bit count */ - buf_put_le32(hd->bctx.buf + 56, lsb); - buf_put_le32(hd->bctx.buf + 60, msb); - burn = transform ( hd, hd->bctx.buf, 1 ); - _gcry_burn_stack (burn); p = hd->bctx.buf; #define X(a) do { buf_put_le32(p, hd->a); p += 4; } while(0) X(A); X(B); X(C); X(D); #undef X + _gcry_burn_stack (burn); } static byte * md4_read (void *context) { MD4_CONTEXT *hd = context; return hd->bctx.buf; } static byte asn[18] = /* Object ID is 1.2.840.113549.2.4 */ { 0x30, 0x20, 0x30, 0x0c, 0x06, 0x08, 0x2a, 0x86,0x48, 0x86, 0xf7, 0x0d, 0x02, 0x04, 0x05, 0x00, 0x04, 0x10 }; static gcry_md_oid_spec_t oid_spec_md4[] = { /* iso.member-body.us.rsadsi.digestAlgorithm.md4 */ { "1.2.840.113549.2.4" }, { NULL }, }; gcry_md_spec_t _gcry_digest_spec_md4 = { GCRY_MD_MD4, {0, 0}, "MD4", asn, DIM (asn), oid_spec_md4,16, md4_init, _gcry_md_block_write, md4_final, md4_read, NULL, NULL, NULL, sizeof (MD4_CONTEXT) }; diff --git a/cipher/md5.c b/cipher/md5.c index e35a500c..c432502f 100644 --- a/cipher/md5.c +++ b/cipher/md5.c @@ -1,318 +1,324 @@ /* md5.c - MD5 Message-Digest Algorithm * Copyright (C) 1995,1996,1998,1999,2001,2002, * 2003 Free Software Foundation, Inc. * * This file is part of Libgcrypt. * * Libgcrypt is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * Libgcrypt is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * * According to the definition of MD5 in RFC 1321 from April 1992. * NOTE: This is *not* the same file as the one from glibc. * Written by Ulrich Drepper , 1995. * heavily modified for GnuPG by Werner Koch */ /* Test values: * "" D4 1D 8C D9 8F 00 B2 04 E9 80 09 98 EC F8 42 7E * "a" 0C C1 75 B9 C0 F1 B6 A8 31 C3 99 E2 69 77 26 61 * "abc 90 01 50 98 3C D2 4F B0 D6 96 3F 7D 28 E1 7F 72 * "message digest" F9 6B 69 7D 7C B7 93 8D 52 5A 2F 31 AA F1 61 D0 */ #include #include #include #include #include "g10lib.h" #include "cipher.h" #include "bithelp.h" #include "bufhelp.h" #include "hash-common.h" typedef struct { gcry_md_block_ctx_t bctx; u32 A,B,C,D; /* chaining variables */ } MD5_CONTEXT; static unsigned int transform ( void *ctx, const unsigned char *data, size_t datalen ); static void md5_init( void *context, unsigned int flags) { MD5_CONTEXT *ctx = context; (void)flags; ctx->A = 0x67452301; ctx->B = 0xefcdab89; ctx->C = 0x98badcfe; ctx->D = 0x10325476; ctx->bctx.nblocks = 0; ctx->bctx.nblocks_high = 0; ctx->bctx.count = 0; ctx->bctx.blocksize = 64; ctx->bctx.bwrite = transform; } /* These are the four functions used in the four steps of the MD5 algorithm and defined in the RFC 1321. The first function is a little bit optimized (as found in Colin Plumbs public domain implementation). */ /* #define FF(b, c, d) ((b & c) | (~b & d)) */ #define FF(b, c, d) (d ^ (b & (c ^ d))) #define FG(b, c, d) FF (d, b, c) #define FH(b, c, d) (b ^ c ^ d) #define FI(b, c, d) (c ^ (b | ~d)) /**************** * transform 64 bytes */ static unsigned int transform_blk ( void *c, const unsigned char *data ) { MD5_CONTEXT *ctx = c; u32 correct_words[16]; register u32 A = ctx->A; register u32 B = ctx->B; register u32 C = ctx->C; register u32 D = ctx->D; u32 *cwp = correct_words; int i; for ( i = 0; i < 16; i++ ) correct_words[i] = buf_get_le32(data + i * 4); #define OP(a, b, c, d, s, T) \ do \ { \ a += FF (b, c, d) + (*cwp++) + T; \ a = rol(a, s); \ a += b; \ } \ while (0) /* Before we start, one word about the strange constants. They are defined in RFC 1321 as T[i] = (int) (4294967296.0 * fabs (sin (i))), i=1..64 */ /* Round 1. */ OP (A, B, C, D, 7, 0xd76aa478); OP (D, A, B, C, 12, 0xe8c7b756); OP (C, D, A, B, 17, 0x242070db); OP (B, C, D, A, 22, 0xc1bdceee); OP (A, B, C, D, 7, 0xf57c0faf); OP (D, A, B, C, 12, 0x4787c62a); OP (C, D, A, B, 17, 0xa8304613); OP (B, C, D, A, 22, 0xfd469501); OP (A, B, C, D, 7, 0x698098d8); OP (D, A, B, C, 12, 0x8b44f7af); OP (C, D, A, B, 17, 0xffff5bb1); OP (B, C, D, A, 22, 0x895cd7be); OP (A, B, C, D, 7, 0x6b901122); OP (D, A, B, C, 12, 0xfd987193); OP (C, D, A, B, 17, 0xa679438e); OP (B, C, D, A, 22, 0x49b40821); #undef OP #define OP(f, a, b, c, d, k, s, T) \ do \ { \ a += f (b, c, d) + correct_words[k] + T; \ a = rol(a, s); \ a += b; \ } \ while (0) /* Round 2. */ OP (FG, A, B, C, D, 1, 5, 0xf61e2562); OP (FG, D, A, B, C, 6, 9, 0xc040b340); OP (FG, C, D, A, B, 11, 14, 0x265e5a51); OP (FG, B, C, D, A, 0, 20, 0xe9b6c7aa); OP (FG, A, B, C, D, 5, 5, 0xd62f105d); OP (FG, D, A, B, C, 10, 9, 0x02441453); OP (FG, C, D, A, B, 15, 14, 0xd8a1e681); OP (FG, B, C, D, A, 4, 20, 0xe7d3fbc8); OP (FG, A, B, C, D, 9, 5, 0x21e1cde6); OP (FG, D, A, B, C, 14, 9, 0xc33707d6); OP (FG, C, D, A, B, 3, 14, 0xf4d50d87); OP (FG, B, C, D, A, 8, 20, 0x455a14ed); OP (FG, A, B, C, D, 13, 5, 0xa9e3e905); OP (FG, D, A, B, C, 2, 9, 0xfcefa3f8); OP (FG, C, D, A, B, 7, 14, 0x676f02d9); OP (FG, B, C, D, A, 12, 20, 0x8d2a4c8a); /* Round 3. */ OP (FH, A, B, C, D, 5, 4, 0xfffa3942); OP (FH, D, A, B, C, 8, 11, 0x8771f681); OP (FH, C, D, A, B, 11, 16, 0x6d9d6122); OP (FH, B, C, D, A, 14, 23, 0xfde5380c); OP (FH, A, B, C, D, 1, 4, 0xa4beea44); OP (FH, D, A, B, C, 4, 11, 0x4bdecfa9); OP (FH, C, D, A, B, 7, 16, 0xf6bb4b60); OP (FH, B, C, D, A, 10, 23, 0xbebfbc70); OP (FH, A, B, C, D, 13, 4, 0x289b7ec6); OP (FH, D, A, B, C, 0, 11, 0xeaa127fa); OP (FH, C, D, A, B, 3, 16, 0xd4ef3085); OP (FH, B, C, D, A, 6, 23, 0x04881d05); OP (FH, A, B, C, D, 9, 4, 0xd9d4d039); OP (FH, D, A, B, C, 12, 11, 0xe6db99e5); OP (FH, C, D, A, B, 15, 16, 0x1fa27cf8); OP (FH, B, C, D, A, 2, 23, 0xc4ac5665); /* Round 4. */ OP (FI, A, B, C, D, 0, 6, 0xf4292244); OP (FI, D, A, B, C, 7, 10, 0x432aff97); OP (FI, C, D, A, B, 14, 15, 0xab9423a7); OP (FI, B, C, D, A, 5, 21, 0xfc93a039); OP (FI, A, B, C, D, 12, 6, 0x655b59c3); OP (FI, D, A, B, C, 3, 10, 0x8f0ccc92); OP (FI, C, D, A, B, 10, 15, 0xffeff47d); OP (FI, B, C, D, A, 1, 21, 0x85845dd1); OP (FI, A, B, C, D, 8, 6, 0x6fa87e4f); OP (FI, D, A, B, C, 15, 10, 0xfe2ce6e0); OP (FI, C, D, A, B, 6, 15, 0xa3014314); OP (FI, B, C, D, A, 13, 21, 0x4e0811a1); OP (FI, A, B, C, D, 4, 6, 0xf7537e82); OP (FI, D, A, B, C, 11, 10, 0xbd3af235); OP (FI, C, D, A, B, 2, 15, 0x2ad7d2bb); OP (FI, B, C, D, A, 9, 21, 0xeb86d391); /* Put checksum in context given as argument. */ ctx->A += A; ctx->B += B; ctx->C += C; ctx->D += D; return /*burn_stack*/ 80+6*sizeof(void*); } static unsigned int transform ( void *c, const unsigned char *data, size_t nblks ) { unsigned int burn; do { burn = transform_blk (c, data); data += 64; } while (--nblks); return burn; } /* The routine final terminates the message-digest computation and * ends with the desired message digest in mdContext->digest[0...15]. * The handle is prepared for a new MD5 cycle. * Returns 16 bytes representing the digest. */ static void md5_final( void *context) { MD5_CONTEXT *hd = context; u32 t, th, msb, lsb; byte *p; unsigned int burn; _gcry_md_block_write(hd, NULL, 0); /* flush */; t = hd->bctx.nblocks; if (sizeof t == sizeof hd->bctx.nblocks) th = hd->bctx.nblocks_high; else th = hd->bctx.nblocks >> 32; /* multiply by 64 to make a byte count */ lsb = t << 6; msb = (th << 6) | (t >> 26); /* add the count */ t = lsb; if( (lsb += hd->bctx.count) < t ) msb++; /* multiply by 8 to make a bit count */ t = lsb; lsb <<= 3; msb <<= 3; msb |= t >> 29; - if( hd->bctx.count < 56 ) /* enough room */ + if (hd->bctx.count < 56) /* enough room */ { hd->bctx.buf[hd->bctx.count++] = 0x80; /* pad */ - while( hd->bctx.count < 56 ) - hd->bctx.buf[hd->bctx.count++] = 0; /* pad */ + if (hd->bctx.count < 56) + memset (&hd->bctx.buf[hd->bctx.count], 0, 56 - hd->bctx.count); + hd->bctx.count = 56; + + /* append the 64 bit count */ + buf_put_le32(hd->bctx.buf + 56, lsb); + buf_put_le32(hd->bctx.buf + 60, msb); + burn = transform (hd, hd->bctx.buf, 1); } - else /* need one extra block */ + else /* need one extra block */ { hd->bctx.buf[hd->bctx.count++] = 0x80; /* pad character */ - while( hd->bctx.count < 64 ) - hd->bctx.buf[hd->bctx.count++] = 0; - _gcry_md_block_write(hd, NULL, 0); /* flush */; - memset(hd->bctx.buf, 0, 56 ); /* fill next block with zeroes */ + /* fill pad and next block with zeroes */ + memset (&hd->bctx.buf[hd->bctx.count], 0, 64 - hd->bctx.count + 56); + hd->bctx.count = 64 + 56; + + /* append the 64 bit count */ + buf_put_le32(hd->bctx.buf + 56, lsb); + buf_put_le32(hd->bctx.buf + 60, msb); + burn = transform (hd, hd->bctx.buf, 2); } - /* append the 64 bit count */ - buf_put_le32(hd->bctx.buf + 56, lsb); - buf_put_le32(hd->bctx.buf + 60, msb); - burn = transform ( hd, hd->bctx.buf, 1 ); - _gcry_burn_stack (burn); p = hd->bctx.buf; #define X(a) do { buf_put_le32(p, hd->a); p += 4; } while(0) X(A); X(B); X(C); X(D); #undef X + _gcry_burn_stack (burn); } static byte * md5_read( void *context ) { MD5_CONTEXT *hd = (MD5_CONTEXT *) context; return hd->bctx.buf; } static byte asn[18] = /* Object ID is 1.2.840.113549.2.5 */ { 0x30, 0x20, 0x30, 0x0c, 0x06, 0x08, 0x2a, 0x86,0x48, 0x86, 0xf7, 0x0d, 0x02, 0x05, 0x05, 0x00, 0x04, 0x10 }; static gcry_md_oid_spec_t oid_spec_md5[] = { /* iso.member-body.us.rsadsi.pkcs.pkcs-1.4 (md5WithRSAEncryption) */ { "1.2.840.113549.1.1.4" }, /* RSADSI digestAlgorithm MD5 */ { "1.2.840.113549.2.5" }, { NULL }, }; gcry_md_spec_t _gcry_digest_spec_md5 = { GCRY_MD_MD5, {0, 0}, "MD5", asn, DIM (asn), oid_spec_md5, 16, md5_init, _gcry_md_block_write, md5_final, md5_read, NULL, NULL, NULL, sizeof (MD5_CONTEXT) }; diff --git a/cipher/rmd160.c b/cipher/rmd160.c index 2d2fae91..231640d2 100644 --- a/cipher/rmd160.c +++ b/cipher/rmd160.c @@ -1,524 +1,531 @@ /* rmd160.c - RIPE-MD160 * Copyright (C) 1998, 2001, 2002, 2003 Free Software Foundation, Inc. * * This file is part of Libgcrypt. * * Libgcrypt is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * Libgcrypt is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #include #include #include #include #include "g10lib.h" #include "hash-common.h" #include "cipher.h" /* Only used for the rmd160_hash_buffer() prototype. */ #include "bithelp.h" #include "bufhelp.h" /********************************* * RIPEMD-160 is not patented, see (as of 25.10.97) * http://www.esat.kuleuven.ac.be/~bosselae/ripemd160.html * Note that the code uses Little Endian byteorder, which is good for * 386 etc, but we must add some conversion when used on a big endian box. * * * Pseudo-code for RIPEMD-160 * * RIPEMD-160 is an iterative hash function that operates on 32-bit words. * The round function takes as input a 5-word chaining variable and a 16-word * message block and maps this to a new chaining variable. All operations are * defined on 32-bit words. Padding is identical to that of MD4. * * * RIPEMD-160: definitions * * * nonlinear functions at bit level: exor, mux, -, mux, - * * f(j, x, y, z) = x XOR y XOR z (0 <= j <= 15) * f(j, x, y, z) = (x AND y) OR (NOT(x) AND z) (16 <= j <= 31) * f(j, x, y, z) = (x OR NOT(y)) XOR z (32 <= j <= 47) * f(j, x, y, z) = (x AND z) OR (y AND NOT(z)) (48 <= j <= 63) * f(j, x, y, z) = x XOR (y OR NOT(z)) (64 <= j <= 79) * * * added constants (hexadecimal) * * K(j) = 0x00000000 (0 <= j <= 15) * K(j) = 0x5A827999 (16 <= j <= 31) int(2**30 x sqrt(2)) * K(j) = 0x6ED9EBA1 (32 <= j <= 47) int(2**30 x sqrt(3)) * K(j) = 0x8F1BBCDC (48 <= j <= 63) int(2**30 x sqrt(5)) * K(j) = 0xA953FD4E (64 <= j <= 79) int(2**30 x sqrt(7)) * K'(j) = 0x50A28BE6 (0 <= j <= 15) int(2**30 x cbrt(2)) * K'(j) = 0x5C4DD124 (16 <= j <= 31) int(2**30 x cbrt(3)) * K'(j) = 0x6D703EF3 (32 <= j <= 47) int(2**30 x cbrt(5)) * K'(j) = 0x7A6D76E9 (48 <= j <= 63) int(2**30 x cbrt(7)) * K'(j) = 0x00000000 (64 <= j <= 79) * * * selection of message word * * r(j) = j (0 <= j <= 15) * r(16..31) = 7, 4, 13, 1, 10, 6, 15, 3, 12, 0, 9, 5, 2, 14, 11, 8 * r(32..47) = 3, 10, 14, 4, 9, 15, 8, 1, 2, 7, 0, 6, 13, 11, 5, 12 * r(48..63) = 1, 9, 11, 10, 0, 8, 12, 4, 13, 3, 7, 15, 14, 5, 6, 2 * r(64..79) = 4, 0, 5, 9, 7, 12, 2, 10, 14, 1, 3, 8, 11, 6, 15, 13 * r0(0..15) = 5, 14, 7, 0, 9, 2, 11, 4, 13, 6, 15, 8, 1, 10, 3, 12 * r0(16..31)= 6, 11, 3, 7, 0, 13, 5, 10, 14, 15, 8, 12, 4, 9, 1, 2 * r0(32..47)= 15, 5, 1, 3, 7, 14, 6, 9, 11, 8, 12, 2, 10, 0, 4, 13 * r0(48..63)= 8, 6, 4, 1, 3, 11, 15, 0, 5, 12, 2, 13, 9, 7, 10, 14 * r0(64..79)= 12, 15, 10, 4, 1, 5, 8, 7, 6, 2, 13, 14, 0, 3, 9, 11 * * * amount for rotate left (rol) * * s(0..15) = 11, 14, 15, 12, 5, 8, 7, 9, 11, 13, 14, 15, 6, 7, 9, 8 * s(16..31) = 7, 6, 8, 13, 11, 9, 7, 15, 7, 12, 15, 9, 11, 7, 13, 12 * s(32..47) = 11, 13, 6, 7, 14, 9, 13, 15, 14, 8, 13, 6, 5, 12, 7, 5 * s(48..63) = 11, 12, 14, 15, 14, 15, 9, 8, 9, 14, 5, 6, 8, 6, 5, 12 * s(64..79) = 9, 15, 5, 11, 6, 8, 13, 12, 5, 12, 13, 14, 11, 8, 5, 6 * s'(0..15) = 8, 9, 9, 11, 13, 15, 15, 5, 7, 7, 8, 11, 14, 14, 12, 6 * s'(16..31)= 9, 13, 15, 7, 12, 8, 9, 11, 7, 7, 12, 7, 6, 15, 13, 11 * s'(32..47)= 9, 7, 15, 11, 8, 6, 6, 14, 12, 13, 5, 14, 13, 13, 7, 5 * s'(48..63)= 15, 5, 8, 11, 14, 14, 6, 14, 6, 9, 12, 9, 12, 5, 15, 8 * s'(64..79)= 8, 5, 12, 9, 12, 5, 14, 6, 8, 13, 6, 5, 15, 13, 11, 11 * * * initial value (hexadecimal) * * h0 = 0x67452301; h1 = 0xEFCDAB89; h2 = 0x98BADCFE; h3 = 0x10325476; * h4 = 0xC3D2E1F0; * * * RIPEMD-160: pseudo-code * * It is assumed that the message after padding consists of t 16-word blocks * that will be denoted with X[i][j], with 0 <= i <= t-1 and 0 <= j <= 15. * The symbol [+] denotes addition modulo 2**32 and rol_s denotes cyclic left * shift (rotate) over s positions. * * * for i := 0 to t-1 { * A := h0; B := h1; C := h2; D = h3; E = h4; * A' := h0; B' := h1; C' := h2; D' = h3; E' = h4; * for j := 0 to 79 { * T := rol_s(j)(A [+] f(j, B, C, D) [+] X[i][r(j)] [+] K(j)) [+] E; * A := E; E := D; D := rol_10(C); C := B; B := T; * T := rol_s'(j)(A' [+] f(79-j, B', C', D') [+] X[i][r'(j)] [+] K'(j)) [+] E'; * A' := E'; E' := D'; D' := rol_10(C'); C' := B'; B' := T; * } * T := h1 [+] C [+] D'; h1 := h2 [+] D [+] E'; h2 := h3 [+] E [+] A'; * h3 := h4 [+] A [+] B'; h4 := h0 [+] B [+] C'; h0 := T; * } */ /* Some examples: * "" 9c1185a5c5e9fc54612808977ee8f548b2258d31 * "a" 0bdc9d2d256b3ee9daae347be6f4dc835a467ffe * "abc" 8eb208f7e05d987a9b044a8e98c6b087f15a0bfc * "message digest" 5d0689ef49d2fae572b881b123a85ffa21595f36 * "a...z" f71c27109c692c1b56bbdceb5b9d2865b3708dbc * "abcdbcde...nopq" 12a053384a9c0c88e405a06c27dcf49ada62eb2b * "A...Za...z0...9" b0e20b6e3116640286ed3a87a5713079b21f5189 * 8 times "1234567890" 9b752e45573d4b39f4dbd3323cab82bf63326bfb * 1 million times "a" 52783243c1697bdbe16d37f97f68f08325dc1528 */ typedef struct { gcry_md_block_ctx_t bctx; u32 h0,h1,h2,h3,h4; } RMD160_CONTEXT; static unsigned int transform ( void *ctx, const unsigned char *data, size_t nblks ); static void rmd160_init (void *context, unsigned int flags) { RMD160_CONTEXT *hd = context; (void)flags; hd->h0 = 0x67452301; hd->h1 = 0xEFCDAB89; hd->h2 = 0x98BADCFE; hd->h3 = 0x10325476; hd->h4 = 0xC3D2E1F0; hd->bctx.nblocks = 0; hd->bctx.nblocks_high = 0; hd->bctx.count = 0; hd->bctx.blocksize = 64; hd->bctx.bwrite = transform; } /**************** * Transform the message X which consists of 16 32-bit-words */ static unsigned int transform_blk ( void *ctx, const unsigned char *data ) { RMD160_CONTEXT *hd = ctx; register u32 al, ar, bl, br, cl, cr, dl, dr, el, er; u32 x[16]; int i; for ( i = 0; i < 16; i++ ) x[i] = buf_get_le32(data + i * 4); #define K0 0x00000000 #define K1 0x5A827999 #define K2 0x6ED9EBA1 #define K3 0x8F1BBCDC #define K4 0xA953FD4E #define KK0 0x50A28BE6 #define KK1 0x5C4DD124 #define KK2 0x6D703EF3 #define KK3 0x7A6D76E9 #define KK4 0x00000000 #define F0(x,y,z) ( (x) ^ (y) ^ (z) ) #define F1(x,y,z) ( ((x) & (y)) | (~(x) & (z)) ) #define F2(x,y,z) ( ((x) | ~(y)) ^ (z) ) #define F3(x,y,z) ( ((x) & (z)) | ((y) & ~(z)) ) #define F4(x,y,z) ( (x) ^ ((y) | ~(z)) ) #define R(a,b,c,d,e,f,k,r,s) do { a += f(b,c,d) + k + x[r]; \ a = rol(a,s) + e; \ c = rol(c,10); \ } while(0) /* left lane and right lanes interleaved */ al = ar = hd->h0; bl = br = hd->h1; cl = cr = hd->h2; dl = dr = hd->h3; el = er = hd->h4; R( al, bl, cl, dl, el, F0, K0, 0, 11 ); R( ar, br, cr, dr, er, F4, KK0, 5, 8); R( el, al, bl, cl, dl, F0, K0, 1, 14 ); R( er, ar, br, cr, dr, F4, KK0, 14, 9); R( dl, el, al, bl, cl, F0, K0, 2, 15 ); R( dr, er, ar, br, cr, F4, KK0, 7, 9); R( cl, dl, el, al, bl, F0, K0, 3, 12 ); R( cr, dr, er, ar, br, F4, KK0, 0, 11); R( bl, cl, dl, el, al, F0, K0, 4, 5 ); R( br, cr, dr, er, ar, F4, KK0, 9, 13); R( al, bl, cl, dl, el, F0, K0, 5, 8 ); R( ar, br, cr, dr, er, F4, KK0, 2, 15); R( el, al, bl, cl, dl, F0, K0, 6, 7 ); R( er, ar, br, cr, dr, F4, KK0, 11, 15); R( dl, el, al, bl, cl, F0, K0, 7, 9 ); R( dr, er, ar, br, cr, F4, KK0, 4, 5); R( cl, dl, el, al, bl, F0, K0, 8, 11 ); R( cr, dr, er, ar, br, F4, KK0, 13, 7); R( bl, cl, dl, el, al, F0, K0, 9, 13 ); R( br, cr, dr, er, ar, F4, KK0, 6, 7); R( al, bl, cl, dl, el, F0, K0, 10, 14 ); R( ar, br, cr, dr, er, F4, KK0, 15, 8); R( el, al, bl, cl, dl, F0, K0, 11, 15 ); R( er, ar, br, cr, dr, F4, KK0, 8, 11); R( dl, el, al, bl, cl, F0, K0, 12, 6 ); R( dr, er, ar, br, cr, F4, KK0, 1, 14); R( cl, dl, el, al, bl, F0, K0, 13, 7 ); R( cr, dr, er, ar, br, F4, KK0, 10, 14); R( bl, cl, dl, el, al, F0, K0, 14, 9 ); R( br, cr, dr, er, ar, F4, KK0, 3, 12); R( al, bl, cl, dl, el, F0, K0, 15, 8 ); R( ar, br, cr, dr, er, F4, KK0, 12, 6); R( el, al, bl, cl, dl, F1, K1, 7, 7 ); R( er, ar, br, cr, dr, F3, KK1, 6, 9); R( dl, el, al, bl, cl, F1, K1, 4, 6 ); R( dr, er, ar, br, cr, F3, KK1, 11, 13); R( cl, dl, el, al, bl, F1, K1, 13, 8 ); R( cr, dr, er, ar, br, F3, KK1, 3, 15); R( bl, cl, dl, el, al, F1, K1, 1, 13 ); R( br, cr, dr, er, ar, F3, KK1, 7, 7); R( al, bl, cl, dl, el, F1, K1, 10, 11 ); R( ar, br, cr, dr, er, F3, KK1, 0, 12); R( el, al, bl, cl, dl, F1, K1, 6, 9 ); R( er, ar, br, cr, dr, F3, KK1, 13, 8); R( dl, el, al, bl, cl, F1, K1, 15, 7 ); R( dr, er, ar, br, cr, F3, KK1, 5, 9); R( cl, dl, el, al, bl, F1, K1, 3, 15 ); R( cr, dr, er, ar, br, F3, KK1, 10, 11); R( bl, cl, dl, el, al, F1, K1, 12, 7 ); R( br, cr, dr, er, ar, F3, KK1, 14, 7); R( al, bl, cl, dl, el, F1, K1, 0, 12 ); R( ar, br, cr, dr, er, F3, KK1, 15, 7); R( el, al, bl, cl, dl, F1, K1, 9, 15 ); R( er, ar, br, cr, dr, F3, KK1, 8, 12); R( dl, el, al, bl, cl, F1, K1, 5, 9 ); R( dr, er, ar, br, cr, F3, KK1, 12, 7); R( cl, dl, el, al, bl, F1, K1, 2, 11 ); R( cr, dr, er, ar, br, F3, KK1, 4, 6); R( bl, cl, dl, el, al, F1, K1, 14, 7 ); R( br, cr, dr, er, ar, F3, KK1, 9, 15); R( al, bl, cl, dl, el, F1, K1, 11, 13 ); R( ar, br, cr, dr, er, F3, KK1, 1, 13); R( el, al, bl, cl, dl, F1, K1, 8, 12 ); R( er, ar, br, cr, dr, F3, KK1, 2, 11); R( dl, el, al, bl, cl, F2, K2, 3, 11 ); R( dr, er, ar, br, cr, F2, KK2, 15, 9); R( cl, dl, el, al, bl, F2, K2, 10, 13 ); R( cr, dr, er, ar, br, F2, KK2, 5, 7); R( bl, cl, dl, el, al, F2, K2, 14, 6 ); R( br, cr, dr, er, ar, F2, KK2, 1, 15); R( al, bl, cl, dl, el, F2, K2, 4, 7 ); R( ar, br, cr, dr, er, F2, KK2, 3, 11); R( el, al, bl, cl, dl, F2, K2, 9, 14 ); R( er, ar, br, cr, dr, F2, KK2, 7, 8); R( dl, el, al, bl, cl, F2, K2, 15, 9 ); R( dr, er, ar, br, cr, F2, KK2, 14, 6); R( cl, dl, el, al, bl, F2, K2, 8, 13 ); R( cr, dr, er, ar, br, F2, KK2, 6, 6); R( bl, cl, dl, el, al, F2, K2, 1, 15 ); R( br, cr, dr, er, ar, F2, KK2, 9, 14); R( al, bl, cl, dl, el, F2, K2, 2, 14 ); R( ar, br, cr, dr, er, F2, KK2, 11, 12); R( el, al, bl, cl, dl, F2, K2, 7, 8 ); R( er, ar, br, cr, dr, F2, KK2, 8, 13); R( dl, el, al, bl, cl, F2, K2, 0, 13 ); R( dr, er, ar, br, cr, F2, KK2, 12, 5); R( cl, dl, el, al, bl, F2, K2, 6, 6 ); R( cr, dr, er, ar, br, F2, KK2, 2, 14); R( bl, cl, dl, el, al, F2, K2, 13, 5 ); R( br, cr, dr, er, ar, F2, KK2, 10, 13); R( al, bl, cl, dl, el, F2, K2, 11, 12 ); R( ar, br, cr, dr, er, F2, KK2, 0, 13); R( el, al, bl, cl, dl, F2, K2, 5, 7 ); R( er, ar, br, cr, dr, F2, KK2, 4, 7); R( dl, el, al, bl, cl, F2, K2, 12, 5 ); R( dr, er, ar, br, cr, F2, KK2, 13, 5); R( cl, dl, el, al, bl, F3, K3, 1, 11 ); R( cr, dr, er, ar, br, F1, KK3, 8, 15); R( bl, cl, dl, el, al, F3, K3, 9, 12 ); R( br, cr, dr, er, ar, F1, KK3, 6, 5); R( al, bl, cl, dl, el, F3, K3, 11, 14 ); R( ar, br, cr, dr, er, F1, KK3, 4, 8); R( el, al, bl, cl, dl, F3, K3, 10, 15 ); R( er, ar, br, cr, dr, F1, KK3, 1, 11); R( dl, el, al, bl, cl, F3, K3, 0, 14 ); R( dr, er, ar, br, cr, F1, KK3, 3, 14); R( cl, dl, el, al, bl, F3, K3, 8, 15 ); R( cr, dr, er, ar, br, F1, KK3, 11, 14); R( bl, cl, dl, el, al, F3, K3, 12, 9 ); R( br, cr, dr, er, ar, F1, KK3, 15, 6); R( al, bl, cl, dl, el, F3, K3, 4, 8 ); R( ar, br, cr, dr, er, F1, KK3, 0, 14); R( el, al, bl, cl, dl, F3, K3, 13, 9 ); R( er, ar, br, cr, dr, F1, KK3, 5, 6); R( dl, el, al, bl, cl, F3, K3, 3, 14 ); R( dr, er, ar, br, cr, F1, KK3, 12, 9); R( cl, dl, el, al, bl, F3, K3, 7, 5 ); R( cr, dr, er, ar, br, F1, KK3, 2, 12); R( bl, cl, dl, el, al, F3, K3, 15, 6 ); R( br, cr, dr, er, ar, F1, KK3, 13, 9); R( al, bl, cl, dl, el, F3, K3, 14, 8 ); R( ar, br, cr, dr, er, F1, KK3, 9, 12); R( el, al, bl, cl, dl, F3, K3, 5, 6 ); R( er, ar, br, cr, dr, F1, KK3, 7, 5); R( dl, el, al, bl, cl, F3, K3, 6, 5 ); R( dr, er, ar, br, cr, F1, KK3, 10, 15); R( cl, dl, el, al, bl, F3, K3, 2, 12 ); R( cr, dr, er, ar, br, F1, KK3, 14, 8); R( bl, cl, dl, el, al, F4, K4, 4, 9 ); R( br, cr, dr, er, ar, F0, KK4, 12, 8); R( al, bl, cl, dl, el, F4, K4, 0, 15 ); R( ar, br, cr, dr, er, F0, KK4, 15, 5); R( el, al, bl, cl, dl, F4, K4, 5, 5 ); R( er, ar, br, cr, dr, F0, KK4, 10, 12); R( dl, el, al, bl, cl, F4, K4, 9, 11 ); R( dr, er, ar, br, cr, F0, KK4, 4, 9); R( cl, dl, el, al, bl, F4, K4, 7, 6 ); R( cr, dr, er, ar, br, F0, KK4, 1, 12); R( bl, cl, dl, el, al, F4, K4, 12, 8 ); R( br, cr, dr, er, ar, F0, KK4, 5, 5); R( al, bl, cl, dl, el, F4, K4, 2, 13 ); R( ar, br, cr, dr, er, F0, KK4, 8, 14); R( el, al, bl, cl, dl, F4, K4, 10, 12 ); R( er, ar, br, cr, dr, F0, KK4, 7, 6); R( dl, el, al, bl, cl, F4, K4, 14, 5 ); R( dr, er, ar, br, cr, F0, KK4, 6, 8); R( cl, dl, el, al, bl, F4, K4, 1, 12 ); R( cr, dr, er, ar, br, F0, KK4, 2, 13); R( bl, cl, dl, el, al, F4, K4, 3, 13 ); R( br, cr, dr, er, ar, F0, KK4, 13, 6); R( al, bl, cl, dl, el, F4, K4, 8, 14 ); R( ar, br, cr, dr, er, F0, KK4, 14, 5); R( el, al, bl, cl, dl, F4, K4, 11, 11 ); R( er, ar, br, cr, dr, F0, KK4, 0, 15); R( dl, el, al, bl, cl, F4, K4, 6, 8 ); R( dr, er, ar, br, cr, F0, KK4, 3, 13); R( cl, dl, el, al, bl, F4, K4, 15, 5 ); R( cr, dr, er, ar, br, F0, KK4, 9, 11); R( bl, cl, dl, el, al, F4, K4, 13, 6 ); R( br, cr, dr, er, ar, F0, KK4, 11, 11); dr += cl + hd->h1; hd->h1 = hd->h2 + dl + er; hd->h2 = hd->h3 + el + ar; hd->h3 = hd->h4 + al + br; hd->h4 = hd->h0 + bl + cr; hd->h0 = dr; return /*burn_stack*/ 104+5*sizeof(void*); } static unsigned int transform ( void *c, const unsigned char *data, size_t nblks ) { unsigned int burn; do { burn = transform_blk (c, data); data += 64; } while (--nblks); return burn; } /* * The routine terminates the computation */ static void rmd160_final( void *context ) { RMD160_CONTEXT *hd = context; u32 t, th, msb, lsb; byte *p; unsigned int burn; _gcry_md_block_write(hd, NULL, 0); /* flush */; t = hd->bctx.nblocks; if (sizeof t == sizeof hd->bctx.nblocks) th = hd->bctx.nblocks_high; else th = hd->bctx.nblocks >> 32; /* multiply by 64 to make a byte count */ lsb = t << 6; msb = (th << 6) | (t >> 26); /* add the count */ t = lsb; if( (lsb += hd->bctx.count) < t ) msb++; /* multiply by 8 to make a bit count */ t = lsb; lsb <<= 3; msb <<= 3; msb |= t >> 29; - if( hd->bctx.count < 56 ) /* enough room */ + if (hd->bctx.count < 56) /* enough room */ { hd->bctx.buf[hd->bctx.count++] = 0x80; /* pad */ - while( hd->bctx.count < 56 ) - hd->bctx.buf[hd->bctx.count++] = 0; /* pad */ + if (hd->bctx.count < 56) + memset (&hd->bctx.buf[hd->bctx.count], 0, 56 - hd->bctx.count); + hd->bctx.count = 56; + + /* append the 64 bit count */ + buf_put_le32(hd->bctx.buf + 56, lsb); + buf_put_le32(hd->bctx.buf + 60, msb); + burn = transform (hd, hd->bctx.buf, 1); } - else /* need one extra block */ + else /* need one extra block */ { hd->bctx.buf[hd->bctx.count++] = 0x80; /* pad character */ - while( hd->bctx.count < 64 ) - hd->bctx.buf[hd->bctx.count++] = 0; - _gcry_md_block_write(hd, NULL, 0); /* flush */; - memset(hd->bctx.buf, 0, 56 ); /* fill next block with zeroes */ + /* fill pad and next block with zeroes */ + memset (&hd->bctx.buf[hd->bctx.count], 0, 64 - hd->bctx.count + 56); + hd->bctx.count = 64 + 56; + + /* append the 64 bit count */ + buf_put_le32(hd->bctx.buf + 56, lsb); + buf_put_le32(hd->bctx.buf + 60, msb); + burn = transform (hd, hd->bctx.buf, 2); } - /* append the 64 bit count */ - buf_put_le32(hd->bctx.buf + 56, lsb); - buf_put_le32(hd->bctx.buf + 60, msb); - burn = transform ( hd, hd->bctx.buf, 1 ); - _gcry_burn_stack (burn); p = hd->bctx.buf; #define X(a) do { buf_put_le32(p, hd->h##a); p += 4; } while(0) X(0); X(1); X(2); X(3); X(4); #undef X + + _gcry_burn_stack (burn); } static byte * rmd160_read( void *context ) { RMD160_CONTEXT *hd = context; return hd->bctx.buf; } /**************** * Shortcut functions which puts the hash value of the supplied buffer * into outbuf which must have a size of 20 bytes. */ void _gcry_rmd160_hash_buffer (void *outbuf, const void *buffer, size_t length ) { RMD160_CONTEXT hd; rmd160_init (&hd, 0); _gcry_md_block_write ( &hd, buffer, length ); rmd160_final ( &hd ); memcpy ( outbuf, hd.bctx.buf, 20 ); } /* Variant of the above shortcut function using a multiple buffers. */ static void _gcry_rmd160_hash_buffers (void *outbuf, const gcry_buffer_t *iov, int iovcnt) { RMD160_CONTEXT hd; rmd160_init (&hd, 0); for (;iovcnt > 0; iov++, iovcnt--) _gcry_md_block_write (&hd, (const char*)iov[0].data + iov[0].off, iov[0].len); rmd160_final ( &hd ); memcpy ( outbuf, hd.bctx.buf, 20 ); } static byte asn[15] = /* Object ID is 1.3.36.3.2.1 */ { 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x24, 0x03, 0x02, 0x01, 0x05, 0x00, 0x04, 0x14 }; static gcry_md_oid_spec_t oid_spec_rmd160[] = { /* rsaSignatureWithripemd160 */ { "1.3.36.3.3.1.2" }, /* TeleTrust hash algorithm. */ { "1.3.36.3.2.1" }, { NULL } }; gcry_md_spec_t _gcry_digest_spec_rmd160 = { GCRY_MD_RMD160, {0, 0}, "RIPEMD160", asn, DIM (asn), oid_spec_rmd160, 20, rmd160_init, _gcry_md_block_write, rmd160_final, rmd160_read, NULL, _gcry_rmd160_hash_buffer, _gcry_rmd160_hash_buffers, sizeof (RMD160_CONTEXT) }; diff --git a/cipher/sha256.c b/cipher/sha256.c index e82a9d90..327e1029 100644 --- a/cipher/sha256.c +++ b/cipher/sha256.c @@ -1,769 +1,776 @@ /* sha256.c - SHA256 hash function * Copyright (C) 2003, 2006, 2008, 2009 Free Software Foundation, Inc. * * This file is part of Libgcrypt. * * Libgcrypt is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * Libgcrypt is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this program; if not, see . */ /* Test vectors: "abc" SHA224: 23097d22 3405d822 8642a477 bda255b3 2aadbce4 bda0b3f7 e36c9da7 SHA256: ba7816bf 8f01cfea 414140de 5dae2223 b00361a3 96177a9c b410ff61 f20015ad "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" SHA224: 75388b16 512776cc 5dba5da1 fd890150 b0c6455c b4f58b19 52522525 SHA256: 248d6a61 d20638b8 e5c02693 0c3e6039 a33ce459 64ff2167 f6ecedd4 19db06c1 "a" one million times SHA224: 20794655 980c91d8 bbb4c1ea 97618a4b f03f4258 1948b2ee 4ee7ad67 SHA256: cdc76e5c 9914fb92 81a1c7e2 84d73e67 f1809a48 a497200e 046d39cc c7112cd0 */ #include #include #include #include #include "g10lib.h" #include "bithelp.h" #include "bufhelp.h" #include "cipher.h" #include "hash-common.h" /* USE_SSSE3 indicates whether to compile with Intel SSSE3 code. */ #undef USE_SSSE3 #if defined(__x86_64__) && defined(HAVE_GCC_INLINE_ASM_SSSE3) && \ defined(HAVE_INTEL_SYNTAX_PLATFORM_AS) && \ (defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) || \ defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS)) # define USE_SSSE3 1 #endif /* USE_AVX indicates whether to compile with Intel AVX code. */ #undef USE_AVX #if defined(__x86_64__) && defined(HAVE_GCC_INLINE_ASM_AVX) && \ defined(HAVE_INTEL_SYNTAX_PLATFORM_AS) && \ (defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) || \ defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS)) # define USE_AVX 1 #endif /* USE_AVX2 indicates whether to compile with Intel AVX2/BMI2 code. */ #undef USE_AVX2 #if defined(__x86_64__) && defined(HAVE_GCC_INLINE_ASM_AVX2) && \ defined(HAVE_GCC_INLINE_ASM_BMI2) && \ defined(HAVE_INTEL_SYNTAX_PLATFORM_AS) && \ (defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) || \ defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS)) # define USE_AVX2 1 #endif /* USE_SHAEXT indicates whether to compile with Intel SHA Extension code. */ #undef USE_SHAEXT #if defined(HAVE_GCC_INLINE_ASM_SHAEXT) && \ defined(HAVE_GCC_INLINE_ASM_SSE41) && \ defined(ENABLE_SHAEXT_SUPPORT) # define USE_SHAEXT 1 #endif /* USE_ARM_CE indicates whether to enable ARMv8 Crypto Extension assembly * code. */ #undef USE_ARM_CE #ifdef ENABLE_ARM_CRYPTO_SUPPORT # if defined(HAVE_ARM_ARCH_V6) && defined(__ARMEL__) \ && defined(HAVE_COMPATIBLE_GCC_ARM_PLATFORM_AS) \ && defined(HAVE_GCC_INLINE_ASM_AARCH32_CRYPTO) # define USE_ARM_CE 1 # elif defined(__AARCH64EL__) \ && defined(HAVE_COMPATIBLE_GCC_AARCH64_PLATFORM_AS) \ && defined(HAVE_GCC_INLINE_ASM_AARCH64_CRYPTO) # define USE_ARM_CE 1 # endif #endif typedef struct { gcry_md_block_ctx_t bctx; u32 h0,h1,h2,h3,h4,h5,h6,h7; } SHA256_CONTEXT; /* Assembly implementations use SystemV ABI, ABI conversion and additional * stack to store XMM6-XMM15 needed on Win64. */ #undef ASM_FUNC_ABI #undef ASM_EXTRA_STACK #if defined(USE_SSSE3) || defined(USE_AVX) || defined(USE_AVX2) || \ defined(USE_SHAEXT) # ifdef HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS # define ASM_FUNC_ABI __attribute__((sysv_abi)) # define ASM_EXTRA_STACK (10 * 16 + sizeof(void *) * 4) # else # define ASM_FUNC_ABI # define ASM_EXTRA_STACK 0 # endif #endif #ifdef USE_SSSE3 unsigned int _gcry_sha256_transform_amd64_ssse3(const void *input_data, u32 state[8], size_t num_blks) ASM_FUNC_ABI; static unsigned int do_sha256_transform_amd64_ssse3(void *ctx, const unsigned char *data, size_t nblks) { SHA256_CONTEXT *hd = ctx; return _gcry_sha256_transform_amd64_ssse3 (data, &hd->h0, nblks) + ASM_EXTRA_STACK; } #endif #ifdef USE_AVX unsigned int _gcry_sha256_transform_amd64_avx(const void *input_data, u32 state[8], size_t num_blks) ASM_FUNC_ABI; static unsigned int do_sha256_transform_amd64_avx(void *ctx, const unsigned char *data, size_t nblks) { SHA256_CONTEXT *hd = ctx; return _gcry_sha256_transform_amd64_avx (data, &hd->h0, nblks) + ASM_EXTRA_STACK; } #endif #ifdef USE_AVX2 unsigned int _gcry_sha256_transform_amd64_avx2(const void *input_data, u32 state[8], size_t num_blks) ASM_FUNC_ABI; static unsigned int do_sha256_transform_amd64_avx2(void *ctx, const unsigned char *data, size_t nblks) { SHA256_CONTEXT *hd = ctx; return _gcry_sha256_transform_amd64_avx2 (data, &hd->h0, nblks) + ASM_EXTRA_STACK; } #endif #ifdef USE_SHAEXT /* Does not need ASM_FUNC_ABI */ unsigned int _gcry_sha256_transform_intel_shaext(u32 state[8], const unsigned char *input_data, size_t num_blks); static unsigned int do_sha256_transform_intel_shaext(void *ctx, const unsigned char *data, size_t nblks) { SHA256_CONTEXT *hd = ctx; return _gcry_sha256_transform_intel_shaext (&hd->h0, data, nblks); } #endif #ifdef USE_ARM_CE unsigned int _gcry_sha256_transform_armv8_ce(u32 state[8], const void *input_data, size_t num_blks); static unsigned int do_sha256_transform_armv8_ce(void *ctx, const unsigned char *data, size_t nblks) { SHA256_CONTEXT *hd = ctx; return _gcry_sha256_transform_armv8_ce (&hd->h0, data, nblks); } #endif static unsigned int do_transform_generic (void *ctx, const unsigned char *data, size_t nblks); static void sha256_init (void *context, unsigned int flags) { SHA256_CONTEXT *hd = context; unsigned int features = _gcry_get_hw_features (); (void)flags; hd->h0 = 0x6a09e667; hd->h1 = 0xbb67ae85; hd->h2 = 0x3c6ef372; hd->h3 = 0xa54ff53a; hd->h4 = 0x510e527f; hd->h5 = 0x9b05688c; hd->h6 = 0x1f83d9ab; hd->h7 = 0x5be0cd19; hd->bctx.nblocks = 0; hd->bctx.nblocks_high = 0; hd->bctx.count = 0; hd->bctx.blocksize = 64; /* Order of feature checks is important here; last match will be * selected. Keep slower implementations at the top and faster at * the bottom. */ hd->bctx.bwrite = do_transform_generic; #ifdef USE_SSSE3 if ((features & HWF_INTEL_SSSE3) != 0) hd->bctx.bwrite = do_sha256_transform_amd64_ssse3; #endif #ifdef USE_AVX /* AVX implementation uses SHLD which is known to be slow on non-Intel CPUs. * Therefore use this implementation on Intel CPUs only. */ if ((features & HWF_INTEL_AVX) && (features & HWF_INTEL_FAST_SHLD)) hd->bctx.bwrite = do_sha256_transform_amd64_avx; #endif #ifdef USE_AVX2 if ((features & HWF_INTEL_AVX2) && (features & HWF_INTEL_BMI2)) hd->bctx.bwrite = do_sha256_transform_amd64_avx2; #endif #ifdef USE_SHAEXT if ((features & HWF_INTEL_SHAEXT) && (features & HWF_INTEL_SSE4_1)) hd->bctx.bwrite = do_sha256_transform_intel_shaext; #endif #ifdef USE_ARM_CE if ((features & HWF_ARM_SHA2) != 0) hd->bctx.bwrite = do_sha256_transform_armv8_ce; #endif (void)features; } static void sha224_init (void *context, unsigned int flags) { SHA256_CONTEXT *hd = context; unsigned int features = _gcry_get_hw_features (); (void)flags; hd->h0 = 0xc1059ed8; hd->h1 = 0x367cd507; hd->h2 = 0x3070dd17; hd->h3 = 0xf70e5939; hd->h4 = 0xffc00b31; hd->h5 = 0x68581511; hd->h6 = 0x64f98fa7; hd->h7 = 0xbefa4fa4; hd->bctx.nblocks = 0; hd->bctx.nblocks_high = 0; hd->bctx.count = 0; hd->bctx.blocksize = 64; /* Order of feature checks is important here; last match will be * selected. Keep slower implementations at the top and faster at * the bottom. */ hd->bctx.bwrite = do_transform_generic; #ifdef USE_SSSE3 if ((features & HWF_INTEL_SSSE3) != 0) hd->bctx.bwrite = do_sha256_transform_amd64_ssse3; #endif #ifdef USE_AVX /* AVX implementation uses SHLD which is known to be slow on non-Intel CPUs. * Therefore use this implementation on Intel CPUs only. */ if ((features & HWF_INTEL_AVX) && (features & HWF_INTEL_FAST_SHLD)) hd->bctx.bwrite = do_sha256_transform_amd64_avx; #endif #ifdef USE_AVX2 if ((features & HWF_INTEL_AVX2) && (features & HWF_INTEL_BMI2)) hd->bctx.bwrite = do_sha256_transform_amd64_avx2; #endif #ifdef USE_SHAEXT if ((features & HWF_INTEL_SHAEXT) && (features & HWF_INTEL_SSE4_1)) hd->bctx.bwrite = do_sha256_transform_intel_shaext; #endif #ifdef USE_ARM_CE if ((features & HWF_ARM_SHA2) != 0) hd->bctx.bwrite = do_sha256_transform_armv8_ce; #endif (void)features; } /* Transform the message X which consists of 16 32-bit-words. See FIPS 180-2 for details. */ #define R(a,b,c,d,e,f,g,h,k,w) do \ { \ t1 = (h) + Sum1((e)) + Cho((e),(f),(g)) + (k) + (w); \ t2 = Sum0((a)) + Maj((a),(b),(c)); \ d += t1; \ h = t1 + t2; \ } while (0) /* (4.2) same as SHA-1's F1. */ #define Cho(x, y, z) (z ^ (x & (y ^ z))) /* (4.3) same as SHA-1's F3 */ #define Maj(x, y, z) ((x & y) + (z & (x ^ y))) /* (4.4) */ #define Sum0(x) (ror (x, 2) ^ ror (x, 13) ^ ror (x, 22)) /* (4.5) */ #define Sum1(x) (ror (x, 6) ^ ror (x, 11) ^ ror (x, 25)) /* Message expansion */ #define S0(x) (ror ((x), 7) ^ ror ((x), 18) ^ ((x) >> 3)) /* (4.6) */ #define S1(x) (ror ((x), 17) ^ ror ((x), 19) ^ ((x) >> 10)) /* (4.7) */ #define I(i) ( w[i] = buf_get_be32(data + i * 4) ) #define W(i) ( w[i&0x0f] = S1(w[(i-2) &0x0f]) \ + w[(i-7) &0x0f] \ + S0(w[(i-15)&0x0f]) \ + w[(i-16)&0x0f] ) static unsigned int do_transform_generic (void *ctx, const unsigned char *data, size_t nblks) { SHA256_CONTEXT *hd = ctx; static const u32 K[64] = { 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 }; do { u32 a,b,c,d,e,f,g,h,t1,t2; u32 w[16]; a = hd->h0; b = hd->h1; c = hd->h2; d = hd->h3; e = hd->h4; f = hd->h5; g = hd->h6; h = hd->h7; R(a, b, c, d, e, f, g, h, K[0], I(0)); R(h, a, b, c, d, e, f, g, K[1], I(1)); R(g, h, a, b, c, d, e, f, K[2], I(2)); R(f, g, h, a, b, c, d, e, K[3], I(3)); R(e, f, g, h, a, b, c, d, K[4], I(4)); R(d, e, f, g, h, a, b, c, K[5], I(5)); R(c, d, e, f, g, h, a, b, K[6], I(6)); R(b, c, d, e, f, g, h, a, K[7], I(7)); R(a, b, c, d, e, f, g, h, K[8], I(8)); R(h, a, b, c, d, e, f, g, K[9], I(9)); R(g, h, a, b, c, d, e, f, K[10], I(10)); R(f, g, h, a, b, c, d, e, K[11], I(11)); R(e, f, g, h, a, b, c, d, K[12], I(12)); R(d, e, f, g, h, a, b, c, K[13], I(13)); R(c, d, e, f, g, h, a, b, K[14], I(14)); R(b, c, d, e, f, g, h, a, K[15], I(15)); R(a, b, c, d, e, f, g, h, K[16], W(16)); R(h, a, b, c, d, e, f, g, K[17], W(17)); R(g, h, a, b, c, d, e, f, K[18], W(18)); R(f, g, h, a, b, c, d, e, K[19], W(19)); R(e, f, g, h, a, b, c, d, K[20], W(20)); R(d, e, f, g, h, a, b, c, K[21], W(21)); R(c, d, e, f, g, h, a, b, K[22], W(22)); R(b, c, d, e, f, g, h, a, K[23], W(23)); R(a, b, c, d, e, f, g, h, K[24], W(24)); R(h, a, b, c, d, e, f, g, K[25], W(25)); R(g, h, a, b, c, d, e, f, K[26], W(26)); R(f, g, h, a, b, c, d, e, K[27], W(27)); R(e, f, g, h, a, b, c, d, K[28], W(28)); R(d, e, f, g, h, a, b, c, K[29], W(29)); R(c, d, e, f, g, h, a, b, K[30], W(30)); R(b, c, d, e, f, g, h, a, K[31], W(31)); R(a, b, c, d, e, f, g, h, K[32], W(32)); R(h, a, b, c, d, e, f, g, K[33], W(33)); R(g, h, a, b, c, d, e, f, K[34], W(34)); R(f, g, h, a, b, c, d, e, K[35], W(35)); R(e, f, g, h, a, b, c, d, K[36], W(36)); R(d, e, f, g, h, a, b, c, K[37], W(37)); R(c, d, e, f, g, h, a, b, K[38], W(38)); R(b, c, d, e, f, g, h, a, K[39], W(39)); R(a, b, c, d, e, f, g, h, K[40], W(40)); R(h, a, b, c, d, e, f, g, K[41], W(41)); R(g, h, a, b, c, d, e, f, K[42], W(42)); R(f, g, h, a, b, c, d, e, K[43], W(43)); R(e, f, g, h, a, b, c, d, K[44], W(44)); R(d, e, f, g, h, a, b, c, K[45], W(45)); R(c, d, e, f, g, h, a, b, K[46], W(46)); R(b, c, d, e, f, g, h, a, K[47], W(47)); R(a, b, c, d, e, f, g, h, K[48], W(48)); R(h, a, b, c, d, e, f, g, K[49], W(49)); R(g, h, a, b, c, d, e, f, K[50], W(50)); R(f, g, h, a, b, c, d, e, K[51], W(51)); R(e, f, g, h, a, b, c, d, K[52], W(52)); R(d, e, f, g, h, a, b, c, K[53], W(53)); R(c, d, e, f, g, h, a, b, K[54], W(54)); R(b, c, d, e, f, g, h, a, K[55], W(55)); R(a, b, c, d, e, f, g, h, K[56], W(56)); R(h, a, b, c, d, e, f, g, K[57], W(57)); R(g, h, a, b, c, d, e, f, K[58], W(58)); R(f, g, h, a, b, c, d, e, K[59], W(59)); R(e, f, g, h, a, b, c, d, K[60], W(60)); R(d, e, f, g, h, a, b, c, K[61], W(61)); R(c, d, e, f, g, h, a, b, K[62], W(62)); R(b, c, d, e, f, g, h, a, K[63], W(63)); hd->h0 += a; hd->h1 += b; hd->h2 += c; hd->h3 += d; hd->h4 += e; hd->h5 += f; hd->h6 += g; hd->h7 += h; data += 64; } while (--nblks); return 26*4 + 32 + 3 * sizeof(void*); } #undef S0 #undef S1 #undef R /* The routine finally terminates the computation and returns the digest. The handle is prepared for a new cycle, but adding bytes to the handle will the destroy the returned buffer. Returns: 32 bytes with the message the digest. */ static void sha256_final(void *context) { SHA256_CONTEXT *hd = context; u32 t, th, msb, lsb; byte *p; unsigned int burn; _gcry_md_block_write (hd, NULL, 0); /* flush */; t = hd->bctx.nblocks; if (sizeof t == sizeof hd->bctx.nblocks) th = hd->bctx.nblocks_high; else th = hd->bctx.nblocks >> 32; /* multiply by 64 to make a byte count */ lsb = t << 6; msb = (th << 6) | (t >> 26); /* add the count */ t = lsb; if ((lsb += hd->bctx.count) < t) msb++; /* multiply by 8 to make a bit count */ t = lsb; lsb <<= 3; msb <<= 3; msb |= t >> 29; - if (hd->bctx.count < 56) - { /* enough room */ + if (hd->bctx.count < 56) /* enough room */ + { hd->bctx.buf[hd->bctx.count++] = 0x80; /* pad */ - while (hd->bctx.count < 56) - hd->bctx.buf[hd->bctx.count++] = 0; /* pad */ + if (hd->bctx.count < 56) + memset (&hd->bctx.buf[hd->bctx.count], 0, 56 - hd->bctx.count); + hd->bctx.count = 56; + + /* append the 64 bit count */ + buf_put_be32(hd->bctx.buf + 56, msb); + buf_put_be32(hd->bctx.buf + 60, lsb); + burn = (*hd->bctx.bwrite) (hd, hd->bctx.buf, 1); } - else - { /* need one extra block */ + else /* need one extra block */ + { hd->bctx.buf[hd->bctx.count++] = 0x80; /* pad character */ - while (hd->bctx.count < 64) - hd->bctx.buf[hd->bctx.count++] = 0; - _gcry_md_block_write (hd, NULL, 0); /* flush */; - memset (hd->bctx.buf, 0, 56 ); /* fill next block with zeroes */ + /* fill pad and next block with zeroes */ + memset (&hd->bctx.buf[hd->bctx.count], 0, 64 - hd->bctx.count + 56); + hd->bctx.count = 64 + 56; + + /* append the 64 bit count */ + buf_put_be32(hd->bctx.buf + 64 + 56, msb); + buf_put_be32(hd->bctx.buf + 64 + 60, lsb); + burn = (*hd->bctx.bwrite) (hd, hd->bctx.buf, 2); } - /* append the 64 bit count */ - buf_put_be32(hd->bctx.buf + 56, msb); - buf_put_be32(hd->bctx.buf + 60, lsb); - burn = (*hd->bctx.bwrite) (hd, hd->bctx.buf, 1); - _gcry_burn_stack (burn); p = hd->bctx.buf; #define X(a) do { buf_put_be32(p, hd->h##a); p += 4; } while(0) X(0); X(1); X(2); X(3); X(4); X(5); X(6); X(7); #undef X + + _gcry_burn_stack (burn); } static byte * sha256_read (void *context) { SHA256_CONTEXT *hd = context; return hd->bctx.buf; } /* Shortcut functions which puts the hash value of the supplied buffer * into outbuf which must have a size of 32 bytes. */ void _gcry_sha256_hash_buffer (void *outbuf, const void *buffer, size_t length) { SHA256_CONTEXT hd; sha256_init (&hd, 0); _gcry_md_block_write (&hd, buffer, length); sha256_final (&hd); memcpy (outbuf, hd.bctx.buf, 32); } /* Variant of the above shortcut function using multiple buffers. */ void _gcry_sha256_hash_buffers (void *outbuf, const gcry_buffer_t *iov, int iovcnt) { SHA256_CONTEXT hd; sha256_init (&hd, 0); for (;iovcnt > 0; iov++, iovcnt--) _gcry_md_block_write (&hd, (const char*)iov[0].data + iov[0].off, iov[0].len); sha256_final (&hd); memcpy (outbuf, hd.bctx.buf, 32); } /* Shortcut functions which puts the hash value of the supplied buffer * into outbuf which must have a size of 28 bytes. */ static void _gcry_sha224_hash_buffer (void *outbuf, const void *buffer, size_t length) { SHA256_CONTEXT hd; sha224_init (&hd, 0); _gcry_md_block_write (&hd, buffer, length); sha256_final (&hd); memcpy (outbuf, hd.bctx.buf, 28); } /* Variant of the above shortcut function using multiple buffers. */ static void _gcry_sha224_hash_buffers (void *outbuf, const gcry_buffer_t *iov, int iovcnt) { SHA256_CONTEXT hd; sha224_init (&hd, 0); for (;iovcnt > 0; iov++, iovcnt--) _gcry_md_block_write (&hd, (const char*)iov[0].data + iov[0].off, iov[0].len); sha256_final (&hd); memcpy (outbuf, hd.bctx.buf, 28); } /* Self-test section. */ static gpg_err_code_t selftests_sha224 (int extended, selftest_report_func_t report) { const char *what; const char *errtxt; what = "short string"; errtxt = _gcry_hash_selftest_check_one (GCRY_MD_SHA224, 0, "abc", 3, "\x23\x09\x7d\x22\x34\x05\xd8\x22\x86\x42\xa4\x77\xbd\xa2\x55\xb3" "\x2a\xad\xbc\xe4\xbd\xa0\xb3\xf7\xe3\x6c\x9d\xa7", 28); if (errtxt) goto failed; if (extended) { what = "long string"; errtxt = _gcry_hash_selftest_check_one (GCRY_MD_SHA224, 0, "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", 56, "\x75\x38\x8b\x16\x51\x27\x76\xcc\x5d\xba\x5d\xa1\xfd\x89\x01\x50" "\xb0\xc6\x45\x5c\xb4\xf5\x8b\x19\x52\x52\x25\x25", 28); if (errtxt) goto failed; what = "one million \"a\""; errtxt = _gcry_hash_selftest_check_one (GCRY_MD_SHA224, 1, NULL, 0, "\x20\x79\x46\x55\x98\x0c\x91\xd8\xbb\xb4\xc1\xea\x97\x61\x8a\x4b" "\xf0\x3f\x42\x58\x19\x48\xb2\xee\x4e\xe7\xad\x67", 28); if (errtxt) goto failed; } return 0; /* Succeeded. */ failed: if (report) report ("digest", GCRY_MD_SHA224, what, errtxt); return GPG_ERR_SELFTEST_FAILED; } static gpg_err_code_t selftests_sha256 (int extended, selftest_report_func_t report) { const char *what; const char *errtxt; what = "short string"; errtxt = _gcry_hash_selftest_check_one (GCRY_MD_SHA256, 0, "abc", 3, "\xba\x78\x16\xbf\x8f\x01\xcf\xea\x41\x41\x40\xde\x5d\xae\x22\x23" "\xb0\x03\x61\xa3\x96\x17\x7a\x9c\xb4\x10\xff\x61\xf2\x00\x15\xad", 32); if (errtxt) goto failed; if (extended) { what = "long string"; errtxt = _gcry_hash_selftest_check_one (GCRY_MD_SHA256, 0, "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", 56, "\x24\x8d\x6a\x61\xd2\x06\x38\xb8\xe5\xc0\x26\x93\x0c\x3e\x60\x39" "\xa3\x3c\xe4\x59\x64\xff\x21\x67\xf6\xec\xed\xd4\x19\xdb\x06\xc1", 32); if (errtxt) goto failed; what = "one million \"a\""; errtxt = _gcry_hash_selftest_check_one (GCRY_MD_SHA256, 1, NULL, 0, "\xcd\xc7\x6e\x5c\x99\x14\xfb\x92\x81\xa1\xc7\xe2\x84\xd7\x3e\x67" "\xf1\x80\x9a\x48\xa4\x97\x20\x0e\x04\x6d\x39\xcc\xc7\x11\x2c\xd0", 32); if (errtxt) goto failed; } return 0; /* Succeeded. */ failed: if (report) report ("digest", GCRY_MD_SHA256, what, errtxt); return GPG_ERR_SELFTEST_FAILED; } /* Run a full self-test for ALGO and return 0 on success. */ static gpg_err_code_t run_selftests (int algo, int extended, selftest_report_func_t report) { gpg_err_code_t ec; switch (algo) { case GCRY_MD_SHA224: ec = selftests_sha224 (extended, report); break; case GCRY_MD_SHA256: ec = selftests_sha256 (extended, report); break; default: ec = GPG_ERR_DIGEST_ALGO; break; } return ec; } static byte asn224[19] = /* Object ID is 2.16.840.1.101.3.4.2.4 */ { 0x30, 0x2D, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x04, 0x05, 0x00, 0x04, 0x1C }; static gcry_md_oid_spec_t oid_spec_sha224[] = { /* From RFC3874, Section 4 */ { "2.16.840.1.101.3.4.2.4" }, { NULL }, }; static byte asn256[19] = /* Object ID is 2.16.840.1.101.3.4.2.1 */ { 0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20 }; static gcry_md_oid_spec_t oid_spec_sha256[] = { /* According to the OpenPGP draft rfc2440-bis06 */ { "2.16.840.1.101.3.4.2.1" }, /* PKCS#1 sha256WithRSAEncryption */ { "1.2.840.113549.1.1.11" }, { NULL }, }; gcry_md_spec_t _gcry_digest_spec_sha224 = { GCRY_MD_SHA224, {0, 1}, "SHA224", asn224, DIM (asn224), oid_spec_sha224, 28, sha224_init, _gcry_md_block_write, sha256_final, sha256_read, NULL, _gcry_sha224_hash_buffer, _gcry_sha224_hash_buffers, sizeof (SHA256_CONTEXT), run_selftests }; gcry_md_spec_t _gcry_digest_spec_sha256 = { GCRY_MD_SHA256, {0, 1}, "SHA256", asn256, DIM (asn256), oid_spec_sha256, 32, sha256_init, _gcry_md_block_write, sha256_final, sha256_read, NULL, _gcry_sha256_hash_buffer, _gcry_sha256_hash_buffers, sizeof (SHA256_CONTEXT), run_selftests }; diff --git a/cipher/sha512.c b/cipher/sha512.c index 721f3405..615b5535 100644 --- a/cipher/sha512.c +++ b/cipher/sha512.c @@ -1,951 +1,953 @@ /* sha512.c - SHA384 and SHA512 hash functions * Copyright (C) 2003, 2008, 2009 Free Software Foundation, Inc. * * This file is part of Libgcrypt. * * Libgcrypt is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser general Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * Libgcrypt is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this program; if not, see . */ /* Test vectors from FIPS-180-2: * * "abc" * 384: * CB00753F 45A35E8B B5A03D69 9AC65007 272C32AB 0EDED163 * 1A8B605A 43FF5BED 8086072B A1E7CC23 58BAECA1 34C825A7 * 512: * DDAF35A1 93617ABA CC417349 AE204131 12E6FA4E 89A97EA2 0A9EEEE6 4B55D39A * 2192992A 274FC1A8 36BA3C23 A3FEEBBD 454D4423 643CE80E 2A9AC94F A54CA49F * * "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu" * 384: * 09330C33 F71147E8 3D192FC7 82CD1B47 53111B17 3B3B05D2 * 2FA08086 E3B0F712 FCC7C71A 557E2DB9 66C3E9FA 91746039 * 512: * 8E959B75 DAE313DA 8CF4F728 14FC143F 8F7779C6 EB9F7FA1 7299AEAD B6889018 * 501D289E 4900F7E4 331B99DE C4B5433A C7D329EE B6DD2654 5E96E55B 874BE909 * * "a" x 1000000 * 384: * 9D0E1809 716474CB 086E834E 310A4A1C ED149E9C 00F24852 * 7972CEC5 704C2A5B 07B8B3DC 38ECC4EB AE97DDD8 7F3D8985 * 512: * E718483D 0CE76964 4E2E42C7 BC15B463 8E1F98B1 3B204428 5632A803 AFA973EB * DE0FF244 877EA60A 4CB0432C E577C31B EB009C5C 2C49AA2E 4EADB217 AD8CC09B */ #include #include #include "g10lib.h" #include "bithelp.h" #include "bufhelp.h" #include "cipher.h" #include "hash-common.h" /* USE_ARM_NEON_ASM indicates whether to enable ARM NEON assembly code. */ #undef USE_ARM_NEON_ASM #ifdef ENABLE_NEON_SUPPORT # if defined(HAVE_ARM_ARCH_V6) && defined(__ARMEL__) \ && defined(HAVE_COMPATIBLE_GCC_ARM_PLATFORM_AS) \ && defined(HAVE_GCC_INLINE_ASM_NEON) # define USE_ARM_NEON_ASM 1 # endif #endif /*ENABLE_NEON_SUPPORT*/ /* USE_ARM_ASM indicates whether to enable ARM assembly code. */ #undef USE_ARM_ASM #if defined(__ARMEL__) && defined(HAVE_COMPATIBLE_GCC_ARM_PLATFORM_AS) # define USE_ARM_ASM 1 #endif /* USE_SSSE3 indicates whether to compile with Intel SSSE3 code. */ #undef USE_SSSE3 #if defined(__x86_64__) && defined(HAVE_GCC_INLINE_ASM_SSSE3) && \ defined(HAVE_INTEL_SYNTAX_PLATFORM_AS) && \ (defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) || \ defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS)) # define USE_SSSE3 1 #endif /* USE_AVX indicates whether to compile with Intel AVX code. */ #undef USE_AVX #if defined(__x86_64__) && defined(HAVE_GCC_INLINE_ASM_AVX) && \ defined(HAVE_INTEL_SYNTAX_PLATFORM_AS) && \ (defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) || \ defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS)) # define USE_AVX 1 #endif /* USE_AVX2 indicates whether to compile with Intel AVX2/rorx code. */ #undef USE_AVX2 #if defined(__x86_64__) && defined(HAVE_GCC_INLINE_ASM_AVX2) && \ defined(HAVE_GCC_INLINE_ASM_BMI2) && \ defined(HAVE_INTEL_SYNTAX_PLATFORM_AS) && \ (defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) || \ defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS)) # define USE_AVX2 1 #endif typedef struct { u64 h0, h1, h2, h3, h4, h5, h6, h7; } SHA512_STATE; typedef struct { gcry_md_block_ctx_t bctx; SHA512_STATE state; } SHA512_CONTEXT; static const u64 k[] = { U64_C(0x428a2f98d728ae22), U64_C(0x7137449123ef65cd), U64_C(0xb5c0fbcfec4d3b2f), U64_C(0xe9b5dba58189dbbc), U64_C(0x3956c25bf348b538), U64_C(0x59f111f1b605d019), U64_C(0x923f82a4af194f9b), U64_C(0xab1c5ed5da6d8118), U64_C(0xd807aa98a3030242), U64_C(0x12835b0145706fbe), U64_C(0x243185be4ee4b28c), U64_C(0x550c7dc3d5ffb4e2), U64_C(0x72be5d74f27b896f), U64_C(0x80deb1fe3b1696b1), U64_C(0x9bdc06a725c71235), U64_C(0xc19bf174cf692694), U64_C(0xe49b69c19ef14ad2), U64_C(0xefbe4786384f25e3), U64_C(0x0fc19dc68b8cd5b5), U64_C(0x240ca1cc77ac9c65), U64_C(0x2de92c6f592b0275), U64_C(0x4a7484aa6ea6e483), U64_C(0x5cb0a9dcbd41fbd4), U64_C(0x76f988da831153b5), U64_C(0x983e5152ee66dfab), U64_C(0xa831c66d2db43210), U64_C(0xb00327c898fb213f), U64_C(0xbf597fc7beef0ee4), U64_C(0xc6e00bf33da88fc2), U64_C(0xd5a79147930aa725), U64_C(0x06ca6351e003826f), U64_C(0x142929670a0e6e70), U64_C(0x27b70a8546d22ffc), U64_C(0x2e1b21385c26c926), U64_C(0x4d2c6dfc5ac42aed), U64_C(0x53380d139d95b3df), U64_C(0x650a73548baf63de), U64_C(0x766a0abb3c77b2a8), U64_C(0x81c2c92e47edaee6), U64_C(0x92722c851482353b), U64_C(0xa2bfe8a14cf10364), U64_C(0xa81a664bbc423001), U64_C(0xc24b8b70d0f89791), U64_C(0xc76c51a30654be30), U64_C(0xd192e819d6ef5218), U64_C(0xd69906245565a910), U64_C(0xf40e35855771202a), U64_C(0x106aa07032bbd1b8), U64_C(0x19a4c116b8d2d0c8), U64_C(0x1e376c085141ab53), U64_C(0x2748774cdf8eeb99), U64_C(0x34b0bcb5e19b48a8), U64_C(0x391c0cb3c5c95a63), U64_C(0x4ed8aa4ae3418acb), U64_C(0x5b9cca4f7763e373), U64_C(0x682e6ff3d6b2b8a3), U64_C(0x748f82ee5defb2fc), U64_C(0x78a5636f43172f60), U64_C(0x84c87814a1f0ab72), U64_C(0x8cc702081a6439ec), U64_C(0x90befffa23631e28), U64_C(0xa4506cebde82bde9), U64_C(0xbef9a3f7b2c67915), U64_C(0xc67178f2e372532b), U64_C(0xca273eceea26619c), U64_C(0xd186b8c721c0c207), U64_C(0xeada7dd6cde0eb1e), U64_C(0xf57d4f7fee6ed178), U64_C(0x06f067aa72176fba), U64_C(0x0a637dc5a2c898a6), U64_C(0x113f9804bef90dae), U64_C(0x1b710b35131c471b), U64_C(0x28db77f523047d84), U64_C(0x32caab7b40c72493), U64_C(0x3c9ebe0a15c9bebc), U64_C(0x431d67c49c100d4c), U64_C(0x4cc5d4becb3e42b6), U64_C(0x597f299cfc657e2a), U64_C(0x5fcb6fab3ad6faec), U64_C(0x6c44198c4a475817) }; /* AMD64 assembly implementations use SystemV ABI, ABI conversion and additional * stack to store XMM6-XMM15 needed on Win64. */ #undef ASM_FUNC_ABI #undef ASM_EXTRA_STACK #if defined(USE_SSSE3) || defined(USE_AVX) || defined(USE_AVX2) # ifdef HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS # define ASM_FUNC_ABI __attribute__((sysv_abi)) # define ASM_EXTRA_STACK (10 * 16 + 4 * sizeof(void *)) # else # define ASM_FUNC_ABI # define ASM_EXTRA_STACK 0 # endif #endif #ifdef USE_ARM_NEON_ASM unsigned int _gcry_sha512_transform_armv7_neon (SHA512_STATE *hd, const unsigned char *data, const u64 k[], size_t num_blks); static unsigned int do_sha512_transform_armv7_neon(void *ctx, const unsigned char *data, size_t nblks) { SHA512_CONTEXT *hd = ctx; return _gcry_sha512_transform_armv7_neon (&hd->state, data, k, nblks); } #endif #ifdef USE_SSSE3 unsigned int _gcry_sha512_transform_amd64_ssse3(const void *input_data, void *state, size_t num_blks) ASM_FUNC_ABI; static unsigned int do_sha512_transform_amd64_ssse3(void *ctx, const unsigned char *data, size_t nblks) { SHA512_CONTEXT *hd = ctx; return _gcry_sha512_transform_amd64_ssse3 (data, &hd->state, nblks) + ASM_EXTRA_STACK; } #endif #ifdef USE_AVX unsigned int _gcry_sha512_transform_amd64_avx(const void *input_data, void *state, size_t num_blks) ASM_FUNC_ABI; static unsigned int do_sha512_transform_amd64_avx(void *ctx, const unsigned char *data, size_t nblks) { SHA512_CONTEXT *hd = ctx; return _gcry_sha512_transform_amd64_avx (data, &hd->state, nblks) + ASM_EXTRA_STACK; } #endif #ifdef USE_AVX2 unsigned int _gcry_sha512_transform_amd64_avx2(const void *input_data, void *state, size_t num_blks) ASM_FUNC_ABI; static unsigned int do_sha512_transform_amd64_avx2(void *ctx, const unsigned char *data, size_t nblks) { SHA512_CONTEXT *hd = ctx; return _gcry_sha512_transform_amd64_avx2 (data, &hd->state, nblks) + ASM_EXTRA_STACK; } #endif #ifdef USE_ARM_ASM unsigned int _gcry_sha512_transform_arm (SHA512_STATE *hd, const unsigned char *data, const u64 k[], size_t num_blks); static unsigned int do_transform_generic (void *context, const unsigned char *data, size_t nblks) { SHA512_CONTEXT *hd = context; return _gcry_sha512_transform_armv7_neon (&hd->state, data, k, nblks); } #else static unsigned int do_transform_generic (void *context, const unsigned char *data, size_t nblks); #endif static void sha512_init (void *context, unsigned int flags) { SHA512_CONTEXT *ctx = context; SHA512_STATE *hd = &ctx->state; unsigned int features = _gcry_get_hw_features (); (void)flags; (void)k; hd->h0 = U64_C(0x6a09e667f3bcc908); hd->h1 = U64_C(0xbb67ae8584caa73b); hd->h2 = U64_C(0x3c6ef372fe94f82b); hd->h3 = U64_C(0xa54ff53a5f1d36f1); hd->h4 = U64_C(0x510e527fade682d1); hd->h5 = U64_C(0x9b05688c2b3e6c1f); hd->h6 = U64_C(0x1f83d9abfb41bd6b); hd->h7 = U64_C(0x5be0cd19137e2179); ctx->bctx.nblocks = 0; ctx->bctx.nblocks_high = 0; ctx->bctx.count = 0; ctx->bctx.blocksize = 128; /* Order of feature checks is important here; last match will be * selected. Keep slower implementations at the top and faster at * the bottom. */ ctx->bctx.bwrite = do_transform_generic; #ifdef USE_ARM_NEON_ASM if ((features & HWF_ARM_NEON) != 0) ctx->bctx.bwrite = do_sha512_transform_armv7_neon; #endif #ifdef USE_SSSE3 if ((features & HWF_INTEL_SSSE3) != 0) ctx->bctx.bwrite = do_sha512_transform_amd64_ssse3; #endif #ifdef USE_AVX if ((features & HWF_INTEL_AVX) && (features & HWF_INTEL_FAST_SHLD)) ctx->bctx.bwrite = do_sha512_transform_amd64_avx; #endif #ifdef USE_AVX2 if ((features & HWF_INTEL_AVX2) && (features & HWF_INTEL_BMI2)) ctx->bctx.bwrite = do_sha512_transform_amd64_avx2; #endif (void)features; } static void sha384_init (void *context, unsigned int flags) { SHA512_CONTEXT *ctx = context; SHA512_STATE *hd = &ctx->state; unsigned int features = _gcry_get_hw_features (); (void)flags; hd->h0 = U64_C(0xcbbb9d5dc1059ed8); hd->h1 = U64_C(0x629a292a367cd507); hd->h2 = U64_C(0x9159015a3070dd17); hd->h3 = U64_C(0x152fecd8f70e5939); hd->h4 = U64_C(0x67332667ffc00b31); hd->h5 = U64_C(0x8eb44a8768581511); hd->h6 = U64_C(0xdb0c2e0d64f98fa7); hd->h7 = U64_C(0x47b5481dbefa4fa4); ctx->bctx.nblocks = 0; ctx->bctx.nblocks_high = 0; ctx->bctx.count = 0; ctx->bctx.blocksize = 128; /* Order of feature checks is important here; last match will be * selected. Keep slower implementations at the top and faster at * the bottom. */ ctx->bctx.bwrite = do_transform_generic; #ifdef USE_ARM_NEON_ASM if ((features & HWF_ARM_NEON) != 0) ctx->bctx.bwrite = do_sha512_transform_armv7_neon; #endif #ifdef USE_SSSE3 if ((features & HWF_INTEL_SSSE3) != 0) ctx->bctx.bwrite = do_sha512_transform_amd64_ssse3; #endif #ifdef USE_AVX if ((features & HWF_INTEL_AVX) && (features & HWF_INTEL_FAST_SHLD)) ctx->bctx.bwrite = do_sha512_transform_amd64_avx; #endif #ifdef USE_AVX2 if ((features & HWF_INTEL_AVX2) && (features & HWF_INTEL_BMI2)) ctx->bctx.bwrite = do_sha512_transform_amd64_avx2; #endif (void)features; } #ifndef USE_ARM_ASM static inline u64 ROTR (u64 x, u64 n) { return ((x >> n) | (x << (64 - n))); } static inline u64 Ch (u64 x, u64 y, u64 z) { return ((x & y) ^ ( ~x & z)); } static inline u64 Maj (u64 x, u64 y, u64 z) { return ((x & y) ^ (x & z) ^ (y & z)); } static inline u64 Sum0 (u64 x) { return (ROTR (x, 28) ^ ROTR (x, 34) ^ ROTR (x, 39)); } static inline u64 Sum1 (u64 x) { return (ROTR (x, 14) ^ ROTR (x, 18) ^ ROTR (x, 41)); } /**************** * Transform the message W which consists of 16 64-bit-words */ static unsigned int do_transform_generic (void *context, const unsigned char *data, size_t nblks) { SHA512_CONTEXT *ctx = context; SHA512_STATE *hd = &ctx->state; do { u64 a, b, c, d, e, f, g, h; u64 w[16]; int t; /* get values from the chaining vars */ a = hd->h0; b = hd->h1; c = hd->h2; d = hd->h3; e = hd->h4; f = hd->h5; g = hd->h6; h = hd->h7; for ( t = 0; t < 16; t++ ) w[t] = buf_get_be64(data + t * 8); #define S0(x) (ROTR((x),1) ^ ROTR((x),8) ^ ((x)>>7)) #define S1(x) (ROTR((x),19) ^ ROTR((x),61) ^ ((x)>>6)) for (t = 0; t < 80 - 16; ) { u64 t1, t2; t1 = h + Sum1 (e) + Ch (e, f, g) + k[t] + w[0]; w[0] += S1 (w[14]) + w[9] + S0 (w[1]); t2 = Sum0 (a) + Maj (a, b, c); d += t1; h = t1 + t2; t1 = g + Sum1 (d) + Ch (d, e, f) + k[t+1] + w[1]; w[1] += S1 (w[15]) + w[10] + S0 (w[2]); t2 = Sum0 (h) + Maj (h, a, b); c += t1; g = t1 + t2; t1 = f + Sum1 (c) + Ch (c, d, e) + k[t+2] + w[2]; w[2] += S1 (w[0]) + w[11] + S0 (w[3]); t2 = Sum0 (g) + Maj (g, h, a); b += t1; f = t1 + t2; t1 = e + Sum1 (b) + Ch (b, c, d) + k[t+3] + w[3]; w[3] += S1 (w[1]) + w[12] + S0 (w[4]); t2 = Sum0 (f) + Maj (f, g, h); a += t1; e = t1 + t2; t1 = d + Sum1 (a) + Ch (a, b, c) + k[t+4] + w[4]; w[4] += S1 (w[2]) + w[13] + S0 (w[5]); t2 = Sum0 (e) + Maj (e, f, g); h += t1; d = t1 + t2; t1 = c + Sum1 (h) + Ch (h, a, b) + k[t+5] + w[5]; w[5] += S1 (w[3]) + w[14] + S0 (w[6]); t2 = Sum0 (d) + Maj (d, e, f); g += t1; c = t1 + t2; t1 = b + Sum1 (g) + Ch (g, h, a) + k[t+6] + w[6]; w[6] += S1 (w[4]) + w[15] + S0 (w[7]); t2 = Sum0 (c) + Maj (c, d, e); f += t1; b = t1 + t2; t1 = a + Sum1 (f) + Ch (f, g, h) + k[t+7] + w[7]; w[7] += S1 (w[5]) + w[0] + S0 (w[8]); t2 = Sum0 (b) + Maj (b, c, d); e += t1; a = t1 + t2; t1 = h + Sum1 (e) + Ch (e, f, g) + k[t+8] + w[8]; w[8] += S1 (w[6]) + w[1] + S0 (w[9]); t2 = Sum0 (a) + Maj (a, b, c); d += t1; h = t1 + t2; t1 = g + Sum1 (d) + Ch (d, e, f) + k[t+9] + w[9]; w[9] += S1 (w[7]) + w[2] + S0 (w[10]); t2 = Sum0 (h) + Maj (h, a, b); c += t1; g = t1 + t2; t1 = f + Sum1 (c) + Ch (c, d, e) + k[t+10] + w[10]; w[10] += S1 (w[8]) + w[3] + S0 (w[11]); t2 = Sum0 (g) + Maj (g, h, a); b += t1; f = t1 + t2; t1 = e + Sum1 (b) + Ch (b, c, d) + k[t+11] + w[11]; w[11] += S1 (w[9]) + w[4] + S0 (w[12]); t2 = Sum0 (f) + Maj (f, g, h); a += t1; e = t1 + t2; t1 = d + Sum1 (a) + Ch (a, b, c) + k[t+12] + w[12]; w[12] += S1 (w[10]) + w[5] + S0 (w[13]); t2 = Sum0 (e) + Maj (e, f, g); h += t1; d = t1 + t2; t1 = c + Sum1 (h) + Ch (h, a, b) + k[t+13] + w[13]; w[13] += S1 (w[11]) + w[6] + S0 (w[14]); t2 = Sum0 (d) + Maj (d, e, f); g += t1; c = t1 + t2; t1 = b + Sum1 (g) + Ch (g, h, a) + k[t+14] + w[14]; w[14] += S1 (w[12]) + w[7] + S0 (w[15]); t2 = Sum0 (c) + Maj (c, d, e); f += t1; b = t1 + t2; t1 = a + Sum1 (f) + Ch (f, g, h) + k[t+15] + w[15]; w[15] += S1 (w[13]) + w[8] + S0 (w[0]); t2 = Sum0 (b) + Maj (b, c, d); e += t1; a = t1 + t2; t += 16; } for (; t < 80; ) { u64 t1, t2; t1 = h + Sum1 (e) + Ch (e, f, g) + k[t] + w[0]; t2 = Sum0 (a) + Maj (a, b, c); d += t1; h = t1 + t2; t1 = g + Sum1 (d) + Ch (d, e, f) + k[t+1] + w[1]; t2 = Sum0 (h) + Maj (h, a, b); c += t1; g = t1 + t2; t1 = f + Sum1 (c) + Ch (c, d, e) + k[t+2] + w[2]; t2 = Sum0 (g) + Maj (g, h, a); b += t1; f = t1 + t2; t1 = e + Sum1 (b) + Ch (b, c, d) + k[t+3] + w[3]; t2 = Sum0 (f) + Maj (f, g, h); a += t1; e = t1 + t2; t1 = d + Sum1 (a) + Ch (a, b, c) + k[t+4] + w[4]; t2 = Sum0 (e) + Maj (e, f, g); h += t1; d = t1 + t2; t1 = c + Sum1 (h) + Ch (h, a, b) + k[t+5] + w[5]; t2 = Sum0 (d) + Maj (d, e, f); g += t1; c = t1 + t2; t1 = b + Sum1 (g) + Ch (g, h, a) + k[t+6] + w[6]; t2 = Sum0 (c) + Maj (c, d, e); f += t1; b = t1 + t2; t1 = a + Sum1 (f) + Ch (f, g, h) + k[t+7] + w[7]; t2 = Sum0 (b) + Maj (b, c, d); e += t1; a = t1 + t2; t1 = h + Sum1 (e) + Ch (e, f, g) + k[t+8] + w[8]; t2 = Sum0 (a) + Maj (a, b, c); d += t1; h = t1 + t2; t1 = g + Sum1 (d) + Ch (d, e, f) + k[t+9] + w[9]; t2 = Sum0 (h) + Maj (h, a, b); c += t1; g = t1 + t2; t1 = f + Sum1 (c) + Ch (c, d, e) + k[t+10] + w[10]; t2 = Sum0 (g) + Maj (g, h, a); b += t1; f = t1 + t2; t1 = e + Sum1 (b) + Ch (b, c, d) + k[t+11] + w[11]; t2 = Sum0 (f) + Maj (f, g, h); a += t1; e = t1 + t2; t1 = d + Sum1 (a) + Ch (a, b, c) + k[t+12] + w[12]; t2 = Sum0 (e) + Maj (e, f, g); h += t1; d = t1 + t2; t1 = c + Sum1 (h) + Ch (h, a, b) + k[t+13] + w[13]; t2 = Sum0 (d) + Maj (d, e, f); g += t1; c = t1 + t2; t1 = b + Sum1 (g) + Ch (g, h, a) + k[t+14] + w[14]; t2 = Sum0 (c) + Maj (c, d, e); f += t1; b = t1 + t2; t1 = a + Sum1 (f) + Ch (f, g, h) + k[t+15] + w[15]; t2 = Sum0 (b) + Maj (b, c, d); e += t1; a = t1 + t2; t += 16; } /* Update chaining vars. */ hd->h0 += a; hd->h1 += b; hd->h2 += c; hd->h3 += d; hd->h4 += e; hd->h5 += f; hd->h6 += g; hd->h7 += h; data += 128; } while (--nblks); return (8 + 16) * sizeof(u64) + sizeof(u32) + 3 * sizeof(void*); } #endif /*!USE_ARM_ASM*/ /* The routine final terminates the computation and * returns the digest. * The handle is prepared for a new cycle, but adding bytes to the * handle will the destroy the returned buffer. * Returns: 64 bytes representing the digest. When used for sha384, * we take the leftmost 48 of those bytes. */ static void sha512_final (void *context) { SHA512_CONTEXT *hd = context; unsigned int stack_burn_depth; u64 t, th, msb, lsb; byte *p; _gcry_md_block_write (context, NULL, 0); /* flush */ ; t = hd->bctx.nblocks; /* if (sizeof t == sizeof hd->bctx.nblocks) */ th = hd->bctx.nblocks_high; /* else */ /* th = hd->bctx.nblocks >> 64; In case we ever use u128 */ /* multiply by 128 to make a byte count */ lsb = t << 7; msb = (th << 7) | (t >> 57); /* add the count */ t = lsb; if ((lsb += hd->bctx.count) < t) msb++; /* multiply by 8 to make a bit count */ t = lsb; lsb <<= 3; msb <<= 3; msb |= t >> 61; if (hd->bctx.count < 112) { /* enough room */ hd->bctx.buf[hd->bctx.count++] = 0x80; /* pad */ - while (hd->bctx.count < 112) - hd->bctx.buf[hd->bctx.count++] = 0; /* pad */ + if (hd->bctx.count < 112) + memset (&hd->bctx.buf[hd->bctx.count], 0, 112 - hd->bctx.count); + hd->bctx.count = 112; } else { /* need one extra block */ hd->bctx.buf[hd->bctx.count++] = 0x80; /* pad character */ - while (hd->bctx.count < 128) - hd->bctx.buf[hd->bctx.count++] = 0; + if (hd->bctx.count < 128) + memset (&hd->bctx.buf[hd->bctx.count], 0, 128 - hd->bctx.count); + hd->bctx.count = 128; _gcry_md_block_write (context, NULL, 0); /* flush */ ; memset (hd->bctx.buf, 0, 112); /* fill next block with zeroes */ } /* append the 128 bit count */ buf_put_be64(hd->bctx.buf + 112, msb); buf_put_be64(hd->bctx.buf + 120, lsb); stack_burn_depth = (*hd->bctx.bwrite) (hd, hd->bctx.buf, 1); _gcry_burn_stack (stack_burn_depth); p = hd->bctx.buf; #define X(a) do { buf_put_be64(p, hd->state.h##a); p += 8; } while (0) X (0); X (1); X (2); X (3); X (4); X (5); /* Note that these last two chunks are included even for SHA384. We just ignore them. */ X (6); X (7); #undef X } static byte * sha512_read (void *context) { SHA512_CONTEXT *hd = (SHA512_CONTEXT *) context; return hd->bctx.buf; } /* Shortcut functions which puts the hash value of the supplied buffer * into outbuf which must have a size of 64 bytes. */ void _gcry_sha512_hash_buffer (void *outbuf, const void *buffer, size_t length) { SHA512_CONTEXT hd; sha512_init (&hd, 0); _gcry_md_block_write (&hd, buffer, length); sha512_final (&hd); memcpy (outbuf, hd.bctx.buf, 64); } /* Variant of the above shortcut function using multiple buffers. */ void _gcry_sha512_hash_buffers (void *outbuf, const gcry_buffer_t *iov, int iovcnt) { SHA512_CONTEXT hd; sha512_init (&hd, 0); for (;iovcnt > 0; iov++, iovcnt--) _gcry_md_block_write (&hd, (const char*)iov[0].data + iov[0].off, iov[0].len); sha512_final (&hd); memcpy (outbuf, hd.bctx.buf, 64); } /* Shortcut functions which puts the hash value of the supplied buffer * into outbuf which must have a size of 48 bytes. */ static void _gcry_sha384_hash_buffer (void *outbuf, const void *buffer, size_t length) { SHA512_CONTEXT hd; sha384_init (&hd, 0); _gcry_md_block_write (&hd, buffer, length); sha512_final (&hd); memcpy (outbuf, hd.bctx.buf, 48); } /* Variant of the above shortcut function using multiple buffers. */ static void _gcry_sha384_hash_buffers (void *outbuf, const gcry_buffer_t *iov, int iovcnt) { SHA512_CONTEXT hd; sha384_init (&hd, 0); for (;iovcnt > 0; iov++, iovcnt--) _gcry_md_block_write (&hd, (const char*)iov[0].data + iov[0].off, iov[0].len); sha512_final (&hd); memcpy (outbuf, hd.bctx.buf, 48); } /* Self-test section. */ static gpg_err_code_t selftests_sha384 (int extended, selftest_report_func_t report) { const char *what; const char *errtxt; what = "short string"; errtxt = _gcry_hash_selftest_check_one (GCRY_MD_SHA384, 0, "abc", 3, "\xcb\x00\x75\x3f\x45\xa3\x5e\x8b\xb5\xa0\x3d\x69\x9a\xc6\x50\x07" "\x27\x2c\x32\xab\x0e\xde\xd1\x63\x1a\x8b\x60\x5a\x43\xff\x5b\xed" "\x80\x86\x07\x2b\xa1\xe7\xcc\x23\x58\xba\xec\xa1\x34\xc8\x25\xa7", 48); if (errtxt) goto failed; if (extended) { what = "long string"; errtxt = _gcry_hash_selftest_check_one (GCRY_MD_SHA384, 0, "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn" "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu", 112, "\x09\x33\x0C\x33\xF7\x11\x47\xE8\x3D\x19\x2F\xC7\x82\xCD\x1B\x47" "\x53\x11\x1B\x17\x3B\x3B\x05\xD2\x2F\xA0\x80\x86\xE3\xB0\xF7\x12" "\xFC\xC7\xC7\x1A\x55\x7E\x2D\xB9\x66\xC3\xE9\xFA\x91\x74\x60\x39", 48); if (errtxt) goto failed; what = "one million \"a\""; errtxt = _gcry_hash_selftest_check_one (GCRY_MD_SHA384, 1, NULL, 0, "\x9D\x0E\x18\x09\x71\x64\x74\xCB\x08\x6E\x83\x4E\x31\x0A\x4A\x1C" "\xED\x14\x9E\x9C\x00\xF2\x48\x52\x79\x72\xCE\xC5\x70\x4C\x2A\x5B" "\x07\xB8\xB3\xDC\x38\xEC\xC4\xEB\xAE\x97\xDD\xD8\x7F\x3D\x89\x85", 48); if (errtxt) goto failed; } return 0; /* Succeeded. */ failed: if (report) report ("digest", GCRY_MD_SHA384, what, errtxt); return GPG_ERR_SELFTEST_FAILED; } static gpg_err_code_t selftests_sha512 (int extended, selftest_report_func_t report) { const char *what; const char *errtxt; what = "short string"; errtxt = _gcry_hash_selftest_check_one (GCRY_MD_SHA512, 0, "abc", 3, "\xDD\xAF\x35\xA1\x93\x61\x7A\xBA\xCC\x41\x73\x49\xAE\x20\x41\x31" "\x12\xE6\xFA\x4E\x89\xA9\x7E\xA2\x0A\x9E\xEE\xE6\x4B\x55\xD3\x9A" "\x21\x92\x99\x2A\x27\x4F\xC1\xA8\x36\xBA\x3C\x23\xA3\xFE\xEB\xBD" "\x45\x4D\x44\x23\x64\x3C\xE8\x0E\x2A\x9A\xC9\x4F\xA5\x4C\xA4\x9F", 64); if (errtxt) goto failed; if (extended) { what = "long string"; errtxt = _gcry_hash_selftest_check_one (GCRY_MD_SHA512, 0, "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn" "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu", 112, "\x8E\x95\x9B\x75\xDA\xE3\x13\xDA\x8C\xF4\xF7\x28\x14\xFC\x14\x3F" "\x8F\x77\x79\xC6\xEB\x9F\x7F\xA1\x72\x99\xAE\xAD\xB6\x88\x90\x18" "\x50\x1D\x28\x9E\x49\x00\xF7\xE4\x33\x1B\x99\xDE\xC4\xB5\x43\x3A" "\xC7\xD3\x29\xEE\xB6\xDD\x26\x54\x5E\x96\xE5\x5B\x87\x4B\xE9\x09", 64); if (errtxt) goto failed; what = "one million \"a\""; errtxt = _gcry_hash_selftest_check_one (GCRY_MD_SHA512, 1, NULL, 0, "\xE7\x18\x48\x3D\x0C\xE7\x69\x64\x4E\x2E\x42\xC7\xBC\x15\xB4\x63" "\x8E\x1F\x98\xB1\x3B\x20\x44\x28\x56\x32\xA8\x03\xAF\xA9\x73\xEB" "\xDE\x0F\xF2\x44\x87\x7E\xA6\x0A\x4C\xB0\x43\x2C\xE5\x77\xC3\x1B" "\xEB\x00\x9C\x5C\x2C\x49\xAA\x2E\x4E\xAD\xB2\x17\xAD\x8C\xC0\x9B", 64); if (errtxt) goto failed; } return 0; /* Succeeded. */ failed: if (report) report ("digest", GCRY_MD_SHA512, what, errtxt); return GPG_ERR_SELFTEST_FAILED; } /* Run a full self-test for ALGO and return 0 on success. */ static gpg_err_code_t run_selftests (int algo, int extended, selftest_report_func_t report) { gpg_err_code_t ec; switch (algo) { case GCRY_MD_SHA384: ec = selftests_sha384 (extended, report); break; case GCRY_MD_SHA512: ec = selftests_sha512 (extended, report); break; default: ec = GPG_ERR_DIGEST_ALGO; break; } return ec; } static byte sha512_asn[] = /* Object ID is 2.16.840.1.101.3.4.2.3 */ { 0x30, 0x51, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, 0x05, 0x00, 0x04, 0x40 }; static gcry_md_oid_spec_t oid_spec_sha512[] = { { "2.16.840.1.101.3.4.2.3" }, /* PKCS#1 sha512WithRSAEncryption */ { "1.2.840.113549.1.1.13" }, { NULL } }; gcry_md_spec_t _gcry_digest_spec_sha512 = { GCRY_MD_SHA512, {0, 1}, "SHA512", sha512_asn, DIM (sha512_asn), oid_spec_sha512, 64, sha512_init, _gcry_md_block_write, sha512_final, sha512_read, NULL, _gcry_sha512_hash_buffer, _gcry_sha512_hash_buffers, sizeof (SHA512_CONTEXT), run_selftests }; static byte sha384_asn[] = /* Object ID is 2.16.840.1.101.3.4.2.2 */ { 0x30, 0x41, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02, 0x05, 0x00, 0x04, 0x30 }; static gcry_md_oid_spec_t oid_spec_sha384[] = { { "2.16.840.1.101.3.4.2.2" }, /* PKCS#1 sha384WithRSAEncryption */ { "1.2.840.113549.1.1.12" }, /* SHA384WithECDSA: RFC 7427 (A.3.3.) */ { "1.2.840.10045.4.3.3" }, { NULL }, }; gcry_md_spec_t _gcry_digest_spec_sha384 = { GCRY_MD_SHA384, {0, 1}, "SHA384", sha384_asn, DIM (sha384_asn), oid_spec_sha384, 48, sha384_init, _gcry_md_block_write, sha512_final, sha512_read, NULL, _gcry_sha384_hash_buffer, _gcry_sha384_hash_buffers, sizeof (SHA512_CONTEXT), run_selftests }; diff --git a/cipher/sm3.c b/cipher/sm3.c index c6f1a091..7bfb37b9 100644 --- a/cipher/sm3.c +++ b/cipher/sm3.c @@ -1,468 +1,475 @@ /* sm3.c - SM3 hash function * Copyright (C) 2017 Jia Zhang * * This file is part of Libgcrypt. * * Libgcrypt is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * Libgcrypt is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this program; if not, see . */ /* Test vectors: "abc" SM3: 66c7f0f4 62eeedd9 d1f2d46b dc10e4e2 4167c487 5cf2f7a2 297da02b 8f4ba8e0 "abcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcd" SM3: debe9ff9 2275b8a1 38604889 c18e5a4d 6fdb70e5 387e5765 293dcba3 9c0c5732 "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" SM3: 639b6cc5 e64d9e37 a390b192 df4fa1ea 0720ab74 7ff692b9 f38c4e66 ad7b8c05 "a" one million times SM3: c8aaf894 29554029 e231941a 2acc0ad6 1ff2a5ac d8fadd25 847a3a73 2b3b02c3 */ #include #include #include #include #include "g10lib.h" #include "bithelp.h" #include "bufhelp.h" #include "cipher.h" #include "hash-common.h" typedef struct { gcry_md_block_ctx_t bctx; u32 h0,h1,h2,h3,h4,h5,h6,h7; } SM3_CONTEXT; static unsigned int transform (void *c, const unsigned char *data, size_t nblks); static void sm3_init (void *context, unsigned int flags) { SM3_CONTEXT *hd = context; unsigned int features = _gcry_get_hw_features (); (void)flags; hd->h0 = 0x7380166f; hd->h1 = 0x4914b2b9; hd->h2 = 0x172442d7; hd->h3 = 0xda8a0600; hd->h4 = 0xa96f30bc; hd->h5 = 0x163138aa; hd->h6 = 0xe38dee4d; hd->h7 = 0xb0fb0e4e; hd->bctx.nblocks = 0; hd->bctx.nblocks_high = 0; hd->bctx.count = 0; hd->bctx.blocksize = 64; hd->bctx.bwrite = transform; (void)features; } /* Transform the message X which consists of 16 32-bit-words. See GM/T 004-2012 for details. */ #define R(i,a,b,c,d,e,f,g,h,t,w1,w2) do \ { \ ss1 = rol ((rol ((a), 12) + (e) + (t)), 7); \ ss2 = ss1 ^ rol ((a), 12); \ d += FF##i(a,b,c) + ss2 + ((w1) ^ (w2)); \ h += GG##i(e,f,g) + ss1 + (w1); \ b = rol ((b), 9); \ f = rol ((f), 19); \ h = P0 ((h)); \ } while (0) #define R1(a,b,c,d,e,f,g,h,t,w1,w2) R(1,a,b,c,d,e,f,g,h,t,w1,w2) #define R2(a,b,c,d,e,f,g,h,t,w1,w2) R(2,a,b,c,d,e,f,g,h,t,w1,w2) #define FF1(x, y, z) (x ^ y ^ z) #define FF2(x, y, z) ((x & y) | (x & z) | (y & z)) #define GG1(x, y, z) (x ^ y ^ z) #define GG2(x, y, z) ((x & y) | ( ~x & z)) /* Message expansion */ #define P0(x) ((x) ^ rol ((x), 9) ^ rol ((x), 17)) #define P1(x) ((x) ^ rol ((x), 15) ^ rol ((x), 23)) #define I(i) ( w[i] = buf_get_be32(data + i * 4) ) #define W1(i) ( w[i&0x0f] ) #define W2(i) ( w[i&0x0f] = P1(w[i &0x0f] \ ^ w[(i-9)&0x0f] \ ^ rol (w[(i-3)&0x0f], 15)) \ ^ rol (w[(i-13)&0x0f], 7) \ ^ w[(i-6)&0x0f] ) static unsigned int transform_blk (void *ctx, const unsigned char *data) { SM3_CONTEXT *hd = ctx; static const u32 K[64] = { 0x79cc4519, 0xf3988a32, 0xe7311465, 0xce6228cb, 0x9cc45197, 0x3988a32f, 0x7311465e, 0xe6228cbc, 0xcc451979, 0x988a32f3, 0x311465e7, 0x6228cbce, 0xc451979c, 0x88a32f39, 0x11465e73, 0x228cbce6, 0x9d8a7a87, 0x3b14f50f, 0x7629ea1e, 0xec53d43c, 0xd8a7a879, 0xb14f50f3, 0x629ea1e7, 0xc53d43ce, 0x8a7a879d, 0x14f50f3b, 0x29ea1e76, 0x53d43cec, 0xa7a879d8, 0x4f50f3b1, 0x9ea1e762, 0x3d43cec5, 0x7a879d8a, 0xf50f3b14, 0xea1e7629, 0xd43cec53, 0xa879d8a7, 0x50f3b14f, 0xa1e7629e, 0x43cec53d, 0x879d8a7a, 0x0f3b14f5, 0x1e7629ea, 0x3cec53d4, 0x79d8a7a8, 0xf3b14f50, 0xe7629ea1, 0xcec53d43, 0x9d8a7a87, 0x3b14f50f, 0x7629ea1e, 0xec53d43c, 0xd8a7a879, 0xb14f50f3, 0x629ea1e7, 0xc53d43ce, 0x8a7a879d, 0x14f50f3b, 0x29ea1e76, 0x53d43cec, 0xa7a879d8, 0x4f50f3b1, 0x9ea1e762, 0x3d43cec5 }; u32 a,b,c,d,e,f,g,h,ss1,ss2; u32 w[16]; a = hd->h0; b = hd->h1; c = hd->h2; d = hd->h3; e = hd->h4; f = hd->h5; g = hd->h6; h = hd->h7; R1(a, b, c, d, e, f, g, h, K[0], I(0), I(4)); R1(d, a, b, c, h, e, f, g, K[1], I(1), I(5)); R1(c, d, a, b, g, h, e, f, K[2], I(2), I(6)); R1(b, c, d, a, f, g, h, e, K[3], I(3), I(7)); R1(a, b, c, d, e, f, g, h, K[4], W1(4), I(8)); R1(d, a, b, c, h, e, f, g, K[5], W1(5), I(9)); R1(c, d, a, b, g, h, e, f, K[6], W1(6), I(10)); R1(b, c, d, a, f, g, h, e, K[7], W1(7), I(11)); R1(a, b, c, d, e, f, g, h, K[8], W1(8), I(12)); R1(d, a, b, c, h, e, f, g, K[9], W1(9), I(13)); R1(c, d, a, b, g, h, e, f, K[10], W1(10), I(14)); R1(b, c, d, a, f, g, h, e, K[11], W1(11), I(15)); R1(a, b, c, d, e, f, g, h, K[12], W1(12), W2(16)); R1(d, a, b, c, h, e, f, g, K[13], W1(13), W2(17)); R1(c, d, a, b, g, h, e, f, K[14], W1(14), W2(18)); R1(b, c, d, a, f, g, h, e, K[15], W1(15), W2(19)); R2(a, b, c, d, e, f, g, h, K[16], W1(16), W2(20)); R2(d, a, b, c, h, e, f, g, K[17], W1(17), W2(21)); R2(c, d, a, b, g, h, e, f, K[18], W1(18), W2(22)); R2(b, c, d, a, f, g, h, e, K[19], W1(19), W2(23)); R2(a, b, c, d, e, f, g, h, K[20], W1(20), W2(24)); R2(d, a, b, c, h, e, f, g, K[21], W1(21), W2(25)); R2(c, d, a, b, g, h, e, f, K[22], W1(22), W2(26)); R2(b, c, d, a, f, g, h, e, K[23], W1(23), W2(27)); R2(a, b, c, d, e, f, g, h, K[24], W1(24), W2(28)); R2(d, a, b, c, h, e, f, g, K[25], W1(25), W2(29)); R2(c, d, a, b, g, h, e, f, K[26], W1(26), W2(30)); R2(b, c, d, a, f, g, h, e, K[27], W1(27), W2(31)); R2(a, b, c, d, e, f, g, h, K[28], W1(28), W2(32)); R2(d, a, b, c, h, e, f, g, K[29], W1(29), W2(33)); R2(c, d, a, b, g, h, e, f, K[30], W1(30), W2(34)); R2(b, c, d, a, f, g, h, e, K[31], W1(31), W2(35)); R2(a, b, c, d, e, f, g, h, K[32], W1(32), W2(36)); R2(d, a, b, c, h, e, f, g, K[33], W1(33), W2(37)); R2(c, d, a, b, g, h, e, f, K[34], W1(34), W2(38)); R2(b, c, d, a, f, g, h, e, K[35], W1(35), W2(39)); R2(a, b, c, d, e, f, g, h, K[36], W1(36), W2(40)); R2(d, a, b, c, h, e, f, g, K[37], W1(37), W2(41)); R2(c, d, a, b, g, h, e, f, K[38], W1(38), W2(42)); R2(b, c, d, a, f, g, h, e, K[39], W1(39), W2(43)); R2(a, b, c, d, e, f, g, h, K[40], W1(40), W2(44)); R2(d, a, b, c, h, e, f, g, K[41], W1(41), W2(45)); R2(c, d, a, b, g, h, e, f, K[42], W1(42), W2(46)); R2(b, c, d, a, f, g, h, e, K[43], W1(43), W2(47)); R2(a, b, c, d, e, f, g, h, K[44], W1(44), W2(48)); R2(d, a, b, c, h, e, f, g, K[45], W1(45), W2(49)); R2(c, d, a, b, g, h, e, f, K[46], W1(46), W2(50)); R2(b, c, d, a, f, g, h, e, K[47], W1(47), W2(51)); R2(a, b, c, d, e, f, g, h, K[48], W1(48), W2(52)); R2(d, a, b, c, h, e, f, g, K[49], W1(49), W2(53)); R2(c, d, a, b, g, h, e, f, K[50], W1(50), W2(54)); R2(b, c, d, a, f, g, h, e, K[51], W1(51), W2(55)); R2(a, b, c, d, e, f, g, h, K[52], W1(52), W2(56)); R2(d, a, b, c, h, e, f, g, K[53], W1(53), W2(57)); R2(c, d, a, b, g, h, e, f, K[54], W1(54), W2(58)); R2(b, c, d, a, f, g, h, e, K[55], W1(55), W2(59)); R2(a, b, c, d, e, f, g, h, K[56], W1(56), W2(60)); R2(d, a, b, c, h, e, f, g, K[57], W1(57), W2(61)); R2(c, d, a, b, g, h, e, f, K[58], W1(58), W2(62)); R2(b, c, d, a, f, g, h, e, K[59], W1(59), W2(63)); R2(a, b, c, d, e, f, g, h, K[60], W1(60), W2(64)); R2(d, a, b, c, h, e, f, g, K[61], W1(61), W2(65)); R2(c, d, a, b, g, h, e, f, K[62], W1(62), W2(66)); R2(b, c, d, a, f, g, h, e, K[63], W1(63), W2(67)); hd->h0 ^= a; hd->h1 ^= b; hd->h2 ^= c; hd->h3 ^= d; hd->h4 ^= e; hd->h5 ^= f; hd->h6 ^= g; hd->h7 ^= h; return /*burn_stack*/ 26*4+32; } #undef P0 #undef P1 #undef R #undef R1 #undef R2 static unsigned int transform (void *ctx, const unsigned char *data, size_t nblks) { SM3_CONTEXT *hd = ctx; unsigned int burn; do { burn = transform_blk (hd, data); data += 64; } while (--nblks); return burn; } /* The routine finally terminates the computation and returns the digest. The handle is prepared for a new cycle, but adding bytes to the handle will the destroy the returned buffer. Returns: 32 bytes with the message the digest. */ static void sm3_final(void *context) { SM3_CONTEXT *hd = context; u32 t, th, msb, lsb; byte *p; unsigned int burn; _gcry_md_block_write (hd, NULL, 0); /* flush */; t = hd->bctx.nblocks; if (sizeof t == sizeof hd->bctx.nblocks) th = hd->bctx.nblocks_high; else th = hd->bctx.nblocks >> 32; /* multiply by 64 to make a byte count */ lsb = t << 6; msb = (th << 6) | (t >> 26); /* add the count */ t = lsb; if ((lsb += hd->bctx.count) < t) msb++; /* multiply by 8 to make a bit count */ t = lsb; lsb <<= 3; msb <<= 3; msb |= t >> 29; - if (hd->bctx.count < 56) - { /* enough room */ + if (hd->bctx.count < 56) /* enough room */ + { hd->bctx.buf[hd->bctx.count++] = 0x80; /* pad */ - while (hd->bctx.count < 56) - hd->bctx.buf[hd->bctx.count++] = 0; /* pad */ + if (hd->bctx.count < 56) + memset (&hd->bctx.buf[hd->bctx.count], 0, 56 - hd->bctx.count); + hd->bctx.count = 56; + + /* append the 64 bit count */ + buf_put_be32(hd->bctx.buf + 56, msb); + buf_put_be32(hd->bctx.buf + 60, lsb); + burn = (*hd->bctx.bwrite) ( hd, hd->bctx.buf, 1 ); } - else - { /* need one extra block */ + else /* need one extra block */ + { hd->bctx.buf[hd->bctx.count++] = 0x80; /* pad character */ - while (hd->bctx.count < 64) - hd->bctx.buf[hd->bctx.count++] = 0; - _gcry_md_block_write (hd, NULL, 0); /* flush */; - memset (hd->bctx.buf, 0, 56 ); /* fill next block with zeroes */ + /* fill pad and next block with zeroes */ + memset (&hd->bctx.buf[hd->bctx.count], 0, 64 - hd->bctx.count + 56); + hd->bctx.count = 64 + 56; + + /* append the 64 bit count */ + buf_put_be32(hd->bctx.buf + 64 + 56, msb); + buf_put_be32(hd->bctx.buf + 64 + 60, lsb); + burn = (*hd->bctx.bwrite) ( hd, hd->bctx.buf, 2 ); } - /* append the 64 bit count */ - buf_put_be32(hd->bctx.buf + 56, msb); - buf_put_be32(hd->bctx.buf + 60, lsb); - burn = transform (hd, hd->bctx.buf, 1); - _gcry_burn_stack (burn); p = hd->bctx.buf; #define X(a) do { buf_put_be32(p, hd->h##a); p += 4; } while(0) X(0); X(1); X(2); X(3); X(4); X(5); X(6); X(7); #undef X + + _gcry_burn_stack (burn); } static byte * sm3_read (void *context) { SM3_CONTEXT *hd = context; return hd->bctx.buf; } /* Shortcut functions which puts the hash value of the supplied buffer * into outbuf which must have a size of 32 bytes. */ void _gcry_sm3_hash_buffer (void *outbuf, const void *buffer, size_t length) { SM3_CONTEXT hd; sm3_init (&hd, 0); _gcry_md_block_write (&hd, buffer, length); sm3_final (&hd); memcpy (outbuf, hd.bctx.buf, 32); } /* Variant of the above shortcut function using multiple buffers. */ void _gcry_sm3_hash_buffers (void *outbuf, const gcry_buffer_t *iov, int iovcnt) { SM3_CONTEXT hd; sm3_init (&hd, 0); for (;iovcnt > 0; iov++, iovcnt--) _gcry_md_block_write (&hd, (const char*)iov[0].data + iov[0].off, iov[0].len); sm3_final (&hd); memcpy (outbuf, hd.bctx.buf, 32); } /* Self-test section. */ static gpg_err_code_t selftests_sm3 (int extended, selftest_report_func_t report) { const char *what; const char *errtxt; what = "short string (spec example 1)"; errtxt = _gcry_hash_selftest_check_one (GCRY_MD_SM3, 0, "abc", 3, "\x66\xc7\xf0\xf4\x62\xee\xed\xd9\xd1\xf2\xd4\x6b\xdc\x10\xe4\xe2" "\x41\x67\xc4\x87\x5c\xf2\xf7\xa2\x29\x7d\xa0\x2b\x8f\x4b\xa8\xe0", 32); if (errtxt) goto failed; if (extended) { what = "long string (spec example 2)"; errtxt = _gcry_hash_selftest_check_one (GCRY_MD_SM3, 0, "abcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcd", 64, "\xde\xbe\x9f\xf9\x22\x75\xb8\xa1\x38\x60\x48\x89\xc1\x8e\x5a\x4d" "\x6f\xdb\x70\xe5\x38\x7e\x57\x65\x29\x3d\xcb\xa3\x9c\x0c\x57\x32", 32); if (errtxt) goto failed; what = "long string"; errtxt = _gcry_hash_selftest_check_one (GCRY_MD_SM3, 0, "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", 56, "\x63\x9b\x6c\xc5\xe6\x4d\x9e\x37\xa3\x90\xb1\x92\xdf\x4f\xa1\xea" "\x07\x20\xab\x74\x7f\xf6\x92\xb9\xf3\x8c\x4e\x66\xad\x7b\x8c\x05", 32); if (errtxt) goto failed; what = "one million \"a\""; errtxt = _gcry_hash_selftest_check_one (GCRY_MD_SM3, 1, NULL, 0, "\xc8\xaa\xf8\x94\x29\x55\x40\x29\xe2\x31\x94\x1a\x2a\xcc\x0a\xd6" "\x1f\xf2\xa5\xac\xd8\xfa\xdd\x25\x84\x7a\x3a\x73\x2b\x3b\x02\xc3", 32); if (errtxt) goto failed; } return 0; /* Succeeded. */ failed: if (report) report ("digest", GCRY_MD_SM3, what, errtxt); return GPG_ERR_SELFTEST_FAILED; } /* Run a full self-test for ALGO and return 0 on success. */ static gpg_err_code_t run_selftests (int algo, int extended, selftest_report_func_t report) { gpg_err_code_t ec; switch (algo) { case GCRY_MD_SM3: ec = selftests_sm3 (extended, report); break; default: ec = GPG_ERR_DIGEST_ALGO; break; } return ec; } static byte asn_sm3[] = /* Object ID is 1.2.156.10197.401 */ { 0x30, 0x2F, 0x30, 0x0B, 0x06, 0x07, 0x2A, 0x81, 0x1C, 0xCF, 0x55, 0x83, 0x11, 0x05, 0x00, 0x04, 0x20 }; static gcry_md_oid_spec_t oid_spec_sm3[] = { /* China Electronics Standardization Instutute, OID White paper (2015), Table 6 */ { "1.2.156.10197.401" }, { NULL }, }; gcry_md_spec_t _gcry_digest_spec_sm3 = { GCRY_MD_SM3, {0, 1}, "SM3", asn_sm3, DIM (asn_sm3), oid_spec_sm3, 32, sm3_init, _gcry_md_block_write, sm3_final, sm3_read, NULL, _gcry_sm3_hash_buffer, _gcry_sm3_hash_buffers, sizeof (SM3_CONTEXT), run_selftests }; diff --git a/cipher/stribog.c b/cipher/stribog.c index 459e4db9..d31dddd3 100644 --- a/cipher/stribog.c +++ b/cipher/stribog.c @@ -1,1358 +1,1359 @@ /* stribog.c - GOST R 34.11-2012 (Stribog) hash function * Copyright (C) 2013 Dmitry Eremin-Solenikov * * This file is part of Libgcrypt. * * Libgcrypt is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * Libgcrypt is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this program; if not, see . */ #include #include #include #include #include "g10lib.h" #include "bithelp.h" #include "bufhelp.h" #include "cipher.h" #include "hash-common.h" typedef struct { gcry_md_block_ctx_t bctx; union { u64 h[8]; unsigned char result[64]; }; u64 N[8]; u64 Sigma[8]; } STRIBOG_CONTEXT; /* Pre-computed results of multiplication of bytes on A and reordered with Pi[]. */ static const u64 stribog_table[8][256] = { /* 0 */ { U64_C(0xd01f715b5c7ef8e6), U64_C(0x16fa240980778325), U64_C(0xa8a42e857ee049c8), U64_C(0x6ac1068fa186465b), U64_C(0x6e417bd7a2e9320b), U64_C(0x665c8167a437daab), U64_C(0x7666681aa89617f6), U64_C(0x4b959163700bdcf5), U64_C(0xf14be6b78df36248), U64_C(0xc585bd689a625cff), U64_C(0x9557d7fca67d82cb), U64_C(0x89f0b969af6dd366), U64_C(0xb0833d48749f6c35), U64_C(0xa1998c23b1ecbc7c), U64_C(0x8d70c431ac02a736), U64_C(0xd6dfbc2fd0a8b69e), U64_C(0x37aeb3e551fa198b), U64_C(0x0b7d128a40b5cf9c), U64_C(0x5a8f2008b5780cbc), U64_C(0xedec882284e333e5), U64_C(0xd25fc177d3c7c2ce), U64_C(0x5e0f5d50b61778ec), U64_C(0x1d873683c0c24cb9), U64_C(0xad040bcbb45d208c), U64_C(0x2f89a0285b853c76), U64_C(0x5732fff6791b8d58), U64_C(0x3e9311439ef6ec3f), U64_C(0xc9183a809fd3c00f), U64_C(0x83adf3f5260a01ee), U64_C(0xa6791941f4e8ef10), U64_C(0x103ae97d0ca1cd5d), U64_C(0x2ce948121dee1b4a), U64_C(0x39738421dbf2bf53), U64_C(0x093da2a6cf0cf5b4), U64_C(0xcd9847d89cbcb45f), U64_C(0xf9561c078b2d8ae8), U64_C(0x9c6a755a6971777f), U64_C(0xbc1ebaa0712ef0c5), U64_C(0x72e61542abf963a6), U64_C(0x78bb5fde229eb12e), U64_C(0x14ba94250fceb90d), U64_C(0x844d6697630e5282), U64_C(0x98ea08026a1e032f), U64_C(0xf06bbea144217f5c), U64_C(0xdb6263d11ccb377a), U64_C(0x641c314b2b8ee083), U64_C(0x320e96ab9b4770cf), U64_C(0x1ee7deb986a96b85), U64_C(0xe96cf57a878c47b5), U64_C(0xfdd6615f8842feb8), U64_C(0xc83862965601dd1b), U64_C(0x2ea9f83e92572162), U64_C(0xf876441142ff97fc), U64_C(0xeb2c455608357d9d), U64_C(0x5612a7e0b0c9904c), U64_C(0x6c01cbfb2d500823), U64_C(0x4548a6a7fa037a2d), U64_C(0xabc4c6bf388b6ef4), U64_C(0xbade77d4fdf8bebd), U64_C(0x799b07c8eb4cac3a), U64_C(0x0c9d87e805b19cf0), U64_C(0xcb588aac106afa27), U64_C(0xea0c1d40c1e76089), U64_C(0x2869354a1e816f1a), U64_C(0xff96d17307fbc490), U64_C(0x9f0a9d602f1a5043), U64_C(0x96373fc6e016a5f7), U64_C(0x5292dab8b3a6e41c), U64_C(0x9b8ae0382c752413), U64_C(0x4f15ec3b7364a8a5), U64_C(0x3fb349555724f12b), U64_C(0xc7c50d4415db66d7), U64_C(0x92b7429ee379d1a7), U64_C(0xd37f99611a15dfda), U64_C(0x231427c05e34a086), U64_C(0xa439a96d7b51d538), U64_C(0xb403401077f01865), U64_C(0xdda2aea5901d7902), U64_C(0x0a5d4a9c8967d288), U64_C(0xc265280adf660f93), U64_C(0x8bb0094520d4e94e), U64_C(0x2a29856691385532), U64_C(0x42a833c5bf072941), U64_C(0x73c64d54622b7eb2), U64_C(0x07e095624504536c), U64_C(0x8a905153e906f45a), U64_C(0x6f6123c16b3b2f1f), U64_C(0xc6e55552dc097bc3), U64_C(0x4468feb133d16739), U64_C(0xe211e7f0c7398829), U64_C(0xa2f96419f7879b40), U64_C(0x19074bdbc3ad38e9), U64_C(0xf4ebc3f9474e0b0c), U64_C(0x43886bd376d53455), U64_C(0xd8028beb5aa01046), U64_C(0x51f23282f5cdc320), U64_C(0xe7b1c2be0d84e16d), U64_C(0x081dfab006dee8a0), U64_C(0x3b33340d544b857b), U64_C(0x7f5bcabc679ae242), U64_C(0x0edd37c48a08a6d8), U64_C(0x81ed43d9a9b33bc6), U64_C(0xb1a3655ebd4d7121), U64_C(0x69a1eeb5e7ed6167), U64_C(0xf6ab73d5c8f73124), U64_C(0x1a67a3e185c61fd5), U64_C(0x2dc91004d43c065e), U64_C(0x0240b02c8fb93a28), U64_C(0x90f7f2b26cc0eb8f), U64_C(0x3cd3a16f114fd617), U64_C(0xaae49ea9f15973e0), U64_C(0x06c0cd748cd64e78), U64_C(0xda423bc7d5192a6e), U64_C(0xc345701c16b41287), U64_C(0x6d2193ede4821537), U64_C(0xfcf639494190e3ac), U64_C(0x7c3b228621f1c57e), U64_C(0xfb16ac2b0494b0c0), U64_C(0xbf7e529a3745d7f9), U64_C(0x6881b6a32e3f7c73), U64_C(0xca78d2bad9b8e733), U64_C(0xbbfe2fc2342aa3a9), U64_C(0x0dbddffecc6381e4), U64_C(0x70a6a56e2440598e), U64_C(0xe4d12a844befc651), U64_C(0x8c509c2765d0ba22), U64_C(0xee8c6018c28814d9), U64_C(0x17da7c1f49a59e31), U64_C(0x609c4c1328e194d3), U64_C(0xb3e3d57232f44b09), U64_C(0x91d7aaa4a512f69b), U64_C(0x0ffd6fd243dabbcc), U64_C(0x50d26a943c1fde34), U64_C(0x6be15e9968545b4f), U64_C(0x94778fea6faf9fdf), U64_C(0x2b09dd7058ea4826), U64_C(0x677cd9716de5c7bf), U64_C(0x49d5214fffb2e6dd), U64_C(0x0360e83a466b273c), U64_C(0x1fc786af4f7b7691), U64_C(0xa0b9d435783ea168), U64_C(0xd49f0c035f118cb6), U64_C(0x01205816c9d21d14), U64_C(0xac2453dd7d8f3d98), U64_C(0x545217cc3f70aa64), U64_C(0x26b4028e9489c9c2), U64_C(0xdec2469fd6765e3e), U64_C(0x04807d58036f7450), U64_C(0xe5f17292823ddb45), U64_C(0xf30b569b024a5860), U64_C(0x62dcfc3fa758aefb), U64_C(0xe84cad6c4e5e5aa1), U64_C(0xccb81fce556ea94b), U64_C(0x53b282ae7a74f908), U64_C(0x1b47fbf74c1402c1), U64_C(0x368eebf39828049f), U64_C(0x7afbeff2ad278b06), U64_C(0xbe5e0a8cfe97caed), U64_C(0xcfd8f7f413058e77), U64_C(0xf78b2bc301252c30), U64_C(0x4d555c17fcdd928d), U64_C(0x5f2f05467fc565f8), U64_C(0x24f4b2a21b30f3ea), U64_C(0x860dd6bbecb768aa), U64_C(0x4c750401350f8f99), U64_C(0x0000000000000000), U64_C(0xecccd0344d312ef1), U64_C(0xb5231806be220571), U64_C(0xc105c030990d28af), U64_C(0x653c695de25cfd97), U64_C(0x159acc33c61ca419), U64_C(0xb89ec7f872418495), U64_C(0xa9847693b73254dc), U64_C(0x58cf90243ac13694), U64_C(0x59efc832f3132b80), U64_C(0x5c4fed7c39ae42c4), U64_C(0x828dabe3efd81cfa), U64_C(0xd13f294d95ace5f2), U64_C(0x7d1b7a90e823d86a), U64_C(0xb643f03cf849224d), U64_C(0x3df3f979d89dcb03), U64_C(0x7426d836272f2dde), U64_C(0xdfe21e891fa4432a), U64_C(0x3a136c1b9d99986f), U64_C(0xfa36f43dcd46add4), U64_C(0xc025982650df35bb), U64_C(0x856d3e81aadc4f96), U64_C(0xc4a5e57e53b041eb), U64_C(0x4708168b75ba4005), U64_C(0xaf44bbe73be41aa4), U64_C(0x971767d029c4b8e3), U64_C(0xb9be9feebb939981), U64_C(0x215497ecd18d9aae), U64_C(0x316e7e91dd2c57f3), U64_C(0xcef8afe2dad79363), U64_C(0x3853dc371220a247), U64_C(0x35ee03c9de4323a3), U64_C(0xe6919aa8c456fc79), U64_C(0xe05157dc4880b201), U64_C(0x7bdbb7e464f59612), U64_C(0x127a59518318f775), U64_C(0x332ecebd52956ddb), U64_C(0x8f30741d23bb9d1e), U64_C(0xd922d3fd93720d52), U64_C(0x7746300c61440ae2), U64_C(0x25d4eab4d2e2eefe), U64_C(0x75068020eefd30ca), U64_C(0x135a01474acaea61), U64_C(0x304e268714fe4ae7), U64_C(0xa519f17bb283c82c), U64_C(0xdc82f6b359cf6416), U64_C(0x5baf781e7caa11a8), U64_C(0xb2c38d64fb26561d), U64_C(0x34ce5bdf17913eb7), U64_C(0x5d6fb56af07c5fd0), U64_C(0x182713cd0a7f25fd), U64_C(0x9e2ac576e6c84d57), U64_C(0x9aaab82ee5a73907), U64_C(0xa3d93c0f3e558654), U64_C(0x7e7b92aaae48ff56), U64_C(0x872d8ead256575be), U64_C(0x41c8dbfff96c0e7d), U64_C(0x99ca5014a3cc1e3b), U64_C(0x40e883e930be1369), U64_C(0x1ca76e95091051ad), U64_C(0x4e35b42dbab6b5b1), U64_C(0x05a0254ecabd6944), U64_C(0xe1710fca8152af15), U64_C(0xf22b0e8dcb984574), U64_C(0xb763a82a319b3f59), U64_C(0x63fca4296e8ab3ef), U64_C(0x9d4a2d4ca0a36a6b), U64_C(0xe331bfe60eeb953d), U64_C(0xd5bf541596c391a2), U64_C(0xf5cb9bef8e9c1618), U64_C(0x46284e9dbc685d11), U64_C(0x2074cffa185f87ba), U64_C(0xbd3ee2b6b8fcedd1), U64_C(0xae64e3f1f23607b0), U64_C(0xfeb68965ce29d984), U64_C(0x55724fdaf6a2b770), U64_C(0x29496d5cd753720e), U64_C(0xa75941573d3af204), U64_C(0x8e102c0bea69800a), U64_C(0x111ab16bc573d049), U64_C(0xd7ffe439197aab8a), U64_C(0xefac380e0b5a09cd), U64_C(0x48f579593660fbc9), U64_C(0x22347fd697e6bd92), U64_C(0x61bc1405e13389c7), U64_C(0x4ab5c975b9d9c1e1), U64_C(0x80cd1bcf606126d2), U64_C(0x7186fd78ed92449a), U64_C(0x93971a882aabccb3), U64_C(0x88d0e17f66bfce72), U64_C(0x27945a985d5bd4d6) }, /* 1 */ { U64_C(0xde553f8c05a811c8), U64_C(0x1906b59631b4f565), U64_C(0x436e70d6b1964ff7), U64_C(0x36d343cb8b1e9d85), U64_C(0x843dfacc858aab5a), U64_C(0xfdfc95c299bfc7f9), U64_C(0x0f634bdea1d51fa2), U64_C(0x6d458b3b76efb3cd), U64_C(0x85c3f77cf8593f80), U64_C(0x3c91315fbe737cb2), U64_C(0x2148b03366ace398), U64_C(0x18f8b8264c6761bf), U64_C(0xc830c1c495c9fb0f), U64_C(0x981a76102086a0aa), U64_C(0xaa16012142f35760), U64_C(0x35cc54060c763cf6), U64_C(0x42907d66cc45db2d), U64_C(0x8203d44b965af4bc), U64_C(0x3d6f3cefc3a0e868), U64_C(0xbc73ff69d292bda7), U64_C(0x8722ed0102e20a29), U64_C(0x8f8185e8cd34deb7), U64_C(0x9b0561dda7ee01d9), U64_C(0x5335a0193227fad6), U64_C(0xc9cecc74e81a6fd5), U64_C(0x54f5832e5c2431ea), U64_C(0x99e47ba05d553470), U64_C(0xf7bee756acd226ce), U64_C(0x384e05a5571816fd), U64_C(0xd1367452a47d0e6a), U64_C(0xf29fde1c386ad85b), U64_C(0x320c77316275f7ca), U64_C(0xd0c879e2d9ae9ab0), U64_C(0xdb7406c69110ef5d), U64_C(0x45505e51a2461011), U64_C(0xfc029872e46c5323), U64_C(0xfa3cb6f5f7bc0cc5), U64_C(0x031f17cd8768a173), U64_C(0xbd8df2d9af41297d), U64_C(0x9d3b4f5ab43e5e3f), U64_C(0x4071671b36feee84), U64_C(0x716207e7d3e3b83d), U64_C(0x48d20ff2f9283a1a), U64_C(0x27769eb4757cbc7e), U64_C(0x5c56ebc793f2e574), U64_C(0xa48b474f9ef5dc18), U64_C(0x52cbada94ff46e0c), U64_C(0x60c7da982d8199c6), U64_C(0x0e9d466edc068b78), U64_C(0x4eec2175eaf865fc), U64_C(0x550b8e9e21f7a530), U64_C(0x6b7ba5bc653fec2b), U64_C(0x5eb7f1ba6949d0dd), U64_C(0x57ea94e3db4c9099), U64_C(0xf640eae6d101b214), U64_C(0xdd4a284182c0b0bb), U64_C(0xff1d8fbf6304f250), U64_C(0xb8accb933bf9d7e8), U64_C(0xe8867c478eb68c4d), U64_C(0x3f8e2692391bddc1), U64_C(0xcb2fd60912a15a7c), U64_C(0xaec935dbab983d2f), U64_C(0xf55ffd2b56691367), U64_C(0x80e2ce366ce1c115), U64_C(0x179bf3f8edb27e1d), U64_C(0x01fe0db07dd394da), U64_C(0xda8a0b76ecc37b87), U64_C(0x44ae53e1df9584cb), U64_C(0xb310b4b77347a205), U64_C(0xdfab323c787b8512), U64_C(0x3b511268d070b78e), U64_C(0x65e6e3d2b9396753), U64_C(0x6864b271e2574d58), U64_C(0x259784c98fc789d7), U64_C(0x02e11a7dfabb35a9), U64_C(0x8841a6dfa337158b), U64_C(0x7ade78c39b5dcdd0), U64_C(0xb7cf804d9a2cc84a), U64_C(0x20b6bd831b7f7742), U64_C(0x75bd331d3a88d272), U64_C(0x418f6aab4b2d7a5e), U64_C(0xd9951cbb6babdaf4), U64_C(0xb6318dfde7ff5c90), U64_C(0x1f389b112264aa83), U64_C(0x492c024284fbaec0), U64_C(0xe33a0363c608f9a0), U64_C(0x2688930408af28a4), U64_C(0xc7538a1a341ce4ad), U64_C(0x5da8e677ee2171ae), U64_C(0x8c9e92254a5c7fc4), U64_C(0x63d8cd55aae938b5), U64_C(0x29ebd8daa97a3706), U64_C(0x959827b37be88aa1), U64_C(0x1484e4356adadf6e), U64_C(0xa7945082199d7d6b), U64_C(0xbf6ce8a455fa1cd4), U64_C(0x9cc542eac9edcae5), U64_C(0x79c16f0e1c356ca3), U64_C(0x89bfab6fdee48151), U64_C(0xd4174d1830c5f0ff), U64_C(0x9258048415eb419d), U64_C(0x6139d72850520d1c), U64_C(0x6a85a80c18ec78f1), U64_C(0xcd11f88e0171059a), U64_C(0xcceff53e7ca29140), U64_C(0xd229639f2315af19), U64_C(0x90b91ef9ef507434), U64_C(0x5977d28d074a1be1), U64_C(0x311360fce51d56b9), U64_C(0xc093a92d5a1f2f91), U64_C(0x1a19a25bb6dc5416), U64_C(0xeb996b8a09de2d3e), U64_C(0xfee3820f1ed7668a), U64_C(0xd7085ad5b7ad518c), U64_C(0x7fff41890fe53345), U64_C(0xec5948bd67dde602), U64_C(0x2fd5f65dbaaa68e0), U64_C(0xa5754affe32648c2), U64_C(0xf8ddac880d07396c), U64_C(0x6fa491468c548664), U64_C(0x0c7c5c1326bdbed1), U64_C(0x4a33158f03930fb3), U64_C(0x699abfc19f84d982), U64_C(0xe4fa2054a80b329c), U64_C(0x6707f9af438252fa), U64_C(0x08a368e9cfd6d49e), U64_C(0x47b1442c58fd25b8), U64_C(0xbbb3dc5ebc91769b), U64_C(0x1665fe489061eac7), U64_C(0x33f27a811fa66310), U64_C(0x93a609346838d547), U64_C(0x30ed6d4c98cec263), U64_C(0x1dd9816cd8df9f2a), U64_C(0x94662a03063b1e7b), U64_C(0x83fdd9fbeb896066), U64_C(0x7b207573e68e590a), U64_C(0x5f49fc0a149a4407), U64_C(0x343259b671a5a82c), U64_C(0xfbc2bb458a6f981f), U64_C(0xc272b350a0a41a38), U64_C(0x3aaf1fd8ada32354), U64_C(0x6cbb868b0b3c2717), U64_C(0xa2b569c88d2583fe), U64_C(0xf180c9d1bf027928), U64_C(0xaf37386bd64ba9f5), U64_C(0x12bacab2790a8088), U64_C(0x4c0d3b0810435055), U64_C(0xb2eeb9070e9436df), U64_C(0xc5b29067cea7d104), U64_C(0xdcb425f1ff132461), U64_C(0x4f122cc5972bf126), U64_C(0xac282fa651230886), U64_C(0xe7e537992f6393ef), U64_C(0xe61b3a2952b00735), U64_C(0x709c0a57ae302ce7), U64_C(0xe02514ae416058d3), U64_C(0xc44c9dd7b37445de), U64_C(0x5a68c5408022ba92), U64_C(0x1c278cdca50c0bf0), U64_C(0x6e5a9cf6f18712be), U64_C(0x86dce0b17f319ef3), U64_C(0x2d34ec2040115d49), U64_C(0x4bcd183f7e409b69), U64_C(0x2815d56ad4a9a3dc), U64_C(0x24698979f2141d0d), U64_C(0x0000000000000000), U64_C(0x1ec696a15fb73e59), U64_C(0xd86b110b16784e2e), U64_C(0x8e7f8858b0e74a6d), U64_C(0x063e2e8713d05fe6), U64_C(0xe2c40ed3bbdb6d7a), U64_C(0xb1f1aeca89fc97ac), U64_C(0xe1db191e3cb3cc09), U64_C(0x6418ee62c4eaf389), U64_C(0xc6ad87aa49cf7077), U64_C(0xd6f65765ca7ec556), U64_C(0x9afb6c6dda3d9503), U64_C(0x7ce05644888d9236), U64_C(0x8d609f95378feb1e), U64_C(0x23a9aa4e9c17d631), U64_C(0x6226c0e5d73aac6f), U64_C(0x56149953a69f0443), U64_C(0xeeb852c09d66d3ab), U64_C(0x2b0ac2a753c102af), U64_C(0x07c023376e03cb3c), U64_C(0x2ccae1903dc2c993), U64_C(0xd3d76e2f5ec63bc3), U64_C(0x9e2458973356ff4c), U64_C(0xa66a5d32644ee9b1), U64_C(0x0a427294356de137), U64_C(0x783f62be61e6f879), U64_C(0x1344c70204d91452), U64_C(0x5b96c8f0fdf12e48), U64_C(0xa90916ecc59bf613), U64_C(0xbe92e5142829880e), U64_C(0x727d102a548b194e), U64_C(0x1be7afebcb0fc0cc), U64_C(0x3e702b2244c8491b), U64_C(0xd5e940a84d166425), U64_C(0x66f9f41f3e51c620), U64_C(0xabe80c913f20c3ba), U64_C(0xf07ec461c2d1edf2), U64_C(0xf361d3ac45b94c81), U64_C(0x0521394a94b8fe95), U64_C(0xadd622162cf09c5c), U64_C(0xe97871f7f3651897), U64_C(0xf4a1f09b2bba87bd), U64_C(0x095d6559b2054044), U64_C(0x0bbc7f2448be75ed), U64_C(0x2af4cf172e129675), U64_C(0x157ae98517094bb4), U64_C(0x9fda55274e856b96), U64_C(0x914713499283e0ee), U64_C(0xb952c623462a4332), U64_C(0x74433ead475b46a8), U64_C(0x8b5eb112245fb4f8), U64_C(0xa34b6478f0f61724), U64_C(0x11a5dd7ffe6221fb), U64_C(0xc16da49d27ccbb4b), U64_C(0x76a224d0bde07301), U64_C(0x8aa0bca2598c2022), U64_C(0x4df336b86d90c48f), U64_C(0xea67663a740db9e4), U64_C(0xef465f70e0b54771), U64_C(0x39b008152acb8227), U64_C(0x7d1e5bf4f55e06ec), U64_C(0x105bd0cf83b1b521), U64_C(0x775c2960c033e7db), U64_C(0x7e014c397236a79f), U64_C(0x811cc386113255cf), U64_C(0xeda7450d1a0e72d8), U64_C(0x5889df3d7a998f3b), U64_C(0x2e2bfbedc779fc3a), U64_C(0xce0eef438619a4e9), U64_C(0x372d4e7bf6cd095f), U64_C(0x04df34fae96b6a4f), U64_C(0xf923a13870d4adb6), U64_C(0xa1aa7e050a4d228d), U64_C(0xa8f71b5cb84862c9), U64_C(0xb52e9a306097fde3), U64_C(0x0d8251a35b6e2a0b), U64_C(0x2257a7fee1c442eb), U64_C(0x73831d9a29588d94), U64_C(0x51d4ba64c89ccf7f), U64_C(0x502ab7d4b54f5ba5), U64_C(0x97793dce8153bf08), U64_C(0xe5042de4d5d8a646), U64_C(0x9687307efc802bd2), U64_C(0xa05473b5779eb657), U64_C(0xb4d097801d446939), U64_C(0xcff0e2f3fbca3033), U64_C(0xc38cbee0dd778ee2), U64_C(0x464f499c252eb162), U64_C(0xcad1dbb96f72cea6), U64_C(0xba4dd1eec142e241), U64_C(0xb00fa37af42f0376) }, /* 2 */ { U64_C(0xcce4cd3aa968b245), U64_C(0x089d5484e80b7faf), U64_C(0x638246c1b3548304), U64_C(0xd2fe0ec8c2355492), U64_C(0xa7fbdf7ff2374eee), U64_C(0x4df1600c92337a16), U64_C(0x84e503ea523b12fb), U64_C(0x0790bbfd53ab0c4a), U64_C(0x198a780f38f6ea9d), U64_C(0x2ab30c8f55ec48cb), U64_C(0xe0f7fed6b2c49db5), U64_C(0xb6ecf3f422cadbdc), U64_C(0x409c9a541358df11), U64_C(0xd3ce8a56dfde3fe3), U64_C(0xc3e9224312c8c1a0), U64_C(0x0d6dfa58816ba507), U64_C(0xddf3e1b179952777), U64_C(0x04c02a42748bb1d9), U64_C(0x94c2abff9f2decb8), U64_C(0x4f91752da8f8acf4), U64_C(0x78682befb169bf7b), U64_C(0xe1c77a48af2ff6c4), U64_C(0x0c5d7ec69c80ce76), U64_C(0x4cc1e4928fd81167), U64_C(0xfeed3d24d9997b62), U64_C(0x518bb6dfc3a54a23), U64_C(0x6dbf2d26151f9b90), U64_C(0xb5bc624b05ea664f), U64_C(0xe86aaa525acfe21a), U64_C(0x4801ced0fb53a0be), U64_C(0xc91463e6c00868ed), U64_C(0x1027a815cd16fe43), U64_C(0xf67069a0319204cd), U64_C(0xb04ccc976c8abce7), U64_C(0xc0b9b3fc35e87c33), U64_C(0xf380c77c58f2de65), U64_C(0x50bb3241de4e2152), U64_C(0xdf93f490435ef195), U64_C(0xf1e0d25d62390887), U64_C(0xaf668bfb1a3c3141), U64_C(0xbc11b251f00a7291), U64_C(0x73a5eed47e427d47), U64_C(0x25bee3f6ee4c3b2e), U64_C(0x43cc0beb34786282), U64_C(0xc824e778dde3039c), U64_C(0xf97d86d98a327728), U64_C(0xf2b043e24519b514), U64_C(0xe297ebf7880f4b57), U64_C(0x3a94a49a98fab688), U64_C(0x868516cb68f0c419), U64_C(0xeffa11af0964ee50), U64_C(0xa4ab4ec0d517f37d), U64_C(0xa9c6b498547c567a), U64_C(0x8e18424f80fbbbb6), U64_C(0x0bcdc53bcf2bc23c), U64_C(0x137739aaea3643d0), U64_C(0x2c1333ec1bac2ff0), U64_C(0x8d48d3f0a7db0625), U64_C(0x1e1ac3f26b5de6d7), U64_C(0xf520f81f16b2b95e), U64_C(0x9f0f6ec450062e84), U64_C(0x0130849e1deb6b71), U64_C(0xd45e31ab8c7533a9), U64_C(0x652279a2fd14e43f), U64_C(0x3209f01e70f1c927), U64_C(0xbe71a770cac1a473), U64_C(0x0e3d6be7a64b1894), U64_C(0x7ec8148cff29d840), U64_C(0xcb7476c7fac3be0f), U64_C(0x72956a4a63a91636), U64_C(0x37f95ec21991138f), U64_C(0x9e3fea5a4ded45f5), U64_C(0x7b38ba50964902e8), U64_C(0x222e580bbde73764), U64_C(0x61e253e0899f55e6), U64_C(0xfc8d2805e352ad80), U64_C(0x35994be3235ac56d), U64_C(0x09add01af5e014de), U64_C(0x5e8659a6780539c6), U64_C(0xb17c48097161d796), U64_C(0x026015213acbd6e2), U64_C(0xd1ae9f77e515e901), U64_C(0xb7dc776a3f21b0ad), U64_C(0xaba6a1b96eb78098), U64_C(0x9bcf4486248d9f5d), U64_C(0x582666c536455efd), U64_C(0xfdbdac9bfeb9c6f1), U64_C(0xc47999be4163cdea), U64_C(0x765540081722a7ef), U64_C(0x3e548ed8ec710751), U64_C(0x3d041f67cb51bac2), U64_C(0x7958af71ac82d40a), U64_C(0x36c9da5c047a78fe), U64_C(0xed9a048e33af38b2), U64_C(0x26ee7249c96c86bd), U64_C(0x900281bdeba65d61), U64_C(0x11172c8bd0fd9532), U64_C(0xea0abf73600434f8), U64_C(0x42fc8f75299309f3), U64_C(0x34a9cf7d3eb1ae1c), U64_C(0x2b838811480723ba), U64_C(0x5ce64c8742ceef24), U64_C(0x1adae9b01fd6570e), U64_C(0x3c349bf9d6bad1b3), U64_C(0x82453c891c7b75c0), U64_C(0x97923a40b80d512b), U64_C(0x4a61dbf1c198765c), U64_C(0xb48ce6d518010d3e), U64_C(0xcfb45c858e480fd6), U64_C(0xd933cbf30d1e96ae), U64_C(0xd70ea014ab558e3a), U64_C(0xc189376228031742), U64_C(0x9262949cd16d8b83), U64_C(0xeb3a3bed7def5f89), U64_C(0x49314a4ee6b8cbcf), U64_C(0xdcc3652f647e4c06), U64_C(0xda635a4c2a3e2b3d), U64_C(0x470c21a940f3d35b), U64_C(0x315961a157d174b4), U64_C(0x6672e81dda3459ac), U64_C(0x5b76f77a1165e36e), U64_C(0x445cb01667d36ec8), U64_C(0xc5491d205c88a69b), U64_C(0x456c34887a3805b9), U64_C(0xffddb9bac4721013), U64_C(0x99af51a71e4649bf), U64_C(0xa15be01cbc7729d5), U64_C(0x52db2760e485f7b0), U64_C(0x8c78576eba306d54), U64_C(0xae560f6507d75a30), U64_C(0x95f22f6182c687c9), U64_C(0x71c5fbf54489aba5), U64_C(0xca44f259e728d57e), U64_C(0x88b87d2ccebbdc8d), U64_C(0xbab18d32be4a15aa), U64_C(0x8be8ec93e99b611e), U64_C(0x17b713e89ebdf209), U64_C(0xb31c5d284baa0174), U64_C(0xeeca9531148f8521), U64_C(0xb8d198138481c348), U64_C(0x8988f9b2d350b7fc), U64_C(0xb9e11c8d996aa839), U64_C(0x5a4673e40c8e881f), U64_C(0x1687977683569978), U64_C(0xbf4123eed72acf02), U64_C(0x4ea1f1b3b513c785), U64_C(0xe767452be16f91ff), U64_C(0x7505d1b730021a7c), U64_C(0xa59bca5ec8fc980c), U64_C(0xad069eda20f7e7a3), U64_C(0x38f4b1bba231606a), U64_C(0x60d2d77e94743e97), U64_C(0x9affc0183966f42c), U64_C(0x248e6768f3a7505f), U64_C(0xcdd449a4b483d934), U64_C(0x87b59255751baf68), U64_C(0x1bea6d2e023d3c7f), U64_C(0x6b1f12455b5ffcab), U64_C(0x743555292de9710d), U64_C(0xd8034f6d10f5fddf), U64_C(0xc6198c9f7ba81b08), U64_C(0xbb8109aca3a17edb), U64_C(0xfa2d1766ad12cabb), U64_C(0xc729080166437079), U64_C(0x9c5fff7b77269317), U64_C(0x0000000000000000), U64_C(0x15d706c9a47624eb), U64_C(0x6fdf38072fd44d72), U64_C(0x5fb6dd3865ee52b7), U64_C(0xa33bf53d86bcff37), U64_C(0xe657c1b5fc84fa8e), U64_C(0xaa962527735cebe9), U64_C(0x39c43525bfda0b1b), U64_C(0x204e4d2a872ce186), U64_C(0x7a083ece8ba26999), U64_C(0x554b9c9db72efbfa), U64_C(0xb22cd9b656416a05), U64_C(0x96a2bedea5e63a5a), U64_C(0x802529a826b0a322), U64_C(0x8115ad363b5bc853), U64_C(0x8375b81701901eb1), U64_C(0x3069e53f4a3a1fc5), U64_C(0xbd2136cfede119e0), U64_C(0x18bafc91251d81ec), U64_C(0x1d4a524d4c7d5b44), U64_C(0x05f0aedc6960daa8), U64_C(0x29e39d3072ccf558), U64_C(0x70f57f6b5962c0d4), U64_C(0x989fd53903ad22ce), U64_C(0xf84d024797d91c59), U64_C(0x547b1803aac5908b), U64_C(0xf0d056c37fd263f6), U64_C(0xd56eb535919e58d8), U64_C(0x1c7ad6d351963035), U64_C(0x2e7326cd2167f912), U64_C(0xac361a443d1c8cd2), U64_C(0x697f076461942a49), U64_C(0x4b515f6fdc731d2d), U64_C(0x8ad8680df4700a6f), U64_C(0x41ac1eca0eb3b460), U64_C(0x7d988533d80965d3), U64_C(0xa8f6300649973d0b), U64_C(0x7765c4960ac9cc9e), U64_C(0x7ca801adc5e20ea2), U64_C(0xdea3700e5eb59ae4), U64_C(0xa06b6482a19c42a4), U64_C(0x6a2f96db46b497da), U64_C(0x27def6d7d487edcc), U64_C(0x463ca5375d18b82a), U64_C(0xa6cb5be1efdc259f), U64_C(0x53eba3fef96e9cc1), U64_C(0xce84d81b93a364a7), U64_C(0xf4107c810b59d22f), U64_C(0x333974806d1aa256), U64_C(0x0f0def79bba073e5), U64_C(0x231edc95a00c5c15), U64_C(0xe437d494c64f2c6c), U64_C(0x91320523f64d3610), U64_C(0x67426c83c7df32dd), U64_C(0x6eefbc99323f2603), U64_C(0x9d6f7be56acdf866), U64_C(0x5916e25b2bae358c), U64_C(0x7ff89012e2c2b331), U64_C(0x035091bf2720bd93), U64_C(0x561b0d22900e4669), U64_C(0x28d319ae6f279e29), U64_C(0x2f43a2533c8c9263), U64_C(0xd09e1be9f8fe8270), U64_C(0xf740ed3e2c796fbc), U64_C(0xdb53ded237d5404c), U64_C(0x62b2c25faebfe875), U64_C(0x0afd41a5d2c0a94d), U64_C(0x6412fd3ce0ff8f4e), U64_C(0xe3a76f6995e42026), U64_C(0x6c8fa9b808f4f0e1), U64_C(0xc2d9a6dd0f23aad1), U64_C(0x8f28c6d19d10d0c7), U64_C(0x85d587744fd0798a), U64_C(0xa20b71a39b579446), U64_C(0x684f83fa7c7f4138), U64_C(0xe507500adba4471d), U64_C(0x3f640a46f19a6c20), U64_C(0x1247bd34f7dd28a1), U64_C(0x2d23b77206474481), U64_C(0x93521002cc86e0f2), U64_C(0x572b89bc8de52d18), U64_C(0xfb1d93f8b0f9a1ca), U64_C(0xe95a2ecc4724896b), U64_C(0x3ba420048511ddf9), U64_C(0xd63e248ab6bee54b), U64_C(0x5dd6c8195f258455), U64_C(0x06a03f634e40673b), U64_C(0x1f2a476c76b68da6), U64_C(0x217ec9b49ac78af7), U64_C(0xecaa80102e4453c3), U64_C(0x14e78257b99d4f9a) }, /* 3 */ { U64_C(0x20329b2cc87bba05), U64_C(0x4f5eb6f86546a531), U64_C(0xd4f44775f751b6b1), U64_C(0x8266a47b850dfa8b), U64_C(0xbb986aa15a6ca985), U64_C(0xc979eb08f9ae0f99), U64_C(0x2da6f447a2375ea1), U64_C(0x1e74275dcd7d8576), U64_C(0xbc20180a800bc5f8), U64_C(0xb4a2f701b2dc65be), U64_C(0xe726946f981b6d66), U64_C(0x48e6c453bf21c94c), U64_C(0x42cad9930f0a4195), U64_C(0xefa47b64aacccd20), U64_C(0x71180a8960409a42), U64_C(0x8bb3329bf6a44e0c), U64_C(0xd34c35de2d36dacc), U64_C(0xa92f5b7cbc23dc96), U64_C(0xb31a85aa68bb09c3), U64_C(0x13e04836a73161d2), U64_C(0xb24dfc4129c51d02), U64_C(0x8ae44b70b7da5acd), U64_C(0xe671ed84d96579a7), U64_C(0xa4bb3417d66f3832), U64_C(0x4572ab38d56d2de8), U64_C(0xb1b47761ea47215c), U64_C(0xe81c09cf70aba15d), U64_C(0xffbdb872ce7f90ac), U64_C(0xa8782297fd5dc857), U64_C(0x0d946f6b6a4ce4a4), U64_C(0xe4df1f4f5b995138), U64_C(0x9ebc71edca8c5762), U64_C(0x0a2c1dc0b02b88d9), U64_C(0x3b503c115d9d7b91), U64_C(0xc64376a8111ec3a2), U64_C(0xcec199a323c963e4), U64_C(0xdc76a87ec58616f7), U64_C(0x09d596e073a9b487), U64_C(0x14583a9d7d560daf), U64_C(0xf4c6dc593f2a0cb4), U64_C(0xdd21d19584f80236), U64_C(0x4a4836983ddde1d3), U64_C(0xe58866a41ae745f9), U64_C(0xf591a5b27e541875), U64_C(0x891dc05074586693), U64_C(0x5b068c651810a89e), U64_C(0xa30346bc0c08544f), U64_C(0x3dbf3751c684032d), U64_C(0x2a1e86ec785032dc), U64_C(0xf73f5779fca830ea), U64_C(0xb60c05ca30204d21), U64_C(0x0cc316802b32f065), U64_C(0x8770241bdd96be69), U64_C(0xb861e18199ee95db), U64_C(0xf805cad91418fcd1), U64_C(0x29e70dccbbd20e82), U64_C(0xc7140f435060d763), U64_C(0x0f3a9da0e8b0cc3b), U64_C(0xa2543f574d76408e), U64_C(0xbd7761e1c175d139), U64_C(0x4b1f4f737ca3f512), U64_C(0x6dc2df1f2fc137ab), U64_C(0xf1d05c3967b14856), U64_C(0xa742bf3715ed046c), U64_C(0x654030141d1697ed), U64_C(0x07b872abda676c7d), U64_C(0x3ce84eba87fa17ec), U64_C(0xc1fb0403cb79afdf), U64_C(0x3e46bc7105063f73), U64_C(0x278ae987121cd678), U64_C(0xa1adb4778ef47cd0), U64_C(0x26dd906c5362c2b9), U64_C(0x05168060589b44e2), U64_C(0xfbfc41f9d79ac08f), U64_C(0x0e6de44ba9ced8fa), U64_C(0x9feb08068bf243a3), U64_C(0x7b341749d06b129b), U64_C(0x229c69e74a87929a), U64_C(0xe09ee6c4427c011b), U64_C(0x5692e30e725c4c3a), U64_C(0xda99a33e5e9f6e4b), U64_C(0x353dd85af453a36b), U64_C(0x25241b4c90e0fee7), U64_C(0x5de987258309d022), U64_C(0xe230140fc0802984), U64_C(0x93281e86a0c0b3c6), U64_C(0xf229d719a4337408), U64_C(0x6f6c2dd4ad3d1f34), U64_C(0x8ea5b2fbae3f0aee), U64_C(0x8331dd90c473ee4a), U64_C(0x346aa1b1b52db7aa), U64_C(0xdf8f235e06042aa9), U64_C(0xcc6f6b68a1354b7b), U64_C(0x6c95a6f46ebf236a), U64_C(0x52d31a856bb91c19), U64_C(0x1a35ded6d498d555), U64_C(0xf37eaef2e54d60c9), U64_C(0x72e181a9a3c2a61c), U64_C(0x98537aad51952fde), U64_C(0x16f6c856ffaa2530), U64_C(0xd960281e9d1d5215), U64_C(0x3a0745fa1ce36f50), U64_C(0x0b7b642bf1559c18), U64_C(0x59a87eae9aec8001), U64_C(0x5e100c05408bec7c), U64_C(0x0441f98b19e55023), U64_C(0xd70dcc5534d38aef), U64_C(0x927f676de1bea707), U64_C(0x9769e70db925e3e5), U64_C(0x7a636ea29115065a), U64_C(0x468b201816ef11b6), U64_C(0xab81a9b73edff409), U64_C(0xc0ac7de88a07bb1e), U64_C(0x1f235eb68c0391b7), U64_C(0x6056b074458dd30f), U64_C(0xbe8eeac102f7ed67), U64_C(0xcd381283e04b5fba), U64_C(0x5cbefecec277c4e3), U64_C(0xd21b4c356c48ce0d), U64_C(0x1019c31664b35d8c), U64_C(0x247362a7d19eea26), U64_C(0xebe582efb3299d03), U64_C(0x02aef2cb82fc289f), U64_C(0x86275df09ce8aaa8), U64_C(0x28b07427faac1a43), U64_C(0x38a9b7319e1f47cf), U64_C(0xc82e92e3b8d01b58), U64_C(0x06ef0b409b1978bc), U64_C(0x62f842bfc771fb90), U64_C(0x9904034610eb3b1f), U64_C(0xded85ab5477a3e68), U64_C(0x90d195a663428f98), U64_C(0x5384636e2ac708d8), U64_C(0xcbd719c37b522706), U64_C(0xae9729d76644b0eb), U64_C(0x7c8c65e20a0c7ee6), U64_C(0x80c856b007f1d214), U64_C(0x8c0b40302cc32271), U64_C(0xdbcedad51fe17a8a), U64_C(0x740e8ae938dbdea0), U64_C(0xa615c6dc549310ad), U64_C(0x19cc55f6171ae90b), U64_C(0x49b1bdb8fe5fdd8d), U64_C(0xed0a89af2830e5bf), U64_C(0x6a7aadb4f5a65bd6), U64_C(0x7e22972988f05679), U64_C(0xf952b3325566e810), U64_C(0x39fecedadf61530e), U64_C(0x6101c99f04f3c7ce), U64_C(0x2e5f7f6761b562ff), U64_C(0xf08725d226cf5c97), U64_C(0x63af3b54860fef51), U64_C(0x8ff2cb10ef411e2f), U64_C(0x884ab9bb35267252), U64_C(0x4df04433e7ba8dae), U64_C(0x9afd8866d3690741), U64_C(0x66b9bb34de94abb3), U64_C(0x9baaf18d92171380), U64_C(0x543c11c5f0a064a5), U64_C(0x17a1b1bdbed431f1), U64_C(0xb5f58eeaf3a2717f), U64_C(0xc355f6c849858740), U64_C(0xec5df044694ef17e), U64_C(0xd83751f5dc6346d4), U64_C(0xfc4433520dfdacf2), U64_C(0x0000000000000000), U64_C(0x5a51f58e596ebc5f), U64_C(0x3285aaf12e34cf16), U64_C(0x8d5c39db6dbd36b0), U64_C(0x12b731dde64f7513), U64_C(0x94906c2d7aa7dfbb), U64_C(0x302b583aacc8e789), U64_C(0x9d45facd090e6b3c), U64_C(0x2165e2c78905aec4), U64_C(0x68d45f7f775a7349), U64_C(0x189b2c1d5664fdca), U64_C(0xe1c99f2f030215da), U64_C(0x6983269436246788), U64_C(0x8489af3b1e148237), U64_C(0xe94b702431d5b59c), U64_C(0x33d2d31a6f4adbd7), U64_C(0xbfd9932a4389f9a6), U64_C(0xb0e30e8aab39359d), U64_C(0xd1e2c715afcaf253), U64_C(0x150f43763c28196e), U64_C(0xc4ed846393e2eb3d), U64_C(0x03f98b20c3823c5e), U64_C(0xfd134ab94c83b833), U64_C(0x556b682eb1de7064), U64_C(0x36c4537a37d19f35), U64_C(0x7559f30279a5ca61), U64_C(0x799ae58252973a04), U64_C(0x9c12832648707ffd), U64_C(0x78cd9c6913e92ec5), U64_C(0x1d8dac7d0effb928), U64_C(0x439da0784e745554), U64_C(0x413352b3cc887dcb), U64_C(0xbacf134a1b12bd44), U64_C(0x114ebafd25cd494d), U64_C(0x2f08068c20cb763e), U64_C(0x76a07822ba27f63f), U64_C(0xeab2fb04f25789c2), U64_C(0xe3676de481fe3d45), U64_C(0x1b62a73d95e6c194), U64_C(0x641749ff5c68832c), U64_C(0xa5ec4dfc97112cf3), U64_C(0xf6682e92bdd6242b), U64_C(0x3f11c59a44782bb2), U64_C(0x317c21d1edb6f348), U64_C(0xd65ab5be75ad9e2e), U64_C(0x6b2dd45fb4d84f17), U64_C(0xfaab381296e4d44e), U64_C(0xd0b5befeeeb4e692), U64_C(0x0882ef0b32d7a046), U64_C(0x512a91a5a83b2047), U64_C(0x963e9ee6f85bf724), U64_C(0x4e09cf132438b1f0), U64_C(0x77f701c9fb59e2fe), U64_C(0x7ddb1c094b726a27), U64_C(0x5f4775ee01f5f8bd), U64_C(0x9186ec4d223c9b59), U64_C(0xfeeac1998f01846d), U64_C(0xac39db1ce4b89874), U64_C(0xb75b7c21715e59e0), U64_C(0xafc0503c273aa42a), U64_C(0x6e3b543fec430bf5), U64_C(0x704f7362213e8e83), U64_C(0x58ff0745db9294c0), U64_C(0x67eec2df9feabf72), U64_C(0xa0facd9ccf8a6811), U64_C(0xb936986ad890811a), U64_C(0x95c715c63bd9cb7a), U64_C(0xca8060283a2c33c7), U64_C(0x507de84ee9453486), U64_C(0x85ded6d05f6a96f6), U64_C(0x1cdad5964f81ade9), U64_C(0xd5a33e9eb62fa270), U64_C(0x40642b588df6690a), U64_C(0x7f75eec2c98e42b8), U64_C(0x2cf18dace3494a60), U64_C(0x23cb100c0bf9865b), U64_C(0xeef3028febb2d9e1), U64_C(0x4425d2d394133929), U64_C(0xaad6d05c7fa1e0c8), U64_C(0xad6ea2f7a5c68cb5), U64_C(0xc2028f2308fb9381), U64_C(0x819f2f5b468fc6d5), U64_C(0xc5bafd88d29cfffc), U64_C(0x47dc59f357910577), U64_C(0x2b49ff07392e261d), U64_C(0x57c59ae5332258fb), U64_C(0x73b6f842e2bcb2dd), U64_C(0xcf96e04862b77725), U64_C(0x4ca73dd8a6c4996f), U64_C(0x015779eb417e14c1), U64_C(0x37932a9176af8bf4) }, /* 4 */ { U64_C(0x190a2c9b249df23e), U64_C(0x2f62f8b62263e1e9), U64_C(0x7a7f754740993655), U64_C(0x330b7ba4d5564d9f), U64_C(0x4c17a16a46672582), U64_C(0xb22f08eb7d05f5b8), U64_C(0x535f47f40bc148cc), U64_C(0x3aec5d27d4883037), U64_C(0x10ed0a1825438f96), U64_C(0x516101f72c233d17), U64_C(0x13cc6f949fd04eae), U64_C(0x739853c441474bfd), U64_C(0x653793d90d3f5b1b), U64_C(0x5240647b96b0fc2f), U64_C(0x0c84890ad27623e0), U64_C(0xd7189b32703aaea3), U64_C(0x2685de3523bd9c41), U64_C(0x99317c5b11bffefa), U64_C(0x0d9baa854f079703), U64_C(0x70b93648fbd48ac5), U64_C(0xa80441fce30bc6be), U64_C(0x7287704bdc36ff1e), U64_C(0xb65384ed33dc1f13), U64_C(0xd36417343ee34408), U64_C(0x39cd38ab6e1bf10f), U64_C(0x5ab861770a1f3564), U64_C(0x0ebacf09f594563b), U64_C(0xd04572b884708530), U64_C(0x3cae9722bdb3af47), U64_C(0x4a556b6f2f5cbaf2), U64_C(0xe1704f1f76c4bd74), U64_C(0x5ec4ed7144c6dfcf), U64_C(0x16afc01d4c7810e6), U64_C(0x283f113cd629ca7a), U64_C(0xaf59a8761741ed2d), U64_C(0xeed5a3991e215fac), U64_C(0x3bf37ea849f984d4), U64_C(0xe413e096a56ce33c), U64_C(0x2c439d3a98f020d1), U64_C(0x637559dc6404c46b), U64_C(0x9e6c95d1e5f5d569), U64_C(0x24bb9836045fe99a), U64_C(0x44efa466dac8ecc9), U64_C(0xc6eab2a5c80895d6), U64_C(0x803b50c035220cc4), U64_C(0x0321658cba93c138), U64_C(0x8f9ebc465dc7ee1c), U64_C(0xd15a5137190131d3), U64_C(0x0fa5ec8668e5e2d8), U64_C(0x91c979578d1037b1), U64_C(0x0642ca05693b9f70), U64_C(0xefca80168350eb4f), U64_C(0x38d21b24f36a45ec), U64_C(0xbeab81e1af73d658), U64_C(0x8cbfd9cae7542f24), U64_C(0xfd19cc0d81f11102), U64_C(0x0ac6430fbb4dbc90), U64_C(0x1d76a09d6a441895), U64_C(0x2a01573ff1cbbfa1), U64_C(0xb572e161894fde2b), U64_C(0x8124734fa853b827), U64_C(0x614b1fdf43e6b1b0), U64_C(0x68ac395c4238cc18), U64_C(0x21d837bfd7f7b7d2), U64_C(0x20c714304a860331), U64_C(0x5cfaab726324aa14), U64_C(0x74c5ba4eb50d606e), U64_C(0xf3a3030474654739), U64_C(0x23e671bcf015c209), U64_C(0x45f087e947b9582a), U64_C(0xd8bd77b418df4c7b), U64_C(0xe06f6c90ebb50997), U64_C(0x0bd96080263c0873), U64_C(0x7e03f9410e40dcfe), U64_C(0xb8e94be4c6484928), U64_C(0xfb5b0608e8ca8e72), U64_C(0x1a2b49179e0e3306), U64_C(0x4e29e76961855059), U64_C(0x4f36c4e6fcf4e4ba), U64_C(0x49740ee395cf7bca), U64_C(0xc2963ea386d17f7d), U64_C(0x90d65ad810618352), U64_C(0x12d34c1b02a1fa4d), U64_C(0xfa44258775bb3a91), U64_C(0x18150f14b9ec46dd), U64_C(0x1491861e6b9a653d), U64_C(0x9a1019d7ab2c3fc2), U64_C(0x3668d42d06fe13d7), U64_C(0xdcc1fbb25606a6d0), U64_C(0x969490dd795a1c22), U64_C(0x3549b1a1bc6dd2ef), U64_C(0xc94f5e23a0ed770e), U64_C(0xb9f6686b5b39fdcb), U64_C(0xc4d4f4a6efeae00d), U64_C(0xe732851a1fff2204), U64_C(0x94aad6de5eb869f9), U64_C(0x3f8ff2ae07206e7f), U64_C(0xfe38a9813b62d03a), U64_C(0xa7a1ad7a8bee2466), U64_C(0x7b6056c8dde882b6), U64_C(0x302a1e286fc58ca7), U64_C(0x8da0fa457a259bc7), U64_C(0xb3302b64e074415b), U64_C(0x5402ae7eff8b635f), U64_C(0x08f8050c9cafc94b), U64_C(0xae468bf98a3059ce), U64_C(0x88c355cca98dc58f), U64_C(0xb10e6d67c7963480), U64_C(0xbad70de7e1aa3cf3), U64_C(0xbfb4a26e320262bb), U64_C(0xcb711820870f02d5), U64_C(0xce12b7a954a75c9d), U64_C(0x563ce87dd8691684), U64_C(0x9f73b65e7884618a), U64_C(0x2b1e74b06cba0b42), U64_C(0x47cec1ea605b2df1), U64_C(0x1c698312f735ac76), U64_C(0x5fdbcefed9b76b2c), U64_C(0x831a354c8fb1cdfc), U64_C(0x820516c312c0791f), U64_C(0xb74ca762aeadabf0), U64_C(0xfc06ef821c80a5e1), U64_C(0x5723cbf24518a267), U64_C(0x9d4df05d5f661451), U64_C(0x588627742dfd40bf), U64_C(0xda8331b73f3d39a0), U64_C(0x17b0e392d109a405), U64_C(0xf965400bcf28fba9), U64_C(0x7c3dbf4229a2a925), U64_C(0x023e460327e275db), U64_C(0x6cd0b55a0ce126b3), U64_C(0xe62da695828e96e7), U64_C(0x42ad6e63b3f373b9), U64_C(0xe50cc319381d57df), U64_C(0xc5cbd729729b54ee), U64_C(0x46d1e265fd2a9912), U64_C(0x6428b056904eeff8), U64_C(0x8be23040131e04b7), U64_C(0x6709d5da2add2ec0), U64_C(0x075de98af44a2b93), U64_C(0x8447dcc67bfbe66f), U64_C(0x6616f655b7ac9a23), U64_C(0xd607b8bded4b1a40), U64_C(0x0563af89d3a85e48), U64_C(0x3db1b4ad20c21ba4), U64_C(0x11f22997b8323b75), U64_C(0x292032b34b587e99), U64_C(0x7f1cdace9331681d), U64_C(0x8e819fc9c0b65aff), U64_C(0xa1e3677fe2d5bb16), U64_C(0xcd33d225ee349da5), U64_C(0xd9a2543b85aef898), U64_C(0x795e10cbfa0af76d), U64_C(0x25a4bbb9992e5d79), U64_C(0x78413344677b438e), U64_C(0xf0826688cef68601), U64_C(0xd27b34bba392f0eb), U64_C(0x551d8df162fad7bc), U64_C(0x1e57c511d0d7d9ad), U64_C(0xdeffbdb171e4d30b), U64_C(0xf4feea8e802f6caa), U64_C(0xa480c8f6317de55e), U64_C(0xa0fc44f07fa40ff5), U64_C(0x95b5f551c3c9dd1a), U64_C(0x22f952336d6476ea), U64_C(0x0000000000000000), U64_C(0xa6be8ef5169f9085), U64_C(0xcc2cf1aa73452946), U64_C(0x2e7ddb39bf12550a), U64_C(0xd526dd3157d8db78), U64_C(0x486b2d6c08becf29), U64_C(0x9b0f3a58365d8b21), U64_C(0xac78cdfaadd22c15), U64_C(0xbc95c7e28891a383), U64_C(0x6a927f5f65dab9c3), U64_C(0xc3891d2c1ba0cb9e), U64_C(0xeaa92f9f50f8b507), U64_C(0xcf0d9426c9d6e87e), U64_C(0xca6e3baf1a7eb636), U64_C(0xab25247059980786), U64_C(0x69b31ad3df4978fb), U64_C(0xe2512a93cc577c4c), U64_C(0xff278a0ea61364d9), U64_C(0x71a615c766a53e26), U64_C(0x89dc764334fc716c), U64_C(0xf87a638452594f4a), U64_C(0xf2bc208be914f3da), U64_C(0x8766b94ac1682757), U64_C(0xbbc82e687cdb8810), U64_C(0x626a7a53f9757088), U64_C(0xa2c202f358467a2e), U64_C(0x4d0882e5db169161), U64_C(0x09e7268301de7da8), U64_C(0xe897699c771ac0dc), U64_C(0xc8507dac3d9cc3ed), U64_C(0xc0a878a0a1330aa6), U64_C(0x978bb352e42ba8c1), U64_C(0xe9884a13ea6b743f), U64_C(0x279afdbabecc28a2), U64_C(0x047c8c064ed9eaab), U64_C(0x507e2278b15289f4), U64_C(0x599904fbb08cf45c), U64_C(0xbd8ae46d15e01760), U64_C(0x31353da7f2b43844), U64_C(0x8558ff49e68a528c), U64_C(0x76fbfc4d92ef15b5), U64_C(0x3456922e211c660c), U64_C(0x86799ac55c1993b4), U64_C(0x3e90d1219a51da9c), U64_C(0x2d5cbeb505819432), U64_C(0x982e5fd48cce4a19), U64_C(0xdb9c1238a24c8d43), U64_C(0xd439febecaa96f9b), U64_C(0x418c0bef0960b281), U64_C(0x158ea591f6ebd1de), U64_C(0x1f48e69e4da66d4e), U64_C(0x8afd13cf8e6fb054), U64_C(0xf5e1c9011d5ed849), U64_C(0xe34e091c5126c8af), U64_C(0xad67ee7530a398f6), U64_C(0x43b24dec2e82c75a), U64_C(0x75da99c1287cd48d), U64_C(0x92e81cdb3783f689), U64_C(0xa3dd217cc537cecd), U64_C(0x60543c50de970553), U64_C(0x93f73f54aaf2426a), U64_C(0xa91b62737e7a725d), U64_C(0xf19d4507538732e2), U64_C(0x77e4dfc20f9ea156), U64_C(0x7d229ccdb4d31dc6), U64_C(0x1b346a98037f87e5), U64_C(0xedf4c615a4b29e94), U64_C(0x4093286094110662), U64_C(0xb0114ee85ae78063), U64_C(0x6ff1d0d6b672e78b), U64_C(0x6dcf96d591909250), U64_C(0xdfe09e3eec9567e8), U64_C(0x3214582b4827f97c), U64_C(0xb46dc2ee143e6ac8), U64_C(0xf6c0ac8da7cd1971), U64_C(0xebb60c10cd8901e4), U64_C(0xf7df8f023abcad92), U64_C(0x9c52d3d2c217a0b2), U64_C(0x6b8d5cd0f8ab0d20), U64_C(0x3777f7a29b8fa734), U64_C(0x011f238f9d71b4e3), U64_C(0xc1b75b2f3c42be45), U64_C(0x5de588fdfe551ef7), U64_C(0x6eeef3592b035368), U64_C(0xaa3a07ffc4e9b365), U64_C(0xecebe59a39c32a77), U64_C(0x5ba742f8976e8187), U64_C(0x4b4a48e0b22d0e11), U64_C(0xddded83dcb771233), U64_C(0xa59feb79ac0c51bd), U64_C(0xc7f5912a55792135) }, /* 5 */ { U64_C(0x6d6ae04668a9b08a), U64_C(0x3ab3f04b0be8c743), U64_C(0xe51e166b54b3c908), U64_C(0xbe90a9eb35c2f139), U64_C(0xb2c7066637f2bec1), U64_C(0xaa6945613392202c), U64_C(0x9a28c36f3b5201eb), U64_C(0xddce5a93ab536994), U64_C(0x0e34133ef6382827), U64_C(0x52a02ba1ec55048b), U64_C(0xa2f88f97c4b2a177), U64_C(0x8640e513ca2251a5), U64_C(0xcdf1d36258137622), U64_C(0xfe6cb708dedf8ddb), U64_C(0x8a174a9ec8121e5d), U64_C(0x679896036b81560e), U64_C(0x59ed033395795fee), U64_C(0x1dd778ab8b74edaf), U64_C(0xee533ef92d9f926d), U64_C(0x2a8c79baf8a8d8f5), U64_C(0x6bcf398e69b119f6), U64_C(0xe20491742fafdd95), U64_C(0x276488e0809c2aec), U64_C(0xea955b82d88f5cce), U64_C(0x7102c63a99d9e0c4), U64_C(0xf9763017a5c39946), U64_C(0x429fa2501f151b3d), U64_C(0x4659c72bea05d59e), U64_C(0x984b7fdccf5a6634), U64_C(0xf742232953fbb161), U64_C(0x3041860e08c021c7), U64_C(0x747bfd9616cd9386), U64_C(0x4bb1367192312787), U64_C(0x1b72a1638a6c44d3), U64_C(0x4a0e68a6e8359a66), U64_C(0x169a5039f258b6ca), U64_C(0xb98a2ef44edee5a4), U64_C(0xd9083fe85e43a737), U64_C(0x967f6ce239624e13), U64_C(0x8874f62d3c1a7982), U64_C(0x3c1629830af06e3f), U64_C(0x9165ebfd427e5a8e), U64_C(0xb5dd81794ceeaa5c), U64_C(0x0de8f15a7834f219), U64_C(0x70bd98ede3dd5d25), U64_C(0xaccc9ca9328a8950), U64_C(0x56664eda1945ca28), U64_C(0x221db34c0f8859ae), U64_C(0x26dbd637fa98970d), U64_C(0x1acdffb4f068f932), U64_C(0x4585254f64090fa0), U64_C(0x72de245e17d53afa), U64_C(0x1546b25d7c546cf4), U64_C(0x207e0ffffb803e71), U64_C(0xfaaad2732bcf4378), U64_C(0xb462dfae36ea17bd), U64_C(0xcf926fd1ac1b11fd), U64_C(0xe0672dc7dba7ba4a), U64_C(0xd3fa49ad5d6b41b3), U64_C(0x8ba81449b216a3bc), U64_C(0x14f9ec8a0650d115), U64_C(0x40fc1ee3eb1d7ce2), U64_C(0x23a2ed9b758ce44f), U64_C(0x782c521b14fddc7e), U64_C(0x1c68267cf170504e), U64_C(0xbcf31558c1ca96e6), U64_C(0xa781b43b4ba6d235), U64_C(0xf6fd7dfe29ff0c80), U64_C(0xb0a4bad5c3fad91e), U64_C(0xd199f51ea963266c), U64_C(0x414340349119c103), U64_C(0x5405f269ed4dadf7), U64_C(0xabd61bb649969dcd), U64_C(0x6813dbeae7bdc3c8), U64_C(0x65fb2ab09f8931d1), U64_C(0xf1e7fae152e3181d), U64_C(0xc1a67cef5a2339da), U64_C(0x7a4feea8e0f5bba1), U64_C(0x1e0b9acf05783791), U64_C(0x5b8ebf8061713831), U64_C(0x80e53cdbcb3af8d9), U64_C(0x7e898bd315e57502), U64_C(0xc6bcfbf0213f2d47), U64_C(0x95a38e86b76e942d), U64_C(0x092e94218d243cba), U64_C(0x8339debf453622e7), U64_C(0xb11be402b9fe64ff), U64_C(0x57d9100d634177c9), U64_C(0xcc4e8db52217cbc3), U64_C(0x3b0cae9c71ec7aa2), U64_C(0xfb158ca451cbfe99), U64_C(0x2b33276d82ac6514), U64_C(0x01bf5ed77a04bde1), U64_C(0xc5601994af33f779), U64_C(0x75c4a3416cc92e67), U64_C(0xf3844652a6eb7fc2), U64_C(0x3487e375fdd0ef64), U64_C(0x18ae430704609eed), U64_C(0x4d14efb993298efb), U64_C(0x815a620cb13e4538), U64_C(0x125c354207487869), U64_C(0x9eeea614ce42cf48), U64_C(0xce2d3106d61fac1c), U64_C(0xbbe99247bad6827b), U64_C(0x071a871f7b1c149d), U64_C(0x2e4a1cc10db81656), U64_C(0x77a71ff298c149b8), U64_C(0x06a5d9c80118a97c), U64_C(0xad73c27e488e34b1), U64_C(0x443a7b981e0db241), U64_C(0xe3bbcfa355ab6074), U64_C(0x0af276450328e684), U64_C(0x73617a896dd1871b), U64_C(0x58525de4ef7de20f), U64_C(0xb7be3dcab8e6cd83), U64_C(0x19111dd07e64230c), U64_C(0x842359a03e2a367a), U64_C(0x103f89f1f3401fb6), U64_C(0xdc710444d157d475), U64_C(0xb835702334da5845), U64_C(0x4320fc876511a6dc), U64_C(0xd026abc9d3679b8d), U64_C(0x17250eee885c0b2b), U64_C(0x90dab52a387ae76f), U64_C(0x31fed8d972c49c26), U64_C(0x89cba8fa461ec463), U64_C(0x2ff5421677bcabb7), U64_C(0x396f122f85e41d7d), U64_C(0xa09b332430bac6a8), U64_C(0xc888e8ced7070560), U64_C(0xaeaf201ac682ee8f), U64_C(0x1180d7268944a257), U64_C(0xf058a43628e7a5fc), U64_C(0xbd4c4b8fbbce2b07), U64_C(0xa1246df34abe7b49), U64_C(0x7d5569b79be9af3c), U64_C(0xa9b5a705bd9efa12), U64_C(0xdb6b835baa4bc0e8), U64_C(0x05793bac8f147342), U64_C(0x21c1512881848390), U64_C(0xfdb0556c50d357e5), U64_C(0x613d4fcb6a99ff72), U64_C(0x03dce2648e0cda3e), U64_C(0xe949b9e6568386f0), U64_C(0xfc0f0bbb2ad7ea04), U64_C(0x6a70675913b5a417), U64_C(0x7f36d5046fe1c8e3), U64_C(0x0c57af8d02304ff8), U64_C(0x32223abdfcc84618), U64_C(0x0891caf6f720815b), U64_C(0xa63eeaec31a26fd4), U64_C(0x2507345374944d33), U64_C(0x49d28ac266394058), U64_C(0xf5219f9aa7f3d6be), U64_C(0x2d96fea583b4cc68), U64_C(0x5a31e1571b7585d0), U64_C(0x8ed12fe53d02d0fe), U64_C(0xdfade6205f5b0e4b), U64_C(0x4cabb16ee92d331a), U64_C(0x04c6657bf510cea3), U64_C(0xd73c2cd6a87b8f10), U64_C(0xe1d87310a1a307ab), U64_C(0x6cd5be9112ad0d6b), U64_C(0x97c032354366f3f2), U64_C(0xd4e0ceb22677552e), U64_C(0x0000000000000000), U64_C(0x29509bde76a402cb), U64_C(0xc27a9e8bd42fe3e4), U64_C(0x5ef7842cee654b73), U64_C(0xaf107ecdbc86536e), U64_C(0x3fcacbe784fcb401), U64_C(0xd55f90655c73e8cf), U64_C(0xe6c2f40fdabf1336), U64_C(0xe8f6e7312c873b11), U64_C(0xeb2a0555a28be12f), U64_C(0xe4a148bc2eb774e9), U64_C(0x9b979db84156bc0a), U64_C(0x6eb60222e6a56ab4), U64_C(0x87ffbbc4b026ec44), U64_C(0xc703a5275b3b90a6), U64_C(0x47e699fc9001687f), U64_C(0x9c8d1aa73a4aa897), U64_C(0x7cea3760e1ed12dd), U64_C(0x4ec80ddd1d2554c5), U64_C(0x13e36b957d4cc588), U64_C(0x5d2b66486069914d), U64_C(0x92b90999cc7280b0), U64_C(0x517cc9c56259deb5), U64_C(0xc937b619ad03b881), U64_C(0xec30824ad997f5b2), U64_C(0xa45d565fc5aa080b), U64_C(0xd6837201d27f32f1), U64_C(0x635ef3789e9198ad), U64_C(0x531f75769651b96a), U64_C(0x4f77530a6721e924), U64_C(0x486dd4151c3dfdb9), U64_C(0x5f48dafb9461f692), U64_C(0x375b011173dc355a), U64_C(0x3da9775470f4d3de), U64_C(0x8d0dcd81b30e0ac0), U64_C(0x36e45fc609d888bb), U64_C(0x55baacbe97491016), U64_C(0x8cb29356c90ab721), U64_C(0x76184125e2c5f459), U64_C(0x99f4210bb55edbd5), U64_C(0x6f095cf59ca1d755), U64_C(0x9f51f8c3b44672a9), U64_C(0x3538bda287d45285), U64_C(0x50c39712185d6354), U64_C(0xf23b1885dcefc223), U64_C(0x79930ccc6ef9619f), U64_C(0xed8fdc9da3934853), U64_C(0xcb540aaa590bdf5e), U64_C(0x5c94389f1a6d2cac), U64_C(0xe77daad8a0bbaed7), U64_C(0x28efc5090ca0bf2a), U64_C(0xbf2ff73c4fc64cd8), U64_C(0xb37858b14df60320), U64_C(0xf8c96ec0dfc724a7), U64_C(0x828680683f329f06), U64_C(0x941cd051cd6a29cc), U64_C(0xc3c5c05cae2b5e05), U64_C(0xb601631dc2e27062), U64_C(0xc01922382027843b), U64_C(0x24b86a840e90f0d2), U64_C(0xd245177a276ffc52), U64_C(0x0f8b4de98c3c95c6), U64_C(0x3e759530fef809e0), U64_C(0x0b4d2892792c5b65), U64_C(0xc4df4743d5374a98), U64_C(0xa5e20888bfaeb5ea), U64_C(0xba56cc90c0d23f9a), U64_C(0x38d04cf8ffe0a09c), U64_C(0x62e1adafe495254c), U64_C(0x0263bcb3f40867df), U64_C(0xcaeb547d230f62bf), U64_C(0x6082111c109d4293), U64_C(0xdad4dd8cd04f7d09), U64_C(0xefec602e579b2f8c), U64_C(0x1fb4c4187f7c8a70), U64_C(0xffd3e9dfa4db303a), U64_C(0x7bf0b07f9af10640), U64_C(0xf49ec14dddf76b5f), U64_C(0x8f6e713247066d1f), U64_C(0x339d646a86ccfbf9), U64_C(0x64447467e58d8c30), U64_C(0x2c29a072f9b07189), U64_C(0xd8b7613f24471ad6), U64_C(0x6627c8d41185ebef), U64_C(0xa347d140beb61c96), U64_C(0xde12b8f7255fb3aa), U64_C(0x9d324470404e1576), U64_C(0x9306574eb6763d51), U64_C(0xa80af9d2c79a47f3), U64_C(0x859c0777442e8b9b), U64_C(0x69ac853d9db97e29) }, /* 6 */ { U64_C(0xc3407dfc2de6377e), U64_C(0x5b9e93eea4256f77), U64_C(0xadb58fdd50c845e0), U64_C(0x5219ff11a75bed86), U64_C(0x356b61cfd90b1de9), U64_C(0xfb8f406e25abe037), U64_C(0x7a5a0231c0f60796), U64_C(0x9d3cd216e1f5020b), U64_C(0x0c6550fb6b48d8f3), U64_C(0xf57508c427ff1c62), U64_C(0x4ad35ffa71cb407d), U64_C(0x6290a2da1666aa6d), U64_C(0xe284ec2349355f9f), U64_C(0xb3c307c53d7c84ec), U64_C(0x05e23c0468365a02), U64_C(0x190bac4d6c9ebfa8), U64_C(0x94bbbee9e28b80fa), U64_C(0xa34fc777529cb9b5), U64_C(0xcc7b39f095bcd978), U64_C(0x2426addb0ce532e3), U64_C(0x7e79329312ce4fc7), U64_C(0xab09a72eebec2917), U64_C(0xf8d15499f6b9d6c2), U64_C(0x1a55b8babf8c895d), U64_C(0xdb8add17fb769a85), U64_C(0xb57f2f368658e81b), U64_C(0x8acd36f18f3f41f6), U64_C(0x5ce3b7bba50f11d3), U64_C(0x114dcc14d5ee2f0a), U64_C(0xb91a7fcded1030e8), U64_C(0x81d5425fe55de7a1), U64_C(0xb6213bc1554adeee), U64_C(0x80144ef95f53f5f2), U64_C(0x1e7688186db4c10c), U64_C(0x3b912965db5fe1bc), U64_C(0xc281715a97e8252d), U64_C(0x54a5d7e21c7f8171), U64_C(0x4b12535ccbc5522e), U64_C(0x1d289cefbea6f7f9), U64_C(0x6ef5f2217d2e729e), U64_C(0xe6a7dc819b0d17ce), U64_C(0x1b94b41c05829b0e), U64_C(0x33d7493c622f711e), U64_C(0xdcf7f942fa5ce421), U64_C(0x600fba8b7f7a8ecb), U64_C(0x46b60f011a83988e), U64_C(0x235b898e0dcf4c47), U64_C(0x957ab24f588592a9), U64_C(0x4354330572b5c28c), U64_C(0xa5f3ef84e9b8d542), U64_C(0x8c711e02341b2d01), U64_C(0x0b1874ae6a62a657), U64_C(0x1213d8e306fc19ff), U64_C(0xfe6d7c6a4d9dba35), U64_C(0x65ed868f174cd4c9), U64_C(0x88522ea0e6236550), U64_C(0x899322065c2d7703), U64_C(0xc01e690bfef4018b), U64_C(0x915982ed8abddaf8), U64_C(0xbe675b98ec3a4e4c), U64_C(0xa996bf7f82f00db1), U64_C(0xe1daf8d49a27696a), U64_C(0x2effd5d3dc8986e7), U64_C(0xd153a51f2b1a2e81), U64_C(0x18caa0ebd690adfb), U64_C(0x390e3134b243c51a), U64_C(0x2778b92cdff70416), U64_C(0x029f1851691c24a6), U64_C(0x5e7cafeacc133575), U64_C(0xfa4e4cc89fa5f264), U64_C(0x5a5f9f481e2b7d24), U64_C(0x484c47ab18d764db), U64_C(0x400a27f2a1a7f479), U64_C(0xaeeb9b2a83da7315), U64_C(0x721c626879869734), U64_C(0x042330a2d2384851), U64_C(0x85f672fd3765aff0), U64_C(0xba446b3a3e02061d), U64_C(0x73dd6ecec3888567), U64_C(0xffac70ccf793a866), U64_C(0xdfa9edb5294ed2d4), U64_C(0x6c6aea7014325638), U64_C(0x834a5a0e8c41c307), U64_C(0xcdba35562fb2cb2b), U64_C(0x0ad97808d06cb404), U64_C(0x0f3b440cb85aee06), U64_C(0xe5f9c876481f213b), U64_C(0x98deee1289c35809), U64_C(0x59018bbfcd394bd1), U64_C(0xe01bf47220297b39), U64_C(0xde68e1139340c087), U64_C(0x9fa3ca4788e926ad), U64_C(0xbb85679c840c144e), U64_C(0x53d8f3b71d55ffd5), U64_C(0x0da45c5dd146caa0), U64_C(0x6f34fe87c72060cd), U64_C(0x57fbc315cf6db784), U64_C(0xcee421a1fca0fdde), U64_C(0x3d2d0196607b8d4b), U64_C(0x642c8a29ad42c69a), U64_C(0x14aff010bdd87508), U64_C(0xac74837beac657b3), U64_C(0x3216459ad821634d), U64_C(0x3fb219c70967a9ed), U64_C(0x06bc28f3bb246cf7), U64_C(0xf2082c9126d562c6), U64_C(0x66b39278c45ee23c), U64_C(0xbd394f6f3f2878b9), U64_C(0xfd33689d9e8f8cc0), U64_C(0x37f4799eb017394f), U64_C(0x108cc0b26fe03d59), U64_C(0xda4bd1b1417888d6), U64_C(0xb09d1332ee6eb219), U64_C(0x2f3ed975668794b4), U64_C(0x58c0871977375982), U64_C(0x7561463d78ace990), U64_C(0x09876cff037e82f1), U64_C(0x7fb83e35a8c05d94), U64_C(0x26b9b58a65f91645), U64_C(0xef20b07e9873953f), U64_C(0x3148516d0b3355b8), U64_C(0x41cb2b541ba9e62a), U64_C(0x790416c613e43163), U64_C(0xa011d380818e8f40), U64_C(0x3a5025c36151f3ef), U64_C(0xd57095bdf92266d0), U64_C(0x498d4b0da2d97688), U64_C(0x8b0c3a57353153a5), U64_C(0x21c491df64d368e1), U64_C(0x8f2f0af5e7091bf4), U64_C(0x2da1c1240f9bb012), U64_C(0xc43d59a92ccc49da), U64_C(0xbfa6573e56345c1f), U64_C(0x828b56a8364fd154), U64_C(0x9a41f643e0df7caf), U64_C(0xbcf843c985266aea), U64_C(0x2b1de9d7b4bfdce5), U64_C(0x20059d79dedd7ab2), U64_C(0x6dabe6d6ae3c446b), U64_C(0x45e81bf6c991ae7b), U64_C(0x6351ae7cac68b83e), U64_C(0xa432e32253b6c711), U64_C(0xd092a9b991143cd2), U64_C(0xcac711032e98b58f), U64_C(0xd8d4c9e02864ac70), U64_C(0xc5fc550f96c25b89), U64_C(0xd7ef8dec903e4276), U64_C(0x67729ede7e50f06f), U64_C(0xeac28c7af045cf3d), U64_C(0xb15c1f945460a04a), U64_C(0x9cfddeb05bfb1058), U64_C(0x93c69abce3a1fe5e), U64_C(0xeb0380dc4a4bdd6e), U64_C(0xd20db1e8f8081874), U64_C(0x229a8528b7c15e14), U64_C(0x44291750739fbc28), U64_C(0xd3ccbd4e42060a27), U64_C(0xf62b1c33f4ed2a97), U64_C(0x86a8660ae4779905), U64_C(0xd62e814a2a305025), U64_C(0x477703a7a08d8add), U64_C(0x7b9b0e977af815c5), U64_C(0x78c51a60a9ea2330), U64_C(0xa6adfb733aaae3b7), U64_C(0x97e5aa1e3199b60f), U64_C(0x0000000000000000), U64_C(0xf4b404629df10e31), U64_C(0x5564db44a6719322), U64_C(0x9207961a59afec0d), U64_C(0x9624a6b88b97a45c), U64_C(0x363575380a192b1c), U64_C(0x2c60cd82b595a241), U64_C(0x7d272664c1dc7932), U64_C(0x7142769faa94a1c1), U64_C(0xa1d0df263b809d13), U64_C(0x1630e841d4c451ae), U64_C(0xc1df65ad44fa13d8), U64_C(0x13d2d445bcf20bac), U64_C(0xd915c546926abe23), U64_C(0x38cf3d92084dd749), U64_C(0xe766d0272103059d), U64_C(0xc7634d5effde7f2f), U64_C(0x077d2455012a7ea4), U64_C(0xedbfa82ff16fb199), U64_C(0xaf2a978c39d46146), U64_C(0x42953fa3c8bbd0df), U64_C(0xcb061da59496a7dc), U64_C(0x25e7a17db6eb20b0), U64_C(0x34aa6d6963050fba), U64_C(0xa76cf7d580a4f1e4), U64_C(0xf7ea10954ee338c4), U64_C(0xfcf2643b24819e93), U64_C(0xcf252d0746aeef8d), U64_C(0x4ef06f58a3f3082c), U64_C(0x563acfb37563a5d7), U64_C(0x5086e740ce47c920), U64_C(0x2982f186dda3f843), U64_C(0x87696aac5e798b56), U64_C(0x5d22bb1d1f010380), U64_C(0x035e14f7d31236f5), U64_C(0x3cec0d30da759f18), U64_C(0xf3c920379cdb7095), U64_C(0xb8db736b571e22bb), U64_C(0xdd36f5e44052f672), U64_C(0xaac8ab8851e23b44), U64_C(0xa857b3d938fe1fe2), U64_C(0x17f1e4e76eca43fd), U64_C(0xec7ea4894b61a3ca), U64_C(0x9e62c6e132e734fe), U64_C(0xd4b1991b432c7483), U64_C(0x6ad6c283af163acf), U64_C(0x1ce9904904a8e5aa), U64_C(0x5fbda34c761d2726), U64_C(0xf910583f4cb7c491), U64_C(0xc6a241f845d06d7c), U64_C(0x4f3163fe19fd1a7f), U64_C(0xe99c988d2357f9c8), U64_C(0x8eee06535d0709a7), U64_C(0x0efa48aa0254fc55), U64_C(0xb4be23903c56fa48), U64_C(0x763f52caabbedf65), U64_C(0xeee1bcd8227d876c), U64_C(0xe345e085f33b4dcc), U64_C(0x3e731561b369bbbe), U64_C(0x2843fd2067adea10), U64_C(0x2adce5710eb1ceb6), U64_C(0xb7e03767ef44ccbd), U64_C(0x8db012a48e153f52), U64_C(0x61ceb62dc5749c98), U64_C(0xe85d942b9959eb9b), U64_C(0x4c6f7709caef2c8a), U64_C(0x84377e5b8d6bbda3), U64_C(0x30895dcbb13d47eb), U64_C(0x74a04a9bc2a2fbc3), U64_C(0x6b17ce251518289c), U64_C(0xe438c4d0f2113368), U64_C(0x1fb784bed7bad35f), U64_C(0x9b80fae55ad16efc), U64_C(0x77fe5e6c11b0cd36), U64_C(0xc858095247849129), U64_C(0x08466059b97090a2), U64_C(0x01c10ca6ba0e1253), U64_C(0x6988d6747c040c3a), U64_C(0x6849dad2c60a1e69), U64_C(0x5147ebe67449db73), U64_C(0xc99905f4fd8a837a), U64_C(0x991fe2b433cd4a5a), U64_C(0xf09734c04fc94660), U64_C(0xa28ecbd1e892abe6), U64_C(0xf1563866f5c75433), U64_C(0x4dae7baf70e13ed9), U64_C(0x7ce62ac27bd26b61), U64_C(0x70837a39109ab392), U64_C(0x90988e4b30b3c8ab), U64_C(0xb2020b63877296bf), U64_C(0x156efcb607d6675b) }, /* 7 */ { U64_C(0xe63f55ce97c331d0), U64_C(0x25b506b0015bba16), U64_C(0xc8706e29e6ad9ba8), U64_C(0x5b43d3775d521f6a), U64_C(0x0bfa3d577035106e), U64_C(0xab95fc172afb0e66), U64_C(0xf64b63979e7a3276), U64_C(0xf58b4562649dad4b), U64_C(0x48f7c3dbae0c83f1), U64_C(0xff31916642f5c8c5), U64_C(0xcbb048dc1c4a0495), U64_C(0x66b8f83cdf622989), U64_C(0x35c130e908e2b9b0), U64_C(0x7c761a61f0b34fa1), U64_C(0x3601161cf205268d), U64_C(0x9e54ccfe2219b7d6), U64_C(0x8b7d90a538940837), U64_C(0x9cd403588ea35d0b), U64_C(0xbc3c6fea9ccc5b5a), U64_C(0xe5ff733b6d24aeed), U64_C(0xceed22de0f7eb8d2), U64_C(0xec8581cab1ab545e), U64_C(0xb96105e88ff8e71d), U64_C(0x8ca03501871a5ead), U64_C(0x76ccce65d6db2a2f), U64_C(0x5883f582a7b58057), U64_C(0x3f7be4ed2e8adc3e), U64_C(0x0fe7be06355cd9c9), U64_C(0xee054e6c1d11be83), U64_C(0x1074365909b903a6), U64_C(0x5dde9f80b4813c10), U64_C(0x4a770c7d02b6692c), U64_C(0x5379c8d5d7809039), U64_C(0xb4067448161ed409), U64_C(0x5f5e5026183bd6cd), U64_C(0xe898029bf4c29df9), U64_C(0x7fb63c940a54d09c), U64_C(0xc5171f897f4ba8bc), U64_C(0xa6f28db7b31d3d72), U64_C(0x2e4f3be7716eaa78), U64_C(0x0d6771a099e63314), U64_C(0x82076254e41bf284), U64_C(0x2f0fd2b42733df98), U64_C(0x5c9e76d3e2dc49f0), U64_C(0x7aeb569619606cdb), U64_C(0x83478b07b2468764), U64_C(0xcfadcb8d5923cd32), U64_C(0x85dac7f05b95a41e), U64_C(0xb5469d1b4043a1e9), U64_C(0xb821ecbbd9a592fd), U64_C(0x1b8e0b0e798c13c8), U64_C(0x62a57b6d9a0be02e), U64_C(0xfcf1b793b81257f8), U64_C(0x9d94ea0bd8fe28eb), U64_C(0x4cea408aeb654a56), U64_C(0x23284a47e888996c), U64_C(0x2d8f1d128b893545), U64_C(0xf4cbac3132c0d8ab), U64_C(0xbd7c86b9ca912eba), U64_C(0x3a268eef3dbe6079), U64_C(0xf0d62f6077a9110c), U64_C(0x2735c916ade150cb), U64_C(0x89fd5f03942ee2ea), U64_C(0x1acee25d2fd16628), U64_C(0x90f39bab41181bff), U64_C(0x430dfe8cde39939f), U64_C(0xf70b8ac4c8274796), U64_C(0x1c53aeaac6024552), U64_C(0x13b410acf35e9c9b), U64_C(0xa532ab4249faa24f), U64_C(0x2b1251e5625a163f), U64_C(0xd7e3e676da4841c7), U64_C(0xa7b264e4e5404892), U64_C(0xda8497d643ae72d3), U64_C(0x861ae105a1723b23), U64_C(0x38a6414991048aa4), U64_C(0x6578dec92585b6b4), U64_C(0x0280cfa6acbaeadd), U64_C(0x88bdb650c273970a), U64_C(0x9333bd5ebbff84c2), U64_C(0x4e6a8f2c47dfa08b), U64_C(0x321c954db76cef2a), U64_C(0x418d312a72837942), U64_C(0xb29b38bfffcdf773), U64_C(0x6c022c38f90a4c07), U64_C(0x5a033a240b0f6a8a), U64_C(0x1f93885f3ce5da6f), U64_C(0xc38a537e96988bc6), U64_C(0x39e6a81ac759ff44), U64_C(0x29929e43cee0fce2), U64_C(0x40cdd87924de0ca2), U64_C(0xe9d8ebc8a29fe819), U64_C(0x0c2798f3cfbb46f4), U64_C(0x55e484223e53b343), U64_C(0x4650948ecd0d2fd8), U64_C(0x20e86cb2126f0651), U64_C(0x6d42c56baf5739e7), U64_C(0xa06fc1405ace1e08), U64_C(0x7babbfc54f3d193b), U64_C(0x424d17df8864e67f), U64_C(0xd8045870ef14980e), U64_C(0xc6d7397c85ac3781), U64_C(0x21a885e1443273b1), U64_C(0x67f8116f893f5c69), U64_C(0x24f5efe35706cff6), U64_C(0xd56329d076f2ab1a), U64_C(0x5e1eb9754e66a32d), U64_C(0x28d2771098bd8902), U64_C(0x8f6013f47dfdc190), U64_C(0x17a993fdb637553c), U64_C(0xe0a219397e1012aa), U64_C(0x786b9930b5da8606), U64_C(0x6e82e39e55b0a6da), U64_C(0x875a0856f72f4ec3), U64_C(0x3741ff4fa458536d), U64_C(0xac4859b3957558fc), U64_C(0x7ef6d5c75c09a57c), U64_C(0xc04a758b6c7f14fb), U64_C(0xf9acdd91ab26ebbf), U64_C(0x7391a467c5ef9668), U64_C(0x335c7c1ee1319aca), U64_C(0xa91533b18641e4bb), U64_C(0xe4bf9a683b79db0d), U64_C(0x8e20faa72ba0b470), U64_C(0x51f907737b3a7ae4), U64_C(0x2268a314bed5ec8c), U64_C(0xd944b123b949edee), U64_C(0x31dcb3b84d8b7017), U64_C(0xd3fe65279f218860), U64_C(0x097af2f1dc8ffab3), U64_C(0x9b09a6fc312d0b91), U64_C(0xcc6ded78a3c4520f), U64_C(0x3481d9ba5ebfcc50), U64_C(0x4f2a667f1182d56b), U64_C(0xdfd9fdd4509ace94), U64_C(0x26752045fbbc252b), U64_C(0xbffc491f662bc467), U64_C(0xdd593272fc202449), U64_C(0x3cbbc218d46d4303), U64_C(0x91b372f817456e1f), U64_C(0x681faf69bc6385a0), U64_C(0xb686bbeebaa43ed4), U64_C(0x1469b5084cd0ca01), U64_C(0x98c98009cbca94ac), U64_C(0x6438379a73d8c354), U64_C(0xc2caba2dc0c5fe26), U64_C(0x3e3b0dbe78d7a9de), U64_C(0x50b9ee202d670f04), U64_C(0x4590b27b37eab0e5), U64_C(0x6025b4cb36b10af3), U64_C(0xfb2c1237079c0162), U64_C(0xa12f28130c936be8), U64_C(0x4b37e52e54eb1ccc), U64_C(0x083a1ba28ad28f53), U64_C(0xc10a9cd83a22611b), U64_C(0x9f1425ad7444c236), U64_C(0x069d4cf7e9d3237a), U64_C(0xedc56899e7f621be), U64_C(0x778c273680865fcf), U64_C(0x309c5aeb1bd605f7), U64_C(0x8de0dc52d1472b4d), U64_C(0xf8ec34c2fd7b9e5f), U64_C(0xea18cd3d58787724), U64_C(0xaad515447ca67b86), U64_C(0x9989695a9d97e14c), U64_C(0x0000000000000000), U64_C(0xf196c63321f464ec), U64_C(0x71116bc169557cb5), U64_C(0xaf887f466f92c7c1), U64_C(0x972e3e0ffe964d65), U64_C(0x190ec4a8d536f915), U64_C(0x95aef1a9522ca7b8), U64_C(0xdc19db21aa7d51a9), U64_C(0x94ee18fa0471d258), U64_C(0x8087adf248a11859), U64_C(0xc457f6da2916dd5c), U64_C(0xfa6cfb6451c17482), U64_C(0xf256e0c6db13fbd1), U64_C(0x6a9f60cf10d96f7d), U64_C(0x4daaa9d9bd383fb6), U64_C(0x03c026f5fae79f3d), U64_C(0xde99148706c7bb74), U64_C(0x2a52b8b6340763df), U64_C(0x6fc20acd03edd33a), U64_C(0xd423c08320afdefa), U64_C(0xbbe1ca4e23420dc0), U64_C(0x966ed75ca8cb3885), U64_C(0xeb58246e0e2502c4), U64_C(0x055d6a021334bc47), U64_C(0xa47242111fa7d7af), U64_C(0xe3623fcc84f78d97), U64_C(0x81c744a11efc6db9), U64_C(0xaec8961539cfb221), U64_C(0xf31609958d4e8e31), U64_C(0x63e5923ecc5695ce), U64_C(0x47107ddd9b505a38), U64_C(0xa3afe7b5a0298135), U64_C(0x792b7063e387f3e6), U64_C(0x0140e953565d75e0), U64_C(0x12f4f9ffa503e97b), U64_C(0x750ce8902c3cb512), U64_C(0xdbc47e8515f30733), U64_C(0x1ed3610c6ab8af8f), U64_C(0x5239218681dde5d9), U64_C(0xe222d69fd2aaf877), U64_C(0xfe71783514a8bd25), U64_C(0xcaf0a18f4a177175), U64_C(0x61655d9860ec7f13), U64_C(0xe77fbc9dc19e4430), U64_C(0x2ccff441ddd440a5), U64_C(0x16e97aaee06a20dc), U64_C(0xa855dae2d01c915b), U64_C(0x1d1347f9905f30b2), U64_C(0xb7c652bdecf94b34), U64_C(0xd03e43d265c6175d), U64_C(0xfdb15ec0ee4f2218), U64_C(0x57644b8492e9599e), U64_C(0x07dda5a4bf8e569a), U64_C(0x54a46d71680ec6a3), U64_C(0x5624a2d7c4b42c7e), U64_C(0xbebca04c3076b187), U64_C(0x7d36f332a6ee3a41), U64_C(0x3b6667bc6be31599), U64_C(0x695f463aea3ef040), U64_C(0xad08b0e0c3282d1c), U64_C(0xb15b1e4a052a684e), U64_C(0x44d05b2861b7c505), U64_C(0x15295c5b1a8dbfe1), U64_C(0x744c01c37a61c0f2), U64_C(0x59c31cd1f1e8f5b7), U64_C(0xef45a73f4b4ccb63), U64_C(0x6bdf899c46841a9d), U64_C(0x3dfb2b4b823036e3), U64_C(0xa2ef0ee6f674f4d5), U64_C(0x184e2dfb836b8cf5), U64_C(0x1134df0a5fe47646), U64_C(0xbaa1231d751f7820), U64_C(0xd17eaa81339b62bd), U64_C(0xb01bf71953771dae), U64_C(0x849a2ea30dc8d1fe), U64_C(0x705182923f080955), U64_C(0x0ea757556301ac29), U64_C(0x041d83514569c9a7), U64_C(0x0abad4042668658e), U64_C(0x49b72a88f851f611), U64_C(0x8a3d79f66ec97dd7), U64_C(0xcd2d042bf59927ef), U64_C(0xc930877ab0f0ee48), U64_C(0x9273540deda2f122), U64_C(0xc797d02fd3f14261), U64_C(0xe1e2f06a284d674a), U64_C(0xd2be8c74c97cfd80), U64_C(0x9a494faf67707e71), U64_C(0xb3dbd1eca9908293), U64_C(0x72d14d3493b2e388), U64_C(0xd6a30f258c153427) }, }; static const u64 C16[12][8] = { { U64_C(0xdd806559f2a64507), U64_C(0x05767436cc744d23), U64_C(0xa2422a08a460d315), U64_C(0x4b7ce09192676901), U64_C(0x714eb88d7585c4fc), U64_C(0x2f6a76432e45d016), U64_C(0xebcb2f81c0657c1f), U64_C(0xb1085bda1ecadae9) }, { U64_C(0xe679047021b19bb7), U64_C(0x55dda21bd7cbcd56), U64_C(0x5cb561c2db0aa7ca), U64_C(0x9ab5176b12d69958), U64_C(0x61d55e0f16b50131), U64_C(0xf3feea720a232b98), U64_C(0x4fe39d460f70b5d7), U64_C(0x6fa3b58aa99d2f1a) }, { U64_C(0x991e96f50aba0ab2), U64_C(0xc2b6f443867adb31), U64_C(0xc1c93a376062db09), U64_C(0xd3e20fe490359eb1), U64_C(0xf2ea7514b1297b7b), U64_C(0x06f15e5f529c1f8b), U64_C(0x0a39fc286a3d8435), U64_C(0xf574dcac2bce2fc7) }, { U64_C(0x220cbebc84e3d12e), U64_C(0x3453eaa193e837f1), U64_C(0xd8b71333935203be), U64_C(0xa9d72c82ed03d675), U64_C(0x9d721cad685e353f), U64_C(0x488e857e335c3c7d), U64_C(0xf948e1a05d71e4dd), U64_C(0xef1fdfb3e81566d2) }, { U64_C(0x601758fd7c6cfe57), U64_C(0x7a56a27ea9ea63f5), U64_C(0xdfff00b723271a16), U64_C(0xbfcd1747253af5a3), U64_C(0x359e35d7800fffbd), U64_C(0x7f151c1f1686104a), U64_C(0x9a3f410c6ca92363), U64_C(0x4bea6bacad474799) }, { U64_C(0xfa68407a46647d6e), U64_C(0xbf71c57236904f35), U64_C(0x0af21f66c2bec6b6), U64_C(0xcffaa6b71c9ab7b4), U64_C(0x187f9ab49af08ec6), U64_C(0x2d66c4f95142a46c), U64_C(0x6fa4c33b7a3039c0), U64_C(0xae4faeae1d3ad3d9) }, { U64_C(0x8886564d3a14d493), U64_C(0x3517454ca23c4af3), U64_C(0x06476983284a0504), U64_C(0x0992abc52d822c37), U64_C(0xd3473e33197a93c9), U64_C(0x399ec6c7e6bf87c9), U64_C(0x51ac86febf240954), U64_C(0xf4c70e16eeaac5ec) }, { U64_C(0xa47f0dd4bf02e71e), U64_C(0x36acc2355951a8d9), U64_C(0x69d18d2bd1a5c42f), U64_C(0xf4892bcb929b0690), U64_C(0x89b4443b4ddbc49a), U64_C(0x4eb7f8719c36de1e), U64_C(0x03e7aa020c6e4141), U64_C(0x9b1f5b424d93c9a7) }, { U64_C(0x7261445183235adb), U64_C(0x0e38dc92cb1f2a60), U64_C(0x7b2b8a9aa6079c54), U64_C(0x800a440bdbb2ceb1), U64_C(0x3cd955b7e00d0984), U64_C(0x3a7d3a1b25894224), U64_C(0x944c9ad8ec165fde), U64_C(0x378f5a541631229b) }, { U64_C(0x74b4c7fb98459ced), U64_C(0x3698fad1153bb6c3), U64_C(0x7a1e6c303b7652f4), U64_C(0x9fe76702af69334b), U64_C(0x1fffe18a1b336103), U64_C(0x8941e71cff8a78db), U64_C(0x382ae548b2e4f3f3), U64_C(0xabbedea680056f52) }, { U64_C(0x6bcaa4cd81f32d1b), U64_C(0xdea2594ac06fd85d), U64_C(0xefbacd1d7d476e98), U64_C(0x8a1d71efea48b9ca), U64_C(0x2001802114846679), U64_C(0xd8fa6bbbebab0761), U64_C(0x3002c6cd635afe94), U64_C(0x7bcd9ed0efc889fb) }, { U64_C(0x48bc924af11bd720), U64_C(0xfaf417d5d9b21b99), U64_C(0xe71da4aa88e12852), U64_C(0x5d80ef9d1891cc86), U64_C(0xf82012d430219f9b), U64_C(0xcda43c32bcdf1d77), U64_C(0xd21380b00449b17a), U64_C(0x378ee767f11631ba) }, }; #define strido(out, temp, i) do { \ u64 t; \ t = stribog_table[0][(temp[0] >> (i * 8)) & 0xff]; \ t ^= stribog_table[1][(temp[1] >> (i * 8)) & 0xff]; \ t ^= stribog_table[2][(temp[2] >> (i * 8)) & 0xff]; \ t ^= stribog_table[3][(temp[3] >> (i * 8)) & 0xff]; \ t ^= stribog_table[4][(temp[4] >> (i * 8)) & 0xff]; \ t ^= stribog_table[5][(temp[5] >> (i * 8)) & 0xff]; \ t ^= stribog_table[6][(temp[6] >> (i * 8)) & 0xff]; \ t ^= stribog_table[7][(temp[7] >> (i * 8)) & 0xff]; \ out[i] = t; } while(0) static void LPSX (u64 *out, const u64 *a, const u64 *b) { u64 temp[8]; temp[0] = a[0] ^ b[0]; temp[1] = a[1] ^ b[1]; temp[2] = a[2] ^ b[2]; temp[3] = a[3] ^ b[3]; temp[4] = a[4] ^ b[4]; temp[5] = a[5] ^ b[5]; temp[6] = a[6] ^ b[6]; temp[7] = a[7] ^ b[7]; strido (out, temp, 0); strido (out, temp, 1); strido (out, temp, 2); strido (out, temp, 3); strido (out, temp, 4); strido (out, temp, 5); strido (out, temp, 6); strido (out, temp, 7); } static inline void g (u64 *h, u64 *m, u64 *N) { u64 K[8]; u64 T[8]; int i; LPSX (K, h, N); LPSX (T, K, m); LPSX (K, K, C16[0]); for (i = 1; i < 12; i++) { LPSX (T, K, T); LPSX (K, K, C16[i]); } h[0] ^= T[0] ^ K[0] ^ m[0]; h[1] ^= T[1] ^ K[1] ^ m[1]; h[2] ^= T[2] ^ K[2] ^ m[2]; h[3] ^= T[3] ^ K[3] ^ m[3]; h[4] ^= T[4] ^ K[4] ^ m[4]; h[5] ^= T[5] ^ K[5] ^ m[5]; h[6] ^= T[6] ^ K[6] ^ m[6]; h[7] ^= T[7] ^ K[7] ^ m[7]; } static unsigned int transform (void *context, const unsigned char *inbuf_arg, size_t datalen); static void stribog_init_512 (void *context, unsigned int flags) { STRIBOG_CONTEXT *hd = context; (void)flags; memset (hd, 0, sizeof (*hd)); hd->bctx.blocksize = 64; hd->bctx.bwrite = transform; } static void stribog_init_256 (void *context, unsigned int flags) { STRIBOG_CONTEXT *hd = context; stribog_init_512 (context, flags); memset (hd->h, 1, 64); } static void transform_bits (STRIBOG_CONTEXT *hd, const unsigned char *data, unsigned count) { u64 M[8]; u64 l; int i; for (i = 0; i < 8; i++) M[i] = buf_get_le64(data + i * 8); g (hd->h, M, hd->N); l = hd->N[0]; hd->N[0] += count; if (hd->N[0] < l) { /* overflow */ for (i = 1; i < 8; i++) { hd->N[i]++; if (hd->N[i] != 0) break; } } hd->Sigma[0] += M[0]; for (i = 1; i < 8; i++) if (hd->Sigma[i-1] < M[i-1]) hd->Sigma[i] += M[i] + 1; else hd->Sigma[i] += M[i]; } static unsigned int transform_blk (void *context, const unsigned char *inbuf_arg) { STRIBOG_CONTEXT *hd = context; transform_bits (hd, inbuf_arg, 64 * 8); return /* burn_stack */ 768; } static unsigned int transform ( void *c, const unsigned char *data, size_t nblks ) { unsigned int burn; do { burn = transform_blk (c, data); data += 64; } while (--nblks); return burn; } /* The routine finally terminates the computation and returns the digest. The handle is prepared for a new cycle, but adding bytes to the handle will the destroy the returned buffer. Returns: 32 bytes with the message the digest. */ static void stribog_final (void *context) { STRIBOG_CONTEXT *hd = context; u64 Z[8] = {}; int i; _gcry_md_block_write (context, NULL, 0); /* flush */ ; /* PAD. It does not count towards message length */ i = hd->bctx.count; /* After flush we have at least one byte free) */ hd->bctx.buf[i++] = 1; - while (i < 64) - hd->bctx.buf[i++] = 0; + if (i < 64) + memset (&hd->bctx.buf[i], 0, 64 - i); + i = 64; transform_bits (hd, hd->bctx.buf, hd->bctx.count * 8); g (hd->h, hd->N, Z); g (hd->h, hd->Sigma, Z); for (i = 0; i < 8; i++) hd->h[i] = le_bswap64(hd->h[i]); _gcry_burn_stack (768); } static byte * stribog_read_512 (void *context) { STRIBOG_CONTEXT *hd = context; return hd->result; } static byte * stribog_read_256 (void *context) { STRIBOG_CONTEXT *hd = context; return hd->result + 32; } static gcry_md_oid_spec_t oid_spec_stribog256[] = { /* id-tc26-signwithdigest-gost3410-12-256 */ { "1.2.643.7.1.1.3.2" }, /* id-tc26-gost3411-12-256 */ { "1.2.643.7.1.1.2.2" }, { NULL }, }; static gcry_md_oid_spec_t oid_spec_stribog512[] = { /* id-tc26-signwithdigest-gost3410-12-512 */ { "1.2.643.7.1.1.3.3" }, /* id-tc26-gost3411-12-512 */ { "1.2.643.7.1.1.2.3" }, { NULL }, }; gcry_md_spec_t _gcry_digest_spec_stribog_256 = { GCRY_MD_STRIBOG256, {0, 0}, "STRIBOG256", NULL, 0, oid_spec_stribog256, 32, stribog_init_256, _gcry_md_block_write, stribog_final, stribog_read_256, NULL, NULL, NULL, sizeof (STRIBOG_CONTEXT) }; gcry_md_spec_t _gcry_digest_spec_stribog_512 = { GCRY_MD_STRIBOG512, {0, 0}, "STRIBOG512", NULL, 0, oid_spec_stribog512, 64, stribog_init_512, _gcry_md_block_write, stribog_final, stribog_read_512, NULL, NULL, NULL, sizeof (STRIBOG_CONTEXT) }; diff --git a/cipher/tiger.c b/cipher/tiger.c index d24d1603..0319b711 100644 --- a/cipher/tiger.c +++ b/cipher/tiger.c @@ -1,855 +1,861 @@ /* tiger.c - The TIGER hash function * Copyright (C) 1998, 2001, 2002, 2003, 2010 Free Software Foundation, Inc. * * This file is part of Libgcrypt. * * Libgcrypt is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * Libgcrypt is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ /* See http://www.cs.technion.ac.il/~biham/Reports/Tiger/ */ #include #include #include #include #include "g10lib.h" #include "cipher.h" #include "hash-common.h" #include "bithelp.h" #include "bufhelp.h" typedef struct { gcry_md_block_ctx_t bctx; u64 a, b, c; int variant; /* 0 = old code, 1 = fixed code, 2 - TIGER2. */ } TIGER_CONTEXT; /********************************* * Okay, okay, this is not the fastest code - improvements are welcome. * */ /* Some test vectors: * "" 24F0130C63AC9332 16166E76B1BB925F F373DE2D49584E7A * "abc" F258C1E88414AB2A 527AB541FFC5B8BF 935F7B951C132951 * "Tiger" 9F00F599072300DD 276ABB38C8EB6DEC 37790C116F9D2BDF * "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-" * 87FB2A9083851CF7 470D2CF810E6DF9E B586445034A5A386 * "ABCDEFGHIJKLMNOPQRSTUVWXYZ=abcdefghijklmnopqrstuvwxyz+0123456789" * 467DB80863EBCE48 8DF1CD1261655DE9 57896565975F9197 * "Tiger - A Fast New Hash Function, by Ross Anderson and Eli Biham" * 0C410A042968868A 1671DA5A3FD29A72 5EC1E457D3CDB303 * "Tiger - A Fast New Hash Function, by Ross Anderson and Eli Biham, proc" * "eedings of Fast Software Encryption 3, Cambridge." * EBF591D5AFA655CE 7F22894FF87F54AC 89C811B6B0DA3193 * "Tiger - A Fast New Hash Function, by Ross Anderson and Eli Biham, proc" * "eedings of Fast Software Encryption 3, Cambridge, 1996." * 3D9AEB03D1BD1A63 57B2774DFD6D5B24 DD68151D503974FC * "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-ABCDEF" * "GHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-" * 00B83EB4E53440C5 76AC6AAEE0A74858 25FD15E70A59FFE4 */ static u64 sbox1[256] = { U64_C(0x02aab17cf7e90c5e) /* 0 */, U64_C(0xac424b03e243a8ec) /* 1 */, U64_C(0x72cd5be30dd5fcd3) /* 2 */, U64_C(0x6d019b93f6f97f3a) /* 3 */, U64_C(0xcd9978ffd21f9193) /* 4 */, U64_C(0x7573a1c9708029e2) /* 5 */, U64_C(0xb164326b922a83c3) /* 6 */, U64_C(0x46883eee04915870) /* 7 */, U64_C(0xeaace3057103ece6) /* 8 */, U64_C(0xc54169b808a3535c) /* 9 */, U64_C(0x4ce754918ddec47c) /* 10 */, U64_C(0x0aa2f4dfdc0df40c) /* 11 */, U64_C(0x10b76f18a74dbefa) /* 12 */, U64_C(0xc6ccb6235ad1ab6a) /* 13 */, U64_C(0x13726121572fe2ff) /* 14 */, U64_C(0x1a488c6f199d921e) /* 15 */, U64_C(0x4bc9f9f4da0007ca) /* 16 */, U64_C(0x26f5e6f6e85241c7) /* 17 */, U64_C(0x859079dbea5947b6) /* 18 */, U64_C(0x4f1885c5c99e8c92) /* 19 */, U64_C(0xd78e761ea96f864b) /* 20 */, U64_C(0x8e36428c52b5c17d) /* 21 */, U64_C(0x69cf6827373063c1) /* 22 */, U64_C(0xb607c93d9bb4c56e) /* 23 */, U64_C(0x7d820e760e76b5ea) /* 24 */, U64_C(0x645c9cc6f07fdc42) /* 25 */, U64_C(0xbf38a078243342e0) /* 26 */, U64_C(0x5f6b343c9d2e7d04) /* 27 */, U64_C(0xf2c28aeb600b0ec6) /* 28 */, U64_C(0x6c0ed85f7254bcac) /* 29 */, U64_C(0x71592281a4db4fe5) /* 30 */, U64_C(0x1967fa69ce0fed9f) /* 31 */, U64_C(0xfd5293f8b96545db) /* 32 */, U64_C(0xc879e9d7f2a7600b) /* 33 */, U64_C(0x860248920193194e) /* 34 */, U64_C(0xa4f9533b2d9cc0b3) /* 35 */, U64_C(0x9053836c15957613) /* 36 */, U64_C(0xdb6dcf8afc357bf1) /* 37 */, U64_C(0x18beea7a7a370f57) /* 38 */, U64_C(0x037117ca50b99066) /* 39 */, U64_C(0x6ab30a9774424a35) /* 40 */, U64_C(0xf4e92f02e325249b) /* 41 */, U64_C(0x7739db07061ccae1) /* 42 */, U64_C(0xd8f3b49ceca42a05) /* 43 */, U64_C(0xbd56be3f51382f73) /* 44 */, U64_C(0x45faed5843b0bb28) /* 45 */, U64_C(0x1c813d5c11bf1f83) /* 46 */, U64_C(0x8af0e4b6d75fa169) /* 47 */, U64_C(0x33ee18a487ad9999) /* 48 */, U64_C(0x3c26e8eab1c94410) /* 49 */, U64_C(0xb510102bc0a822f9) /* 50 */, U64_C(0x141eef310ce6123b) /* 51 */, U64_C(0xfc65b90059ddb154) /* 52 */, U64_C(0xe0158640c5e0e607) /* 53 */, U64_C(0x884e079826c3a3cf) /* 54 */, U64_C(0x930d0d9523c535fd) /* 55 */, U64_C(0x35638d754e9a2b00) /* 56 */, U64_C(0x4085fccf40469dd5) /* 57 */, U64_C(0xc4b17ad28be23a4c) /* 58 */, U64_C(0xcab2f0fc6a3e6a2e) /* 59 */, U64_C(0x2860971a6b943fcd) /* 60 */, U64_C(0x3dde6ee212e30446) /* 61 */, U64_C(0x6222f32ae01765ae) /* 62 */, U64_C(0x5d550bb5478308fe) /* 63 */, U64_C(0xa9efa98da0eda22a) /* 64 */, U64_C(0xc351a71686c40da7) /* 65 */, U64_C(0x1105586d9c867c84) /* 66 */, U64_C(0xdcffee85fda22853) /* 67 */, U64_C(0xccfbd0262c5eef76) /* 68 */, U64_C(0xbaf294cb8990d201) /* 69 */, U64_C(0xe69464f52afad975) /* 70 */, U64_C(0x94b013afdf133e14) /* 71 */, U64_C(0x06a7d1a32823c958) /* 72 */, U64_C(0x6f95fe5130f61119) /* 73 */, U64_C(0xd92ab34e462c06c0) /* 74 */, U64_C(0xed7bde33887c71d2) /* 75 */, U64_C(0x79746d6e6518393e) /* 76 */, U64_C(0x5ba419385d713329) /* 77 */, U64_C(0x7c1ba6b948a97564) /* 78 */, U64_C(0x31987c197bfdac67) /* 79 */, U64_C(0xde6c23c44b053d02) /* 80 */, U64_C(0x581c49fed002d64d) /* 81 */, U64_C(0xdd474d6338261571) /* 82 */, U64_C(0xaa4546c3e473d062) /* 83 */, U64_C(0x928fce349455f860) /* 84 */, U64_C(0x48161bbacaab94d9) /* 85 */, U64_C(0x63912430770e6f68) /* 86 */, U64_C(0x6ec8a5e602c6641c) /* 87 */, U64_C(0x87282515337ddd2b) /* 88 */, U64_C(0x2cda6b42034b701b) /* 89 */, U64_C(0xb03d37c181cb096d) /* 90 */, U64_C(0xe108438266c71c6f) /* 91 */, U64_C(0x2b3180c7eb51b255) /* 92 */, U64_C(0xdf92b82f96c08bbc) /* 93 */, U64_C(0x5c68c8c0a632f3ba) /* 94 */, U64_C(0x5504cc861c3d0556) /* 95 */, U64_C(0xabbfa4e55fb26b8f) /* 96 */, U64_C(0x41848b0ab3baceb4) /* 97 */, U64_C(0xb334a273aa445d32) /* 98 */, U64_C(0xbca696f0a85ad881) /* 99 */, U64_C(0x24f6ec65b528d56c) /* 100 */, U64_C(0x0ce1512e90f4524a) /* 101 */, U64_C(0x4e9dd79d5506d35a) /* 102 */, U64_C(0x258905fac6ce9779) /* 103 */, U64_C(0x2019295b3e109b33) /* 104 */, U64_C(0xf8a9478b73a054cc) /* 105 */, U64_C(0x2924f2f934417eb0) /* 106 */, U64_C(0x3993357d536d1bc4) /* 107 */, U64_C(0x38a81ac21db6ff8b) /* 108 */, U64_C(0x47c4fbf17d6016bf) /* 109 */, U64_C(0x1e0faadd7667e3f5) /* 110 */, U64_C(0x7abcff62938beb96) /* 111 */, U64_C(0xa78dad948fc179c9) /* 112 */, U64_C(0x8f1f98b72911e50d) /* 113 */, U64_C(0x61e48eae27121a91) /* 114 */, U64_C(0x4d62f7ad31859808) /* 115 */, U64_C(0xeceba345ef5ceaeb) /* 116 */, U64_C(0xf5ceb25ebc9684ce) /* 117 */, U64_C(0xf633e20cb7f76221) /* 118 */, U64_C(0xa32cdf06ab8293e4) /* 119 */, U64_C(0x985a202ca5ee2ca4) /* 120 */, U64_C(0xcf0b8447cc8a8fb1) /* 121 */, U64_C(0x9f765244979859a3) /* 122 */, U64_C(0xa8d516b1a1240017) /* 123 */, U64_C(0x0bd7ba3ebb5dc726) /* 124 */, U64_C(0xe54bca55b86adb39) /* 125 */, U64_C(0x1d7a3afd6c478063) /* 126 */, U64_C(0x519ec608e7669edd) /* 127 */, U64_C(0x0e5715a2d149aa23) /* 128 */, U64_C(0x177d4571848ff194) /* 129 */, U64_C(0xeeb55f3241014c22) /* 130 */, U64_C(0x0f5e5ca13a6e2ec2) /* 131 */, U64_C(0x8029927b75f5c361) /* 132 */, U64_C(0xad139fabc3d6e436) /* 133 */, U64_C(0x0d5df1a94ccf402f) /* 134 */, U64_C(0x3e8bd948bea5dfc8) /* 135 */, U64_C(0xa5a0d357bd3ff77e) /* 136 */, U64_C(0xa2d12e251f74f645) /* 137 */, U64_C(0x66fd9e525e81a082) /* 138 */, U64_C(0x2e0c90ce7f687a49) /* 139 */, U64_C(0xc2e8bcbeba973bc5) /* 140 */, U64_C(0x000001bce509745f) /* 141 */, U64_C(0x423777bbe6dab3d6) /* 142 */, U64_C(0xd1661c7eaef06eb5) /* 143 */, U64_C(0xa1781f354daacfd8) /* 144 */, U64_C(0x2d11284a2b16affc) /* 145 */, U64_C(0xf1fc4f67fa891d1f) /* 146 */, U64_C(0x73ecc25dcb920ada) /* 147 */, U64_C(0xae610c22c2a12651) /* 148 */, U64_C(0x96e0a810d356b78a) /* 149 */, U64_C(0x5a9a381f2fe7870f) /* 150 */, U64_C(0xd5ad62ede94e5530) /* 151 */, U64_C(0xd225e5e8368d1427) /* 152 */, U64_C(0x65977b70c7af4631) /* 153 */, U64_C(0x99f889b2de39d74f) /* 154 */, U64_C(0x233f30bf54e1d143) /* 155 */, U64_C(0x9a9675d3d9a63c97) /* 156 */, U64_C(0x5470554ff334f9a8) /* 157 */, U64_C(0x166acb744a4f5688) /* 158 */, U64_C(0x70c74caab2e4aead) /* 159 */, U64_C(0xf0d091646f294d12) /* 160 */, U64_C(0x57b82a89684031d1) /* 161 */, U64_C(0xefd95a5a61be0b6b) /* 162 */, U64_C(0x2fbd12e969f2f29a) /* 163 */, U64_C(0x9bd37013feff9fe8) /* 164 */, U64_C(0x3f9b0404d6085a06) /* 165 */, U64_C(0x4940c1f3166cfe15) /* 166 */, U64_C(0x09542c4dcdf3defb) /* 167 */, U64_C(0xb4c5218385cd5ce3) /* 168 */, U64_C(0xc935b7dc4462a641) /* 169 */, U64_C(0x3417f8a68ed3b63f) /* 170 */, U64_C(0xb80959295b215b40) /* 171 */, U64_C(0xf99cdaef3b8c8572) /* 172 */, U64_C(0x018c0614f8fcb95d) /* 173 */, U64_C(0x1b14accd1a3acdf3) /* 174 */, U64_C(0x84d471f200bb732d) /* 175 */, U64_C(0xc1a3110e95e8da16) /* 176 */, U64_C(0x430a7220bf1a82b8) /* 177 */, U64_C(0xb77e090d39df210e) /* 178 */, U64_C(0x5ef4bd9f3cd05e9d) /* 179 */, U64_C(0x9d4ff6da7e57a444) /* 180 */, U64_C(0xda1d60e183d4a5f8) /* 181 */, U64_C(0xb287c38417998e47) /* 182 */, U64_C(0xfe3edc121bb31886) /* 183 */, U64_C(0xc7fe3ccc980ccbef) /* 184 */, U64_C(0xe46fb590189bfd03) /* 185 */, U64_C(0x3732fd469a4c57dc) /* 186 */, U64_C(0x7ef700a07cf1ad65) /* 187 */, U64_C(0x59c64468a31d8859) /* 188 */, U64_C(0x762fb0b4d45b61f6) /* 189 */, U64_C(0x155baed099047718) /* 190 */, U64_C(0x68755e4c3d50baa6) /* 191 */, U64_C(0xe9214e7f22d8b4df) /* 192 */, U64_C(0x2addbf532eac95f4) /* 193 */, U64_C(0x32ae3909b4bd0109) /* 194 */, U64_C(0x834df537b08e3450) /* 195 */, U64_C(0xfa209da84220728d) /* 196 */, U64_C(0x9e691d9b9efe23f7) /* 197 */, U64_C(0x0446d288c4ae8d7f) /* 198 */, U64_C(0x7b4cc524e169785b) /* 199 */, U64_C(0x21d87f0135ca1385) /* 200 */, U64_C(0xcebb400f137b8aa5) /* 201 */, U64_C(0x272e2b66580796be) /* 202 */, U64_C(0x3612264125c2b0de) /* 203 */, U64_C(0x057702bdad1efbb2) /* 204 */, U64_C(0xd4babb8eacf84be9) /* 205 */, U64_C(0x91583139641bc67b) /* 206 */, U64_C(0x8bdc2de08036e024) /* 207 */, U64_C(0x603c8156f49f68ed) /* 208 */, U64_C(0xf7d236f7dbef5111) /* 209 */, U64_C(0x9727c4598ad21e80) /* 210 */, U64_C(0xa08a0896670a5fd7) /* 211 */, U64_C(0xcb4a8f4309eba9cb) /* 212 */, U64_C(0x81af564b0f7036a1) /* 213 */, U64_C(0xc0b99aa778199abd) /* 214 */, U64_C(0x959f1ec83fc8e952) /* 215 */, U64_C(0x8c505077794a81b9) /* 216 */, U64_C(0x3acaaf8f056338f0) /* 217 */, U64_C(0x07b43f50627a6778) /* 218 */, U64_C(0x4a44ab49f5eccc77) /* 219 */, U64_C(0x3bc3d6e4b679ee98) /* 220 */, U64_C(0x9cc0d4d1cf14108c) /* 221 */, U64_C(0x4406c00b206bc8a0) /* 222 */, U64_C(0x82a18854c8d72d89) /* 223 */, U64_C(0x67e366b35c3c432c) /* 224 */, U64_C(0xb923dd61102b37f2) /* 225 */, U64_C(0x56ab2779d884271d) /* 226 */, U64_C(0xbe83e1b0ff1525af) /* 227 */, U64_C(0xfb7c65d4217e49a9) /* 228 */, U64_C(0x6bdbe0e76d48e7d4) /* 229 */, U64_C(0x08df828745d9179e) /* 230 */, U64_C(0x22ea6a9add53bd34) /* 231 */, U64_C(0xe36e141c5622200a) /* 232 */, U64_C(0x7f805d1b8cb750ee) /* 233 */, U64_C(0xafe5c7a59f58e837) /* 234 */, U64_C(0xe27f996a4fb1c23c) /* 235 */, U64_C(0xd3867dfb0775f0d0) /* 236 */, U64_C(0xd0e673de6e88891a) /* 237 */, U64_C(0x123aeb9eafb86c25) /* 238 */, U64_C(0x30f1d5d5c145b895) /* 239 */, U64_C(0xbb434a2dee7269e7) /* 240 */, U64_C(0x78cb67ecf931fa38) /* 241 */, U64_C(0xf33b0372323bbf9c) /* 242 */, U64_C(0x52d66336fb279c74) /* 243 */, U64_C(0x505f33ac0afb4eaa) /* 244 */, U64_C(0xe8a5cd99a2cce187) /* 245 */, U64_C(0x534974801e2d30bb) /* 246 */, U64_C(0x8d2d5711d5876d90) /* 247 */, U64_C(0x1f1a412891bc038e) /* 248 */, U64_C(0xd6e2e71d82e56648) /* 249 */, U64_C(0x74036c3a497732b7) /* 250 */, U64_C(0x89b67ed96361f5ab) /* 251 */, U64_C(0xffed95d8f1ea02a2) /* 252 */, U64_C(0xe72b3bd61464d43d) /* 253 */, U64_C(0xa6300f170bdc4820) /* 254 */, U64_C(0xebc18760ed78a77a) /* 255 */ }; static u64 sbox2[256] = { U64_C(0xe6a6be5a05a12138) /* 256 */, U64_C(0xb5a122a5b4f87c98) /* 257 */, U64_C(0x563c6089140b6990) /* 258 */, U64_C(0x4c46cb2e391f5dd5) /* 259 */, U64_C(0xd932addbc9b79434) /* 260 */, U64_C(0x08ea70e42015aff5) /* 261 */, U64_C(0xd765a6673e478cf1) /* 262 */, U64_C(0xc4fb757eab278d99) /* 263 */, U64_C(0xdf11c6862d6e0692) /* 264 */, U64_C(0xddeb84f10d7f3b16) /* 265 */, U64_C(0x6f2ef604a665ea04) /* 266 */, U64_C(0x4a8e0f0ff0e0dfb3) /* 267 */, U64_C(0xa5edeef83dbcba51) /* 268 */, U64_C(0xfc4f0a2a0ea4371e) /* 269 */, U64_C(0xe83e1da85cb38429) /* 270 */, U64_C(0xdc8ff882ba1b1ce2) /* 271 */, U64_C(0xcd45505e8353e80d) /* 272 */, U64_C(0x18d19a00d4db0717) /* 273 */, U64_C(0x34a0cfeda5f38101) /* 274 */, U64_C(0x0be77e518887caf2) /* 275 */, U64_C(0x1e341438b3c45136) /* 276 */, U64_C(0xe05797f49089ccf9) /* 277 */, U64_C(0xffd23f9df2591d14) /* 278 */, U64_C(0x543dda228595c5cd) /* 279 */, U64_C(0x661f81fd99052a33) /* 280 */, U64_C(0x8736e641db0f7b76) /* 281 */, U64_C(0x15227725418e5307) /* 282 */, U64_C(0xe25f7f46162eb2fa) /* 283 */, U64_C(0x48a8b2126c13d9fe) /* 284 */, U64_C(0xafdc541792e76eea) /* 285 */, U64_C(0x03d912bfc6d1898f) /* 286 */, U64_C(0x31b1aafa1b83f51b) /* 287 */, U64_C(0xf1ac2796e42ab7d9) /* 288 */, U64_C(0x40a3a7d7fcd2ebac) /* 289 */, U64_C(0x1056136d0afbbcc5) /* 290 */, U64_C(0x7889e1dd9a6d0c85) /* 291 */, U64_C(0xd33525782a7974aa) /* 292 */, U64_C(0xa7e25d09078ac09b) /* 293 */, U64_C(0xbd4138b3eac6edd0) /* 294 */, U64_C(0x920abfbe71eb9e70) /* 295 */, U64_C(0xa2a5d0f54fc2625c) /* 296 */, U64_C(0xc054e36b0b1290a3) /* 297 */, U64_C(0xf6dd59ff62fe932b) /* 298 */, U64_C(0x3537354511a8ac7d) /* 299 */, U64_C(0xca845e9172fadcd4) /* 300 */, U64_C(0x84f82b60329d20dc) /* 301 */, U64_C(0x79c62ce1cd672f18) /* 302 */, U64_C(0x8b09a2add124642c) /* 303 */, U64_C(0xd0c1e96a19d9e726) /* 304 */, U64_C(0x5a786a9b4ba9500c) /* 305 */, U64_C(0x0e020336634c43f3) /* 306 */, U64_C(0xc17b474aeb66d822) /* 307 */, U64_C(0x6a731ae3ec9baac2) /* 308 */, U64_C(0x8226667ae0840258) /* 309 */, U64_C(0x67d4567691caeca5) /* 310 */, U64_C(0x1d94155c4875adb5) /* 311 */, U64_C(0x6d00fd985b813fdf) /* 312 */, U64_C(0x51286efcb774cd06) /* 313 */, U64_C(0x5e8834471fa744af) /* 314 */, U64_C(0xf72ca0aee761ae2e) /* 315 */, U64_C(0xbe40e4cdaee8e09a) /* 316 */, U64_C(0xe9970bbb5118f665) /* 317 */, U64_C(0x726e4beb33df1964) /* 318 */, U64_C(0x703b000729199762) /* 319 */, U64_C(0x4631d816f5ef30a7) /* 320 */, U64_C(0xb880b5b51504a6be) /* 321 */, U64_C(0x641793c37ed84b6c) /* 322 */, U64_C(0x7b21ed77f6e97d96) /* 323 */, U64_C(0x776306312ef96b73) /* 324 */, U64_C(0xae528948e86ff3f4) /* 325 */, U64_C(0x53dbd7f286a3f8f8) /* 326 */, U64_C(0x16cadce74cfc1063) /* 327 */, U64_C(0x005c19bdfa52c6dd) /* 328 */, U64_C(0x68868f5d64d46ad3) /* 329 */, U64_C(0x3a9d512ccf1e186a) /* 330 */, U64_C(0x367e62c2385660ae) /* 331 */, U64_C(0xe359e7ea77dcb1d7) /* 332 */, U64_C(0x526c0773749abe6e) /* 333 */, U64_C(0x735ae5f9d09f734b) /* 334 */, U64_C(0x493fc7cc8a558ba8) /* 335 */, U64_C(0xb0b9c1533041ab45) /* 336 */, U64_C(0x321958ba470a59bd) /* 337 */, U64_C(0x852db00b5f46c393) /* 338 */, U64_C(0x91209b2bd336b0e5) /* 339 */, U64_C(0x6e604f7d659ef19f) /* 340 */, U64_C(0xb99a8ae2782ccb24) /* 341 */, U64_C(0xccf52ab6c814c4c7) /* 342 */, U64_C(0x4727d9afbe11727b) /* 343 */, U64_C(0x7e950d0c0121b34d) /* 344 */, U64_C(0x756f435670ad471f) /* 345 */, U64_C(0xf5add442615a6849) /* 346 */, U64_C(0x4e87e09980b9957a) /* 347 */, U64_C(0x2acfa1df50aee355) /* 348 */, U64_C(0xd898263afd2fd556) /* 349 */, U64_C(0xc8f4924dd80c8fd6) /* 350 */, U64_C(0xcf99ca3d754a173a) /* 351 */, U64_C(0xfe477bacaf91bf3c) /* 352 */, U64_C(0xed5371f6d690c12d) /* 353 */, U64_C(0x831a5c285e687094) /* 354 */, U64_C(0xc5d3c90a3708a0a4) /* 355 */, U64_C(0x0f7f903717d06580) /* 356 */, U64_C(0x19f9bb13b8fdf27f) /* 357 */, U64_C(0xb1bd6f1b4d502843) /* 358 */, U64_C(0x1c761ba38fff4012) /* 359 */, U64_C(0x0d1530c4e2e21f3b) /* 360 */, U64_C(0x8943ce69a7372c8a) /* 361 */, U64_C(0xe5184e11feb5ce66) /* 362 */, U64_C(0x618bdb80bd736621) /* 363 */, U64_C(0x7d29bad68b574d0b) /* 364 */, U64_C(0x81bb613e25e6fe5b) /* 365 */, U64_C(0x071c9c10bc07913f) /* 366 */, U64_C(0xc7beeb7909ac2d97) /* 367 */, U64_C(0xc3e58d353bc5d757) /* 368 */, U64_C(0xeb017892f38f61e8) /* 369 */, U64_C(0xd4effb9c9b1cc21a) /* 370 */, U64_C(0x99727d26f494f7ab) /* 371 */, U64_C(0xa3e063a2956b3e03) /* 372 */, U64_C(0x9d4a8b9a4aa09c30) /* 373 */, U64_C(0x3f6ab7d500090fb4) /* 374 */, U64_C(0x9cc0f2a057268ac0) /* 375 */, U64_C(0x3dee9d2dedbf42d1) /* 376 */, U64_C(0x330f49c87960a972) /* 377 */, U64_C(0xc6b2720287421b41) /* 378 */, U64_C(0x0ac59ec07c00369c) /* 379 */, U64_C(0xef4eac49cb353425) /* 380 */, U64_C(0xf450244eef0129d8) /* 381 */, U64_C(0x8acc46e5caf4deb6) /* 382 */, U64_C(0x2ffeab63989263f7) /* 383 */, U64_C(0x8f7cb9fe5d7a4578) /* 384 */, U64_C(0x5bd8f7644e634635) /* 385 */, U64_C(0x427a7315bf2dc900) /* 386 */, U64_C(0x17d0c4aa2125261c) /* 387 */, U64_C(0x3992486c93518e50) /* 388 */, U64_C(0xb4cbfee0a2d7d4c3) /* 389 */, U64_C(0x7c75d6202c5ddd8d) /* 390 */, U64_C(0xdbc295d8e35b6c61) /* 391 */, U64_C(0x60b369d302032b19) /* 392 */, U64_C(0xce42685fdce44132) /* 393 */, U64_C(0x06f3ddb9ddf65610) /* 394 */, U64_C(0x8ea4d21db5e148f0) /* 395 */, U64_C(0x20b0fce62fcd496f) /* 396 */, U64_C(0x2c1b912358b0ee31) /* 397 */, U64_C(0xb28317b818f5a308) /* 398 */, U64_C(0xa89c1e189ca6d2cf) /* 399 */, U64_C(0x0c6b18576aaadbc8) /* 400 */, U64_C(0xb65deaa91299fae3) /* 401 */, U64_C(0xfb2b794b7f1027e7) /* 402 */, U64_C(0x04e4317f443b5beb) /* 403 */, U64_C(0x4b852d325939d0a6) /* 404 */, U64_C(0xd5ae6beefb207ffc) /* 405 */, U64_C(0x309682b281c7d374) /* 406 */, U64_C(0xbae309a194c3b475) /* 407 */, U64_C(0x8cc3f97b13b49f05) /* 408 */, U64_C(0x98a9422ff8293967) /* 409 */, U64_C(0x244b16b01076ff7c) /* 410 */, U64_C(0xf8bf571c663d67ee) /* 411 */, U64_C(0x1f0d6758eee30da1) /* 412 */, U64_C(0xc9b611d97adeb9b7) /* 413 */, U64_C(0xb7afd5887b6c57a2) /* 414 */, U64_C(0x6290ae846b984fe1) /* 415 */, U64_C(0x94df4cdeacc1a5fd) /* 416 */, U64_C(0x058a5bd1c5483aff) /* 417 */, U64_C(0x63166cc142ba3c37) /* 418 */, U64_C(0x8db8526eb2f76f40) /* 419 */, U64_C(0xe10880036f0d6d4e) /* 420 */, U64_C(0x9e0523c9971d311d) /* 421 */, U64_C(0x45ec2824cc7cd691) /* 422 */, U64_C(0x575b8359e62382c9) /* 423 */, U64_C(0xfa9e400dc4889995) /* 424 */, U64_C(0xd1823ecb45721568) /* 425 */, U64_C(0xdafd983b8206082f) /* 426 */, U64_C(0xaa7d29082386a8cb) /* 427 */, U64_C(0x269fcd4403b87588) /* 428 */, U64_C(0x1b91f5f728bdd1e0) /* 429 */, U64_C(0xe4669f39040201f6) /* 430 */, U64_C(0x7a1d7c218cf04ade) /* 431 */, U64_C(0x65623c29d79ce5ce) /* 432 */, U64_C(0x2368449096c00bb1) /* 433 */, U64_C(0xab9bf1879da503ba) /* 434 */, U64_C(0xbc23ecb1a458058e) /* 435 */, U64_C(0x9a58df01bb401ecc) /* 436 */, U64_C(0xa070e868a85f143d) /* 437 */, U64_C(0x4ff188307df2239e) /* 438 */, U64_C(0x14d565b41a641183) /* 439 */, U64_C(0xee13337452701602) /* 440 */, U64_C(0x950e3dcf3f285e09) /* 441 */, U64_C(0x59930254b9c80953) /* 442 */, U64_C(0x3bf299408930da6d) /* 443 */, U64_C(0xa955943f53691387) /* 444 */, U64_C(0xa15edecaa9cb8784) /* 445 */, U64_C(0x29142127352be9a0) /* 446 */, U64_C(0x76f0371fff4e7afb) /* 447 */, U64_C(0x0239f450274f2228) /* 448 */, U64_C(0xbb073af01d5e868b) /* 449 */, U64_C(0xbfc80571c10e96c1) /* 450 */, U64_C(0xd267088568222e23) /* 451 */, U64_C(0x9671a3d48e80b5b0) /* 452 */, U64_C(0x55b5d38ae193bb81) /* 453 */, U64_C(0x693ae2d0a18b04b8) /* 454 */, U64_C(0x5c48b4ecadd5335f) /* 455 */, U64_C(0xfd743b194916a1ca) /* 456 */, U64_C(0x2577018134be98c4) /* 457 */, U64_C(0xe77987e83c54a4ad) /* 458 */, U64_C(0x28e11014da33e1b9) /* 459 */, U64_C(0x270cc59e226aa213) /* 460 */, U64_C(0x71495f756d1a5f60) /* 461 */, U64_C(0x9be853fb60afef77) /* 462 */, U64_C(0xadc786a7f7443dbf) /* 463 */, U64_C(0x0904456173b29a82) /* 464 */, U64_C(0x58bc7a66c232bd5e) /* 465 */, U64_C(0xf306558c673ac8b2) /* 466 */, U64_C(0x41f639c6b6c9772a) /* 467 */, U64_C(0x216defe99fda35da) /* 468 */, U64_C(0x11640cc71c7be615) /* 469 */, U64_C(0x93c43694565c5527) /* 470 */, U64_C(0xea038e6246777839) /* 471 */, U64_C(0xf9abf3ce5a3e2469) /* 472 */, U64_C(0x741e768d0fd312d2) /* 473 */, U64_C(0x0144b883ced652c6) /* 474 */, U64_C(0xc20b5a5ba33f8552) /* 475 */, U64_C(0x1ae69633c3435a9d) /* 476 */, U64_C(0x97a28ca4088cfdec) /* 477 */, U64_C(0x8824a43c1e96f420) /* 478 */, U64_C(0x37612fa66eeea746) /* 479 */, U64_C(0x6b4cb165f9cf0e5a) /* 480 */, U64_C(0x43aa1c06a0abfb4a) /* 481 */, U64_C(0x7f4dc26ff162796b) /* 482 */, U64_C(0x6cbacc8e54ed9b0f) /* 483 */, U64_C(0xa6b7ffefd2bb253e) /* 484 */, U64_C(0x2e25bc95b0a29d4f) /* 485 */, U64_C(0x86d6a58bdef1388c) /* 486 */, U64_C(0xded74ac576b6f054) /* 487 */, U64_C(0x8030bdbc2b45805d) /* 488 */, U64_C(0x3c81af70e94d9289) /* 489 */, U64_C(0x3eff6dda9e3100db) /* 490 */, U64_C(0xb38dc39fdfcc8847) /* 491 */, U64_C(0x123885528d17b87e) /* 492 */, U64_C(0xf2da0ed240b1b642) /* 493 */, U64_C(0x44cefadcd54bf9a9) /* 494 */, U64_C(0x1312200e433c7ee6) /* 495 */, U64_C(0x9ffcc84f3a78c748) /* 496 */, U64_C(0xf0cd1f72248576bb) /* 497 */, U64_C(0xec6974053638cfe4) /* 498 */, U64_C(0x2ba7b67c0cec4e4c) /* 499 */, U64_C(0xac2f4df3e5ce32ed) /* 500 */, U64_C(0xcb33d14326ea4c11) /* 501 */, U64_C(0xa4e9044cc77e58bc) /* 502 */, U64_C(0x5f513293d934fcef) /* 503 */, U64_C(0x5dc9645506e55444) /* 504 */, U64_C(0x50de418f317de40a) /* 505 */, U64_C(0x388cb31a69dde259) /* 506 */, U64_C(0x2db4a83455820a86) /* 507 */, U64_C(0x9010a91e84711ae9) /* 508 */, U64_C(0x4df7f0b7b1498371) /* 509 */, U64_C(0xd62a2eabc0977179) /* 510 */, U64_C(0x22fac097aa8d5c0e) /* 511 */ }; static u64 sbox3[256] = { U64_C(0xf49fcc2ff1daf39b) /* 512 */, U64_C(0x487fd5c66ff29281) /* 513 */, U64_C(0xe8a30667fcdca83f) /* 514 */, U64_C(0x2c9b4be3d2fcce63) /* 515 */, U64_C(0xda3ff74b93fbbbc2) /* 516 */, U64_C(0x2fa165d2fe70ba66) /* 517 */, U64_C(0xa103e279970e93d4) /* 518 */, U64_C(0xbecdec77b0e45e71) /* 519 */, U64_C(0xcfb41e723985e497) /* 520 */, U64_C(0xb70aaa025ef75017) /* 521 */, U64_C(0xd42309f03840b8e0) /* 522 */, U64_C(0x8efc1ad035898579) /* 523 */, U64_C(0x96c6920be2b2abc5) /* 524 */, U64_C(0x66af4163375a9172) /* 525 */, U64_C(0x2174abdcca7127fb) /* 526 */, U64_C(0xb33ccea64a72ff41) /* 527 */, U64_C(0xf04a4933083066a5) /* 528 */, U64_C(0x8d970acdd7289af5) /* 529 */, U64_C(0x8f96e8e031c8c25e) /* 530 */, U64_C(0xf3fec02276875d47) /* 531 */, U64_C(0xec7bf310056190dd) /* 532 */, U64_C(0xf5adb0aebb0f1491) /* 533 */, U64_C(0x9b50f8850fd58892) /* 534 */, U64_C(0x4975488358b74de8) /* 535 */, U64_C(0xa3354ff691531c61) /* 536 */, U64_C(0x0702bbe481d2c6ee) /* 537 */, U64_C(0x89fb24057deded98) /* 538 */, U64_C(0xac3075138596e902) /* 539 */, U64_C(0x1d2d3580172772ed) /* 540 */, U64_C(0xeb738fc28e6bc30d) /* 541 */, U64_C(0x5854ef8f63044326) /* 542 */, U64_C(0x9e5c52325add3bbe) /* 543 */, U64_C(0x90aa53cf325c4623) /* 544 */, U64_C(0xc1d24d51349dd067) /* 545 */, U64_C(0x2051cfeea69ea624) /* 546 */, U64_C(0x13220f0a862e7e4f) /* 547 */, U64_C(0xce39399404e04864) /* 548 */, U64_C(0xd9c42ca47086fcb7) /* 549 */, U64_C(0x685ad2238a03e7cc) /* 550 */, U64_C(0x066484b2ab2ff1db) /* 551 */, U64_C(0xfe9d5d70efbf79ec) /* 552 */, U64_C(0x5b13b9dd9c481854) /* 553 */, U64_C(0x15f0d475ed1509ad) /* 554 */, U64_C(0x0bebcd060ec79851) /* 555 */, U64_C(0xd58c6791183ab7f8) /* 556 */, U64_C(0xd1187c5052f3eee4) /* 557 */, U64_C(0xc95d1192e54e82ff) /* 558 */, U64_C(0x86eea14cb9ac6ca2) /* 559 */, U64_C(0x3485beb153677d5d) /* 560 */, U64_C(0xdd191d781f8c492a) /* 561 */, U64_C(0xf60866baa784ebf9) /* 562 */, U64_C(0x518f643ba2d08c74) /* 563 */, U64_C(0x8852e956e1087c22) /* 564 */, U64_C(0xa768cb8dc410ae8d) /* 565 */, U64_C(0x38047726bfec8e1a) /* 566 */, U64_C(0xa67738b4cd3b45aa) /* 567 */, U64_C(0xad16691cec0dde19) /* 568 */, U64_C(0xc6d4319380462e07) /* 569 */, U64_C(0xc5a5876d0ba61938) /* 570 */, U64_C(0x16b9fa1fa58fd840) /* 571 */, U64_C(0x188ab1173ca74f18) /* 572 */, U64_C(0xabda2f98c99c021f) /* 573 */, U64_C(0x3e0580ab134ae816) /* 574 */, U64_C(0x5f3b05b773645abb) /* 575 */, U64_C(0x2501a2be5575f2f6) /* 576 */, U64_C(0x1b2f74004e7e8ba9) /* 577 */, U64_C(0x1cd7580371e8d953) /* 578 */, U64_C(0x7f6ed89562764e30) /* 579 */, U64_C(0xb15926ff596f003d) /* 580 */, U64_C(0x9f65293da8c5d6b9) /* 581 */, U64_C(0x6ecef04dd690f84c) /* 582 */, U64_C(0x4782275fff33af88) /* 583 */, U64_C(0xe41433083f820801) /* 584 */, U64_C(0xfd0dfe409a1af9b5) /* 585 */, U64_C(0x4325a3342cdb396b) /* 586 */, U64_C(0x8ae77e62b301b252) /* 587 */, U64_C(0xc36f9e9f6655615a) /* 588 */, U64_C(0x85455a2d92d32c09) /* 589 */, U64_C(0xf2c7dea949477485) /* 590 */, U64_C(0x63cfb4c133a39eba) /* 591 */, U64_C(0x83b040cc6ebc5462) /* 592 */, U64_C(0x3b9454c8fdb326b0) /* 593 */, U64_C(0x56f56a9e87ffd78c) /* 594 */, U64_C(0x2dc2940d99f42bc6) /* 595 */, U64_C(0x98f7df096b096e2d) /* 596 */, U64_C(0x19a6e01e3ad852bf) /* 597 */, U64_C(0x42a99ccbdbd4b40b) /* 598 */, U64_C(0xa59998af45e9c559) /* 599 */, U64_C(0x366295e807d93186) /* 600 */, U64_C(0x6b48181bfaa1f773) /* 601 */, U64_C(0x1fec57e2157a0a1d) /* 602 */, U64_C(0x4667446af6201ad5) /* 603 */, U64_C(0xe615ebcacfb0f075) /* 604 */, U64_C(0xb8f31f4f68290778) /* 605 */, U64_C(0x22713ed6ce22d11e) /* 606 */, U64_C(0x3057c1a72ec3c93b) /* 607 */, U64_C(0xcb46acc37c3f1f2f) /* 608 */, U64_C(0xdbb893fd02aaf50e) /* 609 */, U64_C(0x331fd92e600b9fcf) /* 610 */, U64_C(0xa498f96148ea3ad6) /* 611 */, U64_C(0xa8d8426e8b6a83ea) /* 612 */, U64_C(0xa089b274b7735cdc) /* 613 */, U64_C(0x87f6b3731e524a11) /* 614 */, U64_C(0x118808e5cbc96749) /* 615 */, U64_C(0x9906e4c7b19bd394) /* 616 */, U64_C(0xafed7f7e9b24a20c) /* 617 */, U64_C(0x6509eadeeb3644a7) /* 618 */, U64_C(0x6c1ef1d3e8ef0ede) /* 619 */, U64_C(0xb9c97d43e9798fb4) /* 620 */, U64_C(0xa2f2d784740c28a3) /* 621 */, U64_C(0x7b8496476197566f) /* 622 */, U64_C(0x7a5be3e6b65f069d) /* 623 */, U64_C(0xf96330ed78be6f10) /* 624 */, U64_C(0xeee60de77a076a15) /* 625 */, U64_C(0x2b4bee4aa08b9bd0) /* 626 */, U64_C(0x6a56a63ec7b8894e) /* 627 */, U64_C(0x02121359ba34fef4) /* 628 */, U64_C(0x4cbf99f8283703fc) /* 629 */, U64_C(0x398071350caf30c8) /* 630 */, U64_C(0xd0a77a89f017687a) /* 631 */, U64_C(0xf1c1a9eb9e423569) /* 632 */, U64_C(0x8c7976282dee8199) /* 633 */, U64_C(0x5d1737a5dd1f7abd) /* 634 */, U64_C(0x4f53433c09a9fa80) /* 635 */, U64_C(0xfa8b0c53df7ca1d9) /* 636 */, U64_C(0x3fd9dcbc886ccb77) /* 637 */, U64_C(0xc040917ca91b4720) /* 638 */, U64_C(0x7dd00142f9d1dcdf) /* 639 */, U64_C(0x8476fc1d4f387b58) /* 640 */, U64_C(0x23f8e7c5f3316503) /* 641 */, U64_C(0x032a2244e7e37339) /* 642 */, U64_C(0x5c87a5d750f5a74b) /* 643 */, U64_C(0x082b4cc43698992e) /* 644 */, U64_C(0xdf917becb858f63c) /* 645 */, U64_C(0x3270b8fc5bf86dda) /* 646 */, U64_C(0x10ae72bb29b5dd76) /* 647 */, U64_C(0x576ac94e7700362b) /* 648 */, U64_C(0x1ad112dac61efb8f) /* 649 */, U64_C(0x691bc30ec5faa427) /* 650 */, U64_C(0xff246311cc327143) /* 651 */, U64_C(0x3142368e30e53206) /* 652 */, U64_C(0x71380e31e02ca396) /* 653 */, U64_C(0x958d5c960aad76f1) /* 654 */, U64_C(0xf8d6f430c16da536) /* 655 */, U64_C(0xc8ffd13f1be7e1d2) /* 656 */, U64_C(0x7578ae66004ddbe1) /* 657 */, U64_C(0x05833f01067be646) /* 658 */, U64_C(0xbb34b5ad3bfe586d) /* 659 */, U64_C(0x095f34c9a12b97f0) /* 660 */, U64_C(0x247ab64525d60ca8) /* 661 */, U64_C(0xdcdbc6f3017477d1) /* 662 */, U64_C(0x4a2e14d4decad24d) /* 663 */, U64_C(0xbdb5e6d9be0a1eeb) /* 664 */, U64_C(0x2a7e70f7794301ab) /* 665 */, U64_C(0xdef42d8a270540fd) /* 666 */, U64_C(0x01078ec0a34c22c1) /* 667 */, U64_C(0xe5de511af4c16387) /* 668 */, U64_C(0x7ebb3a52bd9a330a) /* 669 */, U64_C(0x77697857aa7d6435) /* 670 */, U64_C(0x004e831603ae4c32) /* 671 */, U64_C(0xe7a21020ad78e312) /* 672 */, U64_C(0x9d41a70c6ab420f2) /* 673 */, U64_C(0x28e06c18ea1141e6) /* 674 */, U64_C(0xd2b28cbd984f6b28) /* 675 */, U64_C(0x26b75f6c446e9d83) /* 676 */, U64_C(0xba47568c4d418d7f) /* 677 */, U64_C(0xd80badbfe6183d8e) /* 678 */, U64_C(0x0e206d7f5f166044) /* 679 */, U64_C(0xe258a43911cbca3e) /* 680 */, U64_C(0x723a1746b21dc0bc) /* 681 */, U64_C(0xc7caa854f5d7cdd3) /* 682 */, U64_C(0x7cac32883d261d9c) /* 683 */, U64_C(0x7690c26423ba942c) /* 684 */, U64_C(0x17e55524478042b8) /* 685 */, U64_C(0xe0be477656a2389f) /* 686 */, U64_C(0x4d289b5e67ab2da0) /* 687 */, U64_C(0x44862b9c8fbbfd31) /* 688 */, U64_C(0xb47cc8049d141365) /* 689 */, U64_C(0x822c1b362b91c793) /* 690 */, U64_C(0x4eb14655fb13dfd8) /* 691 */, U64_C(0x1ecbba0714e2a97b) /* 692 */, U64_C(0x6143459d5cde5f14) /* 693 */, U64_C(0x53a8fbf1d5f0ac89) /* 694 */, U64_C(0x97ea04d81c5e5b00) /* 695 */, U64_C(0x622181a8d4fdb3f3) /* 696 */, U64_C(0xe9bcd341572a1208) /* 697 */, U64_C(0x1411258643cce58a) /* 698 */, U64_C(0x9144c5fea4c6e0a4) /* 699 */, U64_C(0x0d33d06565cf620f) /* 700 */, U64_C(0x54a48d489f219ca1) /* 701 */, U64_C(0xc43e5eac6d63c821) /* 702 */, U64_C(0xa9728b3a72770daf) /* 703 */, U64_C(0xd7934e7b20df87ef) /* 704 */, U64_C(0xe35503b61a3e86e5) /* 705 */, U64_C(0xcae321fbc819d504) /* 706 */, U64_C(0x129a50b3ac60bfa6) /* 707 */, U64_C(0xcd5e68ea7e9fb6c3) /* 708 */, U64_C(0xb01c90199483b1c7) /* 709 */, U64_C(0x3de93cd5c295376c) /* 710 */, U64_C(0xaed52edf2ab9ad13) /* 711 */, U64_C(0x2e60f512c0a07884) /* 712 */, U64_C(0xbc3d86a3e36210c9) /* 713 */, U64_C(0x35269d9b163951ce) /* 714 */, U64_C(0x0c7d6e2ad0cdb5fa) /* 715 */, U64_C(0x59e86297d87f5733) /* 716 */, U64_C(0x298ef221898db0e7) /* 717 */, U64_C(0x55000029d1a5aa7e) /* 718 */, U64_C(0x8bc08ae1b5061b45) /* 719 */, U64_C(0xc2c31c2b6c92703a) /* 720 */, U64_C(0x94cc596baf25ef42) /* 721 */, U64_C(0x0a1d73db22540456) /* 722 */, U64_C(0x04b6a0f9d9c4179a) /* 723 */, U64_C(0xeffdafa2ae3d3c60) /* 724 */, U64_C(0xf7c8075bb49496c4) /* 725 */, U64_C(0x9cc5c7141d1cd4e3) /* 726 */, U64_C(0x78bd1638218e5534) /* 727 */, U64_C(0xb2f11568f850246a) /* 728 */, U64_C(0xedfabcfa9502bc29) /* 729 */, U64_C(0x796ce5f2da23051b) /* 730 */, U64_C(0xaae128b0dc93537c) /* 731 */, U64_C(0x3a493da0ee4b29ae) /* 732 */, U64_C(0xb5df6b2c416895d7) /* 733 */, U64_C(0xfcabbd25122d7f37) /* 734 */, U64_C(0x70810b58105dc4b1) /* 735 */, U64_C(0xe10fdd37f7882a90) /* 736 */, U64_C(0x524dcab5518a3f5c) /* 737 */, U64_C(0x3c9e85878451255b) /* 738 */, U64_C(0x4029828119bd34e2) /* 739 */, U64_C(0x74a05b6f5d3ceccb) /* 740 */, U64_C(0xb610021542e13eca) /* 741 */, U64_C(0x0ff979d12f59e2ac) /* 742 */, U64_C(0x6037da27e4f9cc50) /* 743 */, U64_C(0x5e92975a0df1847d) /* 744 */, U64_C(0xd66de190d3e623fe) /* 745 */, U64_C(0x5032d6b87b568048) /* 746 */, U64_C(0x9a36b7ce8235216e) /* 747 */, U64_C(0x80272a7a24f64b4a) /* 748 */, U64_C(0x93efed8b8c6916f7) /* 749 */, U64_C(0x37ddbff44cce1555) /* 750 */, U64_C(0x4b95db5d4b99bd25) /* 751 */, U64_C(0x92d3fda169812fc0) /* 752 */, U64_C(0xfb1a4a9a90660bb6) /* 753 */, U64_C(0x730c196946a4b9b2) /* 754 */, U64_C(0x81e289aa7f49da68) /* 755 */, U64_C(0x64669a0f83b1a05f) /* 756 */, U64_C(0x27b3ff7d9644f48b) /* 757 */, U64_C(0xcc6b615c8db675b3) /* 758 */, U64_C(0x674f20b9bcebbe95) /* 759 */, U64_C(0x6f31238275655982) /* 760 */, U64_C(0x5ae488713e45cf05) /* 761 */, U64_C(0xbf619f9954c21157) /* 762 */, U64_C(0xeabac46040a8eae9) /* 763 */, U64_C(0x454c6fe9f2c0c1cd) /* 764 */, U64_C(0x419cf6496412691c) /* 765 */, U64_C(0xd3dc3bef265b0f70) /* 766 */, U64_C(0x6d0e60f5c3578a9e) /* 767 */ }; static u64 sbox4[256] = { U64_C(0x5b0e608526323c55) /* 768 */, U64_C(0x1a46c1a9fa1b59f5) /* 769 */, U64_C(0xa9e245a17c4c8ffa) /* 770 */, U64_C(0x65ca5159db2955d7) /* 771 */, U64_C(0x05db0a76ce35afc2) /* 772 */, U64_C(0x81eac77ea9113d45) /* 773 */, U64_C(0x528ef88ab6ac0a0d) /* 774 */, U64_C(0xa09ea253597be3ff) /* 775 */, U64_C(0x430ddfb3ac48cd56) /* 776 */, U64_C(0xc4b3a67af45ce46f) /* 777 */, U64_C(0x4ececfd8fbe2d05e) /* 778 */, U64_C(0x3ef56f10b39935f0) /* 779 */, U64_C(0x0b22d6829cd619c6) /* 780 */, U64_C(0x17fd460a74df2069) /* 781 */, U64_C(0x6cf8cc8e8510ed40) /* 782 */, U64_C(0xd6c824bf3a6ecaa7) /* 783 */, U64_C(0x61243d581a817049) /* 784 */, U64_C(0x048bacb6bbc163a2) /* 785 */, U64_C(0xd9a38ac27d44cc32) /* 786 */, U64_C(0x7fddff5baaf410ab) /* 787 */, U64_C(0xad6d495aa804824b) /* 788 */, U64_C(0xe1a6a74f2d8c9f94) /* 789 */, U64_C(0xd4f7851235dee8e3) /* 790 */, U64_C(0xfd4b7f886540d893) /* 791 */, U64_C(0x247c20042aa4bfda) /* 792 */, U64_C(0x096ea1c517d1327c) /* 793 */, U64_C(0xd56966b4361a6685) /* 794 */, U64_C(0x277da5c31221057d) /* 795 */, U64_C(0x94d59893a43acff7) /* 796 */, U64_C(0x64f0c51ccdc02281) /* 797 */, U64_C(0x3d33bcc4ff6189db) /* 798 */, U64_C(0xe005cb184ce66af1) /* 799 */, U64_C(0xff5ccd1d1db99bea) /* 800 */, U64_C(0xb0b854a7fe42980f) /* 801 */, U64_C(0x7bd46a6a718d4b9f) /* 802 */, U64_C(0xd10fa8cc22a5fd8c) /* 803 */, U64_C(0xd31484952be4bd31) /* 804 */, U64_C(0xc7fa975fcb243847) /* 805 */, U64_C(0x4886ed1e5846c407) /* 806 */, U64_C(0x28cddb791eb70b04) /* 807 */, U64_C(0xc2b00be2f573417f) /* 808 */, U64_C(0x5c9590452180f877) /* 809 */, U64_C(0x7a6bddfff370eb00) /* 810 */, U64_C(0xce509e38d6d9d6a4) /* 811 */, U64_C(0xebeb0f00647fa702) /* 812 */, U64_C(0x1dcc06cf76606f06) /* 813 */, U64_C(0xe4d9f28ba286ff0a) /* 814 */, U64_C(0xd85a305dc918c262) /* 815 */, U64_C(0x475b1d8732225f54) /* 816 */, U64_C(0x2d4fb51668ccb5fe) /* 817 */, U64_C(0xa679b9d9d72bba20) /* 818 */, U64_C(0x53841c0d912d43a5) /* 819 */, U64_C(0x3b7eaa48bf12a4e8) /* 820 */, U64_C(0x781e0e47f22f1ddf) /* 821 */, U64_C(0xeff20ce60ab50973) /* 822 */, U64_C(0x20d261d19dffb742) /* 823 */, U64_C(0x16a12b03062a2e39) /* 824 */, U64_C(0x1960eb2239650495) /* 825 */, U64_C(0x251c16fed50eb8b8) /* 826 */, U64_C(0x9ac0c330f826016e) /* 827 */, U64_C(0xed152665953e7671) /* 828 */, U64_C(0x02d63194a6369570) /* 829 */, U64_C(0x5074f08394b1c987) /* 830 */, U64_C(0x70ba598c90b25ce1) /* 831 */, U64_C(0x794a15810b9742f6) /* 832 */, U64_C(0x0d5925e9fcaf8c6c) /* 833 */, U64_C(0x3067716cd868744e) /* 834 */, U64_C(0x910ab077e8d7731b) /* 835 */, U64_C(0x6a61bbdb5ac42f61) /* 836 */, U64_C(0x93513efbf0851567) /* 837 */, U64_C(0xf494724b9e83e9d5) /* 838 */, U64_C(0xe887e1985c09648d) /* 839 */, U64_C(0x34b1d3c675370cfd) /* 840 */, U64_C(0xdc35e433bc0d255d) /* 841 */, U64_C(0xd0aab84234131be0) /* 842 */, U64_C(0x08042a50b48b7eaf) /* 843 */, U64_C(0x9997c4ee44a3ab35) /* 844 */, U64_C(0x829a7b49201799d0) /* 845 */, U64_C(0x263b8307b7c54441) /* 846 */, U64_C(0x752f95f4fd6a6ca6) /* 847 */, U64_C(0x927217402c08c6e5) /* 848 */, U64_C(0x2a8ab754a795d9ee) /* 849 */, U64_C(0xa442f7552f72943d) /* 850 */, U64_C(0x2c31334e19781208) /* 851 */, U64_C(0x4fa98d7ceaee6291) /* 852 */, U64_C(0x55c3862f665db309) /* 853 */, U64_C(0xbd0610175d53b1f3) /* 854 */, U64_C(0x46fe6cb840413f27) /* 855 */, U64_C(0x3fe03792df0cfa59) /* 856 */, U64_C(0xcfe700372eb85e8f) /* 857 */, U64_C(0xa7be29e7adbce118) /* 858 */, U64_C(0xe544ee5cde8431dd) /* 859 */, U64_C(0x8a781b1b41f1873e) /* 860 */, U64_C(0xa5c94c78a0d2f0e7) /* 861 */, U64_C(0x39412e2877b60728) /* 862 */, U64_C(0xa1265ef3afc9a62c) /* 863 */, U64_C(0xbcc2770c6a2506c5) /* 864 */, U64_C(0x3ab66dd5dce1ce12) /* 865 */, U64_C(0xe65499d04a675b37) /* 866 */, U64_C(0x7d8f523481bfd216) /* 867 */, U64_C(0x0f6f64fcec15f389) /* 868 */, U64_C(0x74efbe618b5b13c8) /* 869 */, U64_C(0xacdc82b714273e1d) /* 870 */, U64_C(0xdd40bfe003199d17) /* 871 */, U64_C(0x37e99257e7e061f8) /* 872 */, U64_C(0xfa52626904775aaa) /* 873 */, U64_C(0x8bbbf63a463d56f9) /* 874 */, U64_C(0xf0013f1543a26e64) /* 875 */, U64_C(0xa8307e9f879ec898) /* 876 */, U64_C(0xcc4c27a4150177cc) /* 877 */, U64_C(0x1b432f2cca1d3348) /* 878 */, U64_C(0xde1d1f8f9f6fa013) /* 879 */, U64_C(0x606602a047a7ddd6) /* 880 */, U64_C(0xd237ab64cc1cb2c7) /* 881 */, U64_C(0x9b938e7225fcd1d3) /* 882 */, U64_C(0xec4e03708e0ff476) /* 883 */, U64_C(0xfeb2fbda3d03c12d) /* 884 */, U64_C(0xae0bced2ee43889a) /* 885 */, U64_C(0x22cb8923ebfb4f43) /* 886 */, U64_C(0x69360d013cf7396d) /* 887 */, U64_C(0x855e3602d2d4e022) /* 888 */, U64_C(0x073805bad01f784c) /* 889 */, U64_C(0x33e17a133852f546) /* 890 */, U64_C(0xdf4874058ac7b638) /* 891 */, U64_C(0xba92b29c678aa14a) /* 892 */, U64_C(0x0ce89fc76cfaadcd) /* 893 */, U64_C(0x5f9d4e0908339e34) /* 894 */, U64_C(0xf1afe9291f5923b9) /* 895 */, U64_C(0x6e3480f60f4a265f) /* 896 */, U64_C(0xeebf3a2ab29b841c) /* 897 */, U64_C(0xe21938a88f91b4ad) /* 898 */, U64_C(0x57dfeff845c6d3c3) /* 899 */, U64_C(0x2f006b0bf62caaf2) /* 900 */, U64_C(0x62f479ef6f75ee78) /* 901 */, U64_C(0x11a55ad41c8916a9) /* 902 */, U64_C(0xf229d29084fed453) /* 903 */, U64_C(0x42f1c27b16b000e6) /* 904 */, U64_C(0x2b1f76749823c074) /* 905 */, U64_C(0x4b76eca3c2745360) /* 906 */, U64_C(0x8c98f463b91691bd) /* 907 */, U64_C(0x14bcc93cf1ade66a) /* 908 */, U64_C(0x8885213e6d458397) /* 909 */, U64_C(0x8e177df0274d4711) /* 910 */, U64_C(0xb49b73b5503f2951) /* 911 */, U64_C(0x10168168c3f96b6b) /* 912 */, U64_C(0x0e3d963b63cab0ae) /* 913 */, U64_C(0x8dfc4b5655a1db14) /* 914 */, U64_C(0xf789f1356e14de5c) /* 915 */, U64_C(0x683e68af4e51dac1) /* 916 */, U64_C(0xc9a84f9d8d4b0fd9) /* 917 */, U64_C(0x3691e03f52a0f9d1) /* 918 */, U64_C(0x5ed86e46e1878e80) /* 919 */, U64_C(0x3c711a0e99d07150) /* 920 */, U64_C(0x5a0865b20c4e9310) /* 921 */, U64_C(0x56fbfc1fe4f0682e) /* 922 */, U64_C(0xea8d5de3105edf9b) /* 923 */, U64_C(0x71abfdb12379187a) /* 924 */, U64_C(0x2eb99de1bee77b9c) /* 925 */, U64_C(0x21ecc0ea33cf4523) /* 926 */, U64_C(0x59a4d7521805c7a1) /* 927 */, U64_C(0x3896f5eb56ae7c72) /* 928 */, U64_C(0xaa638f3db18f75dc) /* 929 */, U64_C(0x9f39358dabe9808e) /* 930 */, U64_C(0xb7defa91c00b72ac) /* 931 */, U64_C(0x6b5541fd62492d92) /* 932 */, U64_C(0x6dc6dee8f92e4d5b) /* 933 */, U64_C(0x353f57abc4beea7e) /* 934 */, U64_C(0x735769d6da5690ce) /* 935 */, U64_C(0x0a234aa642391484) /* 936 */, U64_C(0xf6f9508028f80d9d) /* 937 */, U64_C(0xb8e319a27ab3f215) /* 938 */, U64_C(0x31ad9c1151341a4d) /* 939 */, U64_C(0x773c22a57bef5805) /* 940 */, U64_C(0x45c7561a07968633) /* 941 */, U64_C(0xf913da9e249dbe36) /* 942 */, U64_C(0xda652d9b78a64c68) /* 943 */, U64_C(0x4c27a97f3bc334ef) /* 944 */, U64_C(0x76621220e66b17f4) /* 945 */, U64_C(0x967743899acd7d0b) /* 946 */, U64_C(0xf3ee5bcae0ed6782) /* 947 */, U64_C(0x409f753600c879fc) /* 948 */, U64_C(0x06d09a39b5926db6) /* 949 */, U64_C(0x6f83aeb0317ac588) /* 950 */, U64_C(0x01e6ca4a86381f21) /* 951 */, U64_C(0x66ff3462d19f3025) /* 952 */, U64_C(0x72207c24ddfd3bfb) /* 953 */, U64_C(0x4af6b6d3e2ece2eb) /* 954 */, U64_C(0x9c994dbec7ea08de) /* 955 */, U64_C(0x49ace597b09a8bc4) /* 956 */, U64_C(0xb38c4766cf0797ba) /* 957 */, U64_C(0x131b9373c57c2a75) /* 958 */, U64_C(0xb1822cce61931e58) /* 959 */, U64_C(0x9d7555b909ba1c0c) /* 960 */, U64_C(0x127fafdd937d11d2) /* 961 */, U64_C(0x29da3badc66d92e4) /* 962 */, U64_C(0xa2c1d57154c2ecbc) /* 963 */, U64_C(0x58c5134d82f6fe24) /* 964 */, U64_C(0x1c3ae3515b62274f) /* 965 */, U64_C(0xe907c82e01cb8126) /* 966 */, U64_C(0xf8ed091913e37fcb) /* 967 */, U64_C(0x3249d8f9c80046c9) /* 968 */, U64_C(0x80cf9bede388fb63) /* 969 */, U64_C(0x1881539a116cf19e) /* 970 */, U64_C(0x5103f3f76bd52457) /* 971 */, U64_C(0x15b7e6f5ae47f7a8) /* 972 */, U64_C(0xdbd7c6ded47e9ccf) /* 973 */, U64_C(0x44e55c410228bb1a) /* 974 */, U64_C(0xb647d4255edb4e99) /* 975 */, U64_C(0x5d11882bb8aafc30) /* 976 */, U64_C(0xf5098bbb29d3212a) /* 977 */, U64_C(0x8fb5ea14e90296b3) /* 978 */, U64_C(0x677b942157dd025a) /* 979 */, U64_C(0xfb58e7c0a390acb5) /* 980 */, U64_C(0x89d3674c83bd4a01) /* 981 */, U64_C(0x9e2da4df4bf3b93b) /* 982 */, U64_C(0xfcc41e328cab4829) /* 983 */, U64_C(0x03f38c96ba582c52) /* 984 */, U64_C(0xcad1bdbd7fd85db2) /* 985 */, U64_C(0xbbb442c16082ae83) /* 986 */, U64_C(0xb95fe86ba5da9ab0) /* 987 */, U64_C(0xb22e04673771a93f) /* 988 */, U64_C(0x845358c9493152d8) /* 989 */, U64_C(0xbe2a488697b4541e) /* 990 */, U64_C(0x95a2dc2dd38e6966) /* 991 */, U64_C(0xc02c11ac923c852b) /* 992 */, U64_C(0x2388b1990df2a87b) /* 993 */, U64_C(0x7c8008fa1b4f37be) /* 994 */, U64_C(0x1f70d0c84d54e503) /* 995 */, U64_C(0x5490adec7ece57d4) /* 996 */, U64_C(0x002b3c27d9063a3a) /* 997 */, U64_C(0x7eaea3848030a2bf) /* 998 */, U64_C(0xc602326ded2003c0) /* 999 */, U64_C(0x83a7287d69a94086) /* 1000 */, U64_C(0xc57a5fcb30f57a8a) /* 1001 */, U64_C(0xb56844e479ebe779) /* 1002 */, U64_C(0xa373b40f05dcbce9) /* 1003 */, U64_C(0xd71a786e88570ee2) /* 1004 */, U64_C(0x879cbacdbde8f6a0) /* 1005 */, U64_C(0x976ad1bcc164a32f) /* 1006 */, U64_C(0xab21e25e9666d78b) /* 1007 */, U64_C(0x901063aae5e5c33c) /* 1008 */, U64_C(0x9818b34448698d90) /* 1009 */, U64_C(0xe36487ae3e1e8abb) /* 1010 */, U64_C(0xafbdf931893bdcb4) /* 1011 */, U64_C(0x6345a0dc5fbbd519) /* 1012 */, U64_C(0x8628fe269b9465ca) /* 1013 */, U64_C(0x1e5d01603f9c51ec) /* 1014 */, U64_C(0x4de44006a15049b7) /* 1015 */, U64_C(0xbf6c70e5f776cbb1) /* 1016 */, U64_C(0x411218f2ef552bed) /* 1017 */, U64_C(0xcb0c0708705a36a3) /* 1018 */, U64_C(0xe74d14754f986044) /* 1019 */, U64_C(0xcd56d9430ea8280e) /* 1020 */, U64_C(0xc12591d7535f5065) /* 1021 */, U64_C(0xc83223f1720aef96) /* 1022 */, U64_C(0xc3a0396f7363a51f) /* 1023 */ }; static unsigned int transform ( void *ctx, const unsigned char *data, size_t nblks ); static void do_init (void *context, int variant) { TIGER_CONTEXT *hd = context; hd->a = 0x0123456789abcdefLL; hd->b = 0xfedcba9876543210LL; hd->c = 0xf096a5b4c3b2e187LL; hd->bctx.nblocks = 0; hd->bctx.nblocks_high = 0; hd->bctx.count = 0; hd->bctx.blocksize = 64; hd->bctx.bwrite = transform; hd->variant = variant; } static void tiger_init (void *context, unsigned int flags) { (void)flags; do_init (context, 0); } static void tiger1_init (void *context, unsigned int flags) { (void)flags; do_init (context, 1); } static void tiger2_init (void *context, unsigned int flags) { (void)flags; do_init (context, 2); } #define tiger_round(xa, xb, xc, xx, xmul) { \ xc ^= xx; \ xa -= ( sbox1[ (xc) & 0xff ] ^ sbox2[ ((xc) >> 16) & 0xff ] \ ^ sbox3[ ((xc) >> 32) & 0xff ] ^ sbox4[ ((xc) >> 48) & 0xff ]); \ xb += ( sbox4[ ((xc) >> 8) & 0xff ] ^ sbox3[ ((xc) >> 24) & 0xff ] \ ^ sbox2[ ((xc) >> 40) & 0xff ] ^ sbox1[ ((xc) >> 56) & 0xff ]); \ xb *= xmul; } #define pass(ya, yb, yc, yx, ymul) { \ tiger_round( ya, yb, yc, yx[0], ymul ); \ tiger_round( yb, yc, ya, yx[1], ymul ); \ tiger_round( yc, ya, yb, yx[2], ymul ); \ tiger_round( ya, yb, yc, yx[3], ymul ); \ tiger_round( yb, yc, ya, yx[4], ymul ); \ tiger_round( yc, ya, yb, yx[5], ymul ); \ tiger_round( ya, yb, yc, yx[6], ymul ); \ tiger_round( yb, yc, ya, yx[7], ymul ); } #define key_schedule(x) { \ x[0] -= x[7] ^ 0xa5a5a5a5a5a5a5a5LL; \ x[1] ^= x[0]; \ x[2] += x[1]; \ x[3] -= x[2] ^ ((~x[1]) << 19 ); \ x[4] ^= x[3]; \ x[5] += x[4]; \ x[6] -= x[5] ^ ((~x[4]) >> 23 ); \ x[7] ^= x[6]; \ x[0] += x[7]; \ x[1] -= x[0] ^ ((~x[7]) << 19 ); \ x[2] ^= x[1]; \ x[3] += x[2]; \ x[4] -= x[3] ^ ((~x[2]) >> 23 ); \ x[5] ^= x[4]; \ x[6] += x[5]; \ x[7] -= x[6] ^ 0x0123456789abcdefLL; } /**************** * Transform the message DATA which consists of 512 bytes (8 words) */ static unsigned int transform_blk ( void *ctx, const unsigned char *data ) { TIGER_CONTEXT *hd = ctx; u64 a,b,c,aa,bb,cc; u64 x[8]; int i; for ( i = 0; i < 8; i++ ) x[i] = buf_get_le64(data + i * 8); /* save */ a = aa = hd->a; b = bb = hd->b; c = cc = hd->c; pass( a, b, c, x, 5); key_schedule( x ); pass( c, a, b, x, 7); key_schedule( x ); pass( b, c, a, x, 9); /* feedforward */ a ^= aa; b -= bb; c += cc; /* store */ hd->a = a; hd->b = b; hd->c = c; return /*burn_stack*/ 21*8+11*sizeof(void*); } static unsigned int transform ( void *c, const unsigned char *data, size_t nblks ) { unsigned int burn; do { burn = transform_blk (c, data); data += 64; } while (--nblks); return burn; } /* The routine terminates the computation */ static void tiger_final( void *context ) { TIGER_CONTEXT *hd = context; u32 t, th, msb, lsb; byte *p; unsigned int burn; byte pad = hd->variant == 2? 0x80 : 0x01; _gcry_md_block_write(hd, NULL, 0); /* flush */; t = hd->bctx.nblocks; if (sizeof t == sizeof hd->bctx.nblocks) th = hd->bctx.nblocks_high; else th = hd->bctx.nblocks >> 32; /* multiply by 64 to make a byte count */ lsb = t << 6; msb = (th << 6) | (t >> 26); /* add the count */ t = lsb; if( (lsb += hd->bctx.count) < t ) msb++; /* multiply by 8 to make a bit count */ t = lsb; lsb <<= 3; msb <<= 3; msb |= t >> 29; if( hd->bctx.count < 56 ) /* enough room */ { hd->bctx.buf[hd->bctx.count++] = pad; - while( hd->bctx.count < 56 ) - hd->bctx.buf[hd->bctx.count++] = 0; /* pad */ + if (hd->bctx.count < 56) + memset (&hd->bctx.buf[hd->bctx.count], 0, 56 - hd->bctx.count); + hd->bctx.count = 56; + /* append the 64 bit count */ + buf_put_le32(hd->bctx.buf + 56, lsb); + buf_put_le32(hd->bctx.buf + 60, msb); + burn = transform( hd, hd->bctx.buf, 1 ); } else /* need one extra block */ { hd->bctx.buf[hd->bctx.count++] = pad; /* pad character */ - while( hd->bctx.count < 64 ) - hd->bctx.buf[hd->bctx.count++] = 0; - _gcry_md_block_write(hd, NULL, 0); /* flush */; - memset(hd->bctx.buf, 0, 56 ); /* fill next block with zeroes */ + /* fill pad and next block with zeroes */ + memset (&hd->bctx.buf[hd->bctx.count], 0, 64 - hd->bctx.count + 56); + hd->bctx.count = 64 + 56; + + /* append the 64 bit count */ + buf_put_le32(hd->bctx.buf + 64 + 56, lsb); + buf_put_le32(hd->bctx.buf + 64 + 60, msb); + burn = transform( hd, hd->bctx.buf, 2 ); } - /* append the 64 bit count */ - buf_put_le32(hd->bctx.buf + 56, lsb); - buf_put_le32(hd->bctx.buf + 60, msb); - burn = transform( hd, hd->bctx.buf, 1 ); - _gcry_burn_stack (burn); p = hd->bctx.buf; #define X(a) do { buf_put_be64(p, hd->a); p += 8; } while(0) #define Y(a) do { buf_put_le64(p, hd->a); p += 8; } while(0) if (hd->variant == 0) { X(a); X(b); X(c); } else { Y(a); Y(b); Y(c); } #undef X #undef Y + + _gcry_burn_stack (burn); } static byte * tiger_read( void *context ) { TIGER_CONTEXT *hd = context; return hd->bctx.buf; } /* This is the old TIGER variant based on the unfixed reference implementation. IT was used in GnupG up to 1.3.2. We don't provide an OID anymore because that would not be correct. */ gcry_md_spec_t _gcry_digest_spec_tiger = { GCRY_MD_TIGER, {0, 0}, "TIGER192", NULL, 0, NULL, 24, tiger_init, _gcry_md_block_write, tiger_final, tiger_read, NULL, NULL, NULL, sizeof (TIGER_CONTEXT) }; /* This is the fixed TIGER implementation. */ static byte asn1[19] = /* Object ID is 1.3.6.1.4.1.11591.12.2 */ { 0x30, 0x29, 0x30, 0x0d, 0x06, 0x09, 0x2b, 0x06, 0x01, 0x04, 0x01, 0xda, 0x47, 0x0c, 0x02, 0x05, 0x00, 0x04, 0x18 }; static gcry_md_oid_spec_t oid_spec_tiger1[] = { /* GNU.digestAlgorithm TIGER */ { "1.3.6.1.4.1.11591.12.2" }, { NULL } }; gcry_md_spec_t _gcry_digest_spec_tiger1 = { GCRY_MD_TIGER1, {0, 0}, "TIGER", asn1, DIM (asn1), oid_spec_tiger1, 24, tiger1_init, _gcry_md_block_write, tiger_final, tiger_read, NULL, NULL, NULL, sizeof (TIGER_CONTEXT) }; /* This is TIGER2 which usues a changed padding algorithm. */ gcry_md_spec_t _gcry_digest_spec_tiger2 = { GCRY_MD_TIGER2, {0, 0}, "TIGER2", NULL, 0, NULL, 24, tiger2_init, _gcry_md_block_write, tiger_final, tiger_read, NULL, NULL, NULL, sizeof (TIGER_CONTEXT) }; diff --git a/cipher/whirlpool.c b/cipher/whirlpool.c index d52375ad..d9b79cf1 100644 --- a/cipher/whirlpool.c +++ b/cipher/whirlpool.c @@ -1,1531 +1,1535 @@ /* whirlpool.c - Whirlpool hashing algorithm * Copyright (C) 2005 Free Software Foundation, Inc. * * This file is part of Libgcrypt. * * Libgcrypt is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * Libgcrypt is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this program; if not, see . */ /* This is an implementation of the Whirlpool hashing algorithm, which has been developed by Vincent Rijmen and Paulo S. L. M. Barreto; it's homepage is located at: http://www.larc.usp.br/~pbarreto/WhirlpoolPage.html The S-Boxes and the structure of the main transformation function, which implements an optimized version of the algorithm, is taken from the reference implementation available from http://www.larc.usp.br/~pbarreto/whirlpool.zip */ #include #include #include #include #include "types.h" #include "g10lib.h" #include "cipher.h" #include "bufhelp.h" #include "hash-common.h" /* USE_AMD64_ASM indicates whether to use AMD64 assembly code. */ #undef USE_AMD64_ASM #if defined(__x86_64__) && (defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) || \ defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS)) # define USE_AMD64_ASM 1 #endif /* Size of a whirlpool block (in bytes). */ #define BLOCK_SIZE 64 /* Number of rounds. */ #define R 10 /* Types. */ typedef u64 whirlpool_block_t[BLOCK_SIZE / 8]; typedef struct { gcry_md_block_ctx_t bctx; whirlpool_block_t hash_state; int use_bugemu; struct { size_t count; unsigned char length[32]; } bugemu; } whirlpool_context_t; /* Macros. */ /* Convert the the buffer BUFFER into a block BLOCK, using I as counter. */ #define buffer_to_block(buffer, block, i) \ for (i = 0; i < 8; i++) \ (block)[i] = buf_get_be64((buffer) + i * 8); /* Convert the block BLOCK into a buffer BUFFER, using I as counter. */ #define block_to_buffer(buffer, block, i) \ for (i = 0; i < 8; i++) \ buf_put_be64((buffer) + i * 8, (block)[i]); /* Copy the block BLOCK_SRC to BLOCK_DST, using I as counter. */ #define block_copy(block_dst, block_src, i) \ for (i = 0; i < 8; i++) \ block_dst[i] = block_src[i]; /* XOR the block BLOCK_SRC into BLOCK_DST, using I as counter. */ #define block_xor(block_dst, block_src, i) \ for (i = 0; i < 8; i++) \ block_dst[i] ^= block_src[i]; struct whirlpool_tables_s { u64 RC[R]; u64 C[8][256]; }; static const struct whirlpool_tables_s tab = { /* Round constants. */ { U64_C (0x1823c6e887b8014f), U64_C (0x36a6d2f5796f9152), U64_C (0x60bc9b8ea30c7b35), U64_C (0x1de0d7c22e4bfe57), U64_C (0x157737e59ff04ada), U64_C (0x58c9290ab1a06b85), U64_C (0xbd5d10f4cb3e0567), U64_C (0xe427418ba77d95d8), U64_C (0xfbee7c66dd17479e), U64_C (0xca2dbf07ad5a8333), }, /* Main lookup boxes. */ { { U64_C (0x18186018c07830d8), U64_C (0x23238c2305af4626), U64_C (0xc6c63fc67ef991b8), U64_C (0xe8e887e8136fcdfb), U64_C (0x878726874ca113cb), U64_C (0xb8b8dab8a9626d11), U64_C (0x0101040108050209), U64_C (0x4f4f214f426e9e0d), U64_C (0x3636d836adee6c9b), U64_C (0xa6a6a2a6590451ff), U64_C (0xd2d26fd2debdb90c), U64_C (0xf5f5f3f5fb06f70e), U64_C (0x7979f979ef80f296), U64_C (0x6f6fa16f5fcede30), U64_C (0x91917e91fcef3f6d), U64_C (0x52525552aa07a4f8), U64_C (0x60609d6027fdc047), U64_C (0xbcbccabc89766535), U64_C (0x9b9b569baccd2b37), U64_C (0x8e8e028e048c018a), U64_C (0xa3a3b6a371155bd2), U64_C (0x0c0c300c603c186c), U64_C (0x7b7bf17bff8af684), U64_C (0x3535d435b5e16a80), U64_C (0x1d1d741de8693af5), U64_C (0xe0e0a7e05347ddb3), U64_C (0xd7d77bd7f6acb321), U64_C (0xc2c22fc25eed999c), U64_C (0x2e2eb82e6d965c43), U64_C (0x4b4b314b627a9629), U64_C (0xfefedffea321e15d), U64_C (0x575741578216aed5), U64_C (0x15155415a8412abd), U64_C (0x7777c1779fb6eee8), U64_C (0x3737dc37a5eb6e92), U64_C (0xe5e5b3e57b56d79e), U64_C (0x9f9f469f8cd92313), U64_C (0xf0f0e7f0d317fd23), U64_C (0x4a4a354a6a7f9420), U64_C (0xdada4fda9e95a944), U64_C (0x58587d58fa25b0a2), U64_C (0xc9c903c906ca8fcf), U64_C (0x2929a429558d527c), U64_C (0x0a0a280a5022145a), U64_C (0xb1b1feb1e14f7f50), U64_C (0xa0a0baa0691a5dc9), U64_C (0x6b6bb16b7fdad614), U64_C (0x85852e855cab17d9), U64_C (0xbdbdcebd8173673c), U64_C (0x5d5d695dd234ba8f), U64_C (0x1010401080502090), U64_C (0xf4f4f7f4f303f507), U64_C (0xcbcb0bcb16c08bdd), U64_C (0x3e3ef83eedc67cd3), U64_C (0x0505140528110a2d), U64_C (0x676781671fe6ce78), U64_C (0xe4e4b7e47353d597), U64_C (0x27279c2725bb4e02), U64_C (0x4141194132588273), U64_C (0x8b8b168b2c9d0ba7), U64_C (0xa7a7a6a7510153f6), U64_C (0x7d7de97dcf94fab2), U64_C (0x95956e95dcfb3749), U64_C (0xd8d847d88e9fad56), U64_C (0xfbfbcbfb8b30eb70), U64_C (0xeeee9fee2371c1cd), U64_C (0x7c7ced7cc791f8bb), U64_C (0x6666856617e3cc71), U64_C (0xdddd53dda68ea77b), U64_C (0x17175c17b84b2eaf), U64_C (0x4747014702468e45), U64_C (0x9e9e429e84dc211a), U64_C (0xcaca0fca1ec589d4), U64_C (0x2d2db42d75995a58), U64_C (0xbfbfc6bf9179632e), U64_C (0x07071c07381b0e3f), U64_C (0xadad8ead012347ac), U64_C (0x5a5a755aea2fb4b0), U64_C (0x838336836cb51bef), U64_C (0x3333cc3385ff66b6), U64_C (0x636391633ff2c65c), U64_C (0x02020802100a0412), U64_C (0xaaaa92aa39384993), U64_C (0x7171d971afa8e2de), U64_C (0xc8c807c80ecf8dc6), U64_C (0x19196419c87d32d1), U64_C (0x494939497270923b), U64_C (0xd9d943d9869aaf5f), U64_C (0xf2f2eff2c31df931), U64_C (0xe3e3abe34b48dba8), U64_C (0x5b5b715be22ab6b9), U64_C (0x88881a8834920dbc), U64_C (0x9a9a529aa4c8293e), U64_C (0x262698262dbe4c0b), U64_C (0x3232c8328dfa64bf), U64_C (0xb0b0fab0e94a7d59), U64_C (0xe9e983e91b6acff2), U64_C (0x0f0f3c0f78331e77), U64_C (0xd5d573d5e6a6b733), U64_C (0x80803a8074ba1df4), U64_C (0xbebec2be997c6127), U64_C (0xcdcd13cd26de87eb), U64_C (0x3434d034bde46889), U64_C (0x48483d487a759032), U64_C (0xffffdbffab24e354), U64_C (0x7a7af57af78ff48d), U64_C (0x90907a90f4ea3d64), U64_C (0x5f5f615fc23ebe9d), U64_C (0x202080201da0403d), U64_C (0x6868bd6867d5d00f), U64_C (0x1a1a681ad07234ca), U64_C (0xaeae82ae192c41b7), U64_C (0xb4b4eab4c95e757d), U64_C (0x54544d549a19a8ce), U64_C (0x93937693ece53b7f), U64_C (0x222288220daa442f), U64_C (0x64648d6407e9c863), U64_C (0xf1f1e3f1db12ff2a), U64_C (0x7373d173bfa2e6cc), U64_C (0x12124812905a2482), U64_C (0x40401d403a5d807a), U64_C (0x0808200840281048), U64_C (0xc3c32bc356e89b95), U64_C (0xecec97ec337bc5df), U64_C (0xdbdb4bdb9690ab4d), U64_C (0xa1a1bea1611f5fc0), U64_C (0x8d8d0e8d1c830791), U64_C (0x3d3df43df5c97ac8), U64_C (0x97976697ccf1335b), U64_C (0x0000000000000000), U64_C (0xcfcf1bcf36d483f9), U64_C (0x2b2bac2b4587566e), U64_C (0x7676c57697b3ece1), U64_C (0x8282328264b019e6), U64_C (0xd6d67fd6fea9b128), U64_C (0x1b1b6c1bd87736c3), U64_C (0xb5b5eeb5c15b7774), U64_C (0xafaf86af112943be), U64_C (0x6a6ab56a77dfd41d), U64_C (0x50505d50ba0da0ea), U64_C (0x45450945124c8a57), U64_C (0xf3f3ebf3cb18fb38), U64_C (0x3030c0309df060ad), U64_C (0xefef9bef2b74c3c4), U64_C (0x3f3ffc3fe5c37eda), U64_C (0x55554955921caac7), U64_C (0xa2a2b2a2791059db), U64_C (0xeaea8fea0365c9e9), U64_C (0x656589650fecca6a), U64_C (0xbabad2bab9686903), U64_C (0x2f2fbc2f65935e4a), U64_C (0xc0c027c04ee79d8e), U64_C (0xdede5fdebe81a160), U64_C (0x1c1c701ce06c38fc), U64_C (0xfdfdd3fdbb2ee746), U64_C (0x4d4d294d52649a1f), U64_C (0x92927292e4e03976), U64_C (0x7575c9758fbceafa), U64_C (0x06061806301e0c36), U64_C (0x8a8a128a249809ae), U64_C (0xb2b2f2b2f940794b), U64_C (0xe6e6bfe66359d185), U64_C (0x0e0e380e70361c7e), U64_C (0x1f1f7c1ff8633ee7), U64_C (0x6262956237f7c455), U64_C (0xd4d477d4eea3b53a), U64_C (0xa8a89aa829324d81), U64_C (0x96966296c4f43152), U64_C (0xf9f9c3f99b3aef62), U64_C (0xc5c533c566f697a3), U64_C (0x2525942535b14a10), U64_C (0x59597959f220b2ab), U64_C (0x84842a8454ae15d0), U64_C (0x7272d572b7a7e4c5), U64_C (0x3939e439d5dd72ec), U64_C (0x4c4c2d4c5a619816), U64_C (0x5e5e655eca3bbc94), U64_C (0x7878fd78e785f09f), U64_C (0x3838e038ddd870e5), U64_C (0x8c8c0a8c14860598), U64_C (0xd1d163d1c6b2bf17), U64_C (0xa5a5aea5410b57e4), U64_C (0xe2e2afe2434dd9a1), U64_C (0x616199612ff8c24e), U64_C (0xb3b3f6b3f1457b42), U64_C (0x2121842115a54234), U64_C (0x9c9c4a9c94d62508), U64_C (0x1e1e781ef0663cee), U64_C (0x4343114322528661), U64_C (0xc7c73bc776fc93b1), U64_C (0xfcfcd7fcb32be54f), U64_C (0x0404100420140824), U64_C (0x51515951b208a2e3), U64_C (0x99995e99bcc72f25), U64_C (0x6d6da96d4fc4da22), U64_C (0x0d0d340d68391a65), U64_C (0xfafacffa8335e979), U64_C (0xdfdf5bdfb684a369), U64_C (0x7e7ee57ed79bfca9), U64_C (0x242490243db44819), U64_C (0x3b3bec3bc5d776fe), U64_C (0xabab96ab313d4b9a), U64_C (0xcece1fce3ed181f0), U64_C (0x1111441188552299), U64_C (0x8f8f068f0c890383), U64_C (0x4e4e254e4a6b9c04), U64_C (0xb7b7e6b7d1517366), U64_C (0xebeb8beb0b60cbe0), U64_C (0x3c3cf03cfdcc78c1), U64_C (0x81813e817cbf1ffd), U64_C (0x94946a94d4fe3540), U64_C (0xf7f7fbf7eb0cf31c), U64_C (0xb9b9deb9a1676f18), U64_C (0x13134c13985f268b), U64_C (0x2c2cb02c7d9c5851), U64_C (0xd3d36bd3d6b8bb05), U64_C (0xe7e7bbe76b5cd38c), U64_C (0x6e6ea56e57cbdc39), U64_C (0xc4c437c46ef395aa), U64_C (0x03030c03180f061b), U64_C (0x565645568a13acdc), U64_C (0x44440d441a49885e), U64_C (0x7f7fe17fdf9efea0), U64_C (0xa9a99ea921374f88), U64_C (0x2a2aa82a4d825467), U64_C (0xbbbbd6bbb16d6b0a), U64_C (0xc1c123c146e29f87), U64_C (0x53535153a202a6f1), U64_C (0xdcdc57dcae8ba572), U64_C (0x0b0b2c0b58271653), U64_C (0x9d9d4e9d9cd32701), U64_C (0x6c6cad6c47c1d82b), U64_C (0x3131c43195f562a4), U64_C (0x7474cd7487b9e8f3), U64_C (0xf6f6fff6e309f115), U64_C (0x464605460a438c4c), U64_C (0xacac8aac092645a5), U64_C (0x89891e893c970fb5), U64_C (0x14145014a04428b4), U64_C (0xe1e1a3e15b42dfba), U64_C (0x16165816b04e2ca6), U64_C (0x3a3ae83acdd274f7), U64_C (0x6969b9696fd0d206), U64_C (0x09092409482d1241), U64_C (0x7070dd70a7ade0d7), U64_C (0xb6b6e2b6d954716f), U64_C (0xd0d067d0ceb7bd1e), U64_C (0xeded93ed3b7ec7d6), U64_C (0xcccc17cc2edb85e2), U64_C (0x424215422a578468), U64_C (0x98985a98b4c22d2c), U64_C (0xa4a4aaa4490e55ed), U64_C (0x2828a0285d885075), U64_C (0x5c5c6d5cda31b886), U64_C (0xf8f8c7f8933fed6b), U64_C (0x8686228644a411c2), }, { U64_C (0xd818186018c07830), U64_C (0x2623238c2305af46), U64_C (0xb8c6c63fc67ef991), U64_C (0xfbe8e887e8136fcd), U64_C (0xcb878726874ca113), U64_C (0x11b8b8dab8a9626d), U64_C (0x0901010401080502), U64_C (0x0d4f4f214f426e9e), U64_C (0x9b3636d836adee6c), U64_C (0xffa6a6a2a6590451), U64_C (0x0cd2d26fd2debdb9), U64_C (0x0ef5f5f3f5fb06f7), U64_C (0x967979f979ef80f2), U64_C (0x306f6fa16f5fcede), U64_C (0x6d91917e91fcef3f), U64_C (0xf852525552aa07a4), U64_C (0x4760609d6027fdc0), U64_C (0x35bcbccabc897665), U64_C (0x379b9b569baccd2b), U64_C (0x8a8e8e028e048c01), U64_C (0xd2a3a3b6a371155b), U64_C (0x6c0c0c300c603c18), U64_C (0x847b7bf17bff8af6), U64_C (0x803535d435b5e16a), U64_C (0xf51d1d741de8693a), U64_C (0xb3e0e0a7e05347dd), U64_C (0x21d7d77bd7f6acb3), U64_C (0x9cc2c22fc25eed99), U64_C (0x432e2eb82e6d965c), U64_C (0x294b4b314b627a96), U64_C (0x5dfefedffea321e1), U64_C (0xd5575741578216ae), U64_C (0xbd15155415a8412a), U64_C (0xe87777c1779fb6ee), U64_C (0x923737dc37a5eb6e), U64_C (0x9ee5e5b3e57b56d7), U64_C (0x139f9f469f8cd923), U64_C (0x23f0f0e7f0d317fd), U64_C (0x204a4a354a6a7f94), U64_C (0x44dada4fda9e95a9), U64_C (0xa258587d58fa25b0), U64_C (0xcfc9c903c906ca8f), U64_C (0x7c2929a429558d52), U64_C (0x5a0a0a280a502214), U64_C (0x50b1b1feb1e14f7f), U64_C (0xc9a0a0baa0691a5d), U64_C (0x146b6bb16b7fdad6), U64_C (0xd985852e855cab17), U64_C (0x3cbdbdcebd817367), U64_C (0x8f5d5d695dd234ba), U64_C (0x9010104010805020), U64_C (0x07f4f4f7f4f303f5), U64_C (0xddcbcb0bcb16c08b), U64_C (0xd33e3ef83eedc67c), U64_C (0x2d0505140528110a), U64_C (0x78676781671fe6ce), U64_C (0x97e4e4b7e47353d5), U64_C (0x0227279c2725bb4e), U64_C (0x7341411941325882), U64_C (0xa78b8b168b2c9d0b), U64_C (0xf6a7a7a6a7510153), U64_C (0xb27d7de97dcf94fa), U64_C (0x4995956e95dcfb37), U64_C (0x56d8d847d88e9fad), U64_C (0x70fbfbcbfb8b30eb), U64_C (0xcdeeee9fee2371c1), U64_C (0xbb7c7ced7cc791f8), U64_C (0x716666856617e3cc), U64_C (0x7bdddd53dda68ea7), U64_C (0xaf17175c17b84b2e), U64_C (0x454747014702468e), U64_C (0x1a9e9e429e84dc21), U64_C (0xd4caca0fca1ec589), U64_C (0x582d2db42d75995a), U64_C (0x2ebfbfc6bf917963), U64_C (0x3f07071c07381b0e), U64_C (0xacadad8ead012347), U64_C (0xb05a5a755aea2fb4), U64_C (0xef838336836cb51b), U64_C (0xb63333cc3385ff66), U64_C (0x5c636391633ff2c6), U64_C (0x1202020802100a04), U64_C (0x93aaaa92aa393849), U64_C (0xde7171d971afa8e2), U64_C (0xc6c8c807c80ecf8d), U64_C (0xd119196419c87d32), U64_C (0x3b49493949727092), U64_C (0x5fd9d943d9869aaf), U64_C (0x31f2f2eff2c31df9), U64_C (0xa8e3e3abe34b48db), U64_C (0xb95b5b715be22ab6), U64_C (0xbc88881a8834920d), U64_C (0x3e9a9a529aa4c829), U64_C (0x0b262698262dbe4c), U64_C (0xbf3232c8328dfa64), U64_C (0x59b0b0fab0e94a7d), U64_C (0xf2e9e983e91b6acf), U64_C (0x770f0f3c0f78331e), U64_C (0x33d5d573d5e6a6b7), U64_C (0xf480803a8074ba1d), U64_C (0x27bebec2be997c61), U64_C (0xebcdcd13cd26de87), U64_C (0x893434d034bde468), U64_C (0x3248483d487a7590), U64_C (0x54ffffdbffab24e3), U64_C (0x8d7a7af57af78ff4), U64_C (0x6490907a90f4ea3d), U64_C (0x9d5f5f615fc23ebe), U64_C (0x3d202080201da040), U64_C (0x0f6868bd6867d5d0), U64_C (0xca1a1a681ad07234), U64_C (0xb7aeae82ae192c41), U64_C (0x7db4b4eab4c95e75), U64_C (0xce54544d549a19a8), U64_C (0x7f93937693ece53b), U64_C (0x2f222288220daa44), U64_C (0x6364648d6407e9c8), U64_C (0x2af1f1e3f1db12ff), U64_C (0xcc7373d173bfa2e6), U64_C (0x8212124812905a24), U64_C (0x7a40401d403a5d80), U64_C (0x4808082008402810), U64_C (0x95c3c32bc356e89b), U64_C (0xdfecec97ec337bc5), U64_C (0x4ddbdb4bdb9690ab), U64_C (0xc0a1a1bea1611f5f), U64_C (0x918d8d0e8d1c8307), U64_C (0xc83d3df43df5c97a), U64_C (0x5b97976697ccf133), U64_C (0x0000000000000000), U64_C (0xf9cfcf1bcf36d483), U64_C (0x6e2b2bac2b458756), U64_C (0xe17676c57697b3ec), U64_C (0xe68282328264b019), U64_C (0x28d6d67fd6fea9b1), U64_C (0xc31b1b6c1bd87736), U64_C (0x74b5b5eeb5c15b77), U64_C (0xbeafaf86af112943), U64_C (0x1d6a6ab56a77dfd4), U64_C (0xea50505d50ba0da0), U64_C (0x5745450945124c8a), U64_C (0x38f3f3ebf3cb18fb), U64_C (0xad3030c0309df060), U64_C (0xc4efef9bef2b74c3), U64_C (0xda3f3ffc3fe5c37e), U64_C (0xc755554955921caa), U64_C (0xdba2a2b2a2791059), U64_C (0xe9eaea8fea0365c9), U64_C (0x6a656589650fecca), U64_C (0x03babad2bab96869), U64_C (0x4a2f2fbc2f65935e), U64_C (0x8ec0c027c04ee79d), U64_C (0x60dede5fdebe81a1), U64_C (0xfc1c1c701ce06c38), U64_C (0x46fdfdd3fdbb2ee7), U64_C (0x1f4d4d294d52649a), U64_C (0x7692927292e4e039), U64_C (0xfa7575c9758fbcea), U64_C (0x3606061806301e0c), U64_C (0xae8a8a128a249809), U64_C (0x4bb2b2f2b2f94079), U64_C (0x85e6e6bfe66359d1), U64_C (0x7e0e0e380e70361c), U64_C (0xe71f1f7c1ff8633e), U64_C (0x556262956237f7c4), U64_C (0x3ad4d477d4eea3b5), U64_C (0x81a8a89aa829324d), U64_C (0x5296966296c4f431), U64_C (0x62f9f9c3f99b3aef), U64_C (0xa3c5c533c566f697), U64_C (0x102525942535b14a), U64_C (0xab59597959f220b2), U64_C (0xd084842a8454ae15), U64_C (0xc57272d572b7a7e4), U64_C (0xec3939e439d5dd72), U64_C (0x164c4c2d4c5a6198), U64_C (0x945e5e655eca3bbc), U64_C (0x9f7878fd78e785f0), U64_C (0xe53838e038ddd870), U64_C (0x988c8c0a8c148605), U64_C (0x17d1d163d1c6b2bf), U64_C (0xe4a5a5aea5410b57), U64_C (0xa1e2e2afe2434dd9), U64_C (0x4e616199612ff8c2), U64_C (0x42b3b3f6b3f1457b), U64_C (0x342121842115a542), U64_C (0x089c9c4a9c94d625), U64_C (0xee1e1e781ef0663c), U64_C (0x6143431143225286), U64_C (0xb1c7c73bc776fc93), U64_C (0x4ffcfcd7fcb32be5), U64_C (0x2404041004201408), U64_C (0xe351515951b208a2), U64_C (0x2599995e99bcc72f), U64_C (0x226d6da96d4fc4da), U64_C (0x650d0d340d68391a), U64_C (0x79fafacffa8335e9), U64_C (0x69dfdf5bdfb684a3), U64_C (0xa97e7ee57ed79bfc), U64_C (0x19242490243db448), U64_C (0xfe3b3bec3bc5d776), U64_C (0x9aabab96ab313d4b), U64_C (0xf0cece1fce3ed181), U64_C (0x9911114411885522), U64_C (0x838f8f068f0c8903), U64_C (0x044e4e254e4a6b9c), U64_C (0x66b7b7e6b7d15173), U64_C (0xe0ebeb8beb0b60cb), U64_C (0xc13c3cf03cfdcc78), U64_C (0xfd81813e817cbf1f), U64_C (0x4094946a94d4fe35), U64_C (0x1cf7f7fbf7eb0cf3), U64_C (0x18b9b9deb9a1676f), U64_C (0x8b13134c13985f26), U64_C (0x512c2cb02c7d9c58), U64_C (0x05d3d36bd3d6b8bb), U64_C (0x8ce7e7bbe76b5cd3), U64_C (0x396e6ea56e57cbdc), U64_C (0xaac4c437c46ef395), U64_C (0x1b03030c03180f06), U64_C (0xdc565645568a13ac), U64_C (0x5e44440d441a4988), U64_C (0xa07f7fe17fdf9efe), U64_C (0x88a9a99ea921374f), U64_C (0x672a2aa82a4d8254), U64_C (0x0abbbbd6bbb16d6b), U64_C (0x87c1c123c146e29f), U64_C (0xf153535153a202a6), U64_C (0x72dcdc57dcae8ba5), U64_C (0x530b0b2c0b582716), U64_C (0x019d9d4e9d9cd327), U64_C (0x2b6c6cad6c47c1d8), U64_C (0xa43131c43195f562), U64_C (0xf37474cd7487b9e8), U64_C (0x15f6f6fff6e309f1), U64_C (0x4c464605460a438c), U64_C (0xa5acac8aac092645), U64_C (0xb589891e893c970f), U64_C (0xb414145014a04428), U64_C (0xbae1e1a3e15b42df), U64_C (0xa616165816b04e2c), U64_C (0xf73a3ae83acdd274), U64_C (0x066969b9696fd0d2), U64_C (0x4109092409482d12), U64_C (0xd77070dd70a7ade0), U64_C (0x6fb6b6e2b6d95471), U64_C (0x1ed0d067d0ceb7bd), U64_C (0xd6eded93ed3b7ec7), U64_C (0xe2cccc17cc2edb85), U64_C (0x68424215422a5784), U64_C (0x2c98985a98b4c22d), U64_C (0xeda4a4aaa4490e55), U64_C (0x752828a0285d8850), U64_C (0x865c5c6d5cda31b8), U64_C (0x6bf8f8c7f8933fed), U64_C (0xc28686228644a411), }, { U64_C (0x30d818186018c078), U64_C (0x462623238c2305af), U64_C (0x91b8c6c63fc67ef9), U64_C (0xcdfbe8e887e8136f), U64_C (0x13cb878726874ca1), U64_C (0x6d11b8b8dab8a962), U64_C (0x0209010104010805), U64_C (0x9e0d4f4f214f426e), U64_C (0x6c9b3636d836adee), U64_C (0x51ffa6a6a2a65904), U64_C (0xb90cd2d26fd2debd), U64_C (0xf70ef5f5f3f5fb06), U64_C (0xf2967979f979ef80), U64_C (0xde306f6fa16f5fce), U64_C (0x3f6d91917e91fcef), U64_C (0xa4f852525552aa07), U64_C (0xc04760609d6027fd), U64_C (0x6535bcbccabc8976), U64_C (0x2b379b9b569baccd), U64_C (0x018a8e8e028e048c), U64_C (0x5bd2a3a3b6a37115), U64_C (0x186c0c0c300c603c), U64_C (0xf6847b7bf17bff8a), U64_C (0x6a803535d435b5e1), U64_C (0x3af51d1d741de869), U64_C (0xddb3e0e0a7e05347), U64_C (0xb321d7d77bd7f6ac), U64_C (0x999cc2c22fc25eed), U64_C (0x5c432e2eb82e6d96), U64_C (0x96294b4b314b627a), U64_C (0xe15dfefedffea321), U64_C (0xaed5575741578216), U64_C (0x2abd15155415a841), U64_C (0xeee87777c1779fb6), U64_C (0x6e923737dc37a5eb), U64_C (0xd79ee5e5b3e57b56), U64_C (0x23139f9f469f8cd9), U64_C (0xfd23f0f0e7f0d317), U64_C (0x94204a4a354a6a7f), U64_C (0xa944dada4fda9e95), U64_C (0xb0a258587d58fa25), U64_C (0x8fcfc9c903c906ca), U64_C (0x527c2929a429558d), U64_C (0x145a0a0a280a5022), U64_C (0x7f50b1b1feb1e14f), U64_C (0x5dc9a0a0baa0691a), U64_C (0xd6146b6bb16b7fda), U64_C (0x17d985852e855cab), U64_C (0x673cbdbdcebd8173), U64_C (0xba8f5d5d695dd234), U64_C (0x2090101040108050), U64_C (0xf507f4f4f7f4f303), U64_C (0x8bddcbcb0bcb16c0), U64_C (0x7cd33e3ef83eedc6), U64_C (0x0a2d050514052811), U64_C (0xce78676781671fe6), U64_C (0xd597e4e4b7e47353), U64_C (0x4e0227279c2725bb), U64_C (0x8273414119413258), U64_C (0x0ba78b8b168b2c9d), U64_C (0x53f6a7a7a6a75101), U64_C (0xfab27d7de97dcf94), U64_C (0x374995956e95dcfb), U64_C (0xad56d8d847d88e9f), U64_C (0xeb70fbfbcbfb8b30), U64_C (0xc1cdeeee9fee2371), U64_C (0xf8bb7c7ced7cc791), U64_C (0xcc716666856617e3), U64_C (0xa77bdddd53dda68e), U64_C (0x2eaf17175c17b84b), U64_C (0x8e45474701470246), U64_C (0x211a9e9e429e84dc), U64_C (0x89d4caca0fca1ec5), U64_C (0x5a582d2db42d7599), U64_C (0x632ebfbfc6bf9179), U64_C (0x0e3f07071c07381b), U64_C (0x47acadad8ead0123), U64_C (0xb4b05a5a755aea2f), U64_C (0x1bef838336836cb5), U64_C (0x66b63333cc3385ff), U64_C (0xc65c636391633ff2), U64_C (0x041202020802100a), U64_C (0x4993aaaa92aa3938), U64_C (0xe2de7171d971afa8), U64_C (0x8dc6c8c807c80ecf), U64_C (0x32d119196419c87d), U64_C (0x923b494939497270), U64_C (0xaf5fd9d943d9869a), U64_C (0xf931f2f2eff2c31d), U64_C (0xdba8e3e3abe34b48), U64_C (0xb6b95b5b715be22a), U64_C (0x0dbc88881a883492), U64_C (0x293e9a9a529aa4c8), U64_C (0x4c0b262698262dbe), U64_C (0x64bf3232c8328dfa), U64_C (0x7d59b0b0fab0e94a), U64_C (0xcff2e9e983e91b6a), U64_C (0x1e770f0f3c0f7833), U64_C (0xb733d5d573d5e6a6), U64_C (0x1df480803a8074ba), U64_C (0x6127bebec2be997c), U64_C (0x87ebcdcd13cd26de), U64_C (0x68893434d034bde4), U64_C (0x903248483d487a75), U64_C (0xe354ffffdbffab24), U64_C (0xf48d7a7af57af78f), U64_C (0x3d6490907a90f4ea), U64_C (0xbe9d5f5f615fc23e), U64_C (0x403d202080201da0), U64_C (0xd00f6868bd6867d5), U64_C (0x34ca1a1a681ad072), U64_C (0x41b7aeae82ae192c), U64_C (0x757db4b4eab4c95e), U64_C (0xa8ce54544d549a19), U64_C (0x3b7f93937693ece5), U64_C (0x442f222288220daa), U64_C (0xc86364648d6407e9), U64_C (0xff2af1f1e3f1db12), U64_C (0xe6cc7373d173bfa2), U64_C (0x248212124812905a), U64_C (0x807a40401d403a5d), U64_C (0x1048080820084028), U64_C (0x9b95c3c32bc356e8), U64_C (0xc5dfecec97ec337b), U64_C (0xab4ddbdb4bdb9690), U64_C (0x5fc0a1a1bea1611f), U64_C (0x07918d8d0e8d1c83), U64_C (0x7ac83d3df43df5c9), U64_C (0x335b97976697ccf1), U64_C (0x0000000000000000), U64_C (0x83f9cfcf1bcf36d4), U64_C (0x566e2b2bac2b4587), U64_C (0xece17676c57697b3), U64_C (0x19e68282328264b0), U64_C (0xb128d6d67fd6fea9), U64_C (0x36c31b1b6c1bd877), U64_C (0x7774b5b5eeb5c15b), U64_C (0x43beafaf86af1129), U64_C (0xd41d6a6ab56a77df), U64_C (0xa0ea50505d50ba0d), U64_C (0x8a5745450945124c), U64_C (0xfb38f3f3ebf3cb18), U64_C (0x60ad3030c0309df0), U64_C (0xc3c4efef9bef2b74), U64_C (0x7eda3f3ffc3fe5c3), U64_C (0xaac755554955921c), U64_C (0x59dba2a2b2a27910), U64_C (0xc9e9eaea8fea0365), U64_C (0xca6a656589650fec), U64_C (0x6903babad2bab968), U64_C (0x5e4a2f2fbc2f6593), U64_C (0x9d8ec0c027c04ee7), U64_C (0xa160dede5fdebe81), U64_C (0x38fc1c1c701ce06c), U64_C (0xe746fdfdd3fdbb2e), U64_C (0x9a1f4d4d294d5264), U64_C (0x397692927292e4e0), U64_C (0xeafa7575c9758fbc), U64_C (0x0c3606061806301e), U64_C (0x09ae8a8a128a2498), U64_C (0x794bb2b2f2b2f940), U64_C (0xd185e6e6bfe66359), U64_C (0x1c7e0e0e380e7036), U64_C (0x3ee71f1f7c1ff863), U64_C (0xc4556262956237f7), U64_C (0xb53ad4d477d4eea3), U64_C (0x4d81a8a89aa82932), U64_C (0x315296966296c4f4), U64_C (0xef62f9f9c3f99b3a), U64_C (0x97a3c5c533c566f6), U64_C (0x4a102525942535b1), U64_C (0xb2ab59597959f220), U64_C (0x15d084842a8454ae), U64_C (0xe4c57272d572b7a7), U64_C (0x72ec3939e439d5dd), U64_C (0x98164c4c2d4c5a61), U64_C (0xbc945e5e655eca3b), U64_C (0xf09f7878fd78e785), U64_C (0x70e53838e038ddd8), U64_C (0x05988c8c0a8c1486), U64_C (0xbf17d1d163d1c6b2), U64_C (0x57e4a5a5aea5410b), U64_C (0xd9a1e2e2afe2434d), U64_C (0xc24e616199612ff8), U64_C (0x7b42b3b3f6b3f145), U64_C (0x42342121842115a5), U64_C (0x25089c9c4a9c94d6), U64_C (0x3cee1e1e781ef066), U64_C (0x8661434311432252), U64_C (0x93b1c7c73bc776fc), U64_C (0xe54ffcfcd7fcb32b), U64_C (0x0824040410042014), U64_C (0xa2e351515951b208), U64_C (0x2f2599995e99bcc7), U64_C (0xda226d6da96d4fc4), U64_C (0x1a650d0d340d6839), U64_C (0xe979fafacffa8335), U64_C (0xa369dfdf5bdfb684), U64_C (0xfca97e7ee57ed79b), U64_C (0x4819242490243db4), U64_C (0x76fe3b3bec3bc5d7), U64_C (0x4b9aabab96ab313d), U64_C (0x81f0cece1fce3ed1), U64_C (0x2299111144118855), U64_C (0x03838f8f068f0c89), U64_C (0x9c044e4e254e4a6b), U64_C (0x7366b7b7e6b7d151), U64_C (0xcbe0ebeb8beb0b60), U64_C (0x78c13c3cf03cfdcc), U64_C (0x1ffd81813e817cbf), U64_C (0x354094946a94d4fe), U64_C (0xf31cf7f7fbf7eb0c), U64_C (0x6f18b9b9deb9a167), U64_C (0x268b13134c13985f), U64_C (0x58512c2cb02c7d9c), U64_C (0xbb05d3d36bd3d6b8), U64_C (0xd38ce7e7bbe76b5c), U64_C (0xdc396e6ea56e57cb), U64_C (0x95aac4c437c46ef3), U64_C (0x061b03030c03180f), U64_C (0xacdc565645568a13), U64_C (0x885e44440d441a49), U64_C (0xfea07f7fe17fdf9e), U64_C (0x4f88a9a99ea92137), U64_C (0x54672a2aa82a4d82), U64_C (0x6b0abbbbd6bbb16d), U64_C (0x9f87c1c123c146e2), U64_C (0xa6f153535153a202), U64_C (0xa572dcdc57dcae8b), U64_C (0x16530b0b2c0b5827), U64_C (0x27019d9d4e9d9cd3), U64_C (0xd82b6c6cad6c47c1), U64_C (0x62a43131c43195f5), U64_C (0xe8f37474cd7487b9), U64_C (0xf115f6f6fff6e309), U64_C (0x8c4c464605460a43), U64_C (0x45a5acac8aac0926), U64_C (0x0fb589891e893c97), U64_C (0x28b414145014a044), U64_C (0xdfbae1e1a3e15b42), U64_C (0x2ca616165816b04e), U64_C (0x74f73a3ae83acdd2), U64_C (0xd2066969b9696fd0), U64_C (0x124109092409482d), U64_C (0xe0d77070dd70a7ad), U64_C (0x716fb6b6e2b6d954), U64_C (0xbd1ed0d067d0ceb7), U64_C (0xc7d6eded93ed3b7e), U64_C (0x85e2cccc17cc2edb), U64_C (0x8468424215422a57), U64_C (0x2d2c98985a98b4c2), U64_C (0x55eda4a4aaa4490e), U64_C (0x50752828a0285d88), U64_C (0xb8865c5c6d5cda31), U64_C (0xed6bf8f8c7f8933f), U64_C (0x11c28686228644a4), }, { U64_C (0x7830d818186018c0), U64_C (0xaf462623238c2305), U64_C (0xf991b8c6c63fc67e), U64_C (0x6fcdfbe8e887e813), U64_C (0xa113cb878726874c), U64_C (0x626d11b8b8dab8a9), U64_C (0x0502090101040108), U64_C (0x6e9e0d4f4f214f42), U64_C (0xee6c9b3636d836ad), U64_C (0x0451ffa6a6a2a659), U64_C (0xbdb90cd2d26fd2de), U64_C (0x06f70ef5f5f3f5fb), U64_C (0x80f2967979f979ef), U64_C (0xcede306f6fa16f5f), U64_C (0xef3f6d91917e91fc), U64_C (0x07a4f852525552aa), U64_C (0xfdc04760609d6027), U64_C (0x766535bcbccabc89), U64_C (0xcd2b379b9b569bac), U64_C (0x8c018a8e8e028e04), U64_C (0x155bd2a3a3b6a371), U64_C (0x3c186c0c0c300c60), U64_C (0x8af6847b7bf17bff), U64_C (0xe16a803535d435b5), U64_C (0x693af51d1d741de8), U64_C (0x47ddb3e0e0a7e053), U64_C (0xacb321d7d77bd7f6), U64_C (0xed999cc2c22fc25e), U64_C (0x965c432e2eb82e6d), U64_C (0x7a96294b4b314b62), U64_C (0x21e15dfefedffea3), U64_C (0x16aed55757415782), U64_C (0x412abd15155415a8), U64_C (0xb6eee87777c1779f), U64_C (0xeb6e923737dc37a5), U64_C (0x56d79ee5e5b3e57b), U64_C (0xd923139f9f469f8c), U64_C (0x17fd23f0f0e7f0d3), U64_C (0x7f94204a4a354a6a), U64_C (0x95a944dada4fda9e), U64_C (0x25b0a258587d58fa), U64_C (0xca8fcfc9c903c906), U64_C (0x8d527c2929a42955), U64_C (0x22145a0a0a280a50), U64_C (0x4f7f50b1b1feb1e1), U64_C (0x1a5dc9a0a0baa069), U64_C (0xdad6146b6bb16b7f), U64_C (0xab17d985852e855c), U64_C (0x73673cbdbdcebd81), U64_C (0x34ba8f5d5d695dd2), U64_C (0x5020901010401080), U64_C (0x03f507f4f4f7f4f3), U64_C (0xc08bddcbcb0bcb16), U64_C (0xc67cd33e3ef83eed), U64_C (0x110a2d0505140528), U64_C (0xe6ce78676781671f), U64_C (0x53d597e4e4b7e473), U64_C (0xbb4e0227279c2725), U64_C (0x5882734141194132), U64_C (0x9d0ba78b8b168b2c), U64_C (0x0153f6a7a7a6a751), U64_C (0x94fab27d7de97dcf), U64_C (0xfb374995956e95dc), U64_C (0x9fad56d8d847d88e), U64_C (0x30eb70fbfbcbfb8b), U64_C (0x71c1cdeeee9fee23), U64_C (0x91f8bb7c7ced7cc7), U64_C (0xe3cc716666856617), U64_C (0x8ea77bdddd53dda6), U64_C (0x4b2eaf17175c17b8), U64_C (0x468e454747014702), U64_C (0xdc211a9e9e429e84), U64_C (0xc589d4caca0fca1e), U64_C (0x995a582d2db42d75), U64_C (0x79632ebfbfc6bf91), U64_C (0x1b0e3f07071c0738), U64_C (0x2347acadad8ead01), U64_C (0x2fb4b05a5a755aea), U64_C (0xb51bef838336836c), U64_C (0xff66b63333cc3385), U64_C (0xf2c65c636391633f), U64_C (0x0a04120202080210), U64_C (0x384993aaaa92aa39), U64_C (0xa8e2de7171d971af), U64_C (0xcf8dc6c8c807c80e), U64_C (0x7d32d119196419c8), U64_C (0x70923b4949394972), U64_C (0x9aaf5fd9d943d986), U64_C (0x1df931f2f2eff2c3), U64_C (0x48dba8e3e3abe34b), U64_C (0x2ab6b95b5b715be2), U64_C (0x920dbc88881a8834), U64_C (0xc8293e9a9a529aa4), U64_C (0xbe4c0b262698262d), U64_C (0xfa64bf3232c8328d), U64_C (0x4a7d59b0b0fab0e9), U64_C (0x6acff2e9e983e91b), U64_C (0x331e770f0f3c0f78), U64_C (0xa6b733d5d573d5e6), U64_C (0xba1df480803a8074), U64_C (0x7c6127bebec2be99), U64_C (0xde87ebcdcd13cd26), U64_C (0xe468893434d034bd), U64_C (0x75903248483d487a), U64_C (0x24e354ffffdbffab), U64_C (0x8ff48d7a7af57af7), U64_C (0xea3d6490907a90f4), U64_C (0x3ebe9d5f5f615fc2), U64_C (0xa0403d202080201d), U64_C (0xd5d00f6868bd6867), U64_C (0x7234ca1a1a681ad0), U64_C (0x2c41b7aeae82ae19), U64_C (0x5e757db4b4eab4c9), U64_C (0x19a8ce54544d549a), U64_C (0xe53b7f93937693ec), U64_C (0xaa442f222288220d), U64_C (0xe9c86364648d6407), U64_C (0x12ff2af1f1e3f1db), U64_C (0xa2e6cc7373d173bf), U64_C (0x5a24821212481290), U64_C (0x5d807a40401d403a), U64_C (0x2810480808200840), U64_C (0xe89b95c3c32bc356), U64_C (0x7bc5dfecec97ec33), U64_C (0x90ab4ddbdb4bdb96), U64_C (0x1f5fc0a1a1bea161), U64_C (0x8307918d8d0e8d1c), U64_C (0xc97ac83d3df43df5), U64_C (0xf1335b97976697cc), U64_C (0x0000000000000000), U64_C (0xd483f9cfcf1bcf36), U64_C (0x87566e2b2bac2b45), U64_C (0xb3ece17676c57697), U64_C (0xb019e68282328264), U64_C (0xa9b128d6d67fd6fe), U64_C (0x7736c31b1b6c1bd8), U64_C (0x5b7774b5b5eeb5c1), U64_C (0x2943beafaf86af11), U64_C (0xdfd41d6a6ab56a77), U64_C (0x0da0ea50505d50ba), U64_C (0x4c8a574545094512), U64_C (0x18fb38f3f3ebf3cb), U64_C (0xf060ad3030c0309d), U64_C (0x74c3c4efef9bef2b), U64_C (0xc37eda3f3ffc3fe5), U64_C (0x1caac75555495592), U64_C (0x1059dba2a2b2a279), U64_C (0x65c9e9eaea8fea03), U64_C (0xecca6a656589650f), U64_C (0x686903babad2bab9), U64_C (0x935e4a2f2fbc2f65), U64_C (0xe79d8ec0c027c04e), U64_C (0x81a160dede5fdebe), U64_C (0x6c38fc1c1c701ce0), U64_C (0x2ee746fdfdd3fdbb), U64_C (0x649a1f4d4d294d52), U64_C (0xe0397692927292e4), U64_C (0xbceafa7575c9758f), U64_C (0x1e0c360606180630), U64_C (0x9809ae8a8a128a24), U64_C (0x40794bb2b2f2b2f9), U64_C (0x59d185e6e6bfe663), U64_C (0x361c7e0e0e380e70), U64_C (0x633ee71f1f7c1ff8), U64_C (0xf7c4556262956237), U64_C (0xa3b53ad4d477d4ee), U64_C (0x324d81a8a89aa829), U64_C (0xf4315296966296c4), U64_C (0x3aef62f9f9c3f99b), U64_C (0xf697a3c5c533c566), U64_C (0xb14a102525942535), U64_C (0x20b2ab59597959f2), U64_C (0xae15d084842a8454), U64_C (0xa7e4c57272d572b7), U64_C (0xdd72ec3939e439d5), U64_C (0x6198164c4c2d4c5a), U64_C (0x3bbc945e5e655eca), U64_C (0x85f09f7878fd78e7), U64_C (0xd870e53838e038dd), U64_C (0x8605988c8c0a8c14), U64_C (0xb2bf17d1d163d1c6), U64_C (0x0b57e4a5a5aea541), U64_C (0x4dd9a1e2e2afe243), U64_C (0xf8c24e616199612f), U64_C (0x457b42b3b3f6b3f1), U64_C (0xa542342121842115), U64_C (0xd625089c9c4a9c94), U64_C (0x663cee1e1e781ef0), U64_C (0x5286614343114322), U64_C (0xfc93b1c7c73bc776), U64_C (0x2be54ffcfcd7fcb3), U64_C (0x1408240404100420), U64_C (0x08a2e351515951b2), U64_C (0xc72f2599995e99bc), U64_C (0xc4da226d6da96d4f), U64_C (0x391a650d0d340d68), U64_C (0x35e979fafacffa83), U64_C (0x84a369dfdf5bdfb6), U64_C (0x9bfca97e7ee57ed7), U64_C (0xb44819242490243d), U64_C (0xd776fe3b3bec3bc5), U64_C (0x3d4b9aabab96ab31), U64_C (0xd181f0cece1fce3e), U64_C (0x5522991111441188), U64_C (0x8903838f8f068f0c), U64_C (0x6b9c044e4e254e4a), U64_C (0x517366b7b7e6b7d1), U64_C (0x60cbe0ebeb8beb0b), U64_C (0xcc78c13c3cf03cfd), U64_C (0xbf1ffd81813e817c), U64_C (0xfe354094946a94d4), U64_C (0x0cf31cf7f7fbf7eb), U64_C (0x676f18b9b9deb9a1), U64_C (0x5f268b13134c1398), U64_C (0x9c58512c2cb02c7d), U64_C (0xb8bb05d3d36bd3d6), U64_C (0x5cd38ce7e7bbe76b), U64_C (0xcbdc396e6ea56e57), U64_C (0xf395aac4c437c46e), U64_C (0x0f061b03030c0318), U64_C (0x13acdc565645568a), U64_C (0x49885e44440d441a), U64_C (0x9efea07f7fe17fdf), U64_C (0x374f88a9a99ea921), U64_C (0x8254672a2aa82a4d), U64_C (0x6d6b0abbbbd6bbb1), U64_C (0xe29f87c1c123c146), U64_C (0x02a6f153535153a2), U64_C (0x8ba572dcdc57dcae), U64_C (0x2716530b0b2c0b58), U64_C (0xd327019d9d4e9d9c), U64_C (0xc1d82b6c6cad6c47), U64_C (0xf562a43131c43195), U64_C (0xb9e8f37474cd7487), U64_C (0x09f115f6f6fff6e3), U64_C (0x438c4c464605460a), U64_C (0x2645a5acac8aac09), U64_C (0x970fb589891e893c), U64_C (0x4428b414145014a0), U64_C (0x42dfbae1e1a3e15b), U64_C (0x4e2ca616165816b0), U64_C (0xd274f73a3ae83acd), U64_C (0xd0d2066969b9696f), U64_C (0x2d12410909240948), U64_C (0xade0d77070dd70a7), U64_C (0x54716fb6b6e2b6d9), U64_C (0xb7bd1ed0d067d0ce), U64_C (0x7ec7d6eded93ed3b), U64_C (0xdb85e2cccc17cc2e), U64_C (0x578468424215422a), U64_C (0xc22d2c98985a98b4), U64_C (0x0e55eda4a4aaa449), U64_C (0x8850752828a0285d), U64_C (0x31b8865c5c6d5cda), U64_C (0x3fed6bf8f8c7f893), U64_C (0xa411c28686228644), }, { U64_C (0xc07830d818186018), U64_C (0x05af462623238c23), U64_C (0x7ef991b8c6c63fc6), U64_C (0x136fcdfbe8e887e8), U64_C (0x4ca113cb87872687), U64_C (0xa9626d11b8b8dab8), U64_C (0x0805020901010401), U64_C (0x426e9e0d4f4f214f), U64_C (0xadee6c9b3636d836), U64_C (0x590451ffa6a6a2a6), U64_C (0xdebdb90cd2d26fd2), U64_C (0xfb06f70ef5f5f3f5), U64_C (0xef80f2967979f979), U64_C (0x5fcede306f6fa16f), U64_C (0xfcef3f6d91917e91), U64_C (0xaa07a4f852525552), U64_C (0x27fdc04760609d60), U64_C (0x89766535bcbccabc), U64_C (0xaccd2b379b9b569b), U64_C (0x048c018a8e8e028e), U64_C (0x71155bd2a3a3b6a3), U64_C (0x603c186c0c0c300c), U64_C (0xff8af6847b7bf17b), U64_C (0xb5e16a803535d435), U64_C (0xe8693af51d1d741d), U64_C (0x5347ddb3e0e0a7e0), U64_C (0xf6acb321d7d77bd7), U64_C (0x5eed999cc2c22fc2), U64_C (0x6d965c432e2eb82e), U64_C (0x627a96294b4b314b), U64_C (0xa321e15dfefedffe), U64_C (0x8216aed557574157), U64_C (0xa8412abd15155415), U64_C (0x9fb6eee87777c177), U64_C (0xa5eb6e923737dc37), U64_C (0x7b56d79ee5e5b3e5), U64_C (0x8cd923139f9f469f), U64_C (0xd317fd23f0f0e7f0), U64_C (0x6a7f94204a4a354a), U64_C (0x9e95a944dada4fda), U64_C (0xfa25b0a258587d58), U64_C (0x06ca8fcfc9c903c9), U64_C (0x558d527c2929a429), U64_C (0x5022145a0a0a280a), U64_C (0xe14f7f50b1b1feb1), U64_C (0x691a5dc9a0a0baa0), U64_C (0x7fdad6146b6bb16b), U64_C (0x5cab17d985852e85), U64_C (0x8173673cbdbdcebd), U64_C (0xd234ba8f5d5d695d), U64_C (0x8050209010104010), U64_C (0xf303f507f4f4f7f4), U64_C (0x16c08bddcbcb0bcb), U64_C (0xedc67cd33e3ef83e), U64_C (0x28110a2d05051405), U64_C (0x1fe6ce7867678167), U64_C (0x7353d597e4e4b7e4), U64_C (0x25bb4e0227279c27), U64_C (0x3258827341411941), U64_C (0x2c9d0ba78b8b168b), U64_C (0x510153f6a7a7a6a7), U64_C (0xcf94fab27d7de97d), U64_C (0xdcfb374995956e95), U64_C (0x8e9fad56d8d847d8), U64_C (0x8b30eb70fbfbcbfb), U64_C (0x2371c1cdeeee9fee), U64_C (0xc791f8bb7c7ced7c), U64_C (0x17e3cc7166668566), U64_C (0xa68ea77bdddd53dd), U64_C (0xb84b2eaf17175c17), U64_C (0x02468e4547470147), U64_C (0x84dc211a9e9e429e), U64_C (0x1ec589d4caca0fca), U64_C (0x75995a582d2db42d), U64_C (0x9179632ebfbfc6bf), U64_C (0x381b0e3f07071c07), U64_C (0x012347acadad8ead), U64_C (0xea2fb4b05a5a755a), U64_C (0x6cb51bef83833683), U64_C (0x85ff66b63333cc33), U64_C (0x3ff2c65c63639163), U64_C (0x100a041202020802), U64_C (0x39384993aaaa92aa), U64_C (0xafa8e2de7171d971), U64_C (0x0ecf8dc6c8c807c8), U64_C (0xc87d32d119196419), U64_C (0x7270923b49493949), U64_C (0x869aaf5fd9d943d9), U64_C (0xc31df931f2f2eff2), U64_C (0x4b48dba8e3e3abe3), U64_C (0xe22ab6b95b5b715b), U64_C (0x34920dbc88881a88), U64_C (0xa4c8293e9a9a529a), U64_C (0x2dbe4c0b26269826), U64_C (0x8dfa64bf3232c832), U64_C (0xe94a7d59b0b0fab0), U64_C (0x1b6acff2e9e983e9), U64_C (0x78331e770f0f3c0f), U64_C (0xe6a6b733d5d573d5), U64_C (0x74ba1df480803a80), U64_C (0x997c6127bebec2be), U64_C (0x26de87ebcdcd13cd), U64_C (0xbde468893434d034), U64_C (0x7a75903248483d48), U64_C (0xab24e354ffffdbff), U64_C (0xf78ff48d7a7af57a), U64_C (0xf4ea3d6490907a90), U64_C (0xc23ebe9d5f5f615f), U64_C (0x1da0403d20208020), U64_C (0x67d5d00f6868bd68), U64_C (0xd07234ca1a1a681a), U64_C (0x192c41b7aeae82ae), U64_C (0xc95e757db4b4eab4), U64_C (0x9a19a8ce54544d54), U64_C (0xece53b7f93937693), U64_C (0x0daa442f22228822), U64_C (0x07e9c86364648d64), U64_C (0xdb12ff2af1f1e3f1), U64_C (0xbfa2e6cc7373d173), U64_C (0x905a248212124812), U64_C (0x3a5d807a40401d40), U64_C (0x4028104808082008), U64_C (0x56e89b95c3c32bc3), U64_C (0x337bc5dfecec97ec), U64_C (0x9690ab4ddbdb4bdb), U64_C (0x611f5fc0a1a1bea1), U64_C (0x1c8307918d8d0e8d), U64_C (0xf5c97ac83d3df43d), U64_C (0xccf1335b97976697), U64_C (0x0000000000000000), U64_C (0x36d483f9cfcf1bcf), U64_C (0x4587566e2b2bac2b), U64_C (0x97b3ece17676c576), U64_C (0x64b019e682823282), U64_C (0xfea9b128d6d67fd6), U64_C (0xd87736c31b1b6c1b), U64_C (0xc15b7774b5b5eeb5), U64_C (0x112943beafaf86af), U64_C (0x77dfd41d6a6ab56a), U64_C (0xba0da0ea50505d50), U64_C (0x124c8a5745450945), U64_C (0xcb18fb38f3f3ebf3), U64_C (0x9df060ad3030c030), U64_C (0x2b74c3c4efef9bef), U64_C (0xe5c37eda3f3ffc3f), U64_C (0x921caac755554955), U64_C (0x791059dba2a2b2a2), U64_C (0x0365c9e9eaea8fea), U64_C (0x0fecca6a65658965), U64_C (0xb9686903babad2ba), U64_C (0x65935e4a2f2fbc2f), U64_C (0x4ee79d8ec0c027c0), U64_C (0xbe81a160dede5fde), U64_C (0xe06c38fc1c1c701c), U64_C (0xbb2ee746fdfdd3fd), U64_C (0x52649a1f4d4d294d), U64_C (0xe4e0397692927292), U64_C (0x8fbceafa7575c975), U64_C (0x301e0c3606061806), U64_C (0x249809ae8a8a128a), U64_C (0xf940794bb2b2f2b2), U64_C (0x6359d185e6e6bfe6), U64_C (0x70361c7e0e0e380e), U64_C (0xf8633ee71f1f7c1f), U64_C (0x37f7c45562629562), U64_C (0xeea3b53ad4d477d4), U64_C (0x29324d81a8a89aa8), U64_C (0xc4f4315296966296), U64_C (0x9b3aef62f9f9c3f9), U64_C (0x66f697a3c5c533c5), U64_C (0x35b14a1025259425), U64_C (0xf220b2ab59597959), U64_C (0x54ae15d084842a84), U64_C (0xb7a7e4c57272d572), U64_C (0xd5dd72ec3939e439), U64_C (0x5a6198164c4c2d4c), U64_C (0xca3bbc945e5e655e), U64_C (0xe785f09f7878fd78), U64_C (0xddd870e53838e038), U64_C (0x148605988c8c0a8c), U64_C (0xc6b2bf17d1d163d1), U64_C (0x410b57e4a5a5aea5), U64_C (0x434dd9a1e2e2afe2), U64_C (0x2ff8c24e61619961), U64_C (0xf1457b42b3b3f6b3), U64_C (0x15a5423421218421), U64_C (0x94d625089c9c4a9c), U64_C (0xf0663cee1e1e781e), U64_C (0x2252866143431143), U64_C (0x76fc93b1c7c73bc7), U64_C (0xb32be54ffcfcd7fc), U64_C (0x2014082404041004), U64_C (0xb208a2e351515951), U64_C (0xbcc72f2599995e99), U64_C (0x4fc4da226d6da96d), U64_C (0x68391a650d0d340d), U64_C (0x8335e979fafacffa), U64_C (0xb684a369dfdf5bdf), U64_C (0xd79bfca97e7ee57e), U64_C (0x3db4481924249024), U64_C (0xc5d776fe3b3bec3b), U64_C (0x313d4b9aabab96ab), U64_C (0x3ed181f0cece1fce), U64_C (0x8855229911114411), U64_C (0x0c8903838f8f068f), U64_C (0x4a6b9c044e4e254e), U64_C (0xd1517366b7b7e6b7), U64_C (0x0b60cbe0ebeb8beb), U64_C (0xfdcc78c13c3cf03c), U64_C (0x7cbf1ffd81813e81), U64_C (0xd4fe354094946a94), U64_C (0xeb0cf31cf7f7fbf7), U64_C (0xa1676f18b9b9deb9), U64_C (0x985f268b13134c13), U64_C (0x7d9c58512c2cb02c), U64_C (0xd6b8bb05d3d36bd3), U64_C (0x6b5cd38ce7e7bbe7), U64_C (0x57cbdc396e6ea56e), U64_C (0x6ef395aac4c437c4), U64_C (0x180f061b03030c03), U64_C (0x8a13acdc56564556), U64_C (0x1a49885e44440d44), U64_C (0xdf9efea07f7fe17f), U64_C (0x21374f88a9a99ea9), U64_C (0x4d8254672a2aa82a), U64_C (0xb16d6b0abbbbd6bb), U64_C (0x46e29f87c1c123c1), U64_C (0xa202a6f153535153), U64_C (0xae8ba572dcdc57dc), U64_C (0x582716530b0b2c0b), U64_C (0x9cd327019d9d4e9d), U64_C (0x47c1d82b6c6cad6c), U64_C (0x95f562a43131c431), U64_C (0x87b9e8f37474cd74), U64_C (0xe309f115f6f6fff6), U64_C (0x0a438c4c46460546), U64_C (0x092645a5acac8aac), U64_C (0x3c970fb589891e89), U64_C (0xa04428b414145014), U64_C (0x5b42dfbae1e1a3e1), U64_C (0xb04e2ca616165816), U64_C (0xcdd274f73a3ae83a), U64_C (0x6fd0d2066969b969), U64_C (0x482d124109092409), U64_C (0xa7ade0d77070dd70), U64_C (0xd954716fb6b6e2b6), U64_C (0xceb7bd1ed0d067d0), U64_C (0x3b7ec7d6eded93ed), U64_C (0x2edb85e2cccc17cc), U64_C (0x2a57846842421542), U64_C (0xb4c22d2c98985a98), U64_C (0x490e55eda4a4aaa4), U64_C (0x5d8850752828a028), U64_C (0xda31b8865c5c6d5c), U64_C (0x933fed6bf8f8c7f8), U64_C (0x44a411c286862286), }, { U64_C (0x18c07830d8181860), U64_C (0x2305af462623238c), U64_C (0xc67ef991b8c6c63f), U64_C (0xe8136fcdfbe8e887), U64_C (0x874ca113cb878726), U64_C (0xb8a9626d11b8b8da), U64_C (0x0108050209010104), U64_C (0x4f426e9e0d4f4f21), U64_C (0x36adee6c9b3636d8), U64_C (0xa6590451ffa6a6a2), U64_C (0xd2debdb90cd2d26f), U64_C (0xf5fb06f70ef5f5f3), U64_C (0x79ef80f2967979f9), U64_C (0x6f5fcede306f6fa1), U64_C (0x91fcef3f6d91917e), U64_C (0x52aa07a4f8525255), U64_C (0x6027fdc04760609d), U64_C (0xbc89766535bcbcca), U64_C (0x9baccd2b379b9b56), U64_C (0x8e048c018a8e8e02), U64_C (0xa371155bd2a3a3b6), U64_C (0x0c603c186c0c0c30), U64_C (0x7bff8af6847b7bf1), U64_C (0x35b5e16a803535d4), U64_C (0x1de8693af51d1d74), U64_C (0xe05347ddb3e0e0a7), U64_C (0xd7f6acb321d7d77b), U64_C (0xc25eed999cc2c22f), U64_C (0x2e6d965c432e2eb8), U64_C (0x4b627a96294b4b31), U64_C (0xfea321e15dfefedf), U64_C (0x578216aed5575741), U64_C (0x15a8412abd151554), U64_C (0x779fb6eee87777c1), U64_C (0x37a5eb6e923737dc), U64_C (0xe57b56d79ee5e5b3), U64_C (0x9f8cd923139f9f46), U64_C (0xf0d317fd23f0f0e7), U64_C (0x4a6a7f94204a4a35), U64_C (0xda9e95a944dada4f), U64_C (0x58fa25b0a258587d), U64_C (0xc906ca8fcfc9c903), U64_C (0x29558d527c2929a4), U64_C (0x0a5022145a0a0a28), U64_C (0xb1e14f7f50b1b1fe), U64_C (0xa0691a5dc9a0a0ba), U64_C (0x6b7fdad6146b6bb1), U64_C (0x855cab17d985852e), U64_C (0xbd8173673cbdbdce), U64_C (0x5dd234ba8f5d5d69), U64_C (0x1080502090101040), U64_C (0xf4f303f507f4f4f7), U64_C (0xcb16c08bddcbcb0b), U64_C (0x3eedc67cd33e3ef8), U64_C (0x0528110a2d050514), U64_C (0x671fe6ce78676781), U64_C (0xe47353d597e4e4b7), U64_C (0x2725bb4e0227279c), U64_C (0x4132588273414119), U64_C (0x8b2c9d0ba78b8b16), U64_C (0xa7510153f6a7a7a6), U64_C (0x7dcf94fab27d7de9), U64_C (0x95dcfb374995956e), U64_C (0xd88e9fad56d8d847), U64_C (0xfb8b30eb70fbfbcb), U64_C (0xee2371c1cdeeee9f), U64_C (0x7cc791f8bb7c7ced), U64_C (0x6617e3cc71666685), U64_C (0xdda68ea77bdddd53), U64_C (0x17b84b2eaf17175c), U64_C (0x4702468e45474701), U64_C (0x9e84dc211a9e9e42), U64_C (0xca1ec589d4caca0f), U64_C (0x2d75995a582d2db4), U64_C (0xbf9179632ebfbfc6), U64_C (0x07381b0e3f07071c), U64_C (0xad012347acadad8e), U64_C (0x5aea2fb4b05a5a75), U64_C (0x836cb51bef838336), U64_C (0x3385ff66b63333cc), U64_C (0x633ff2c65c636391), U64_C (0x02100a0412020208), U64_C (0xaa39384993aaaa92), U64_C (0x71afa8e2de7171d9), U64_C (0xc80ecf8dc6c8c807), U64_C (0x19c87d32d1191964), U64_C (0x497270923b494939), U64_C (0xd9869aaf5fd9d943), U64_C (0xf2c31df931f2f2ef), U64_C (0xe34b48dba8e3e3ab), U64_C (0x5be22ab6b95b5b71), U64_C (0x8834920dbc88881a), U64_C (0x9aa4c8293e9a9a52), U64_C (0x262dbe4c0b262698), U64_C (0x328dfa64bf3232c8), U64_C (0xb0e94a7d59b0b0fa), U64_C (0xe91b6acff2e9e983), U64_C (0x0f78331e770f0f3c), U64_C (0xd5e6a6b733d5d573), U64_C (0x8074ba1df480803a), U64_C (0xbe997c6127bebec2), U64_C (0xcd26de87ebcdcd13), U64_C (0x34bde468893434d0), U64_C (0x487a75903248483d), U64_C (0xffab24e354ffffdb), U64_C (0x7af78ff48d7a7af5), U64_C (0x90f4ea3d6490907a), U64_C (0x5fc23ebe9d5f5f61), U64_C (0x201da0403d202080), U64_C (0x6867d5d00f6868bd), U64_C (0x1ad07234ca1a1a68), U64_C (0xae192c41b7aeae82), U64_C (0xb4c95e757db4b4ea), U64_C (0x549a19a8ce54544d), U64_C (0x93ece53b7f939376), U64_C (0x220daa442f222288), U64_C (0x6407e9c86364648d), U64_C (0xf1db12ff2af1f1e3), U64_C (0x73bfa2e6cc7373d1), U64_C (0x12905a2482121248), U64_C (0x403a5d807a40401d), U64_C (0x0840281048080820), U64_C (0xc356e89b95c3c32b), U64_C (0xec337bc5dfecec97), U64_C (0xdb9690ab4ddbdb4b), U64_C (0xa1611f5fc0a1a1be), U64_C (0x8d1c8307918d8d0e), U64_C (0x3df5c97ac83d3df4), U64_C (0x97ccf1335b979766), U64_C (0x0000000000000000), U64_C (0xcf36d483f9cfcf1b), U64_C (0x2b4587566e2b2bac), U64_C (0x7697b3ece17676c5), U64_C (0x8264b019e6828232), U64_C (0xd6fea9b128d6d67f), U64_C (0x1bd87736c31b1b6c), U64_C (0xb5c15b7774b5b5ee), U64_C (0xaf112943beafaf86), U64_C (0x6a77dfd41d6a6ab5), U64_C (0x50ba0da0ea50505d), U64_C (0x45124c8a57454509), U64_C (0xf3cb18fb38f3f3eb), U64_C (0x309df060ad3030c0), U64_C (0xef2b74c3c4efef9b), U64_C (0x3fe5c37eda3f3ffc), U64_C (0x55921caac7555549), U64_C (0xa2791059dba2a2b2), U64_C (0xea0365c9e9eaea8f), U64_C (0x650fecca6a656589), U64_C (0xbab9686903babad2), U64_C (0x2f65935e4a2f2fbc), U64_C (0xc04ee79d8ec0c027), U64_C (0xdebe81a160dede5f), U64_C (0x1ce06c38fc1c1c70), U64_C (0xfdbb2ee746fdfdd3), U64_C (0x4d52649a1f4d4d29), U64_C (0x92e4e03976929272), U64_C (0x758fbceafa7575c9), U64_C (0x06301e0c36060618), U64_C (0x8a249809ae8a8a12), U64_C (0xb2f940794bb2b2f2), U64_C (0xe66359d185e6e6bf), U64_C (0x0e70361c7e0e0e38), U64_C (0x1ff8633ee71f1f7c), U64_C (0x6237f7c455626295), U64_C (0xd4eea3b53ad4d477), U64_C (0xa829324d81a8a89a), U64_C (0x96c4f43152969662), U64_C (0xf99b3aef62f9f9c3), U64_C (0xc566f697a3c5c533), U64_C (0x2535b14a10252594), U64_C (0x59f220b2ab595979), U64_C (0x8454ae15d084842a), U64_C (0x72b7a7e4c57272d5), U64_C (0x39d5dd72ec3939e4), U64_C (0x4c5a6198164c4c2d), U64_C (0x5eca3bbc945e5e65), U64_C (0x78e785f09f7878fd), U64_C (0x38ddd870e53838e0), U64_C (0x8c148605988c8c0a), U64_C (0xd1c6b2bf17d1d163), U64_C (0xa5410b57e4a5a5ae), U64_C (0xe2434dd9a1e2e2af), U64_C (0x612ff8c24e616199), U64_C (0xb3f1457b42b3b3f6), U64_C (0x2115a54234212184), U64_C (0x9c94d625089c9c4a), U64_C (0x1ef0663cee1e1e78), U64_C (0x4322528661434311), U64_C (0xc776fc93b1c7c73b), U64_C (0xfcb32be54ffcfcd7), U64_C (0x0420140824040410), U64_C (0x51b208a2e3515159), U64_C (0x99bcc72f2599995e), U64_C (0x6d4fc4da226d6da9), U64_C (0x0d68391a650d0d34), U64_C (0xfa8335e979fafacf), U64_C (0xdfb684a369dfdf5b), U64_C (0x7ed79bfca97e7ee5), U64_C (0x243db44819242490), U64_C (0x3bc5d776fe3b3bec), U64_C (0xab313d4b9aabab96), U64_C (0xce3ed181f0cece1f), U64_C (0x1188552299111144), U64_C (0x8f0c8903838f8f06), U64_C (0x4e4a6b9c044e4e25), U64_C (0xb7d1517366b7b7e6), U64_C (0xeb0b60cbe0ebeb8b), U64_C (0x3cfdcc78c13c3cf0), U64_C (0x817cbf1ffd81813e), U64_C (0x94d4fe354094946a), U64_C (0xf7eb0cf31cf7f7fb), U64_C (0xb9a1676f18b9b9de), U64_C (0x13985f268b13134c), U64_C (0x2c7d9c58512c2cb0), U64_C (0xd3d6b8bb05d3d36b), U64_C (0xe76b5cd38ce7e7bb), U64_C (0x6e57cbdc396e6ea5), U64_C (0xc46ef395aac4c437), U64_C (0x03180f061b03030c), U64_C (0x568a13acdc565645), U64_C (0x441a49885e44440d), U64_C (0x7fdf9efea07f7fe1), U64_C (0xa921374f88a9a99e), U64_C (0x2a4d8254672a2aa8), U64_C (0xbbb16d6b0abbbbd6), U64_C (0xc146e29f87c1c123), U64_C (0x53a202a6f1535351), U64_C (0xdcae8ba572dcdc57), U64_C (0x0b582716530b0b2c), U64_C (0x9d9cd327019d9d4e), U64_C (0x6c47c1d82b6c6cad), U64_C (0x3195f562a43131c4), U64_C (0x7487b9e8f37474cd), U64_C (0xf6e309f115f6f6ff), U64_C (0x460a438c4c464605), U64_C (0xac092645a5acac8a), U64_C (0x893c970fb589891e), U64_C (0x14a04428b4141450), U64_C (0xe15b42dfbae1e1a3), U64_C (0x16b04e2ca6161658), U64_C (0x3acdd274f73a3ae8), U64_C (0x696fd0d2066969b9), U64_C (0x09482d1241090924), U64_C (0x70a7ade0d77070dd), U64_C (0xb6d954716fb6b6e2), U64_C (0xd0ceb7bd1ed0d067), U64_C (0xed3b7ec7d6eded93), U64_C (0xcc2edb85e2cccc17), U64_C (0x422a578468424215), U64_C (0x98b4c22d2c98985a), U64_C (0xa4490e55eda4a4aa), U64_C (0x285d8850752828a0), U64_C (0x5cda31b8865c5c6d), U64_C (0xf8933fed6bf8f8c7), U64_C (0x8644a411c2868622), }, { U64_C (0x6018c07830d81818), U64_C (0x8c2305af46262323), U64_C (0x3fc67ef991b8c6c6), U64_C (0x87e8136fcdfbe8e8), U64_C (0x26874ca113cb8787), U64_C (0xdab8a9626d11b8b8), U64_C (0x0401080502090101), U64_C (0x214f426e9e0d4f4f), U64_C (0xd836adee6c9b3636), U64_C (0xa2a6590451ffa6a6), U64_C (0x6fd2debdb90cd2d2), U64_C (0xf3f5fb06f70ef5f5), U64_C (0xf979ef80f2967979), U64_C (0xa16f5fcede306f6f), U64_C (0x7e91fcef3f6d9191), U64_C (0x5552aa07a4f85252), U64_C (0x9d6027fdc0476060), U64_C (0xcabc89766535bcbc), U64_C (0x569baccd2b379b9b), U64_C (0x028e048c018a8e8e), U64_C (0xb6a371155bd2a3a3), U64_C (0x300c603c186c0c0c), U64_C (0xf17bff8af6847b7b), U64_C (0xd435b5e16a803535), U64_C (0x741de8693af51d1d), U64_C (0xa7e05347ddb3e0e0), U64_C (0x7bd7f6acb321d7d7), U64_C (0x2fc25eed999cc2c2), U64_C (0xb82e6d965c432e2e), U64_C (0x314b627a96294b4b), U64_C (0xdffea321e15dfefe), U64_C (0x41578216aed55757), U64_C (0x5415a8412abd1515), U64_C (0xc1779fb6eee87777), U64_C (0xdc37a5eb6e923737), U64_C (0xb3e57b56d79ee5e5), U64_C (0x469f8cd923139f9f), U64_C (0xe7f0d317fd23f0f0), U64_C (0x354a6a7f94204a4a), U64_C (0x4fda9e95a944dada), U64_C (0x7d58fa25b0a25858), U64_C (0x03c906ca8fcfc9c9), U64_C (0xa429558d527c2929), U64_C (0x280a5022145a0a0a), U64_C (0xfeb1e14f7f50b1b1), U64_C (0xbaa0691a5dc9a0a0), U64_C (0xb16b7fdad6146b6b), U64_C (0x2e855cab17d98585), U64_C (0xcebd8173673cbdbd), U64_C (0x695dd234ba8f5d5d), U64_C (0x4010805020901010), U64_C (0xf7f4f303f507f4f4), U64_C (0x0bcb16c08bddcbcb), U64_C (0xf83eedc67cd33e3e), U64_C (0x140528110a2d0505), U64_C (0x81671fe6ce786767), U64_C (0xb7e47353d597e4e4), U64_C (0x9c2725bb4e022727), U64_C (0x1941325882734141), U64_C (0x168b2c9d0ba78b8b), U64_C (0xa6a7510153f6a7a7), U64_C (0xe97dcf94fab27d7d), U64_C (0x6e95dcfb37499595), U64_C (0x47d88e9fad56d8d8), U64_C (0xcbfb8b30eb70fbfb), U64_C (0x9fee2371c1cdeeee), U64_C (0xed7cc791f8bb7c7c), U64_C (0x856617e3cc716666), U64_C (0x53dda68ea77bdddd), U64_C (0x5c17b84b2eaf1717), U64_C (0x014702468e454747), U64_C (0x429e84dc211a9e9e), U64_C (0x0fca1ec589d4caca), U64_C (0xb42d75995a582d2d), U64_C (0xc6bf9179632ebfbf), U64_C (0x1c07381b0e3f0707), U64_C (0x8ead012347acadad), U64_C (0x755aea2fb4b05a5a), U64_C (0x36836cb51bef8383), U64_C (0xcc3385ff66b63333), U64_C (0x91633ff2c65c6363), U64_C (0x0802100a04120202), U64_C (0x92aa39384993aaaa), U64_C (0xd971afa8e2de7171), U64_C (0x07c80ecf8dc6c8c8), U64_C (0x6419c87d32d11919), U64_C (0x39497270923b4949), U64_C (0x43d9869aaf5fd9d9), U64_C (0xeff2c31df931f2f2), U64_C (0xabe34b48dba8e3e3), U64_C (0x715be22ab6b95b5b), U64_C (0x1a8834920dbc8888), U64_C (0x529aa4c8293e9a9a), U64_C (0x98262dbe4c0b2626), U64_C (0xc8328dfa64bf3232), U64_C (0xfab0e94a7d59b0b0), U64_C (0x83e91b6acff2e9e9), U64_C (0x3c0f78331e770f0f), U64_C (0x73d5e6a6b733d5d5), U64_C (0x3a8074ba1df48080), U64_C (0xc2be997c6127bebe), U64_C (0x13cd26de87ebcdcd), U64_C (0xd034bde468893434), U64_C (0x3d487a7590324848), U64_C (0xdbffab24e354ffff), U64_C (0xf57af78ff48d7a7a), U64_C (0x7a90f4ea3d649090), U64_C (0x615fc23ebe9d5f5f), U64_C (0x80201da0403d2020), U64_C (0xbd6867d5d00f6868), U64_C (0x681ad07234ca1a1a), U64_C (0x82ae192c41b7aeae), U64_C (0xeab4c95e757db4b4), U64_C (0x4d549a19a8ce5454), U64_C (0x7693ece53b7f9393), U64_C (0x88220daa442f2222), U64_C (0x8d6407e9c8636464), U64_C (0xe3f1db12ff2af1f1), U64_C (0xd173bfa2e6cc7373), U64_C (0x4812905a24821212), U64_C (0x1d403a5d807a4040), U64_C (0x2008402810480808), U64_C (0x2bc356e89b95c3c3), U64_C (0x97ec337bc5dfecec), U64_C (0x4bdb9690ab4ddbdb), U64_C (0xbea1611f5fc0a1a1), U64_C (0x0e8d1c8307918d8d), U64_C (0xf43df5c97ac83d3d), U64_C (0x6697ccf1335b9797), U64_C (0x0000000000000000), U64_C (0x1bcf36d483f9cfcf), U64_C (0xac2b4587566e2b2b), U64_C (0xc57697b3ece17676), U64_C (0x328264b019e68282), U64_C (0x7fd6fea9b128d6d6), U64_C (0x6c1bd87736c31b1b), U64_C (0xeeb5c15b7774b5b5), U64_C (0x86af112943beafaf), U64_C (0xb56a77dfd41d6a6a), U64_C (0x5d50ba0da0ea5050), U64_C (0x0945124c8a574545), U64_C (0xebf3cb18fb38f3f3), U64_C (0xc0309df060ad3030), U64_C (0x9bef2b74c3c4efef), U64_C (0xfc3fe5c37eda3f3f), U64_C (0x4955921caac75555), U64_C (0xb2a2791059dba2a2), U64_C (0x8fea0365c9e9eaea), U64_C (0x89650fecca6a6565), U64_C (0xd2bab9686903baba), U64_C (0xbc2f65935e4a2f2f), U64_C (0x27c04ee79d8ec0c0), U64_C (0x5fdebe81a160dede), U64_C (0x701ce06c38fc1c1c), U64_C (0xd3fdbb2ee746fdfd), U64_C (0x294d52649a1f4d4d), U64_C (0x7292e4e039769292), U64_C (0xc9758fbceafa7575), U64_C (0x1806301e0c360606), U64_C (0x128a249809ae8a8a), U64_C (0xf2b2f940794bb2b2), U64_C (0xbfe66359d185e6e6), U64_C (0x380e70361c7e0e0e), U64_C (0x7c1ff8633ee71f1f), U64_C (0x956237f7c4556262), U64_C (0x77d4eea3b53ad4d4), U64_C (0x9aa829324d81a8a8), U64_C (0x6296c4f431529696), U64_C (0xc3f99b3aef62f9f9), U64_C (0x33c566f697a3c5c5), U64_C (0x942535b14a102525), U64_C (0x7959f220b2ab5959), U64_C (0x2a8454ae15d08484), U64_C (0xd572b7a7e4c57272), U64_C (0xe439d5dd72ec3939), U64_C (0x2d4c5a6198164c4c), U64_C (0x655eca3bbc945e5e), U64_C (0xfd78e785f09f7878), U64_C (0xe038ddd870e53838), U64_C (0x0a8c148605988c8c), U64_C (0x63d1c6b2bf17d1d1), U64_C (0xaea5410b57e4a5a5), U64_C (0xafe2434dd9a1e2e2), U64_C (0x99612ff8c24e6161), U64_C (0xf6b3f1457b42b3b3), U64_C (0x842115a542342121), U64_C (0x4a9c94d625089c9c), U64_C (0x781ef0663cee1e1e), U64_C (0x1143225286614343), U64_C (0x3bc776fc93b1c7c7), U64_C (0xd7fcb32be54ffcfc), U64_C (0x1004201408240404), U64_C (0x5951b208a2e35151), U64_C (0x5e99bcc72f259999), U64_C (0xa96d4fc4da226d6d), U64_C (0x340d68391a650d0d), U64_C (0xcffa8335e979fafa), U64_C (0x5bdfb684a369dfdf), U64_C (0xe57ed79bfca97e7e), U64_C (0x90243db448192424), U64_C (0xec3bc5d776fe3b3b), U64_C (0x96ab313d4b9aabab), U64_C (0x1fce3ed181f0cece), U64_C (0x4411885522991111), U64_C (0x068f0c8903838f8f), U64_C (0x254e4a6b9c044e4e), U64_C (0xe6b7d1517366b7b7), U64_C (0x8beb0b60cbe0ebeb), U64_C (0xf03cfdcc78c13c3c), U64_C (0x3e817cbf1ffd8181), U64_C (0x6a94d4fe35409494), U64_C (0xfbf7eb0cf31cf7f7), U64_C (0xdeb9a1676f18b9b9), U64_C (0x4c13985f268b1313), U64_C (0xb02c7d9c58512c2c), U64_C (0x6bd3d6b8bb05d3d3), U64_C (0xbbe76b5cd38ce7e7), U64_C (0xa56e57cbdc396e6e), U64_C (0x37c46ef395aac4c4), U64_C (0x0c03180f061b0303), U64_C (0x45568a13acdc5656), U64_C (0x0d441a49885e4444), U64_C (0xe17fdf9efea07f7f), U64_C (0x9ea921374f88a9a9), U64_C (0xa82a4d8254672a2a), U64_C (0xd6bbb16d6b0abbbb), U64_C (0x23c146e29f87c1c1), U64_C (0x5153a202a6f15353), U64_C (0x57dcae8ba572dcdc), U64_C (0x2c0b582716530b0b), U64_C (0x4e9d9cd327019d9d), U64_C (0xad6c47c1d82b6c6c), U64_C (0xc43195f562a43131), U64_C (0xcd7487b9e8f37474), U64_C (0xfff6e309f115f6f6), U64_C (0x05460a438c4c4646), U64_C (0x8aac092645a5acac), U64_C (0x1e893c970fb58989), U64_C (0x5014a04428b41414), U64_C (0xa3e15b42dfbae1e1), U64_C (0x5816b04e2ca61616), U64_C (0xe83acdd274f73a3a), U64_C (0xb9696fd0d2066969), U64_C (0x2409482d12410909), U64_C (0xdd70a7ade0d77070), U64_C (0xe2b6d954716fb6b6), U64_C (0x67d0ceb7bd1ed0d0), U64_C (0x93ed3b7ec7d6eded), U64_C (0x17cc2edb85e2cccc), U64_C (0x15422a5784684242), U64_C (0x5a98b4c22d2c9898), U64_C (0xaaa4490e55eda4a4), U64_C (0xa0285d8850752828), U64_C (0x6d5cda31b8865c5c), U64_C (0xc7f8933fed6bf8f8), U64_C (0x228644a411c28686), }, { U64_C (0x186018c07830d818), U64_C (0x238c2305af462623), U64_C (0xc63fc67ef991b8c6), U64_C (0xe887e8136fcdfbe8), U64_C (0x8726874ca113cb87), U64_C (0xb8dab8a9626d11b8), U64_C (0x0104010805020901), U64_C (0x4f214f426e9e0d4f), U64_C (0x36d836adee6c9b36), U64_C (0xa6a2a6590451ffa6), U64_C (0xd26fd2debdb90cd2), U64_C (0xf5f3f5fb06f70ef5), U64_C (0x79f979ef80f29679), U64_C (0x6fa16f5fcede306f), U64_C (0x917e91fcef3f6d91), U64_C (0x525552aa07a4f852), U64_C (0x609d6027fdc04760), U64_C (0xbccabc89766535bc), U64_C (0x9b569baccd2b379b), U64_C (0x8e028e048c018a8e), U64_C (0xa3b6a371155bd2a3), U64_C (0x0c300c603c186c0c), U64_C (0x7bf17bff8af6847b), U64_C (0x35d435b5e16a8035), U64_C (0x1d741de8693af51d), U64_C (0xe0a7e05347ddb3e0), U64_C (0xd77bd7f6acb321d7), U64_C (0xc22fc25eed999cc2), U64_C (0x2eb82e6d965c432e), U64_C (0x4b314b627a96294b), U64_C (0xfedffea321e15dfe), U64_C (0x5741578216aed557), U64_C (0x155415a8412abd15), U64_C (0x77c1779fb6eee877), U64_C (0x37dc37a5eb6e9237), U64_C (0xe5b3e57b56d79ee5), U64_C (0x9f469f8cd923139f), U64_C (0xf0e7f0d317fd23f0), U64_C (0x4a354a6a7f94204a), U64_C (0xda4fda9e95a944da), U64_C (0x587d58fa25b0a258), U64_C (0xc903c906ca8fcfc9), U64_C (0x29a429558d527c29), U64_C (0x0a280a5022145a0a), U64_C (0xb1feb1e14f7f50b1), U64_C (0xa0baa0691a5dc9a0), U64_C (0x6bb16b7fdad6146b), U64_C (0x852e855cab17d985), U64_C (0xbdcebd8173673cbd), U64_C (0x5d695dd234ba8f5d), U64_C (0x1040108050209010), U64_C (0xf4f7f4f303f507f4), U64_C (0xcb0bcb16c08bddcb), U64_C (0x3ef83eedc67cd33e), U64_C (0x05140528110a2d05), U64_C (0x6781671fe6ce7867), U64_C (0xe4b7e47353d597e4), U64_C (0x279c2725bb4e0227), U64_C (0x4119413258827341), U64_C (0x8b168b2c9d0ba78b), U64_C (0xa7a6a7510153f6a7), U64_C (0x7de97dcf94fab27d), U64_C (0x956e95dcfb374995), U64_C (0xd847d88e9fad56d8), U64_C (0xfbcbfb8b30eb70fb), U64_C (0xee9fee2371c1cdee), U64_C (0x7ced7cc791f8bb7c), U64_C (0x66856617e3cc7166), U64_C (0xdd53dda68ea77bdd), U64_C (0x175c17b84b2eaf17), U64_C (0x47014702468e4547), U64_C (0x9e429e84dc211a9e), U64_C (0xca0fca1ec589d4ca), U64_C (0x2db42d75995a582d), U64_C (0xbfc6bf9179632ebf), U64_C (0x071c07381b0e3f07), U64_C (0xad8ead012347acad), U64_C (0x5a755aea2fb4b05a), U64_C (0x8336836cb51bef83), U64_C (0x33cc3385ff66b633), U64_C (0x6391633ff2c65c63), U64_C (0x020802100a041202), U64_C (0xaa92aa39384993aa), U64_C (0x71d971afa8e2de71), U64_C (0xc807c80ecf8dc6c8), U64_C (0x196419c87d32d119), U64_C (0x4939497270923b49), U64_C (0xd943d9869aaf5fd9), U64_C (0xf2eff2c31df931f2), U64_C (0xe3abe34b48dba8e3), U64_C (0x5b715be22ab6b95b), U64_C (0x881a8834920dbc88), U64_C (0x9a529aa4c8293e9a), U64_C (0x2698262dbe4c0b26), U64_C (0x32c8328dfa64bf32), U64_C (0xb0fab0e94a7d59b0), U64_C (0xe983e91b6acff2e9), U64_C (0x0f3c0f78331e770f), U64_C (0xd573d5e6a6b733d5), U64_C (0x803a8074ba1df480), U64_C (0xbec2be997c6127be), U64_C (0xcd13cd26de87ebcd), U64_C (0x34d034bde4688934), U64_C (0x483d487a75903248), U64_C (0xffdbffab24e354ff), U64_C (0x7af57af78ff48d7a), U64_C (0x907a90f4ea3d6490), U64_C (0x5f615fc23ebe9d5f), U64_C (0x2080201da0403d20), U64_C (0x68bd6867d5d00f68), U64_C (0x1a681ad07234ca1a), U64_C (0xae82ae192c41b7ae), U64_C (0xb4eab4c95e757db4), U64_C (0x544d549a19a8ce54), U64_C (0x937693ece53b7f93), U64_C (0x2288220daa442f22), U64_C (0x648d6407e9c86364), U64_C (0xf1e3f1db12ff2af1), U64_C (0x73d173bfa2e6cc73), U64_C (0x124812905a248212), U64_C (0x401d403a5d807a40), U64_C (0x0820084028104808), U64_C (0xc32bc356e89b95c3), U64_C (0xec97ec337bc5dfec), U64_C (0xdb4bdb9690ab4ddb), U64_C (0xa1bea1611f5fc0a1), U64_C (0x8d0e8d1c8307918d), U64_C (0x3df43df5c97ac83d), U64_C (0x976697ccf1335b97), U64_C (0x0000000000000000), U64_C (0xcf1bcf36d483f9cf), U64_C (0x2bac2b4587566e2b), U64_C (0x76c57697b3ece176), U64_C (0x82328264b019e682), U64_C (0xd67fd6fea9b128d6), U64_C (0x1b6c1bd87736c31b), U64_C (0xb5eeb5c15b7774b5), U64_C (0xaf86af112943beaf), U64_C (0x6ab56a77dfd41d6a), U64_C (0x505d50ba0da0ea50), U64_C (0x450945124c8a5745), U64_C (0xf3ebf3cb18fb38f3), U64_C (0x30c0309df060ad30), U64_C (0xef9bef2b74c3c4ef), U64_C (0x3ffc3fe5c37eda3f), U64_C (0x554955921caac755), U64_C (0xa2b2a2791059dba2), U64_C (0xea8fea0365c9e9ea), U64_C (0x6589650fecca6a65), U64_C (0xbad2bab9686903ba), U64_C (0x2fbc2f65935e4a2f), U64_C (0xc027c04ee79d8ec0), U64_C (0xde5fdebe81a160de), U64_C (0x1c701ce06c38fc1c), U64_C (0xfdd3fdbb2ee746fd), U64_C (0x4d294d52649a1f4d), U64_C (0x927292e4e0397692), U64_C (0x75c9758fbceafa75), U64_C (0x061806301e0c3606), U64_C (0x8a128a249809ae8a), U64_C (0xb2f2b2f940794bb2), U64_C (0xe6bfe66359d185e6), U64_C (0x0e380e70361c7e0e), U64_C (0x1f7c1ff8633ee71f), U64_C (0x62956237f7c45562), U64_C (0xd477d4eea3b53ad4), U64_C (0xa89aa829324d81a8), U64_C (0x966296c4f4315296), U64_C (0xf9c3f99b3aef62f9), U64_C (0xc533c566f697a3c5), U64_C (0x25942535b14a1025), U64_C (0x597959f220b2ab59), U64_C (0x842a8454ae15d084), U64_C (0x72d572b7a7e4c572), U64_C (0x39e439d5dd72ec39), U64_C (0x4c2d4c5a6198164c), U64_C (0x5e655eca3bbc945e), U64_C (0x78fd78e785f09f78), U64_C (0x38e038ddd870e538), U64_C (0x8c0a8c148605988c), U64_C (0xd163d1c6b2bf17d1), U64_C (0xa5aea5410b57e4a5), U64_C (0xe2afe2434dd9a1e2), U64_C (0x6199612ff8c24e61), U64_C (0xb3f6b3f1457b42b3), U64_C (0x21842115a5423421), U64_C (0x9c4a9c94d625089c), U64_C (0x1e781ef0663cee1e), U64_C (0x4311432252866143), U64_C (0xc73bc776fc93b1c7), U64_C (0xfcd7fcb32be54ffc), U64_C (0x0410042014082404), U64_C (0x515951b208a2e351), U64_C (0x995e99bcc72f2599), U64_C (0x6da96d4fc4da226d), U64_C (0x0d340d68391a650d), U64_C (0xfacffa8335e979fa), U64_C (0xdf5bdfb684a369df), U64_C (0x7ee57ed79bfca97e), U64_C (0x2490243db4481924), U64_C (0x3bec3bc5d776fe3b), U64_C (0xab96ab313d4b9aab), U64_C (0xce1fce3ed181f0ce), U64_C (0x1144118855229911), U64_C (0x8f068f0c8903838f), U64_C (0x4e254e4a6b9c044e), U64_C (0xb7e6b7d1517366b7), U64_C (0xeb8beb0b60cbe0eb), U64_C (0x3cf03cfdcc78c13c), U64_C (0x813e817cbf1ffd81), U64_C (0x946a94d4fe354094), U64_C (0xf7fbf7eb0cf31cf7), U64_C (0xb9deb9a1676f18b9), U64_C (0x134c13985f268b13), U64_C (0x2cb02c7d9c58512c), U64_C (0xd36bd3d6b8bb05d3), U64_C (0xe7bbe76b5cd38ce7), U64_C (0x6ea56e57cbdc396e), U64_C (0xc437c46ef395aac4), U64_C (0x030c03180f061b03), U64_C (0x5645568a13acdc56), U64_C (0x440d441a49885e44), U64_C (0x7fe17fdf9efea07f), U64_C (0xa99ea921374f88a9), U64_C (0x2aa82a4d8254672a), U64_C (0xbbd6bbb16d6b0abb), U64_C (0xc123c146e29f87c1), U64_C (0x535153a202a6f153), U64_C (0xdc57dcae8ba572dc), U64_C (0x0b2c0b582716530b), U64_C (0x9d4e9d9cd327019d), U64_C (0x6cad6c47c1d82b6c), U64_C (0x31c43195f562a431), U64_C (0x74cd7487b9e8f374), U64_C (0xf6fff6e309f115f6), U64_C (0x4605460a438c4c46), U64_C (0xac8aac092645a5ac), U64_C (0x891e893c970fb589), U64_C (0x145014a04428b414), U64_C (0xe1a3e15b42dfbae1), U64_C (0x165816b04e2ca616), U64_C (0x3ae83acdd274f73a), U64_C (0x69b9696fd0d20669), U64_C (0x092409482d124109), U64_C (0x70dd70a7ade0d770), U64_C (0xb6e2b6d954716fb6), U64_C (0xd067d0ceb7bd1ed0), U64_C (0xed93ed3b7ec7d6ed), U64_C (0xcc17cc2edb85e2cc), U64_C (0x4215422a57846842), U64_C (0x985a98b4c22d2c98), U64_C (0xa4aaa4490e55eda4), U64_C (0x28a0285d88507528), U64_C (0x5c6d5cda31b8865c), U64_C (0xf8c7f8933fed6bf8), U64_C (0x86228644a411c286), } } }; #define C tab.C #define C0 C[0] #define C1 C[1] #define C2 C[2] #define C3 C[3] #define C4 C[4] #define C5 C[5] #define C6 C[6] #define C7 C[7] #define rc tab.RC static unsigned int whirlpool_transform (void *ctx, const unsigned char *data, size_t nblks); static void whirlpool_init (void *ctx, unsigned int flags) { whirlpool_context_t *context = ctx; memset (context, 0, sizeof (*context)); context->bctx.blocksize = BLOCK_SIZE; context->bctx.bwrite = whirlpool_transform; if ((flags & GCRY_MD_FLAG_BUGEMU1)) { memset (&context->bugemu, 0, sizeof context->bugemu); context->use_bugemu = 1; } else context->use_bugemu = 0; } #ifdef USE_AMD64_ASM #ifdef HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS # define ASM_FUNC_ABI __attribute__((sysv_abi)) # define ASM_EXTRA_STACK (10 * 16) #else # define ASM_FUNC_ABI # define ASM_EXTRA_STACK 0 #endif extern unsigned int _gcry_whirlpool_transform_amd64(u64 *state, const unsigned char *data, size_t nblks, const struct whirlpool_tables_s *tables) ASM_FUNC_ABI; static unsigned int whirlpool_transform (void *ctx, const unsigned char *data, size_t nblks) { whirlpool_context_t *context = ctx; return _gcry_whirlpool_transform_amd64( context->hash_state, data, nblks, &tab) + ASM_EXTRA_STACK; } #else /* USE_AMD64_ASM */ /* * Transform block. */ static unsigned int whirlpool_transform_blk (void *ctx, const unsigned char *data) { whirlpool_context_t *context = ctx; whirlpool_block_t data_block; whirlpool_block_t key; whirlpool_block_t state; whirlpool_block_t block; unsigned int r; unsigned int i; buffer_to_block (data, data_block, i); block_copy (key, context->hash_state, i); block_copy (state, context->hash_state, i); block_xor (state, data_block, i); for (r = 0; r < R; r++) { /* Compute round key K^r. */ block[0] = (C0[(key[0] >> 56) & 0xFF] ^ C1[(key[7] >> 48) & 0xFF] ^ C2[(key[6] >> 40) & 0xFF] ^ C3[(key[5] >> 32) & 0xFF] ^ C4[(key[4] >> 24) & 0xFF] ^ C5[(key[3] >> 16) & 0xFF] ^ C6[(key[2] >> 8) & 0xFF] ^ C7[(key[1] >> 0) & 0xFF] ^ rc[r]); block[1] = (C0[(key[1] >> 56) & 0xFF] ^ C1[(key[0] >> 48) & 0xFF] ^ C2[(key[7] >> 40) & 0xFF] ^ C3[(key[6] >> 32) & 0xFF] ^ C4[(key[5] >> 24) & 0xFF] ^ C5[(key[4] >> 16) & 0xFF] ^ C6[(key[3] >> 8) & 0xFF] ^ C7[(key[2] >> 0) & 0xFF]); block[2] = (C0[(key[2] >> 56) & 0xFF] ^ C1[(key[1] >> 48) & 0xFF] ^ C2[(key[0] >> 40) & 0xFF] ^ C3[(key[7] >> 32) & 0xFF] ^ C4[(key[6] >> 24) & 0xFF] ^ C5[(key[5] >> 16) & 0xFF] ^ C6[(key[4] >> 8) & 0xFF] ^ C7[(key[3] >> 0) & 0xFF]); block[3] = (C0[(key[3] >> 56) & 0xFF] ^ C1[(key[2] >> 48) & 0xFF] ^ C2[(key[1] >> 40) & 0xFF] ^ C3[(key[0] >> 32) & 0xFF] ^ C4[(key[7] >> 24) & 0xFF] ^ C5[(key[6] >> 16) & 0xFF] ^ C6[(key[5] >> 8) & 0xFF] ^ C7[(key[4] >> 0) & 0xFF]); block[4] = (C0[(key[4] >> 56) & 0xFF] ^ C1[(key[3] >> 48) & 0xFF] ^ C2[(key[2] >> 40) & 0xFF] ^ C3[(key[1] >> 32) & 0xFF] ^ C4[(key[0] >> 24) & 0xFF] ^ C5[(key[7] >> 16) & 0xFF] ^ C6[(key[6] >> 8) & 0xFF] ^ C7[(key[5] >> 0) & 0xFF]); block[5] = (C0[(key[5] >> 56) & 0xFF] ^ C1[(key[4] >> 48) & 0xFF] ^ C2[(key[3] >> 40) & 0xFF] ^ C3[(key[2] >> 32) & 0xFF] ^ C4[(key[1] >> 24) & 0xFF] ^ C5[(key[0] >> 16) & 0xFF] ^ C6[(key[7] >> 8) & 0xFF] ^ C7[(key[6] >> 0) & 0xFF]); block[6] = (C0[(key[6] >> 56) & 0xFF] ^ C1[(key[5] >> 48) & 0xFF] ^ C2[(key[4] >> 40) & 0xFF] ^ C3[(key[3] >> 32) & 0xFF] ^ C4[(key[2] >> 24) & 0xFF] ^ C5[(key[1] >> 16) & 0xFF] ^ C6[(key[0] >> 8) & 0xFF] ^ C7[(key[7] >> 0) & 0xFF]); block[7] = (C0[(key[7] >> 56) & 0xFF] ^ C1[(key[6] >> 48) & 0xFF] ^ C2[(key[5] >> 40) & 0xFF] ^ C3[(key[4] >> 32) & 0xFF] ^ C4[(key[3] >> 24) & 0xFF] ^ C5[(key[2] >> 16) & 0xFF] ^ C6[(key[1] >> 8) & 0xFF] ^ C7[(key[0] >> 0) & 0xFF]); block_copy (key, block, i); /* Apply r-th round transformation. */ block[0] = (C0[(state[0] >> 56) & 0xFF] ^ C1[(state[7] >> 48) & 0xFF] ^ C2[(state[6] >> 40) & 0xFF] ^ C3[(state[5] >> 32) & 0xFF] ^ C4[(state[4] >> 24) & 0xFF] ^ C5[(state[3] >> 16) & 0xFF] ^ C6[(state[2] >> 8) & 0xFF] ^ C7[(state[1] >> 0) & 0xFF] ^ key[0]); block[1] = (C0[(state[1] >> 56) & 0xFF] ^ C1[(state[0] >> 48) & 0xFF] ^ C2[(state[7] >> 40) & 0xFF] ^ C3[(state[6] >> 32) & 0xFF] ^ C4[(state[5] >> 24) & 0xFF] ^ C5[(state[4] >> 16) & 0xFF] ^ C6[(state[3] >> 8) & 0xFF] ^ C7[(state[2] >> 0) & 0xFF] ^ key[1]); block[2] = (C0[(state[2] >> 56) & 0xFF] ^ C1[(state[1] >> 48) & 0xFF] ^ C2[(state[0] >> 40) & 0xFF] ^ C3[(state[7] >> 32) & 0xFF] ^ C4[(state[6] >> 24) & 0xFF] ^ C5[(state[5] >> 16) & 0xFF] ^ C6[(state[4] >> 8) & 0xFF] ^ C7[(state[3] >> 0) & 0xFF] ^ key[2]); block[3] = (C0[(state[3] >> 56) & 0xFF] ^ C1[(state[2] >> 48) & 0xFF] ^ C2[(state[1] >> 40) & 0xFF] ^ C3[(state[0] >> 32) & 0xFF] ^ C4[(state[7] >> 24) & 0xFF] ^ C5[(state[6] >> 16) & 0xFF] ^ C6[(state[5] >> 8) & 0xFF] ^ C7[(state[4] >> 0) & 0xFF] ^ key[3]); block[4] = (C0[(state[4] >> 56) & 0xFF] ^ C1[(state[3] >> 48) & 0xFF] ^ C2[(state[2] >> 40) & 0xFF] ^ C3[(state[1] >> 32) & 0xFF] ^ C4[(state[0] >> 24) & 0xFF] ^ C5[(state[7] >> 16) & 0xFF] ^ C6[(state[6] >> 8) & 0xFF] ^ C7[(state[5] >> 0) & 0xFF] ^ key[4]); block[5] = (C0[(state[5] >> 56) & 0xFF] ^ C1[(state[4] >> 48) & 0xFF] ^ C2[(state[3] >> 40) & 0xFF] ^ C3[(state[2] >> 32) & 0xFF] ^ C4[(state[1] >> 24) & 0xFF] ^ C5[(state[0] >> 16) & 0xFF] ^ C6[(state[7] >> 8) & 0xFF] ^ C7[(state[6] >> 0) & 0xFF] ^ key[5]); block[6] = (C0[(state[6] >> 56) & 0xFF] ^ C1[(state[5] >> 48) & 0xFF] ^ C2[(state[4] >> 40) & 0xFF] ^ C3[(state[3] >> 32) & 0xFF] ^ C4[(state[2] >> 24) & 0xFF] ^ C5[(state[1] >> 16) & 0xFF] ^ C6[(state[0] >> 8) & 0xFF] ^ C7[(state[7] >> 0) & 0xFF] ^ key[6]); block[7] = (C0[(state[7] >> 56) & 0xFF] ^ C1[(state[6] >> 48) & 0xFF] ^ C2[(state[5] >> 40) & 0xFF] ^ C3[(state[4] >> 32) & 0xFF] ^ C4[(state[3] >> 24) & 0xFF] ^ C5[(state[2] >> 16) & 0xFF] ^ C6[(state[1] >> 8) & 0xFF] ^ C7[(state[0] >> 0) & 0xFF] ^ key[7]); block_copy (state, block, i); } /* Compression. */ block_xor (context->hash_state, data_block, i); block_xor (context->hash_state, state, i); return /*burn_stack*/ 4 * sizeof(whirlpool_block_t) + 2 * sizeof(int) + 4 * sizeof(void*); } static unsigned int whirlpool_transform ( void *c, const unsigned char *data, size_t nblks ) { unsigned int burn; do { burn = whirlpool_transform_blk (c, data); data += BLOCK_SIZE; } while (--nblks); return burn; } #endif /* !USE_AMD64_ASM */ /* Bug compatibility Whirlpool version. */ static void whirlpool_add_bugemu (whirlpool_context_t *context, const void *buffer_arg, size_t buffer_n) { const unsigned char *buffer = buffer_arg; u64 buffer_size; unsigned int carry; unsigned int i; buffer_size = buffer_n; if (context->bugemu.count == BLOCK_SIZE) { /* Flush the buffer. */ whirlpool_transform (context, context->bctx.buf, 1); context->bugemu.count = 0; } if (! buffer) return; /* Nothing to add. */ if (context->bugemu.count) { while (buffer_n && (context->bugemu.count < BLOCK_SIZE)) { context->bctx.buf[context->bugemu.count++] = *buffer++; buffer_n--; } whirlpool_add_bugemu (context, NULL, 0); if (!buffer_n) return; /* Done. This is the bug we emulate. */ } while (buffer_n >= BLOCK_SIZE) { whirlpool_transform (context, buffer, 1); context->bugemu.count = 0; buffer_n -= BLOCK_SIZE; buffer += BLOCK_SIZE; } while (buffer_n && (context->bugemu.count < BLOCK_SIZE)) { context->bctx.buf[context->bugemu.count++] = *buffer++; buffer_n--; } /* Update bit counter. */ carry = 0; buffer_size <<= 3; for (i = 1; i <= 32; i++) { if (! (buffer_size || carry)) break; carry += context->bugemu.length[32 - i] + (buffer_size & 0xFF); context->bugemu.length[32 - i] = carry; buffer_size >>= 8; carry >>= 8; } gcry_assert (! (buffer_size || carry)); } /* Bug compatibility Whirlpool version. */ static void whirlpool_final_bugemu (void *ctx) { whirlpool_context_t *context = ctx; unsigned int i; /* Flush. */ whirlpool_add_bugemu (context, NULL, 0); /* Pad. */ context->bctx.buf[context->bugemu.count++] = 0x80; if (context->bugemu.count > 32) { /* An extra block is necessary. */ while (context->bugemu.count < 64) context->bctx.buf[context->bugemu.count++] = 0; whirlpool_add_bugemu (context, NULL, 0); } while (context->bugemu.count < 32) context->bctx.buf[context->bugemu.count++] = 0; /* Add length of message. */ memcpy (context->bctx.buf + context->bugemu.count, context->bugemu.length, 32); context->bugemu.count += 32; whirlpool_add_bugemu (context, NULL, 0); block_to_buffer (context->bctx.buf, context->hash_state, i); } static void whirlpool_write (void *ctx, const void *buffer, size_t buffer_n) { whirlpool_context_t *context = ctx; if (context->use_bugemu) { whirlpool_add_bugemu (context, buffer, buffer_n); } else { u64 old_nblocks = context->bctx.nblocks; _gcry_md_block_write (context, buffer, buffer_n); gcry_assert (old_nblocks <= context->bctx.nblocks); } } static void whirlpool_final (void *ctx) { whirlpool_context_t *context = ctx; unsigned int i; u64 t, th, lsb, msb; unsigned char *length; if (context->use_bugemu) { whirlpool_final_bugemu (ctx); return; } t = context->bctx.nblocks; /* if (sizeof t == sizeof context->bctx.nblocks) */ th = context->bctx.nblocks_high; /* else */ /* th = context->bctx.nblocks >> 64; In case we ever use u128 */ /* multiply by 64 to make a byte count */ lsb = t << 6; msb = (th << 6) | (t >> 58); /* add the count */ t = lsb; if ((lsb += context->bctx.count) < t) msb++; /* multiply by 8 to make a bit count */ t = lsb; lsb <<= 3; msb <<= 3; msb |= t >> 61; /* Flush. */ whirlpool_write (context, NULL, 0); /* Pad. */ context->bctx.buf[context->bctx.count++] = 0x80; if (context->bctx.count > 32) { /* An extra block is necessary. */ - while (context->bctx.count < 64) - context->bctx.buf[context->bctx.count++] = 0; + if (context->bctx.count < 64) + memset (&context->bctx.buf[context->bctx.count], 0, + 64 - context->bctx.count); + context->bctx.count = 64; whirlpool_write (context, NULL, 0); } - while (context->bctx.count < 32) - context->bctx.buf[context->bctx.count++] = 0; + if (context->bctx.count < 32) + memset (&context->bctx.buf[context->bctx.count], 0, + 32 - context->bctx.count); + context->bctx.count = 32; /* Add length of message. */ length = context->bctx.buf + context->bctx.count; buf_put_be64(&length[0 * 8], 0); buf_put_be64(&length[1 * 8], 0); buf_put_be64(&length[2 * 8], msb); buf_put_be64(&length[3 * 8], lsb); context->bctx.count += 32; whirlpool_write (context, NULL, 0); block_to_buffer (context->bctx.buf, context->hash_state, i); } static byte * whirlpool_read (void *ctx) { whirlpool_context_t *context = ctx; return context->bctx.buf; } gcry_md_spec_t _gcry_digest_spec_whirlpool = { GCRY_MD_WHIRLPOOL, {0, 0}, "WHIRLPOOL", NULL, 0, NULL, 64, whirlpool_init, whirlpool_write, whirlpool_final, whirlpool_read, NULL, NULL, NULL, sizeof (whirlpool_context_t) };