Replaced system SQLite with SQLCipher to support encrypted database

This commit is contained in:
Oleksii Zghurskyi
2025-06-07 18:11:17 +03:00
parent f4198d62a7
commit 177d74700f
534 changed files with 362771 additions and 21 deletions

View File

@@ -0,0 +1,628 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
/* SPDX-License-Identifier: Unlicense */
/*
BLAKE2 reference source code package - reference C implementations
Copyright 2012, Samuel Neves <sneves@dei.uc.pt>. You may use this under the
terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at
your option. The terms of these licenses can be found at:
- CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0
- OpenSSL license : https://www.openssl.org/source/license.html
- Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0
More information about the BLAKE2 hash function can be found at
https://blake2.net.
*/
/* see also https://www.ietf.org/rfc/rfc7693.txt */
#include "tomcrypt_private.h"
#ifdef LTC_BLAKE2B
enum blake2b_constant {
BLAKE2B_BLOCKBYTES = 128,
BLAKE2B_OUTBYTES = 64,
BLAKE2B_KEYBYTES = 64,
BLAKE2B_SALTBYTES = 16,
BLAKE2B_PERSONALBYTES = 16,
BLAKE2B_PARAM_SIZE = 64
};
/* param offsets */
enum {
BLAKE2B_O_DIGEST_LENGTH = 0,
BLAKE2B_O_KEY_LENGTH = 1,
BLAKE2B_O_FANOUT = 2,
BLAKE2B_O_DEPTH = 3,
BLAKE2B_O_LEAF_LENGTH = 4,
BLAKE2B_O_NODE_OFFSET = 8,
BLAKE2B_O_XOF_LENGTH = 12,
BLAKE2B_O_NODE_DEPTH = 16,
BLAKE2B_O_INNER_LENGTH = 17,
BLAKE2B_O_RESERVED = 18,
BLAKE2B_O_SALT = 32,
BLAKE2B_O_PERSONAL = 48
};
/*
struct blake2b_param {
unsigned char digest_length;
unsigned char key_length;
unsigned char fanout;
unsigned char depth;
ulong32 leaf_length;
ulong32 node_offset;
ulong32 xof_length;
unsigned char node_depth;
unsigned char inner_length;
unsigned char reserved[14];
unsigned char salt[BLAKE2B_SALTBYTES];
unsigned char personal[BLAKE2B_PERSONALBYTES];
};
*/
const struct ltc_hash_descriptor blake2b_160_desc =
{
"blake2b-160",
25,
20,
128,
{ 1, 3, 6, 1, 4, 1, 1722, 12, 2, 1, 5 },
11,
&blake2b_160_init,
&blake2b_process,
&blake2b_done,
&blake2b_160_test,
NULL
};
const struct ltc_hash_descriptor blake2b_256_desc =
{
"blake2b-256",
26,
32,
128,
{ 1, 3, 6, 1, 4, 1, 1722, 12, 2, 1, 8 },
11,
&blake2b_256_init,
&blake2b_process,
&blake2b_done,
&blake2b_256_test,
NULL
};
const struct ltc_hash_descriptor blake2b_384_desc =
{
"blake2b-384",
27,
48,
128,
{ 1, 3, 6, 1, 4, 1, 1722, 12, 2, 1, 12 },
11,
&blake2b_384_init,
&blake2b_process,
&blake2b_done,
&blake2b_384_test,
NULL
};
const struct ltc_hash_descriptor blake2b_512_desc =
{
"blake2b-512",
28,
64,
128,
{ 1, 3, 6, 1, 4, 1, 1722, 12, 2, 1, 16 },
11,
&blake2b_512_init,
&blake2b_process,
&blake2b_done,
&blake2b_512_test,
NULL
};
static const ulong64 blake2b_IV[8] =
{
CONST64(0x6a09e667f3bcc908), CONST64(0xbb67ae8584caa73b),
CONST64(0x3c6ef372fe94f82b), CONST64(0xa54ff53a5f1d36f1),
CONST64(0x510e527fade682d1), CONST64(0x9b05688c2b3e6c1f),
CONST64(0x1f83d9abfb41bd6b), CONST64(0x5be0cd19137e2179)
};
static const unsigned char blake2b_sigma[12][16] =
{
{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 } ,
{ 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 } ,
{ 11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4 } ,
{ 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8 } ,
{ 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13 } ,
{ 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9 } ,
{ 12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11 } ,
{ 13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10 } ,
{ 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5 } ,
{ 10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13 , 0 } ,
{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 } ,
{ 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 }
};
static void s_blake2b_set_lastnode(hash_state *md) { md->blake2b.f[1] = CONST64(0xffffffffffffffff); }
/* Some helper functions, not necessarily useful */
static int s_blake2b_is_lastblock(const hash_state *md) { return md->blake2b.f[0] != 0; }
static void s_blake2b_set_lastblock(hash_state *md)
{
if (md->blake2b.last_node) {
s_blake2b_set_lastnode(md);
}
md->blake2b.f[0] = CONST64(0xffffffffffffffff);
}
static void s_blake2b_increment_counter(hash_state *md, ulong64 inc)
{
md->blake2b.t[0] += inc;
if (md->blake2b.t[0] < inc) md->blake2b.t[1]++;
}
static void s_blake2b_init0(hash_state *md)
{
unsigned long i;
XMEMSET(&md->blake2b, 0, sizeof(md->blake2b));
for (i = 0; i < 8; ++i) {
md->blake2b.h[i] = blake2b_IV[i];
}
}
/* init xors IV with input parameter block */
static int s_blake2b_init_param(hash_state *md, const unsigned char *P)
{
unsigned long i;
s_blake2b_init0(md);
/* IV XOR ParamBlock */
for (i = 0; i < 8; ++i) {
ulong64 tmp;
LOAD64L(tmp, P + i * 8);
md->blake2b.h[i] ^= tmp;
}
md->blake2b.outlen = P[BLAKE2B_O_DIGEST_LENGTH];
return CRYPT_OK;
}
/**
Initialize the hash/MAC state
Use this function to init for arbitrary sizes.
Give a key and keylen to init for MAC mode.
@param md The hash state you wish to initialize
@param outlen The desired output-length
@param key The key of the MAC
@param keylen The length of the key
@return CRYPT_OK if successful
*/
int blake2b_init(hash_state *md, unsigned long outlen, const unsigned char *key, unsigned long keylen)
{
unsigned char P[BLAKE2B_PARAM_SIZE];
int err;
LTC_ARGCHK(md != NULL);
if ((!outlen) || (outlen > BLAKE2B_OUTBYTES)) {
return CRYPT_INVALID_ARG;
}
if ((key && !keylen) || (keylen && !key) || (keylen > BLAKE2B_KEYBYTES)) {
return CRYPT_INVALID_ARG;
}
XMEMSET(P, 0, sizeof(P));
P[BLAKE2B_O_DIGEST_LENGTH] = (unsigned char)outlen;
P[BLAKE2B_O_KEY_LENGTH] = (unsigned char)keylen;
P[BLAKE2B_O_FANOUT] = 1;
P[BLAKE2B_O_DEPTH] = 1;
err = s_blake2b_init_param(md, P);
if (err != CRYPT_OK) return err;
if (key) {
unsigned char block[BLAKE2B_BLOCKBYTES];
XMEMSET(block, 0, BLAKE2B_BLOCKBYTES);
XMEMCPY(block, key, keylen);
blake2b_process(md, block, BLAKE2B_BLOCKBYTES);
#ifdef LTC_CLEAN_STACK
zeromem(block, sizeof(block));
#endif
}
return CRYPT_OK;
}
/**
Initialize the hash state
@param md The hash state you wish to initialize
@return CRYPT_OK if successful
*/
int blake2b_160_init(hash_state *md) { return blake2b_init(md, 20, NULL, 0); }
/**
Initialize the hash state
@param md The hash state you wish to initialize
@return CRYPT_OK if successful
*/
int blake2b_256_init(hash_state *md) { return blake2b_init(md, 32, NULL, 0); }
/**
Initialize the hash state
@param md The hash state you wish to initialize
@return CRYPT_OK if successful
*/
int blake2b_384_init(hash_state *md) { return blake2b_init(md, 48, NULL, 0); }
/**
Initialize the hash state
@param md The hash state you wish to initialize
@return CRYPT_OK if successful
*/
int blake2b_512_init(hash_state *md) { return blake2b_init(md, 64, NULL, 0); }
#define G(r, i, a, b, c, d) \
do { \
a = a + b + m[blake2b_sigma[r][2 * i + 0]]; \
d = ROR64(d ^ a, 32); \
c = c + d; \
b = ROR64(b ^ c, 24); \
a = a + b + m[blake2b_sigma[r][2 * i + 1]]; \
d = ROR64(d ^ a, 16); \
c = c + d; \
b = ROR64(b ^ c, 63); \
} while (0)
#define ROUND(r) \
do { \
G(r, 0, v[0], v[4], v[8], v[12]); \
G(r, 1, v[1], v[5], v[9], v[13]); \
G(r, 2, v[2], v[6], v[10], v[14]); \
G(r, 3, v[3], v[7], v[11], v[15]); \
G(r, 4, v[0], v[5], v[10], v[15]); \
G(r, 5, v[1], v[6], v[11], v[12]); \
G(r, 6, v[2], v[7], v[8], v[13]); \
G(r, 7, v[3], v[4], v[9], v[14]); \
} while (0)
#ifdef LTC_CLEAN_STACK
static int ss_blake2b_compress(hash_state *md, const unsigned char *buf)
#else
static int s_blake2b_compress(hash_state *md, const unsigned char *buf)
#endif
{
ulong64 m[16];
ulong64 v[16];
unsigned long i;
for (i = 0; i < 16; ++i) {
LOAD64L(m[i], buf + i * sizeof(m[i]));
}
for (i = 0; i < 8; ++i) {
v[i] = md->blake2b.h[i];
}
v[8] = blake2b_IV[0];
v[9] = blake2b_IV[1];
v[10] = blake2b_IV[2];
v[11] = blake2b_IV[3];
v[12] = blake2b_IV[4] ^ md->blake2b.t[0];
v[13] = blake2b_IV[5] ^ md->blake2b.t[1];
v[14] = blake2b_IV[6] ^ md->blake2b.f[0];
v[15] = blake2b_IV[7] ^ md->blake2b.f[1];
ROUND(0);
ROUND(1);
ROUND(2);
ROUND(3);
ROUND(4);
ROUND(5);
ROUND(6);
ROUND(7);
ROUND(8);
ROUND(9);
ROUND(10);
ROUND(11);
for (i = 0; i < 8; ++i) {
md->blake2b.h[i] = md->blake2b.h[i] ^ v[i] ^ v[i + 8];
}
return CRYPT_OK;
}
#undef G
#undef ROUND
#ifdef LTC_CLEAN_STACK
static int s_blake2b_compress(hash_state *md, const unsigned char *buf)
{
int err;
err = ss_blake2b_compress(md, buf);
burn_stack(sizeof(ulong64) * 32 + sizeof(unsigned long));
return err;
}
#endif
/**
Process a block of memory through the hash
@param md The hash state
@param in The data to hash
@param inlen The length of the data (octets)
@return CRYPT_OK if successful
*/
int blake2b_process(hash_state *md, const unsigned char *in, unsigned long inlen)
{
LTC_ARGCHK(md != NULL);
LTC_ARGCHK(in != NULL);
if (md->blake2b.curlen > sizeof(md->blake2b.buf)) {
return CRYPT_INVALID_ARG;
}
if (inlen > 0) {
unsigned long left = md->blake2b.curlen;
unsigned long fill = BLAKE2B_BLOCKBYTES - left;
if (inlen > fill) {
md->blake2b.curlen = 0;
XMEMCPY(md->blake2b.buf + (left % sizeof(md->blake2b.buf)), in, fill); /* Fill buffer */
s_blake2b_increment_counter(md, BLAKE2B_BLOCKBYTES);
s_blake2b_compress(md, md->blake2b.buf); /* Compress */
in += fill;
inlen -= fill;
while (inlen > BLAKE2B_BLOCKBYTES) {
s_blake2b_increment_counter(md, BLAKE2B_BLOCKBYTES);
s_blake2b_compress(md, in);
in += BLAKE2B_BLOCKBYTES;
inlen -= BLAKE2B_BLOCKBYTES;
}
}
XMEMCPY(md->blake2b.buf + md->blake2b.curlen, in, inlen);
md->blake2b.curlen += inlen;
}
return CRYPT_OK;
}
/**
Terminate the hash to get the digest
@param md The hash state
@param out [out] The destination of the hash (size depending on the length used on init)
@return CRYPT_OK if successful
*/
int blake2b_done(hash_state *md, unsigned char *out)
{
unsigned char buffer[BLAKE2B_OUTBYTES] = { 0 };
unsigned long i;
LTC_ARGCHK(md != NULL);
LTC_ARGCHK(out != NULL);
/* if(md->blakebs.outlen != outlen) return CRYPT_INVALID_ARG; */
if (s_blake2b_is_lastblock(md)) {
return CRYPT_ERROR;
}
s_blake2b_increment_counter(md, md->blake2b.curlen);
s_blake2b_set_lastblock(md);
XMEMSET(md->blake2b.buf + md->blake2b.curlen, 0, BLAKE2B_BLOCKBYTES - md->blake2b.curlen); /* Padding */
s_blake2b_compress(md, md->blake2b.buf);
for (i = 0; i < 8; ++i) { /* Output full hash to temp buffer */
STORE64L(md->blake2b.h[i], buffer + i * 8);
}
XMEMCPY(out, buffer, md->blake2b.outlen);
zeromem(md, sizeof(hash_state));
#ifdef LTC_CLEAN_STACK
zeromem(buffer, sizeof(buffer));
#endif
return CRYPT_OK;
}
/**
Self-test the hash
@return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled
*/
int blake2b_512_test(void)
{
#ifndef LTC_TEST
return CRYPT_NOP;
#else
static const struct {
const char *msg;
unsigned char hash[64];
} tests[] = {
{ "",
{ 0x78, 0x6a, 0x02, 0xf7, 0x42, 0x01, 0x59, 0x03,
0xc6, 0xc6, 0xfd, 0x85, 0x25, 0x52, 0xd2, 0x72,
0x91, 0x2f, 0x47, 0x40, 0xe1, 0x58, 0x47, 0x61,
0x8a, 0x86, 0xe2, 0x17, 0xf7, 0x1f, 0x54, 0x19,
0xd2, 0x5e, 0x10, 0x31, 0xaf, 0xee, 0x58, 0x53,
0x13, 0x89, 0x64, 0x44, 0x93, 0x4e, 0xb0, 0x4b,
0x90, 0x3a, 0x68, 0x5b, 0x14, 0x48, 0xb7, 0x55,
0xd5, 0x6f, 0x70, 0x1a, 0xfe, 0x9b, 0xe2, 0xce } },
{ "abc",
{ 0xba, 0x80, 0xa5, 0x3f, 0x98, 0x1c, 0x4d, 0x0d,
0x6a, 0x27, 0x97, 0xb6, 0x9f, 0x12, 0xf6, 0xe9,
0x4c, 0x21, 0x2f, 0x14, 0x68, 0x5a, 0xc4, 0xb7,
0x4b, 0x12, 0xbb, 0x6f, 0xdb, 0xff, 0xa2, 0xd1,
0x7d, 0x87, 0xc5, 0x39, 0x2a, 0xab, 0x79, 0x2d,
0xc2, 0x52, 0xd5, 0xde, 0x45, 0x33, 0xcc, 0x95,
0x18, 0xd3, 0x8a, 0xa8, 0xdb, 0xf1, 0x92, 0x5a,
0xb9, 0x23, 0x86, 0xed, 0xd4, 0x00, 0x99, 0x23 } },
{ NULL, { 0 } }
};
int i;
unsigned char tmp[64];
hash_state md;
for (i = 0; tests[i].msg != NULL; i++) {
blake2b_512_init(&md);
blake2b_process(&md, (unsigned char *)tests[i].msg, (unsigned long)XSTRLEN(tests[i].msg));
blake2b_done(&md, tmp);
if (compare_testvector(tmp, sizeof(tmp), tests[i].hash, sizeof(tests[i].hash), "BLAKE2B_512", i)) {
return CRYPT_FAIL_TESTVECTOR;
}
}
return CRYPT_OK;
#endif
}
/**
Self-test the hash
@return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled
*/
int blake2b_384_test(void)
{
#ifndef LTC_TEST
return CRYPT_NOP;
#else
static const struct {
const char *msg;
unsigned char hash[48];
} tests[] = {
{ "",
{ 0xb3, 0x28, 0x11, 0x42, 0x33, 0x77, 0xf5, 0x2d,
0x78, 0x62, 0x28, 0x6e, 0xe1, 0xa7, 0x2e, 0xe5,
0x40, 0x52, 0x43, 0x80, 0xfd, 0xa1, 0x72, 0x4a,
0x6f, 0x25, 0xd7, 0x97, 0x8c, 0x6f, 0xd3, 0x24,
0x4a, 0x6c, 0xaf, 0x04, 0x98, 0x81, 0x26, 0x73,
0xc5, 0xe0, 0x5e, 0xf5, 0x83, 0x82, 0x51, 0x00 } },
{ "abc",
{ 0x6f, 0x56, 0xa8, 0x2c, 0x8e, 0x7e, 0xf5, 0x26,
0xdf, 0xe1, 0x82, 0xeb, 0x52, 0x12, 0xf7, 0xdb,
0x9d, 0xf1, 0x31, 0x7e, 0x57, 0x81, 0x5d, 0xbd,
0xa4, 0x60, 0x83, 0xfc, 0x30, 0xf5, 0x4e, 0xe6,
0xc6, 0x6b, 0xa8, 0x3b, 0xe6, 0x4b, 0x30, 0x2d,
0x7c, 0xba, 0x6c, 0xe1, 0x5b, 0xb5, 0x56, 0xf4 } },
{ NULL, { 0 } }
};
int i;
unsigned char tmp[48];
hash_state md;
for (i = 0; tests[i].msg != NULL; i++) {
blake2b_384_init(&md);
blake2b_process(&md, (unsigned char *)tests[i].msg, (unsigned long)XSTRLEN(tests[i].msg));
blake2b_done(&md, tmp);
if (compare_testvector(tmp, sizeof(tmp), tests[i].hash, sizeof(tests[i].hash), "BLAKE2B_384", i)) {
return CRYPT_FAIL_TESTVECTOR;
}
}
return CRYPT_OK;
#endif
}
/**
Self-test the hash
@return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled
*/
int blake2b_256_test(void)
{
#ifndef LTC_TEST
return CRYPT_NOP;
#else
static const struct {
const char *msg;
unsigned char hash[32];
} tests[] = {
{ "",
{ 0x0e, 0x57, 0x51, 0xc0, 0x26, 0xe5, 0x43, 0xb2,
0xe8, 0xab, 0x2e, 0xb0, 0x60, 0x99, 0xda, 0xa1,
0xd1, 0xe5, 0xdf, 0x47, 0x77, 0x8f, 0x77, 0x87,
0xfa, 0xab, 0x45, 0xcd, 0xf1, 0x2f, 0xe3, 0xa8 } },
{ "abc",
{ 0xbd, 0xdd, 0x81, 0x3c, 0x63, 0x42, 0x39, 0x72,
0x31, 0x71, 0xef, 0x3f, 0xee, 0x98, 0x57, 0x9b,
0x94, 0x96, 0x4e, 0x3b, 0xb1, 0xcb, 0x3e, 0x42,
0x72, 0x62, 0xc8, 0xc0, 0x68, 0xd5, 0x23, 0x19 } },
{ "12345678901234567890123456789012345678901234567890"
"12345678901234567890123456789012345678901234567890"
"12345678901234567890123456789012345678901234567890"
"12345678901234567890123456789012345678901234567890"
"12345678901234567890123456789012345678901234567890"
"12345678901234567890123456789012345678901234567890",
{ 0x0f, 0x6e, 0x01, 0x8d, 0x38, 0xd6, 0x3f, 0x08,
0x4d, 0x58, 0xe3, 0x0c, 0x90, 0xfb, 0xa2, 0x41,
0x5f, 0xca, 0x17, 0xfa, 0x66, 0x26, 0x49, 0xf3,
0x8a, 0x30, 0x41, 0x7c, 0x57, 0xcd, 0xa8, 0x14 } },
{ NULL, { 0 } }
};
int i;
unsigned char tmp[32];
hash_state md;
for (i = 0; tests[i].msg != NULL; i++) {
blake2b_256_init(&md);
blake2b_process(&md, (unsigned char *)tests[i].msg, (unsigned long)XSTRLEN(tests[i].msg));
blake2b_done(&md, tmp);
if (compare_testvector(tmp, sizeof(tmp), tests[i].hash, sizeof(tests[i].hash), "BLAKE2B_256", i)) {
return CRYPT_FAIL_TESTVECTOR;
}
}
return CRYPT_OK;
#endif
}
/**
Self-test the hash
@return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled
*/
int blake2b_160_test(void)
{
#ifndef LTC_TEST
return CRYPT_NOP;
#else
static const struct {
const char *msg;
unsigned char hash[20];
} tests[] = {
{ "",
{ 0x33, 0x45, 0x52, 0x4a, 0xbf, 0x6b, 0xbe, 0x18,
0x09, 0x44, 0x92, 0x24, 0xb5, 0x97, 0x2c, 0x41,
0x79, 0x0b, 0x6c, 0xf2 } },
{ "abc",
{ 0x38, 0x42, 0x64, 0xf6, 0x76, 0xf3, 0x95, 0x36,
0x84, 0x05, 0x23, 0xf2, 0x84, 0x92, 0x1c, 0xdc,
0x68, 0xb6, 0x84, 0x6b } },
{ NULL, { 0 } }
};
int i;
unsigned char tmp[20];
hash_state md;
for (i = 0; tests[i].msg != NULL; i++) {
blake2b_160_init(&md);
blake2b_process(&md, (unsigned char *)tests[i].msg, (unsigned long)XSTRLEN(tests[i].msg));
blake2b_done(&md, tmp);
if (compare_testvector(tmp, sizeof(tmp), tests[i].hash, sizeof(tests[i].hash), "BLAKE2B_160", i)) {
return CRYPT_FAIL_TESTVECTOR;
}
}
return CRYPT_OK;
#endif
}
#endif

View File

@@ -0,0 +1,609 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
/* SPDX-License-Identifier: Unlicense */
/*
BLAKE2 reference source code package - reference C implementations
Copyright 2012, Samuel Neves <sneves@dei.uc.pt>. You may use this under the
terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at
your option. The terms of these licenses can be found at:
- CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0
- OpenSSL license : https://www.openssl.org/source/license.html
- Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0
More information about the BLAKE2 hash function can be found at
https://blake2.net.
*/
/* see also https://www.ietf.org/rfc/rfc7693.txt */
#include "tomcrypt_private.h"
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wconversion"
#pragma clang diagnostic ignored "-Wshorten-64-to-32"
#ifdef LTC_BLAKE2S
enum blake2s_constant {
BLAKE2S_BLOCKBYTES = 64,
BLAKE2S_OUTBYTES = 32,
BLAKE2S_KEYBYTES = 32,
BLAKE2S_SALTBYTES = 8,
BLAKE2S_PERSONALBYTES = 8,
BLAKE2S_PARAM_SIZE = 32
};
/* param offsets */
enum {
BLAKE2S_O_DIGEST_LENGTH = 0,
BLAKE2S_O_KEY_LENGTH = 1,
BLAKE2S_O_FANOUT = 2,
BLAKE2S_O_DEPTH = 3,
BLAKE2S_O_LEAF_LENGTH = 4,
BLAKE2S_O_NODE_OFFSET = 8,
BLAKE2S_O_XOF_LENGTH = 12,
BLAKE2S_O_NODE_DEPTH = 14,
BLAKE2S_O_INNER_LENGTH = 15,
BLAKE2S_O_SALT = 16,
BLAKE2S_O_PERSONAL = 24
};
/*
struct blake2s_param {
unsigned char digest_length;
unsigned char key_length;
unsigned char fanout;
unsigned char depth;
ulong32 leaf_length;
ulong32 node_offset;
ushort16 xof_length;
unsigned char node_depth;
unsigned char inner_length;
unsigned char salt[BLAKE2S_SALTBYTES];
unsigned char personal[BLAKE2S_PERSONALBYTES];
};
*/
const struct ltc_hash_descriptor blake2s_128_desc =
{
"blake2s-128",
21,
16,
64,
{ 1, 3, 6, 1, 4, 1, 1722, 12, 2, 2, 4 },
11,
&blake2s_128_init,
&blake2s_process,
&blake2s_done,
&blake2s_128_test,
NULL
};
const struct ltc_hash_descriptor blake2s_160_desc =
{
"blake2s-160",
22,
20,
64,
{ 1, 3, 6, 1, 4, 1, 1722, 12, 2, 2, 5 },
11,
&blake2s_160_init,
&blake2s_process,
&blake2s_done,
&blake2s_160_test,
NULL
};
const struct ltc_hash_descriptor blake2s_224_desc =
{
"blake2s-224",
23,
28,
64,
{ 1, 3, 6, 1, 4, 1, 1722, 12, 2, 2, 7 },
11,
&blake2s_224_init,
&blake2s_process,
&blake2s_done,
&blake2s_224_test,
NULL
};
const struct ltc_hash_descriptor blake2s_256_desc =
{
"blake2s-256",
24,
32,
64,
{ 1, 3, 6, 1, 4, 1, 1722, 12, 2, 2, 8 },
11,
&blake2s_256_init,
&blake2s_process,
&blake2s_done,
&blake2s_256_test,
NULL
};
static const ulong32 blake2s_IV[8] = {
0x6A09E667UL, 0xBB67AE85UL, 0x3C6EF372UL, 0xA54FF53AUL,
0x510E527FUL, 0x9B05688CUL, 0x1F83D9ABUL, 0x5BE0CD19UL
};
static const unsigned char blake2s_sigma[10][16] = {
{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 },
{ 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 },
{ 11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4 },
{ 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8 },
{ 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13 },
{ 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9 },
{ 12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11 },
{ 13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10 },
{ 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5 },
{ 10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13, 0 },
};
static void s_blake2s_set_lastnode(hash_state *md) { md->blake2s.f[1] = 0xffffffffUL; }
/* Some helper functions, not necessarily useful */
static int s_blake2s_is_lastblock(const hash_state *md) { return md->blake2s.f[0] != 0; }
static void s_blake2s_set_lastblock(hash_state *md)
{
if (md->blake2s.last_node) {
s_blake2s_set_lastnode(md);
}
md->blake2s.f[0] = 0xffffffffUL;
}
static void s_blake2s_increment_counter(hash_state *md, const ulong32 inc)
{
md->blake2s.t[0] += inc;
if (md->blake2s.t[0] < inc) md->blake2s.t[1]++;
}
static int s_blake2s_init0(hash_state *md)
{
int i;
XMEMSET(&md->blake2s, 0, sizeof(struct blake2s_state));
for (i = 0; i < 8; ++i) {
md->blake2s.h[i] = blake2s_IV[i];
}
return CRYPT_OK;
}
/* init2 xors IV with input parameter block */
static int s_blake2s_init_param(hash_state *md, const unsigned char *P)
{
unsigned long i;
s_blake2s_init0(md);
/* IV XOR ParamBlock */
for (i = 0; i < 8; ++i) {
ulong32 tmp;
LOAD32L(tmp, P + i * 4);
md->blake2s.h[i] ^= tmp;
}
md->blake2s.outlen = P[BLAKE2S_O_DIGEST_LENGTH];
return CRYPT_OK;
}
/**
Initialize the hash/MAC state
Use this function to init for arbitrary sizes.
Give a key and keylen to init for MAC mode.
@param md The hash state you wish to initialize
@param outlen The desired output-length
@param key The key of the MAC
@param keylen The length of the key
@return CRYPT_OK if successful
*/
int blake2s_init(hash_state *md, unsigned long outlen, const unsigned char *key, unsigned long keylen)
{
unsigned char P[BLAKE2S_PARAM_SIZE];
int err;
LTC_ARGCHK(md != NULL);
if ((!outlen) || (outlen > BLAKE2S_OUTBYTES)) {
return CRYPT_INVALID_ARG;
}
if ((key && !keylen) || (keylen && !key) || (keylen > BLAKE2S_KEYBYTES)) {
return CRYPT_INVALID_ARG;
}
XMEMSET(P, 0, sizeof(P));
P[BLAKE2S_O_DIGEST_LENGTH] = (unsigned char)outlen;
P[BLAKE2S_O_KEY_LENGTH] = (unsigned char)keylen;
P[BLAKE2S_O_FANOUT] = 1;
P[BLAKE2S_O_DEPTH] = 1;
err = s_blake2s_init_param(md, P);
if (err != CRYPT_OK) return err;
if (key) {
unsigned char block[BLAKE2S_BLOCKBYTES];
XMEMSET(block, 0, BLAKE2S_BLOCKBYTES);
XMEMCPY(block, key, keylen);
blake2s_process(md, block, BLAKE2S_BLOCKBYTES);
#ifdef LTC_CLEAN_STACK
zeromem(block, sizeof(block));
#endif
}
return CRYPT_OK;
}
/**
Initialize the hash state
@param md The hash state you wish to initialize
@return CRYPT_OK if successful
*/
int blake2s_128_init(hash_state *md) { return blake2s_init(md, 16, NULL, 0); }
/**
Initialize the hash state
@param md The hash state you wish to initialize
@return CRYPT_OK if successful
*/
int blake2s_160_init(hash_state *md) { return blake2s_init(md, 20, NULL, 0); }
/**
Initialize the hash state
@param md The hash state you wish to initialize
@return CRYPT_OK if successful
*/
int blake2s_224_init(hash_state *md) { return blake2s_init(md, 28, NULL, 0); }
/**
Initialize the hash state
@param md The hash state you wish to initialize
@return CRYPT_OK if successful
*/
int blake2s_256_init(hash_state *md) { return blake2s_init(md, 32, NULL, 0); }
#define G(r, i, a, b, c, d) \
do { \
a = a + b + m[blake2s_sigma[r][2 * i + 0]]; \
d = ROR(d ^ a, 16); \
c = c + d; \
b = ROR(b ^ c, 12); \
a = a + b + m[blake2s_sigma[r][2 * i + 1]]; \
d = ROR(d ^ a, 8); \
c = c + d; \
b = ROR(b ^ c, 7); \
} while (0)
#define ROUND(r) \
do { \
G(r, 0, v[0], v[4], v[8], v[12]); \
G(r, 1, v[1], v[5], v[9], v[13]); \
G(r, 2, v[2], v[6], v[10], v[14]); \
G(r, 3, v[3], v[7], v[11], v[15]); \
G(r, 4, v[0], v[5], v[10], v[15]); \
G(r, 5, v[1], v[6], v[11], v[12]); \
G(r, 6, v[2], v[7], v[8], v[13]); \
G(r, 7, v[3], v[4], v[9], v[14]); \
} while (0)
#ifdef LTC_CLEAN_STACK
static int ss_blake2s_compress(hash_state *md, const unsigned char *buf)
#else
static int s_blake2s_compress(hash_state *md, const unsigned char *buf)
#endif
{
unsigned long i;
ulong32 m[16];
ulong32 v[16];
for (i = 0; i < 16; ++i) {
LOAD32L(m[i], buf + i * sizeof(m[i]));
}
for (i = 0; i < 8; ++i) {
v[i] = md->blake2s.h[i];
}
v[8] = blake2s_IV[0];
v[9] = blake2s_IV[1];
v[10] = blake2s_IV[2];
v[11] = blake2s_IV[3];
v[12] = md->blake2s.t[0] ^ blake2s_IV[4];
v[13] = md->blake2s.t[1] ^ blake2s_IV[5];
v[14] = md->blake2s.f[0] ^ blake2s_IV[6];
v[15] = md->blake2s.f[1] ^ blake2s_IV[7];
ROUND(0);
ROUND(1);
ROUND(2);
ROUND(3);
ROUND(4);
ROUND(5);
ROUND(6);
ROUND(7);
ROUND(8);
ROUND(9);
for (i = 0; i < 8; ++i) {
md->blake2s.h[i] = md->blake2s.h[i] ^ v[i] ^ v[i + 8];
}
return CRYPT_OK;
}
#undef G
#undef ROUND
#ifdef LTC_CLEAN_STACK
static int s_blake2s_compress(hash_state *md, const unsigned char *buf)
{
int err;
err = ss_blake2s_compress(md, buf);
burn_stack(sizeof(ulong32) * (32) + sizeof(unsigned long));
return err;
}
#endif
/**
Process a block of memory through the hash
@param md The hash state
@param in The data to hash
@param inlen The length of the data (octets)
@return CRYPT_OK if successful
*/
int blake2s_process(hash_state *md, const unsigned char *in, unsigned long inlen)
{
LTC_ARGCHK(md != NULL);
LTC_ARGCHK(in != NULL);
if (md->blake2s.curlen > sizeof(md->blake2s.buf)) {
return CRYPT_INVALID_ARG;
}
if (inlen > 0) {
unsigned long left = md->blake2s.curlen;
unsigned long fill = BLAKE2S_BLOCKBYTES - left;
if (inlen > fill) {
md->blake2s.curlen = 0;
XMEMCPY(md->blake2s.buf + (left % sizeof(md->blake2s.buf)), in, fill); /* Fill buffer */
s_blake2s_increment_counter(md, BLAKE2S_BLOCKBYTES);
s_blake2s_compress(md, md->blake2s.buf); /* Compress */
in += fill;
inlen -= fill;
while (inlen > BLAKE2S_BLOCKBYTES) {
s_blake2s_increment_counter(md, BLAKE2S_BLOCKBYTES);
s_blake2s_compress(md, in);
in += BLAKE2S_BLOCKBYTES;
inlen -= BLAKE2S_BLOCKBYTES;
}
}
XMEMCPY(md->blake2s.buf + md->blake2s.curlen, in, inlen);
md->blake2s.curlen += inlen;
}
return CRYPT_OK;
}
/**
Terminate the hash to get the digest
@param md The hash state
@param out [out] The destination of the hash (size depending on the length used on init)
@return CRYPT_OK if successful
*/
int blake2s_done(hash_state *md, unsigned char *out)
{
unsigned char buffer[BLAKE2S_OUTBYTES] = { 0 };
unsigned long i;
LTC_ARGCHK(md != NULL);
LTC_ARGCHK(out != NULL);
/* if(md->blake2s.outlen != outlen) return CRYPT_INVALID_ARG; */
if (s_blake2s_is_lastblock(md)) {
return CRYPT_ERROR;
}
s_blake2s_increment_counter(md, md->blake2s.curlen);
s_blake2s_set_lastblock(md);
XMEMSET(md->blake2s.buf + md->blake2s.curlen, 0, BLAKE2S_BLOCKBYTES - md->blake2s.curlen); /* Padding */
s_blake2s_compress(md, md->blake2s.buf);
for (i = 0; i < 8; ++i) { /* Output full hash to temp buffer */
STORE32L(md->blake2s.h[i], buffer + i * 4);
}
XMEMCPY(out, buffer, md->blake2s.outlen);
zeromem(md, sizeof(hash_state));
#ifdef LTC_CLEAN_STACK
zeromem(buffer, sizeof(buffer));
#endif
return CRYPT_OK;
}
/**
Self-test the hash
@return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled
*/
int blake2s_256_test(void)
{
#ifndef LTC_TEST
return CRYPT_NOP;
#else
static const struct {
const char *msg;
unsigned char hash[32];
} tests[] = {
{ "",
{ 0x69, 0x21, 0x7a, 0x30, 0x79, 0x90, 0x80, 0x94,
0xe1, 0x11, 0x21, 0xd0, 0x42, 0x35, 0x4a, 0x7c,
0x1f, 0x55, 0xb6, 0x48, 0x2c, 0xa1, 0xa5, 0x1e,
0x1b, 0x25, 0x0d, 0xfd, 0x1e, 0xd0, 0xee, 0xf9 } },
{ "abc",
{ 0x50, 0x8c, 0x5e, 0x8c, 0x32, 0x7c, 0x14, 0xe2,
0xe1, 0xa7, 0x2b, 0xa3, 0x4e, 0xeb, 0x45, 0x2f,
0x37, 0x45, 0x8b, 0x20, 0x9e, 0xd6, 0x3a, 0x29,
0x4d, 0x99, 0x9b, 0x4c, 0x86, 0x67, 0x59, 0x82 } },
{ "12345678901234567890123456789012345678901234567890"
"12345678901234567890123456789012345678901234567890"
"12345678901234567890123456789012345678901234567890"
"12345678901234567890123456789012345678901234567890"
"12345678901234567890123456789012345678901234567890"
"12345678901234567890123456789012345678901234567890",
{ 0xa3, 0x78, 0x8b, 0x5b, 0x59, 0xee, 0xe4, 0x41,
0x95, 0x23, 0x58, 0x00, 0xa4, 0xf9, 0xfa, 0x41,
0x86, 0x0c, 0x7b, 0x1c, 0x35, 0xa2, 0x42, 0x70,
0x50, 0x80, 0x79, 0x56, 0xe3, 0xbe, 0x31, 0x74 } },
{ NULL, { 0 } }
};
int i;
unsigned char tmp[32];
hash_state md;
for (i = 0; tests[i].msg != NULL; i++) {
blake2s_256_init(&md);
blake2s_process(&md, (unsigned char *)tests[i].msg, (unsigned long)XSTRLEN(tests[i].msg));
blake2s_done(&md, tmp);
if (compare_testvector(tmp, sizeof(tmp), tests[i].hash, sizeof(tests[i].hash), "BLAKE2S_256", i)) {
return CRYPT_FAIL_TESTVECTOR;
}
}
return CRYPT_OK;
#endif
}
/**
Self-test the hash
@return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled
*/
int blake2s_224_test(void)
{
#ifndef LTC_TEST
return CRYPT_NOP;
#else
static const struct {
const char *msg;
unsigned char hash[28];
} tests[] = {
{ "",
{ 0x1f, 0xa1, 0x29, 0x1e, 0x65, 0x24, 0x8b, 0x37,
0xb3, 0x43, 0x34, 0x75, 0xb2, 0xa0, 0xdd, 0x63,
0xd5, 0x4a, 0x11, 0xec, 0xc4, 0xe3, 0xe0, 0x34,
0xe7, 0xbc, 0x1e, 0xf4 } },
{ "abc",
{ 0x0b, 0x03, 0x3f, 0xc2, 0x26, 0xdf, 0x7a, 0xbd,
0xe2, 0x9f, 0x67, 0xa0, 0x5d, 0x3d, 0xc6, 0x2c,
0xf2, 0x71, 0xef, 0x3d, 0xfe, 0xa4, 0xd3, 0x87,
0x40, 0x7f, 0xbd, 0x55 } },
{ NULL, { 0 } }
};
int i;
unsigned char tmp[28];
hash_state md;
for (i = 0; tests[i].msg != NULL; i++) {
blake2s_224_init(&md);
blake2s_process(&md, (unsigned char *)tests[i].msg, (unsigned long)XSTRLEN(tests[i].msg));
blake2s_done(&md, tmp);
if (compare_testvector(tmp, sizeof(tmp), tests[i].hash, sizeof(tests[i].hash), "BLAKE2S_224", i)) {
return CRYPT_FAIL_TESTVECTOR;
}
}
return CRYPT_OK;
#endif
}
/**
Self-test the hash
@return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled
*/
int blake2s_160_test(void)
{
#ifndef LTC_TEST
return CRYPT_NOP;
#else
static const struct {
const char *msg;
unsigned char hash[20];
} tests[] = {
{ "",
{ 0x35, 0x4c, 0x9c, 0x33, 0xf7, 0x35, 0x96, 0x24,
0x18, 0xbd, 0xac, 0xb9, 0x47, 0x98, 0x73, 0x42,
0x9c, 0x34, 0x91, 0x6f} },
{ "abc",
{ 0x5a, 0xe3, 0xb9, 0x9b, 0xe2, 0x9b, 0x01, 0x83,
0x4c, 0x3b, 0x50, 0x85, 0x21, 0xed, 0xe6, 0x04,
0x38, 0xf8, 0xde, 0x17 } },
{ NULL, { 0 } }
};
int i;
unsigned char tmp[20];
hash_state md;
for (i = 0; tests[i].msg != NULL; i++) {
blake2s_160_init(&md);
blake2s_process(&md, (unsigned char *)tests[i].msg, (unsigned long)XSTRLEN(tests[i].msg));
blake2s_done(&md, tmp);
if (compare_testvector(tmp, sizeof(tmp), tests[i].hash, sizeof(tests[i].hash), "BLAKE2S_160", i)) {
return CRYPT_FAIL_TESTVECTOR;
}
}
return CRYPT_OK;
#endif
}
/**
Self-test the hash
@return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled
*/
int blake2s_128_test(void)
{
#ifndef LTC_TEST
return CRYPT_NOP;
#else
static const struct {
const char *msg;
unsigned char hash[16];
} tests[] = {
{ "",
{ 0x64, 0x55, 0x0d, 0x6f, 0xfe, 0x2c, 0x0a, 0x01,
0xa1, 0x4a, 0xba, 0x1e, 0xad, 0xe0, 0x20, 0x0c } },
{ "abc",
{ 0xaa, 0x49, 0x38, 0x11, 0x9b, 0x1d, 0xc7, 0xb8,
0x7c, 0xba, 0xd0, 0xff, 0xd2, 0x00, 0xd0, 0xae } },
{ NULL, { 0 } }
};
int i;
unsigned char tmp[16];
hash_state md;
for (i = 0; tests[i].msg != NULL; i++) {
blake2s_128_init(&md);
blake2s_process(&md, (unsigned char *)tests[i].msg, (unsigned long)XSTRLEN(tests[i].msg));
blake2s_done(&md, tmp);
if (compare_testvector(tmp, sizeof(tmp), tests[i].hash, sizeof(tests[i].hash), "BLAKE2S_128", i)) {
return CRYPT_FAIL_TESTVECTOR;
}
}
return CRYPT_OK;
#endif
}
#endif
#pragma clang diagnostic pop

View File

@@ -0,0 +1,302 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
/* SPDX-License-Identifier: Unlicense */
#include "tomcrypt_private.h"
/**
@file chc.c
CHC support. (Tom St Denis)
*/
#ifdef LTC_CHC_HASH
#define UNDEFED_HASH -17
/* chc settings */
static int cipher_idx=UNDEFED_HASH, /* which cipher */
cipher_blocksize; /* blocksize of cipher */
const struct ltc_hash_descriptor chc_desc = {
"chc_hash", 12, 0, 0, { 0 }, 0,
&chc_init,
&chc_process,
&chc_done,
&chc_test,
NULL
};
/**
Initialize the CHC state with a given cipher
@param cipher The index of the cipher you wish to bind
@return CRYPT_OK if successful
*/
int chc_register(int cipher)
{
int err, kl, idx;
if ((err = cipher_is_valid(cipher)) != CRYPT_OK) {
return err;
}
/* will it be valid? */
kl = cipher_descriptor[cipher].block_length;
/* must be >64 bit block */
if (kl <= 8) {
return CRYPT_INVALID_CIPHER;
}
/* can we use the ideal keysize? */
if ((err = cipher_descriptor[cipher].keysize(&kl)) != CRYPT_OK) {
return err;
}
/* we require that key size == block size be a valid choice */
if (kl != cipher_descriptor[cipher].block_length) {
return CRYPT_INVALID_CIPHER;
}
/* determine if chc_hash has been register_hash'ed already */
if ((err = hash_is_valid(idx = find_hash("chc_hash"))) != CRYPT_OK) {
return err;
}
/* store into descriptor */
hash_descriptor[idx].hashsize =
hash_descriptor[idx].blocksize = cipher_descriptor[cipher].block_length;
/* store the idx and block size */
cipher_idx = cipher;
cipher_blocksize = cipher_descriptor[cipher].block_length;
return CRYPT_OK;
}
/**
Initialize the hash state
@param md The hash state you wish to initialize
@return CRYPT_OK if successful
*/
int chc_init(hash_state *md)
{
symmetric_key *key;
unsigned char buf[MAXBLOCKSIZE];
int err;
LTC_ARGCHK(md != NULL);
/* is the cipher valid? */
if ((err = cipher_is_valid(cipher_idx)) != CRYPT_OK) {
return err;
}
if (cipher_blocksize != cipher_descriptor[cipher_idx].block_length) {
return CRYPT_INVALID_CIPHER;
}
if ((key = XMALLOC(sizeof(*key))) == NULL) {
return CRYPT_MEM;
}
/* zero key and what not */
zeromem(buf, cipher_blocksize);
if ((err = cipher_descriptor[cipher_idx].setup(buf, cipher_blocksize, 0, key)) != CRYPT_OK) {
XFREE(key);
return err;
}
/* encrypt zero block */
cipher_descriptor[cipher_idx].ecb_encrypt(buf, md->chc.state, key);
/* zero other members */
md->chc.length = 0;
md->chc.curlen = 0;
zeromem(md->chc.buf, sizeof(md->chc.buf));
XFREE(key);
return CRYPT_OK;
}
/*
key <= state
T0,T1 <= block
T0 <= encrypt T0
state <= state xor T0 xor T1
*/
static int s_chc_compress(hash_state *md, const unsigned char *buf)
{
unsigned char T[2][MAXBLOCKSIZE];
symmetric_key *key;
int err, x;
if ((key = XMALLOC(sizeof(*key))) == NULL) {
return CRYPT_MEM;
}
if ((err = cipher_descriptor[cipher_idx].setup(md->chc.state, cipher_blocksize, 0, key)) != CRYPT_OK) {
XFREE(key);
return err;
}
XMEMCPY(T[1], buf, cipher_blocksize);
cipher_descriptor[cipher_idx].ecb_encrypt(buf, T[0], key);
for (x = 0; x < cipher_blocksize; x++) {
md->chc.state[x] ^= T[0][x] ^ T[1][x];
}
#ifdef LTC_CLEAN_STACK
zeromem(T, sizeof(T));
zeromem(key, sizeof(*key));
#endif
XFREE(key);
return CRYPT_OK;
}
/**
Function for processing blocks
@param md The hash state
@param buf The data to hash
@param len The length of the data (octets)
@return CRYPT_OK if successful
*/
static int ss_chc_process(hash_state * md, const unsigned char *in, unsigned long inlen);
static HASH_PROCESS(ss_chc_process, s_chc_compress, chc, (unsigned long)cipher_blocksize)
/**
Process a block of memory though the hash
@param md The hash state
@param in The data to hash
@param inlen The length of the data (octets)
@return CRYPT_OK if successful
*/
int chc_process(hash_state * md, const unsigned char *in, unsigned long inlen)
{
int err;
LTC_ARGCHK(md != NULL);
LTC_ARGCHK(in != NULL);
/* is the cipher valid? */
if ((err = cipher_is_valid(cipher_idx)) != CRYPT_OK) {
return err;
}
if (cipher_blocksize != cipher_descriptor[cipher_idx].block_length) {
return CRYPT_INVALID_CIPHER;
}
return ss_chc_process(md, in, inlen);
}
/**
Terminate the hash to get the digest
@param md The hash state
@param out [out] The destination of the hash (length of the block size of the block cipher)
@return CRYPT_OK if successful
*/
int chc_done(hash_state *md, unsigned char *out)
{
int err;
LTC_ARGCHK(md != NULL);
LTC_ARGCHK(out != NULL);
/* is the cipher valid? */
if ((err = cipher_is_valid(cipher_idx)) != CRYPT_OK) {
return err;
}
if (cipher_blocksize != cipher_descriptor[cipher_idx].block_length) {
return CRYPT_INVALID_CIPHER;
}
if (md->chc.curlen >= sizeof(md->chc.buf)) {
return CRYPT_INVALID_ARG;
}
/* increase the length of the message */
md->chc.length += md->chc.curlen * 8;
/* append the '1' bit */
md->chc.buf[md->chc.curlen++] = (unsigned char)0x80;
/* if the length is currently above l-8 bytes we append zeros
* then compress. Then we can fall back to padding zeros and length
* encoding like normal.
*/
if (md->chc.curlen > (unsigned long)(cipher_blocksize - 8)) {
while (md->chc.curlen < (unsigned long)cipher_blocksize) {
md->chc.buf[md->chc.curlen++] = (unsigned char)0;
}
s_chc_compress(md, md->chc.buf);
md->chc.curlen = 0;
}
/* pad upto l-8 bytes of zeroes */
while (md->chc.curlen < (unsigned long)(cipher_blocksize - 8)) {
md->chc.buf[md->chc.curlen++] = (unsigned char)0;
}
/* store length */
STORE64L(md->chc.length, md->chc.buf+(cipher_blocksize-8));
s_chc_compress(md, md->chc.buf);
/* copy output */
XMEMCPY(out, md->chc.state, cipher_blocksize);
#ifdef LTC_CLEAN_STACK
zeromem(md, sizeof(hash_state));
#endif
return CRYPT_OK;
}
/**
Self-test the hash
@return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled
*/
int chc_test(void)
{
#ifndef LTC_TEST
return CRYPT_NOP;
#else
static const struct {
unsigned char *msg,
hash[MAXBLOCKSIZE];
int len;
} tests[] = {
{
(unsigned char *)"hello world",
{ 0xcf, 0x57, 0x9d, 0xc3, 0x0a, 0x0e, 0xea, 0x61,
0x0d, 0x54, 0x47, 0xc4, 0x3c, 0x06, 0xf5, 0x4e },
16
}
};
int i, oldhashidx, idx, err;
unsigned char tmp[MAXBLOCKSIZE];
hash_state md;
/* AES can be under rijndael or aes... try to find it */
if ((idx = find_cipher("aes")) == -1) {
if ((idx = find_cipher("rijndael")) == -1) {
return CRYPT_NOP;
}
}
oldhashidx = cipher_idx;
chc_register(idx);
for (i = 0; i < (int)(sizeof(tests)/sizeof(tests[0])); i++) {
if ((err = chc_init(&md)) != CRYPT_OK) {
return err;
}
if ((err = chc_process(&md, tests[i].msg, XSTRLEN((char *)tests[i].msg))) != CRYPT_OK) {
return err;
}
if ((err = chc_done(&md, tmp)) != CRYPT_OK) {
return err;
}
if (compare_testvector(tmp, tests[i].len, tests[i].hash, tests[i].len, "CHC", i)) {
return CRYPT_FAIL_TESTVECTOR;
}
}
if (oldhashidx != UNDEFED_HASH) {
chc_register(oldhashidx);
}
return CRYPT_OK;
#endif
}
#endif

View File

@@ -0,0 +1,43 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
/* SPDX-License-Identifier: Unlicense */
#include "tomcrypt_private.h"
#ifndef LTC_NO_FILE
/**
@file hash_file.c
Hash a file, Tom St Denis
*/
/**
@param hash The index of the hash desired
@param fname The name of the file you wish to hash
@param out [out] The destination of the digest
@param outlen [in/out] The max size and resulting size of the message digest
@result CRYPT_OK if successful
*/
int hash_file(int hash, const char *fname, unsigned char *out, unsigned long *outlen)
{
FILE *in;
int err;
LTC_ARGCHK(fname != NULL);
LTC_ARGCHK(out != NULL);
LTC_ARGCHK(outlen != NULL);
if ((err = hash_is_valid(hash)) != CRYPT_OK) {
return err;
}
in = fopen(fname, "rb");
if (in == NULL) {
return CRYPT_FILE_NOTFOUND;
}
err = hash_filehandle(hash, in, out, outlen);
if (fclose(in) != 0) {
return CRYPT_ERROR;
}
return err;
}
#endif /* #ifndef LTC_NO_FILE */

View File

@@ -0,0 +1,64 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
/* SPDX-License-Identifier: Unlicense */
#include "tomcrypt_private.h"
#ifndef LTC_NO_FILE
/**
@file hash_filehandle.c
Hash open files, Tom St Denis
*/
/**
Hash data from an open file handle.
@param hash The index of the hash you want to use
@param in The FILE* handle of the file you want to hash
@param out [out] The destination of the digest
@param outlen [in/out] The max size and resulting size of the digest
@result CRYPT_OK if successful
*/
int hash_filehandle(int hash, FILE *in, unsigned char *out, unsigned long *outlen)
{
hash_state md;
unsigned char *buf;
size_t x;
int err;
LTC_ARGCHK(out != NULL);
LTC_ARGCHK(outlen != NULL);
LTC_ARGCHK(in != NULL);
if ((buf = XMALLOC(LTC_FILE_READ_BUFSIZE)) == NULL) {
return CRYPT_MEM;
}
if ((err = hash_is_valid(hash)) != CRYPT_OK) {
goto LBL_ERR;
}
if (*outlen < hash_descriptor[hash].hashsize) {
*outlen = hash_descriptor[hash].hashsize;
err = CRYPT_BUFFER_OVERFLOW;
goto LBL_ERR;
}
if ((err = hash_descriptor[hash].init(&md)) != CRYPT_OK) {
goto LBL_ERR;
}
do {
x = fread(buf, 1, LTC_FILE_READ_BUFSIZE, in);
if ((err = hash_descriptor[hash].process(&md, buf, (unsigned long)x)) != CRYPT_OK) {
goto LBL_CLEANBUF;
}
} while (x == LTC_FILE_READ_BUFSIZE);
if ((err = hash_descriptor[hash].done(&md, out)) == CRYPT_OK) {
*outlen = hash_descriptor[hash].hashsize;
}
LBL_CLEANBUF:
zeromem(buf, LTC_FILE_READ_BUFSIZE);
LBL_ERR:
XFREE(buf);
return err;
}
#endif /* #ifndef LTC_NO_FILE */

View File

@@ -0,0 +1,59 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
/* SPDX-License-Identifier: Unlicense */
#include "tomcrypt_private.h"
#ifdef LTC_HASH_HELPERS
/**
@file hash_memory.c
Hash memory helper, Tom St Denis
*/
/**
Hash a block of memory and store the digest.
@param hash The index of the hash you wish to use
@param in The data you wish to hash
@param inlen The length of the data to hash (octets)
@param out [out] Where to store the digest
@param outlen [in/out] Max size and resulting size of the digest
@return CRYPT_OK if successful
*/
int hash_memory(int hash, const unsigned char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen)
{
hash_state *md;
int err;
LTC_ARGCHK(in != NULL);
LTC_ARGCHK(out != NULL);
LTC_ARGCHK(outlen != NULL);
if ((err = hash_is_valid(hash)) != CRYPT_OK) {
return err;
}
if (*outlen < hash_descriptor[hash].hashsize) {
*outlen = hash_descriptor[hash].hashsize;
return CRYPT_BUFFER_OVERFLOW;
}
md = XMALLOC(sizeof(hash_state));
if (md == NULL) {
return CRYPT_MEM;
}
if ((err = hash_descriptor[hash].init(md)) != CRYPT_OK) {
goto LBL_ERR;
}
if ((err = hash_descriptor[hash].process(md, in, inlen)) != CRYPT_OK) {
goto LBL_ERR;
}
err = hash_descriptor[hash].done(md, out);
*outlen = hash_descriptor[hash].hashsize;
LBL_ERR:
#ifdef LTC_CLEAN_STACK
zeromem(md, sizeof(hash_state));
#endif
XFREE(md);
return err;
}
#endif /* #ifdef LTC_HASH_HELPERS */

View File

@@ -0,0 +1,77 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
/* SPDX-License-Identifier: Unlicense */
#include "tomcrypt_private.h"
#ifdef LTC_HASH_HELPERS
/**
@file hash_memory_multi.c
Hash (multiple buffers) memory helper, Tom St Denis
*/
/**
Hash multiple (non-adjacent) blocks of memory at once.
@param hash The index of the hash you wish to use
@param out [out] Where to store the digest
@param outlen [in/out] Max size and resulting size of the digest
@param in The data you wish to hash
@param inlen The length of the data to hash (octets)
@param ... tuples of (data,len) pairs to hash, terminated with a (NULL,x) (x=don't care)
@return CRYPT_OK if successful
*/
int hash_memory_multi(int hash, unsigned char *out, unsigned long *outlen,
const unsigned char *in, unsigned long inlen, ...)
{
hash_state *md;
int err;
va_list args;
const unsigned char *curptr;
unsigned long curlen;
LTC_ARGCHK(in != NULL);
LTC_ARGCHK(out != NULL);
LTC_ARGCHK(outlen != NULL);
if ((err = hash_is_valid(hash)) != CRYPT_OK) {
return err;
}
if (*outlen < hash_descriptor[hash].hashsize) {
*outlen = hash_descriptor[hash].hashsize;
return CRYPT_BUFFER_OVERFLOW;
}
md = XMALLOC(sizeof(hash_state));
if (md == NULL) {
return CRYPT_MEM;
}
if ((err = hash_descriptor[hash].init(md)) != CRYPT_OK) {
goto LBL_ERR;
}
va_start(args, inlen);
curptr = in;
curlen = inlen;
for (;;) {
/* process buf */
if ((err = hash_descriptor[hash].process(md, curptr, curlen)) != CRYPT_OK) {
goto LBL_ERR;
}
/* step to next */
curptr = va_arg(args, const unsigned char*);
if (curptr == NULL) {
break;
}
curlen = va_arg(args, unsigned long);
}
err = hash_descriptor[hash].done(md, out);
*outlen = hash_descriptor[hash].hashsize;
LBL_ERR:
#ifdef LTC_CLEAN_STACK
zeromem(md, sizeof(hash_state));
#endif
XFREE(md);
va_end(args);
return err;
}
#endif /* #ifdef LTC_HASH_HELPERS */

View File

@@ -0,0 +1,240 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
/* SPDX-License-Identifier: Unlicense */
#include "tomcrypt_private.h"
/**
@param md2.c
LTC_MD2 (RFC 1319) hash function implementation by Tom St Denis
*/
#ifdef LTC_MD2
const struct ltc_hash_descriptor md2_desc =
{
"md2",
7,
16,
16,
/* OID */
{ 1, 2, 840, 113549, 2, 2, },
6,
&md2_init,
&md2_process,
&md2_done,
&md2_test,
NULL
};
static const unsigned char PI_SUBST[256] = {
41, 46, 67, 201, 162, 216, 124, 1, 61, 54, 84, 161, 236, 240, 6,
19, 98, 167, 5, 243, 192, 199, 115, 140, 152, 147, 43, 217, 188,
76, 130, 202, 30, 155, 87, 60, 253, 212, 224, 22, 103, 66, 111, 24,
138, 23, 229, 18, 190, 78, 196, 214, 218, 158, 222, 73, 160, 251,
245, 142, 187, 47, 238, 122, 169, 104, 121, 145, 21, 178, 7, 63,
148, 194, 16, 137, 11, 34, 95, 33, 128, 127, 93, 154, 90, 144, 50,
39, 53, 62, 204, 231, 191, 247, 151, 3, 255, 25, 48, 179, 72, 165,
181, 209, 215, 94, 146, 42, 172, 86, 170, 198, 79, 184, 56, 210,
150, 164, 125, 182, 118, 252, 107, 226, 156, 116, 4, 241, 69, 157,
112, 89, 100, 113, 135, 32, 134, 91, 207, 101, 230, 45, 168, 2, 27,
96, 37, 173, 174, 176, 185, 246, 28, 70, 97, 105, 52, 64, 126, 15,
85, 71, 163, 35, 221, 81, 175, 58, 195, 92, 249, 206, 186, 197,
234, 38, 44, 83, 13, 110, 133, 40, 132, 9, 211, 223, 205, 244, 65,
129, 77, 82, 106, 220, 55, 200, 108, 193, 171, 250, 36, 225, 123,
8, 12, 189, 177, 74, 120, 136, 149, 139, 227, 99, 232, 109, 233,
203, 213, 254, 59, 0, 29, 57, 242, 239, 183, 14, 102, 88, 208, 228,
166, 119, 114, 248, 235, 117, 75, 10, 49, 68, 80, 180, 143, 237,
31, 26, 219, 153, 141, 51, 159, 17, 131, 20
};
/* adds 16 bytes to the checksum */
static void s_md2_update_chksum(hash_state *md)
{
int j;
unsigned char L;
L = md->md2.chksum[15];
for (j = 0; j < 16; j++) {
/* caution, the RFC says its "C[j] = S[M[i*16+j] xor L]" but the reference source code [and test vectors] say
otherwise.
*/
L = (md->md2.chksum[j] ^= PI_SUBST[(int)(md->md2.buf[j] ^ L)] & 255);
}
}
static void s_md2_compress(hash_state *md)
{
int j, k;
unsigned char t;
/* copy block */
for (j = 0; j < 16; j++) {
md->md2.X[16+j] = md->md2.buf[j];
md->md2.X[32+j] = md->md2.X[j] ^ md->md2.X[16+j];
}
t = (unsigned char)0;
/* do 18 rounds */
for (j = 0; j < 18; j++) {
for (k = 0; k < 48; k++) {
t = (md->md2.X[k] ^= PI_SUBST[(int)(t & 255)]);
}
t = (t + (unsigned char)j) & 255;
}
}
/**
Initialize the hash state
@param md The hash state you wish to initialize
@return CRYPT_OK if successful
*/
int md2_init(hash_state *md)
{
LTC_ARGCHK(md != NULL);
/* LTC_MD2 uses a zero'ed state... */
zeromem(md->md2.X, sizeof(md->md2.X));
zeromem(md->md2.chksum, sizeof(md->md2.chksum));
zeromem(md->md2.buf, sizeof(md->md2.buf));
md->md2.curlen = 0;
return CRYPT_OK;
}
/**
Process a block of memory though the hash
@param md The hash state
@param in The data to hash
@param inlen The length of the data (octets)
@return CRYPT_OK if successful
*/
int md2_process(hash_state *md, const unsigned char *in, unsigned long inlen)
{
unsigned long n;
LTC_ARGCHK(md != NULL);
LTC_ARGCHK(in != NULL);
if (md-> md2 .curlen > sizeof(md-> md2 .buf)) {
return CRYPT_INVALID_ARG;
}
while (inlen > 0) {
n = MIN(inlen, (16 - md->md2.curlen));
XMEMCPY(md->md2.buf + md->md2.curlen, in, (size_t)n);
md->md2.curlen += n;
in += n;
inlen -= n;
/* is 16 bytes full? */
if (md->md2.curlen == 16) {
s_md2_compress(md);
s_md2_update_chksum(md);
md->md2.curlen = 0;
}
}
return CRYPT_OK;
}
/**
Terminate the hash to get the digest
@param md The hash state
@param out [out] The destination of the hash (16 bytes)
@return CRYPT_OK if successful
*/
int md2_done(hash_state * md, unsigned char *out)
{
unsigned long i, k;
LTC_ARGCHK(md != NULL);
LTC_ARGCHK(out != NULL);
if (md->md2.curlen >= sizeof(md->md2.buf)) {
return CRYPT_INVALID_ARG;
}
/* pad the message */
k = 16 - md->md2.curlen;
for (i = md->md2.curlen; i < 16; i++) {
md->md2.buf[i] = (unsigned char)k;
}
/* hash and update */
s_md2_compress(md);
s_md2_update_chksum(md);
/* hash checksum */
XMEMCPY(md->md2.buf, md->md2.chksum, 16);
s_md2_compress(md);
/* output is lower 16 bytes of X */
XMEMCPY(out, md->md2.X, 16);
#ifdef LTC_CLEAN_STACK
zeromem(md, sizeof(hash_state));
#endif
return CRYPT_OK;
}
/**
Self-test the hash
@return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled
*/
int md2_test(void)
{
#ifndef LTC_TEST
return CRYPT_NOP;
#else
static const struct {
const char *msg;
unsigned char hash[16];
} tests[] = {
{ "",
{0x83,0x50,0xe5,0xa3,0xe2,0x4c,0x15,0x3d,
0xf2,0x27,0x5c,0x9f,0x80,0x69,0x27,0x73
}
},
{ "a",
{0x32,0xec,0x01,0xec,0x4a,0x6d,0xac,0x72,
0xc0,0xab,0x96,0xfb,0x34,0xc0,0xb5,0xd1
}
},
{ "message digest",
{0xab,0x4f,0x49,0x6b,0xfb,0x2a,0x53,0x0b,
0x21,0x9f,0xf3,0x30,0x31,0xfe,0x06,0xb0
}
},
{ "abcdefghijklmnopqrstuvwxyz",
{0x4e,0x8d,0xdf,0xf3,0x65,0x02,0x92,0xab,
0x5a,0x41,0x08,0xc3,0xaa,0x47,0x94,0x0b
}
},
{ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
{0xda,0x33,0xde,0xf2,0xa4,0x2d,0xf1,0x39,
0x75,0x35,0x28,0x46,0xc3,0x03,0x38,0xcd
}
},
{ "12345678901234567890123456789012345678901234567890123456789012345678901234567890",
{0xd5,0x97,0x6f,0x79,0xd8,0x3d,0x3a,0x0d,
0xc9,0x80,0x6c,0x3c,0x66,0xf3,0xef,0xd8
}
}
};
int i;
unsigned char tmp[16];
hash_state md;
for (i = 0; i < (int)(sizeof(tests) / sizeof(tests[0])); i++) {
md2_init(&md);
md2_process(&md, (unsigned char*)tests[i].msg, (unsigned long)XSTRLEN(tests[i].msg));
md2_done(&md, tmp);
if (compare_testvector(tmp, sizeof(tmp), tests[i].hash, sizeof(tests[i].hash), "MD2", i)) {
return CRYPT_FAIL_TESTVECTOR;
}
}
return CRYPT_OK;
#endif
}
#endif

View File

@@ -0,0 +1,316 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
/* SPDX-License-Identifier: Unlicense */
#include "tomcrypt_private.h"
/**
@param md4.c
Submitted by Dobes Vandermeer (dobes@smartt.com)
*/
#ifdef LTC_MD4
const struct ltc_hash_descriptor md4_desc =
{
"md4",
6,
16,
64,
/* OID */
{ 1, 2, 840, 113549, 2, 4, },
6,
&md4_init,
&md4_process,
&md4_done,
&md4_test,
NULL
};
#define S11 3
#define S12 7
#define S13 11
#define S14 19
#define S21 3
#define S22 5
#define S23 9
#define S24 13
#define S31 3
#define S32 9
#define S33 11
#define S34 15
/* F, G and H are basic LTC_MD4 functions. */
#define F(x, y, z) (z ^ (x & (y ^ z)))
#define G(x, y, z) ((x & y) | (z & (x | y)))
#define H(x, y, z) ((x) ^ (y) ^ (z))
/* ROTATE_LEFT rotates x left n bits. */
#define ROTATE_LEFT(x, n) ROLc(x, n)
/* FF, GG and HH are transformations for rounds 1, 2 and 3 */
/* Rotation is separate from addition to prevent recomputation */
#define FF(a, b, c, d, x, s) { \
(a) += F ((b), (c), (d)) + (x); \
(a) = ROTATE_LEFT ((a), (s)); \
}
#define GG(a, b, c, d, x, s) { \
(a) += G ((b), (c), (d)) + (x) + 0x5a827999UL; \
(a) = ROTATE_LEFT ((a), (s)); \
}
#define HH(a, b, c, d, x, s) { \
(a) += H ((b), (c), (d)) + (x) + 0x6ed9eba1UL; \
(a) = ROTATE_LEFT ((a), (s)); \
}
#ifdef LTC_CLEAN_STACK
static int ss_md4_compress(hash_state *md, const unsigned char *buf)
#else
static int s_md4_compress(hash_state *md, const unsigned char *buf)
#endif
{
ulong32 x[16], a, b, c, d;
int i;
/* copy state */
a = md->md4.state[0];
b = md->md4.state[1];
c = md->md4.state[2];
d = md->md4.state[3];
/* copy the state into 512-bits into W[0..15] */
for (i = 0; i < 16; i++) {
LOAD32L(x[i], buf + (4*i));
}
/* Round 1 */
FF (a, b, c, d, x[ 0], S11); /* 1 */
FF (d, a, b, c, x[ 1], S12); /* 2 */
FF (c, d, a, b, x[ 2], S13); /* 3 */
FF (b, c, d, a, x[ 3], S14); /* 4 */
FF (a, b, c, d, x[ 4], S11); /* 5 */
FF (d, a, b, c, x[ 5], S12); /* 6 */
FF (c, d, a, b, x[ 6], S13); /* 7 */
FF (b, c, d, a, x[ 7], S14); /* 8 */
FF (a, b, c, d, x[ 8], S11); /* 9 */
FF (d, a, b, c, x[ 9], S12); /* 10 */
FF (c, d, a, b, x[10], S13); /* 11 */
FF (b, c, d, a, x[11], S14); /* 12 */
FF (a, b, c, d, x[12], S11); /* 13 */
FF (d, a, b, c, x[13], S12); /* 14 */
FF (c, d, a, b, x[14], S13); /* 15 */
FF (b, c, d, a, x[15], S14); /* 16 */
/* Round 2 */
GG (a, b, c, d, x[ 0], S21); /* 17 */
GG (d, a, b, c, x[ 4], S22); /* 18 */
GG (c, d, a, b, x[ 8], S23); /* 19 */
GG (b, c, d, a, x[12], S24); /* 20 */
GG (a, b, c, d, x[ 1], S21); /* 21 */
GG (d, a, b, c, x[ 5], S22); /* 22 */
GG (c, d, a, b, x[ 9], S23); /* 23 */
GG (b, c, d, a, x[13], S24); /* 24 */
GG (a, b, c, d, x[ 2], S21); /* 25 */
GG (d, a, b, c, x[ 6], S22); /* 26 */
GG (c, d, a, b, x[10], S23); /* 27 */
GG (b, c, d, a, x[14], S24); /* 28 */
GG (a, b, c, d, x[ 3], S21); /* 29 */
GG (d, a, b, c, x[ 7], S22); /* 30 */
GG (c, d, a, b, x[11], S23); /* 31 */
GG (b, c, d, a, x[15], S24); /* 32 */
/* Round 3 */
HH (a, b, c, d, x[ 0], S31); /* 33 */
HH (d, a, b, c, x[ 8], S32); /* 34 */
HH (c, d, a, b, x[ 4], S33); /* 35 */
HH (b, c, d, a, x[12], S34); /* 36 */
HH (a, b, c, d, x[ 2], S31); /* 37 */
HH (d, a, b, c, x[10], S32); /* 38 */
HH (c, d, a, b, x[ 6], S33); /* 39 */
HH (b, c, d, a, x[14], S34); /* 40 */
HH (a, b, c, d, x[ 1], S31); /* 41 */
HH (d, a, b, c, x[ 9], S32); /* 42 */
HH (c, d, a, b, x[ 5], S33); /* 43 */
HH (b, c, d, a, x[13], S34); /* 44 */
HH (a, b, c, d, x[ 3], S31); /* 45 */
HH (d, a, b, c, x[11], S32); /* 46 */
HH (c, d, a, b, x[ 7], S33); /* 47 */
HH (b, c, d, a, x[15], S34); /* 48 */
/* Update our state */
md->md4.state[0] = md->md4.state[0] + a;
md->md4.state[1] = md->md4.state[1] + b;
md->md4.state[2] = md->md4.state[2] + c;
md->md4.state[3] = md->md4.state[3] + d;
return CRYPT_OK;
}
#ifdef LTC_CLEAN_STACK
static int s_md4_compress(hash_state *md, const unsigned char *buf)
{
int err;
err = ss_md4_compress(md, buf);
burn_stack(sizeof(ulong32) * 20 + sizeof(int));
return err;
}
#endif
/**
Initialize the hash state
@param md The hash state you wish to initialize
@return CRYPT_OK if successful
*/
int md4_init(hash_state * md)
{
LTC_ARGCHK(md != NULL);
md->md4.state[0] = 0x67452301UL;
md->md4.state[1] = 0xefcdab89UL;
md->md4.state[2] = 0x98badcfeUL;
md->md4.state[3] = 0x10325476UL;
md->md4.length = 0;
md->md4.curlen = 0;
return CRYPT_OK;
}
/**
Process a block of memory though the hash
@param md The hash state
@param in The data to hash
@param inlen The length of the data (octets)
@return CRYPT_OK if successful
*/
HASH_PROCESS(md4_process, s_md4_compress, md4, 64)
/**
Terminate the hash to get the digest
@param md The hash state
@param out [out] The destination of the hash (16 bytes)
@return CRYPT_OK if successful
*/
int md4_done(hash_state * md, unsigned char *out)
{
int i;
LTC_ARGCHK(md != NULL);
LTC_ARGCHK(out != NULL);
if (md->md4.curlen >= sizeof(md->md4.buf)) {
return CRYPT_INVALID_ARG;
}
/* increase the length of the message */
md->md4.length += md->md4.curlen * 8;
/* append the '1' bit */
md->md4.buf[md->md4.curlen++] = (unsigned char)0x80;
/* if the length is currently above 56 bytes we append zeros
* then compress. Then we can fall back to padding zeros and length
* encoding like normal.
*/
if (md->md4.curlen > 56) {
while (md->md4.curlen < 64) {
md->md4.buf[md->md4.curlen++] = (unsigned char)0;
}
s_md4_compress(md, md->md4.buf);
md->md4.curlen = 0;
}
/* pad upto 56 bytes of zeroes */
while (md->md4.curlen < 56) {
md->md4.buf[md->md4.curlen++] = (unsigned char)0;
}
/* store length */
STORE64L(md->md4.length, md->md4.buf+56);
s_md4_compress(md, md->md4.buf);
/* copy output */
for (i = 0; i < 4; i++) {
STORE32L(md->md4.state[i], out+(4*i));
}
#ifdef LTC_CLEAN_STACK
zeromem(md, sizeof(hash_state));
#endif
return CRYPT_OK;
}
/**
Self-test the hash
@return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled
*/
int md4_test(void)
{
#ifndef LTC_TEST
return CRYPT_NOP;
#else
static const struct md4_test_case {
const char *input;
unsigned char hash[16];
} tests[] = {
{ "",
{0x31, 0xd6, 0xcf, 0xe0, 0xd1, 0x6a, 0xe9, 0x31,
0xb7, 0x3c, 0x59, 0xd7, 0xe0, 0xc0, 0x89, 0xc0} },
{ "a",
{0xbd, 0xe5, 0x2c, 0xb3, 0x1d, 0xe3, 0x3e, 0x46,
0x24, 0x5e, 0x05, 0xfb, 0xdb, 0xd6, 0xfb, 0x24} },
{ "abc",
{0xa4, 0x48, 0x01, 0x7a, 0xaf, 0x21, 0xd8, 0x52,
0x5f, 0xc1, 0x0a, 0xe8, 0x7a, 0xa6, 0x72, 0x9d} },
{ "message digest",
{0xd9, 0x13, 0x0a, 0x81, 0x64, 0x54, 0x9f, 0xe8,
0x18, 0x87, 0x48, 0x06, 0xe1, 0xc7, 0x01, 0x4b} },
{ "abcdefghijklmnopqrstuvwxyz",
{0xd7, 0x9e, 0x1c, 0x30, 0x8a, 0xa5, 0xbb, 0xcd,
0xee, 0xa8, 0xed, 0x63, 0xdf, 0x41, 0x2d, 0xa9} },
{ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
{0x04, 0x3f, 0x85, 0x82, 0xf2, 0x41, 0xdb, 0x35,
0x1c, 0xe6, 0x27, 0xe1, 0x53, 0xe7, 0xf0, 0xe4} },
{ "12345678901234567890123456789012345678901234567890123456789012345678901234567890",
{0xe3, 0x3b, 0x4d, 0xdc, 0x9c, 0x38, 0xf2, 0x19,
0x9c, 0x3e, 0x7b, 0x16, 0x4f, 0xcc, 0x05, 0x36} },
};
int i;
unsigned char tmp[16];
hash_state md;
for(i = 0; i < (int)(sizeof(tests) / sizeof(tests[0])); i++) {
md4_init(&md);
md4_process(&md, (unsigned char *)tests[i].input, (unsigned long)XSTRLEN(tests[i].input));
md4_done(&md, tmp);
if (compare_testvector(tmp, sizeof(tmp), tests[i].hash, sizeof(tests[i].hash), "MD4", i)) {
return CRYPT_FAIL_TESTVECTOR;
}
}
return CRYPT_OK;
#endif
}
#undef F
#undef G
#undef H
#undef FF
#undef GG
#undef HH
#undef S11
#undef S12
#undef S13
#undef S14
#undef S21
#undef S22
#undef S23
#undef S24
#undef S31
#undef S32
#undef S33
#undef S34
#undef ROTATE_LEFT
#endif

View File

@@ -0,0 +1,363 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
/* SPDX-License-Identifier: Unlicense */
#include "tomcrypt_private.h"
/**
@file md5.c
LTC_MD5 hash function by Tom St Denis
*/
#ifdef LTC_MD5
const struct ltc_hash_descriptor md5_desc =
{
"md5",
3,
16,
64,
/* OID */
{ 1, 2, 840, 113549, 2, 5, },
6,
&md5_init,
&md5_process,
&md5_done,
&md5_test,
NULL
};
#define F(x,y,z) (z ^ (x & (y ^ z)))
#define G(x,y,z) (y ^ (z & (y ^ x)))
#define H(x,y,z) (x^y^z)
#define I(x,y,z) (y^(x|(~z)))
#ifdef LTC_SMALL_CODE
#define FF(a,b,c,d,M,s,t) \
a = (a + F(b,c,d) + M + t); a = ROL(a, s) + b;
#define GG(a,b,c,d,M,s,t) \
a = (a + G(b,c,d) + M + t); a = ROL(a, s) + b;
#define HH(a,b,c,d,M,s,t) \
a = (a + H(b,c,d) + M + t); a = ROL(a, s) + b;
#define II(a,b,c,d,M,s,t) \
a = (a + I(b,c,d) + M + t); a = ROL(a, s) + b;
static const unsigned char Worder[64] = {
0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,
1,6,11,0,5,10,15,4,9,14,3,8,13,2,7,12,
5,8,11,14,1,4,7,10,13,0,3,6,9,12,15,2,
0,7,14,5,12,3,10,1,8,15,6,13,4,11,2,9
};
static const unsigned char Rorder[64] = {
7,12,17,22,7,12,17,22,7,12,17,22,7,12,17,22,
5,9,14,20,5,9,14,20,5,9,14,20,5,9,14,20,
4,11,16,23,4,11,16,23,4,11,16,23,4,11,16,23,
6,10,15,21,6,10,15,21,6,10,15,21,6,10,15,21
};
static const ulong32 Korder[64] = {
0xd76aa478UL, 0xe8c7b756UL, 0x242070dbUL, 0xc1bdceeeUL, 0xf57c0fafUL, 0x4787c62aUL, 0xa8304613UL, 0xfd469501UL,
0x698098d8UL, 0x8b44f7afUL, 0xffff5bb1UL, 0x895cd7beUL, 0x6b901122UL, 0xfd987193UL, 0xa679438eUL, 0x49b40821UL,
0xf61e2562UL, 0xc040b340UL, 0x265e5a51UL, 0xe9b6c7aaUL, 0xd62f105dUL, 0x02441453UL, 0xd8a1e681UL, 0xe7d3fbc8UL,
0x21e1cde6UL, 0xc33707d6UL, 0xf4d50d87UL, 0x455a14edUL, 0xa9e3e905UL, 0xfcefa3f8UL, 0x676f02d9UL, 0x8d2a4c8aUL,
0xfffa3942UL, 0x8771f681UL, 0x6d9d6122UL, 0xfde5380cUL, 0xa4beea44UL, 0x4bdecfa9UL, 0xf6bb4b60UL, 0xbebfbc70UL,
0x289b7ec6UL, 0xeaa127faUL, 0xd4ef3085UL, 0x04881d05UL, 0xd9d4d039UL, 0xe6db99e5UL, 0x1fa27cf8UL, 0xc4ac5665UL,
0xf4292244UL, 0x432aff97UL, 0xab9423a7UL, 0xfc93a039UL, 0x655b59c3UL, 0x8f0ccc92UL, 0xffeff47dUL, 0x85845dd1UL,
0x6fa87e4fUL, 0xfe2ce6e0UL, 0xa3014314UL, 0x4e0811a1UL, 0xf7537e82UL, 0xbd3af235UL, 0x2ad7d2bbUL, 0xeb86d391UL
};
#else
#define FF(a,b,c,d,M,s,t) \
a = (a + F(b,c,d) + M + t); a = ROLc(a, s) + b;
#define GG(a,b,c,d,M,s,t) \
a = (a + G(b,c,d) + M + t); a = ROLc(a, s) + b;
#define HH(a,b,c,d,M,s,t) \
a = (a + H(b,c,d) + M + t); a = ROLc(a, s) + b;
#define II(a,b,c,d,M,s,t) \
a = (a + I(b,c,d) + M + t); a = ROLc(a, s) + b;
#endif
#ifdef LTC_CLEAN_STACK
static int ss_md5_compress(hash_state *md, const unsigned char *buf)
#else
static int s_md5_compress(hash_state *md, const unsigned char *buf)
#endif
{
ulong32 i, W[16], a, b, c, d;
#ifdef LTC_SMALL_CODE
ulong32 t;
#endif
/* copy the state into 512-bits into W[0..15] */
for (i = 0; i < 16; i++) {
LOAD32L(W[i], buf + (4*i));
}
/* copy state */
a = md->md5.state[0];
b = md->md5.state[1];
c = md->md5.state[2];
d = md->md5.state[3];
#ifdef LTC_SMALL_CODE
for (i = 0; i < 16; ++i) {
FF(a,b,c,d,W[Worder[i]],Rorder[i],Korder[i]);
t = d; d = c; c = b; b = a; a = t;
}
for (; i < 32; ++i) {
GG(a,b,c,d,W[Worder[i]],Rorder[i],Korder[i]);
t = d; d = c; c = b; b = a; a = t;
}
for (; i < 48; ++i) {
HH(a,b,c,d,W[Worder[i]],Rorder[i],Korder[i]);
t = d; d = c; c = b; b = a; a = t;
}
for (; i < 64; ++i) {
II(a,b,c,d,W[Worder[i]],Rorder[i],Korder[i]);
t = d; d = c; c = b; b = a; a = t;
}
#else
FF(a,b,c,d,W[0],7,0xd76aa478UL)
FF(d,a,b,c,W[1],12,0xe8c7b756UL)
FF(c,d,a,b,W[2],17,0x242070dbUL)
FF(b,c,d,a,W[3],22,0xc1bdceeeUL)
FF(a,b,c,d,W[4],7,0xf57c0fafUL)
FF(d,a,b,c,W[5],12,0x4787c62aUL)
FF(c,d,a,b,W[6],17,0xa8304613UL)
FF(b,c,d,a,W[7],22,0xfd469501UL)
FF(a,b,c,d,W[8],7,0x698098d8UL)
FF(d,a,b,c,W[9],12,0x8b44f7afUL)
FF(c,d,a,b,W[10],17,0xffff5bb1UL)
FF(b,c,d,a,W[11],22,0x895cd7beUL)
FF(a,b,c,d,W[12],7,0x6b901122UL)
FF(d,a,b,c,W[13],12,0xfd987193UL)
FF(c,d,a,b,W[14],17,0xa679438eUL)
FF(b,c,d,a,W[15],22,0x49b40821UL)
GG(a,b,c,d,W[1],5,0xf61e2562UL)
GG(d,a,b,c,W[6],9,0xc040b340UL)
GG(c,d,a,b,W[11],14,0x265e5a51UL)
GG(b,c,d,a,W[0],20,0xe9b6c7aaUL)
GG(a,b,c,d,W[5],5,0xd62f105dUL)
GG(d,a,b,c,W[10],9,0x02441453UL)
GG(c,d,a,b,W[15],14,0xd8a1e681UL)
GG(b,c,d,a,W[4],20,0xe7d3fbc8UL)
GG(a,b,c,d,W[9],5,0x21e1cde6UL)
GG(d,a,b,c,W[14],9,0xc33707d6UL)
GG(c,d,a,b,W[3],14,0xf4d50d87UL)
GG(b,c,d,a,W[8],20,0x455a14edUL)
GG(a,b,c,d,W[13],5,0xa9e3e905UL)
GG(d,a,b,c,W[2],9,0xfcefa3f8UL)
GG(c,d,a,b,W[7],14,0x676f02d9UL)
GG(b,c,d,a,W[12],20,0x8d2a4c8aUL)
HH(a,b,c,d,W[5],4,0xfffa3942UL)
HH(d,a,b,c,W[8],11,0x8771f681UL)
HH(c,d,a,b,W[11],16,0x6d9d6122UL)
HH(b,c,d,a,W[14],23,0xfde5380cUL)
HH(a,b,c,d,W[1],4,0xa4beea44UL)
HH(d,a,b,c,W[4],11,0x4bdecfa9UL)
HH(c,d,a,b,W[7],16,0xf6bb4b60UL)
HH(b,c,d,a,W[10],23,0xbebfbc70UL)
HH(a,b,c,d,W[13],4,0x289b7ec6UL)
HH(d,a,b,c,W[0],11,0xeaa127faUL)
HH(c,d,a,b,W[3],16,0xd4ef3085UL)
HH(b,c,d,a,W[6],23,0x04881d05UL)
HH(a,b,c,d,W[9],4,0xd9d4d039UL)
HH(d,a,b,c,W[12],11,0xe6db99e5UL)
HH(c,d,a,b,W[15],16,0x1fa27cf8UL)
HH(b,c,d,a,W[2],23,0xc4ac5665UL)
II(a,b,c,d,W[0],6,0xf4292244UL)
II(d,a,b,c,W[7],10,0x432aff97UL)
II(c,d,a,b,W[14],15,0xab9423a7UL)
II(b,c,d,a,W[5],21,0xfc93a039UL)
II(a,b,c,d,W[12],6,0x655b59c3UL)
II(d,a,b,c,W[3],10,0x8f0ccc92UL)
II(c,d,a,b,W[10],15,0xffeff47dUL)
II(b,c,d,a,W[1],21,0x85845dd1UL)
II(a,b,c,d,W[8],6,0x6fa87e4fUL)
II(d,a,b,c,W[15],10,0xfe2ce6e0UL)
II(c,d,a,b,W[6],15,0xa3014314UL)
II(b,c,d,a,W[13],21,0x4e0811a1UL)
II(a,b,c,d,W[4],6,0xf7537e82UL)
II(d,a,b,c,W[11],10,0xbd3af235UL)
II(c,d,a,b,W[2],15,0x2ad7d2bbUL)
II(b,c,d,a,W[9],21,0xeb86d391UL)
#endif
md->md5.state[0] = md->md5.state[0] + a;
md->md5.state[1] = md->md5.state[1] + b;
md->md5.state[2] = md->md5.state[2] + c;
md->md5.state[3] = md->md5.state[3] + d;
return CRYPT_OK;
}
#ifdef LTC_CLEAN_STACK
static int s_md5_compress(hash_state *md, const unsigned char *buf)
{
int err;
err = ss_md5_compress(md, buf);
burn_stack(sizeof(ulong32) * 21);
return err;
}
#endif
/**
Initialize the hash state
@param md The hash state you wish to initialize
@return CRYPT_OK if successful
*/
int md5_init(hash_state * md)
{
LTC_ARGCHK(md != NULL);
md->md5.state[0] = 0x67452301UL;
md->md5.state[1] = 0xefcdab89UL;
md->md5.state[2] = 0x98badcfeUL;
md->md5.state[3] = 0x10325476UL;
md->md5.curlen = 0;
md->md5.length = 0;
return CRYPT_OK;
}
/**
Process a block of memory though the hash
@param md The hash state
@param in The data to hash
@param inlen The length of the data (octets)
@return CRYPT_OK if successful
*/
HASH_PROCESS(md5_process, s_md5_compress, md5, 64)
/**
Terminate the hash to get the digest
@param md The hash state
@param out [out] The destination of the hash (16 bytes)
@return CRYPT_OK if successful
*/
int md5_done(hash_state * md, unsigned char *out)
{
int i;
LTC_ARGCHK(md != NULL);
LTC_ARGCHK(out != NULL);
if (md->md5.curlen >= sizeof(md->md5.buf)) {
return CRYPT_INVALID_ARG;
}
/* increase the length of the message */
md->md5.length += md->md5.curlen * 8;
/* append the '1' bit */
md->md5.buf[md->md5.curlen++] = (unsigned char)0x80;
/* if the length is currently above 56 bytes we append zeros
* then compress. Then we can fall back to padding zeros and length
* encoding like normal.
*/
if (md->md5.curlen > 56) {
while (md->md5.curlen < 64) {
md->md5.buf[md->md5.curlen++] = (unsigned char)0;
}
s_md5_compress(md, md->md5.buf);
md->md5.curlen = 0;
}
/* pad upto 56 bytes of zeroes */
while (md->md5.curlen < 56) {
md->md5.buf[md->md5.curlen++] = (unsigned char)0;
}
/* store length */
STORE64L(md->md5.length, md->md5.buf+56);
s_md5_compress(md, md->md5.buf);
/* copy output */
for (i = 0; i < 4; i++) {
STORE32L(md->md5.state[i], out+(4*i));
}
#ifdef LTC_CLEAN_STACK
zeromem(md, sizeof(hash_state));
#endif
return CRYPT_OK;
}
/**
Self-test the hash
@return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled
*/
int md5_test(void)
{
#ifndef LTC_TEST
return CRYPT_NOP;
#else
static const struct {
const char *msg;
unsigned char hash[16];
} tests[] = {
{ "",
{ 0xd4, 0x1d, 0x8c, 0xd9, 0x8f, 0x00, 0xb2, 0x04,
0xe9, 0x80, 0x09, 0x98, 0xec, 0xf8, 0x42, 0x7e } },
{ "a",
{0x0c, 0xc1, 0x75, 0xb9, 0xc0, 0xf1, 0xb6, 0xa8,
0x31, 0xc3, 0x99, 0xe2, 0x69, 0x77, 0x26, 0x61 } },
{ "abc",
{ 0x90, 0x01, 0x50, 0x98, 0x3c, 0xd2, 0x4f, 0xb0,
0xd6, 0x96, 0x3f, 0x7d, 0x28, 0xe1, 0x7f, 0x72 } },
{ "message digest",
{ 0xf9, 0x6b, 0x69, 0x7d, 0x7c, 0xb7, 0x93, 0x8d,
0x52, 0x5a, 0x2f, 0x31, 0xaa, 0xf1, 0x61, 0xd0 } },
{ "abcdefghijklmnopqrstuvwxyz",
{ 0xc3, 0xfc, 0xd3, 0xd7, 0x61, 0x92, 0xe4, 0x00,
0x7d, 0xfb, 0x49, 0x6c, 0xca, 0x67, 0xe1, 0x3b } },
{ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
{ 0xd1, 0x74, 0xab, 0x98, 0xd2, 0x77, 0xd9, 0xf5,
0xa5, 0x61, 0x1c, 0x2c, 0x9f, 0x41, 0x9d, 0x9f } },
{ "12345678901234567890123456789012345678901234567890123456789012345678901234567890",
{ 0x57, 0xed, 0xf4, 0xa2, 0x2b, 0xe3, 0xc9, 0x55,
0xac, 0x49, 0xda, 0x2e, 0x21, 0x07, 0xb6, 0x7a } },
{ NULL, { 0 } }
};
int i;
unsigned char tmp[16];
hash_state md;
for (i = 0; tests[i].msg != NULL; i++) {
md5_init(&md);
md5_process(&md, (unsigned char *)tests[i].msg, (unsigned long)XSTRLEN(tests[i].msg));
md5_done(&md, tmp);
if (compare_testvector(tmp, sizeof(tmp), tests[i].hash, sizeof(tests[i].hash), "MD5", i)) {
return CRYPT_FAIL_TESTVECTOR;
}
}
return CRYPT_OK;
#endif
}
#undef F
#undef G
#undef H
#undef I
#undef FF
#undef GG
#undef HH
#undef II
#endif

View File

@@ -0,0 +1,408 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
/* SPDX-License-Identifier: Unlicense */
#include "tomcrypt_private.h"
/**
@param rmd128.c
RMD128 Hash function
*/
/* Implementation of LTC_RIPEMD-128 based on the source by Antoon Bosselaers, ESAT-COSIC
*
* This source has been radically overhauled to be portable and work within
* the LibTomCrypt API by Tom St Denis
*/
#ifdef LTC_RIPEMD128
const struct ltc_hash_descriptor rmd128_desc =
{
"rmd128",
8,
16,
64,
/* OID */
{ 1, 0, 10118, 3, 0, 50 },
6,
&rmd128_init,
&rmd128_process,
&rmd128_done,
&rmd128_test,
NULL
};
/* the four basic functions F(), G() and H() */
#define F(x, y, z) ((x) ^ (y) ^ (z))
#define G(x, y, z) (((x) & (y)) | (~(x) & (z)))
#define H(x, y, z) (((x) | ~(y)) ^ (z))
#define I(x, y, z) (((x) & (z)) | ((y) & ~(z)))
/* the eight basic operations FF() through III() */
#define FF(a, b, c, d, x, s) \
(a) += F((b), (c), (d)) + (x);\
(a) = ROLc((a), (s));
#define GG(a, b, c, d, x, s) \
(a) += G((b), (c), (d)) + (x) + 0x5a827999UL;\
(a) = ROLc((a), (s));
#define HH(a, b, c, d, x, s) \
(a) += H((b), (c), (d)) + (x) + 0x6ed9eba1UL;\
(a) = ROLc((a), (s));
#define II(a, b, c, d, x, s) \
(a) += I((b), (c), (d)) + (x) + 0x8f1bbcdcUL;\
(a) = ROLc((a), (s));
#define FFF(a, b, c, d, x, s) \
(a) += F((b), (c), (d)) + (x);\
(a) = ROLc((a), (s));
#define GGG(a, b, c, d, x, s) \
(a) += G((b), (c), (d)) + (x) + 0x6d703ef3UL;\
(a) = ROLc((a), (s));
#define HHH(a, b, c, d, x, s) \
(a) += H((b), (c), (d)) + (x) + 0x5c4dd124UL;\
(a) = ROLc((a), (s));
#define III(a, b, c, d, x, s) \
(a) += I((b), (c), (d)) + (x) + 0x50a28be6UL;\
(a) = ROLc((a), (s));
#ifdef LTC_CLEAN_STACK
static int ss_rmd128_compress(hash_state *md, const unsigned char *buf)
#else
static int s_rmd128_compress(hash_state *md, const unsigned char *buf)
#endif
{
ulong32 aa,bb,cc,dd,aaa,bbb,ccc,ddd,X[16];
int i;
/* load words X */
for (i = 0; i < 16; i++){
LOAD32L(X[i], buf + (4 * i));
}
/* load state */
aa = aaa = md->rmd128.state[0];
bb = bbb = md->rmd128.state[1];
cc = ccc = md->rmd128.state[2];
dd = ddd = md->rmd128.state[3];
/* round 1 */
FF(aa, bb, cc, dd, X[ 0], 11);
FF(dd, aa, bb, cc, X[ 1], 14);
FF(cc, dd, aa, bb, X[ 2], 15);
FF(bb, cc, dd, aa, X[ 3], 12);
FF(aa, bb, cc, dd, X[ 4], 5);
FF(dd, aa, bb, cc, X[ 5], 8);
FF(cc, dd, aa, bb, X[ 6], 7);
FF(bb, cc, dd, aa, X[ 7], 9);
FF(aa, bb, cc, dd, X[ 8], 11);
FF(dd, aa, bb, cc, X[ 9], 13);
FF(cc, dd, aa, bb, X[10], 14);
FF(bb, cc, dd, aa, X[11], 15);
FF(aa, bb, cc, dd, X[12], 6);
FF(dd, aa, bb, cc, X[13], 7);
FF(cc, dd, aa, bb, X[14], 9);
FF(bb, cc, dd, aa, X[15], 8);
/* round 2 */
GG(aa, bb, cc, dd, X[ 7], 7);
GG(dd, aa, bb, cc, X[ 4], 6);
GG(cc, dd, aa, bb, X[13], 8);
GG(bb, cc, dd, aa, X[ 1], 13);
GG(aa, bb, cc, dd, X[10], 11);
GG(dd, aa, bb, cc, X[ 6], 9);
GG(cc, dd, aa, bb, X[15], 7);
GG(bb, cc, dd, aa, X[ 3], 15);
GG(aa, bb, cc, dd, X[12], 7);
GG(dd, aa, bb, cc, X[ 0], 12);
GG(cc, dd, aa, bb, X[ 9], 15);
GG(bb, cc, dd, aa, X[ 5], 9);
GG(aa, bb, cc, dd, X[ 2], 11);
GG(dd, aa, bb, cc, X[14], 7);
GG(cc, dd, aa, bb, X[11], 13);
GG(bb, cc, dd, aa, X[ 8], 12);
/* round 3 */
HH(aa, bb, cc, dd, X[ 3], 11);
HH(dd, aa, bb, cc, X[10], 13);
HH(cc, dd, aa, bb, X[14], 6);
HH(bb, cc, dd, aa, X[ 4], 7);
HH(aa, bb, cc, dd, X[ 9], 14);
HH(dd, aa, bb, cc, X[15], 9);
HH(cc, dd, aa, bb, X[ 8], 13);
HH(bb, cc, dd, aa, X[ 1], 15);
HH(aa, bb, cc, dd, X[ 2], 14);
HH(dd, aa, bb, cc, X[ 7], 8);
HH(cc, dd, aa, bb, X[ 0], 13);
HH(bb, cc, dd, aa, X[ 6], 6);
HH(aa, bb, cc, dd, X[13], 5);
HH(dd, aa, bb, cc, X[11], 12);
HH(cc, dd, aa, bb, X[ 5], 7);
HH(bb, cc, dd, aa, X[12], 5);
/* round 4 */
II(aa, bb, cc, dd, X[ 1], 11);
II(dd, aa, bb, cc, X[ 9], 12);
II(cc, dd, aa, bb, X[11], 14);
II(bb, cc, dd, aa, X[10], 15);
II(aa, bb, cc, dd, X[ 0], 14);
II(dd, aa, bb, cc, X[ 8], 15);
II(cc, dd, aa, bb, X[12], 9);
II(bb, cc, dd, aa, X[ 4], 8);
II(aa, bb, cc, dd, X[13], 9);
II(dd, aa, bb, cc, X[ 3], 14);
II(cc, dd, aa, bb, X[ 7], 5);
II(bb, cc, dd, aa, X[15], 6);
II(aa, bb, cc, dd, X[14], 8);
II(dd, aa, bb, cc, X[ 5], 6);
II(cc, dd, aa, bb, X[ 6], 5);
II(bb, cc, dd, aa, X[ 2], 12);
/* parallel round 1 */
III(aaa, bbb, ccc, ddd, X[ 5], 8);
III(ddd, aaa, bbb, ccc, X[14], 9);
III(ccc, ddd, aaa, bbb, X[ 7], 9);
III(bbb, ccc, ddd, aaa, X[ 0], 11);
III(aaa, bbb, ccc, ddd, X[ 9], 13);
III(ddd, aaa, bbb, ccc, X[ 2], 15);
III(ccc, ddd, aaa, bbb, X[11], 15);
III(bbb, ccc, ddd, aaa, X[ 4], 5);
III(aaa, bbb, ccc, ddd, X[13], 7);
III(ddd, aaa, bbb, ccc, X[ 6], 7);
III(ccc, ddd, aaa, bbb, X[15], 8);
III(bbb, ccc, ddd, aaa, X[ 8], 11);
III(aaa, bbb, ccc, ddd, X[ 1], 14);
III(ddd, aaa, bbb, ccc, X[10], 14);
III(ccc, ddd, aaa, bbb, X[ 3], 12);
III(bbb, ccc, ddd, aaa, X[12], 6);
/* parallel round 2 */
HHH(aaa, bbb, ccc, ddd, X[ 6], 9);
HHH(ddd, aaa, bbb, ccc, X[11], 13);
HHH(ccc, ddd, aaa, bbb, X[ 3], 15);
HHH(bbb, ccc, ddd, aaa, X[ 7], 7);
HHH(aaa, bbb, ccc, ddd, X[ 0], 12);
HHH(ddd, aaa, bbb, ccc, X[13], 8);
HHH(ccc, ddd, aaa, bbb, X[ 5], 9);
HHH(bbb, ccc, ddd, aaa, X[10], 11);
HHH(aaa, bbb, ccc, ddd, X[14], 7);
HHH(ddd, aaa, bbb, ccc, X[15], 7);
HHH(ccc, ddd, aaa, bbb, X[ 8], 12);
HHH(bbb, ccc, ddd, aaa, X[12], 7);
HHH(aaa, bbb, ccc, ddd, X[ 4], 6);
HHH(ddd, aaa, bbb, ccc, X[ 9], 15);
HHH(ccc, ddd, aaa, bbb, X[ 1], 13);
HHH(bbb, ccc, ddd, aaa, X[ 2], 11);
/* parallel round 3 */
GGG(aaa, bbb, ccc, ddd, X[15], 9);
GGG(ddd, aaa, bbb, ccc, X[ 5], 7);
GGG(ccc, ddd, aaa, bbb, X[ 1], 15);
GGG(bbb, ccc, ddd, aaa, X[ 3], 11);
GGG(aaa, bbb, ccc, ddd, X[ 7], 8);
GGG(ddd, aaa, bbb, ccc, X[14], 6);
GGG(ccc, ddd, aaa, bbb, X[ 6], 6);
GGG(bbb, ccc, ddd, aaa, X[ 9], 14);
GGG(aaa, bbb, ccc, ddd, X[11], 12);
GGG(ddd, aaa, bbb, ccc, X[ 8], 13);
GGG(ccc, ddd, aaa, bbb, X[12], 5);
GGG(bbb, ccc, ddd, aaa, X[ 2], 14);
GGG(aaa, bbb, ccc, ddd, X[10], 13);
GGG(ddd, aaa, bbb, ccc, X[ 0], 13);
GGG(ccc, ddd, aaa, bbb, X[ 4], 7);
GGG(bbb, ccc, ddd, aaa, X[13], 5);
/* parallel round 4 */
FFF(aaa, bbb, ccc, ddd, X[ 8], 15);
FFF(ddd, aaa, bbb, ccc, X[ 6], 5);
FFF(ccc, ddd, aaa, bbb, X[ 4], 8);
FFF(bbb, ccc, ddd, aaa, X[ 1], 11);
FFF(aaa, bbb, ccc, ddd, X[ 3], 14);
FFF(ddd, aaa, bbb, ccc, X[11], 14);
FFF(ccc, ddd, aaa, bbb, X[15], 6);
FFF(bbb, ccc, ddd, aaa, X[ 0], 14);
FFF(aaa, bbb, ccc, ddd, X[ 5], 6);
FFF(ddd, aaa, bbb, ccc, X[12], 9);
FFF(ccc, ddd, aaa, bbb, X[ 2], 12);
FFF(bbb, ccc, ddd, aaa, X[13], 9);
FFF(aaa, bbb, ccc, ddd, X[ 9], 12);
FFF(ddd, aaa, bbb, ccc, X[ 7], 5);
FFF(ccc, ddd, aaa, bbb, X[10], 15);
FFF(bbb, ccc, ddd, aaa, X[14], 8);
/* combine results */
ddd += cc + md->rmd128.state[1]; /* final result for MDbuf[0] */
md->rmd128.state[1] = md->rmd128.state[2] + dd + aaa;
md->rmd128.state[2] = md->rmd128.state[3] + aa + bbb;
md->rmd128.state[3] = md->rmd128.state[0] + bb + ccc;
md->rmd128.state[0] = ddd;
return CRYPT_OK;
}
#ifdef LTC_CLEAN_STACK
static int s_rmd128_compress(hash_state *md, const unsigned char *buf)
{
int err;
err = ss_rmd128_compress(md, buf);
burn_stack(sizeof(ulong32) * 24 + sizeof(int));
return err;
}
#endif
/**
Initialize the hash state
@param md The hash state you wish to initialize
@return CRYPT_OK if successful
*/
int rmd128_init(hash_state * md)
{
LTC_ARGCHK(md != NULL);
md->rmd128.state[0] = 0x67452301UL;
md->rmd128.state[1] = 0xefcdab89UL;
md->rmd128.state[2] = 0x98badcfeUL;
md->rmd128.state[3] = 0x10325476UL;
md->rmd128.curlen = 0;
md->rmd128.length = 0;
return CRYPT_OK;
}
/**
Process a block of memory though the hash
@param md The hash state
@param in The data to hash
@param inlen The length of the data (octets)
@return CRYPT_OK if successful
*/
HASH_PROCESS(rmd128_process, s_rmd128_compress, rmd128, 64)
/**
Terminate the hash to get the digest
@param md The hash state
@param out [out] The destination of the hash (16 bytes)
@return CRYPT_OK if successful
*/
int rmd128_done(hash_state * md, unsigned char *out)
{
int i;
LTC_ARGCHK(md != NULL);
LTC_ARGCHK(out != NULL);
if (md->rmd128.curlen >= sizeof(md->rmd128.buf)) {
return CRYPT_INVALID_ARG;
}
/* increase the length of the message */
md->rmd128.length += md->rmd128.curlen * 8;
/* append the '1' bit */
md->rmd128.buf[md->rmd128.curlen++] = (unsigned char)0x80;
/* if the length is currently above 56 bytes we append zeros
* then compress. Then we can fall back to padding zeros and length
* encoding like normal.
*/
if (md->rmd128.curlen > 56) {
while (md->rmd128.curlen < 64) {
md->rmd128.buf[md->rmd128.curlen++] = (unsigned char)0;
}
s_rmd128_compress(md, md->rmd128.buf);
md->rmd128.curlen = 0;
}
/* pad upto 56 bytes of zeroes */
while (md->rmd128.curlen < 56) {
md->rmd128.buf[md->rmd128.curlen++] = (unsigned char)0;
}
/* store length */
STORE64L(md->rmd128.length, md->rmd128.buf+56);
s_rmd128_compress(md, md->rmd128.buf);
/* copy output */
for (i = 0; i < 4; i++) {
STORE32L(md->rmd128.state[i], out+(4*i));
}
#ifdef LTC_CLEAN_STACK
zeromem(md, sizeof(hash_state));
#endif
return CRYPT_OK;
}
/**
Self-test the hash
@return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled
*/
int rmd128_test(void)
{
#ifndef LTC_TEST
return CRYPT_NOP;
#else
static const struct {
const char *msg;
unsigned char hash[16];
} tests[] = {
{ "",
{ 0xcd, 0xf2, 0x62, 0x13, 0xa1, 0x50, 0xdc, 0x3e,
0xcb, 0x61, 0x0f, 0x18, 0xf6, 0xb3, 0x8b, 0x46 }
},
{ "a",
{ 0x86, 0xbe, 0x7a, 0xfa, 0x33, 0x9d, 0x0f, 0xc7,
0xcf, 0xc7, 0x85, 0xe7, 0x2f, 0x57, 0x8d, 0x33 }
},
{ "abc",
{ 0xc1, 0x4a, 0x12, 0x19, 0x9c, 0x66, 0xe4, 0xba,
0x84, 0x63, 0x6b, 0x0f, 0x69, 0x14, 0x4c, 0x77 }
},
{ "message digest",
{ 0x9e, 0x32, 0x7b, 0x3d, 0x6e, 0x52, 0x30, 0x62,
0xaf, 0xc1, 0x13, 0x2d, 0x7d, 0xf9, 0xd1, 0xb8 }
},
{ "abcdefghijklmnopqrstuvwxyz",
{ 0xfd, 0x2a, 0xa6, 0x07, 0xf7, 0x1d, 0xc8, 0xf5,
0x10, 0x71, 0x49, 0x22, 0xb3, 0x71, 0x83, 0x4e }
},
{ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
{ 0xd1, 0xe9, 0x59, 0xeb, 0x17, 0x9c, 0x91, 0x1f,
0xae, 0xa4, 0x62, 0x4c, 0x60, 0xc5, 0xc7, 0x02 }
}
};
int i;
unsigned char tmp[16];
hash_state md;
for (i = 0; i < (int)(sizeof(tests)/sizeof(tests[0])); i++) {
rmd128_init(&md);
rmd128_process(&md, (unsigned char *)tests[i].msg, XSTRLEN(tests[i].msg));
rmd128_done(&md, tmp);
if (compare_testvector(tmp, sizeof(tmp), tests[i].hash, sizeof(tests[i].hash), "RIPEMD128", i)) {
return CRYPT_FAIL_TESTVECTOR;
}
}
return CRYPT_OK;
#endif
}
#undef F
#undef G
#undef H
#undef I
#undef FF
#undef GG
#undef HH
#undef II
#undef FFF
#undef GGG
#undef HHH
#undef III
#endif

View File

@@ -0,0 +1,470 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
/* SPDX-License-Identifier: Unlicense */
#include "tomcrypt_private.h"
/**
@file rmd160.c
RMD160 hash function
*/
/* Implementation of LTC_RIPEMD-160 based on the source by Antoon Bosselaers, ESAT-COSIC
*
* This source has been radically overhauled to be portable and work within
* the LibTomCrypt API by Tom St Denis
*/
#ifdef LTC_RIPEMD160
const struct ltc_hash_descriptor rmd160_desc =
{
"rmd160",
9,
20,
64,
/* OID */
{ 1, 3, 36, 3, 2, 1, },
6,
&rmd160_init,
&rmd160_process,
&rmd160_done,
&rmd160_test,
NULL
};
/* the five basic functions F(), G() and H() */
#define F(x, y, z) ((x) ^ (y) ^ (z))
#define G(x, y, z) (((x) & (y)) | (~(x) & (z)))
#define H(x, y, z) (((x) | ~(y)) ^ (z))
#define I(x, y, z) (((x) & (z)) | ((y) & ~(z)))
#define J(x, y, z) ((x) ^ ((y) | ~(z)))
/* the ten basic operations FF() through III() */
#define FF(a, b, c, d, e, x, s) \
(a) += F((b), (c), (d)) + (x);\
(a) = ROLc((a), (s)) + (e);\
(c) = ROLc((c), 10);
#define GG(a, b, c, d, e, x, s) \
(a) += G((b), (c), (d)) + (x) + 0x5a827999UL;\
(a) = ROLc((a), (s)) + (e);\
(c) = ROLc((c), 10);
#define HH(a, b, c, d, e, x, s) \
(a) += H((b), (c), (d)) + (x) + 0x6ed9eba1UL;\
(a) = ROLc((a), (s)) + (e);\
(c) = ROLc((c), 10);
#define II(a, b, c, d, e, x, s) \
(a) += I((b), (c), (d)) + (x) + 0x8f1bbcdcUL;\
(a) = ROLc((a), (s)) + (e);\
(c) = ROLc((c), 10);
#define JJ(a, b, c, d, e, x, s) \
(a) += J((b), (c), (d)) + (x) + 0xa953fd4eUL;\
(a) = ROLc((a), (s)) + (e);\
(c) = ROLc((c), 10);
#define FFF(a, b, c, d, e, x, s) \
(a) += F((b), (c), (d)) + (x);\
(a) = ROLc((a), (s)) + (e);\
(c) = ROLc((c), 10);
#define GGG(a, b, c, d, e, x, s) \
(a) += G((b), (c), (d)) + (x) + 0x7a6d76e9UL;\
(a) = ROLc((a), (s)) + (e);\
(c) = ROLc((c), 10);
#define HHH(a, b, c, d, e, x, s) \
(a) += H((b), (c), (d)) + (x) + 0x6d703ef3UL;\
(a) = ROLc((a), (s)) + (e);\
(c) = ROLc((c), 10);
#define III(a, b, c, d, e, x, s) \
(a) += I((b), (c), (d)) + (x) + 0x5c4dd124UL;\
(a) = ROLc((a), (s)) + (e);\
(c) = ROLc((c), 10);
#define JJJ(a, b, c, d, e, x, s) \
(a) += J((b), (c), (d)) + (x) + 0x50a28be6UL;\
(a) = ROLc((a), (s)) + (e);\
(c) = ROLc((c), 10);
#ifdef LTC_CLEAN_STACK
static int ss_rmd160_compress(hash_state *md, const unsigned char *buf)
#else
static int s_rmd160_compress(hash_state *md, const unsigned char *buf)
#endif
{
ulong32 aa,bb,cc,dd,ee,aaa,bbb,ccc,ddd,eee,X[16];
int i;
/* load words X */
for (i = 0; i < 16; i++){
LOAD32L(X[i], buf + (4 * i));
}
/* load state */
aa = aaa = md->rmd160.state[0];
bb = bbb = md->rmd160.state[1];
cc = ccc = md->rmd160.state[2];
dd = ddd = md->rmd160.state[3];
ee = eee = md->rmd160.state[4];
/* round 1 */
FF(aa, bb, cc, dd, ee, X[ 0], 11);
FF(ee, aa, bb, cc, dd, X[ 1], 14);
FF(dd, ee, aa, bb, cc, X[ 2], 15);
FF(cc, dd, ee, aa, bb, X[ 3], 12);
FF(bb, cc, dd, ee, aa, X[ 4], 5);
FF(aa, bb, cc, dd, ee, X[ 5], 8);
FF(ee, aa, bb, cc, dd, X[ 6], 7);
FF(dd, ee, aa, bb, cc, X[ 7], 9);
FF(cc, dd, ee, aa, bb, X[ 8], 11);
FF(bb, cc, dd, ee, aa, X[ 9], 13);
FF(aa, bb, cc, dd, ee, X[10], 14);
FF(ee, aa, bb, cc, dd, X[11], 15);
FF(dd, ee, aa, bb, cc, X[12], 6);
FF(cc, dd, ee, aa, bb, X[13], 7);
FF(bb, cc, dd, ee, aa, X[14], 9);
FF(aa, bb, cc, dd, ee, X[15], 8);
/* round 2 */
GG(ee, aa, bb, cc, dd, X[ 7], 7);
GG(dd, ee, aa, bb, cc, X[ 4], 6);
GG(cc, dd, ee, aa, bb, X[13], 8);
GG(bb, cc, dd, ee, aa, X[ 1], 13);
GG(aa, bb, cc, dd, ee, X[10], 11);
GG(ee, aa, bb, cc, dd, X[ 6], 9);
GG(dd, ee, aa, bb, cc, X[15], 7);
GG(cc, dd, ee, aa, bb, X[ 3], 15);
GG(bb, cc, dd, ee, aa, X[12], 7);
GG(aa, bb, cc, dd, ee, X[ 0], 12);
GG(ee, aa, bb, cc, dd, X[ 9], 15);
GG(dd, ee, aa, bb, cc, X[ 5], 9);
GG(cc, dd, ee, aa, bb, X[ 2], 11);
GG(bb, cc, dd, ee, aa, X[14], 7);
GG(aa, bb, cc, dd, ee, X[11], 13);
GG(ee, aa, bb, cc, dd, X[ 8], 12);
/* round 3 */
HH(dd, ee, aa, bb, cc, X[ 3], 11);
HH(cc, dd, ee, aa, bb, X[10], 13);
HH(bb, cc, dd, ee, aa, X[14], 6);
HH(aa, bb, cc, dd, ee, X[ 4], 7);
HH(ee, aa, bb, cc, dd, X[ 9], 14);
HH(dd, ee, aa, bb, cc, X[15], 9);
HH(cc, dd, ee, aa, bb, X[ 8], 13);
HH(bb, cc, dd, ee, aa, X[ 1], 15);
HH(aa, bb, cc, dd, ee, X[ 2], 14);
HH(ee, aa, bb, cc, dd, X[ 7], 8);
HH(dd, ee, aa, bb, cc, X[ 0], 13);
HH(cc, dd, ee, aa, bb, X[ 6], 6);
HH(bb, cc, dd, ee, aa, X[13], 5);
HH(aa, bb, cc, dd, ee, X[11], 12);
HH(ee, aa, bb, cc, dd, X[ 5], 7);
HH(dd, ee, aa, bb, cc, X[12], 5);
/* round 4 */
II(cc, dd, ee, aa, bb, X[ 1], 11);
II(bb, cc, dd, ee, aa, X[ 9], 12);
II(aa, bb, cc, dd, ee, X[11], 14);
II(ee, aa, bb, cc, dd, X[10], 15);
II(dd, ee, aa, bb, cc, X[ 0], 14);
II(cc, dd, ee, aa, bb, X[ 8], 15);
II(bb, cc, dd, ee, aa, X[12], 9);
II(aa, bb, cc, dd, ee, X[ 4], 8);
II(ee, aa, bb, cc, dd, X[13], 9);
II(dd, ee, aa, bb, cc, X[ 3], 14);
II(cc, dd, ee, aa, bb, X[ 7], 5);
II(bb, cc, dd, ee, aa, X[15], 6);
II(aa, bb, cc, dd, ee, X[14], 8);
II(ee, aa, bb, cc, dd, X[ 5], 6);
II(dd, ee, aa, bb, cc, X[ 6], 5);
II(cc, dd, ee, aa, bb, X[ 2], 12);
/* round 5 */
JJ(bb, cc, dd, ee, aa, X[ 4], 9);
JJ(aa, bb, cc, dd, ee, X[ 0], 15);
JJ(ee, aa, bb, cc, dd, X[ 5], 5);
JJ(dd, ee, aa, bb, cc, X[ 9], 11);
JJ(cc, dd, ee, aa, bb, X[ 7], 6);
JJ(bb, cc, dd, ee, aa, X[12], 8);
JJ(aa, bb, cc, dd, ee, X[ 2], 13);
JJ(ee, aa, bb, cc, dd, X[10], 12);
JJ(dd, ee, aa, bb, cc, X[14], 5);
JJ(cc, dd, ee, aa, bb, X[ 1], 12);
JJ(bb, cc, dd, ee, aa, X[ 3], 13);
JJ(aa, bb, cc, dd, ee, X[ 8], 14);
JJ(ee, aa, bb, cc, dd, X[11], 11);
JJ(dd, ee, aa, bb, cc, X[ 6], 8);
JJ(cc, dd, ee, aa, bb, X[15], 5);
JJ(bb, cc, dd, ee, aa, X[13], 6);
/* parallel round 1 */
JJJ(aaa, bbb, ccc, ddd, eee, X[ 5], 8);
JJJ(eee, aaa, bbb, ccc, ddd, X[14], 9);
JJJ(ddd, eee, aaa, bbb, ccc, X[ 7], 9);
JJJ(ccc, ddd, eee, aaa, bbb, X[ 0], 11);
JJJ(bbb, ccc, ddd, eee, aaa, X[ 9], 13);
JJJ(aaa, bbb, ccc, ddd, eee, X[ 2], 15);
JJJ(eee, aaa, bbb, ccc, ddd, X[11], 15);
JJJ(ddd, eee, aaa, bbb, ccc, X[ 4], 5);
JJJ(ccc, ddd, eee, aaa, bbb, X[13], 7);
JJJ(bbb, ccc, ddd, eee, aaa, X[ 6], 7);
JJJ(aaa, bbb, ccc, ddd, eee, X[15], 8);
JJJ(eee, aaa, bbb, ccc, ddd, X[ 8], 11);
JJJ(ddd, eee, aaa, bbb, ccc, X[ 1], 14);
JJJ(ccc, ddd, eee, aaa, bbb, X[10], 14);
JJJ(bbb, ccc, ddd, eee, aaa, X[ 3], 12);
JJJ(aaa, bbb, ccc, ddd, eee, X[12], 6);
/* parallel round 2 */
III(eee, aaa, bbb, ccc, ddd, X[ 6], 9);
III(ddd, eee, aaa, bbb, ccc, X[11], 13);
III(ccc, ddd, eee, aaa, bbb, X[ 3], 15);
III(bbb, ccc, ddd, eee, aaa, X[ 7], 7);
III(aaa, bbb, ccc, ddd, eee, X[ 0], 12);
III(eee, aaa, bbb, ccc, ddd, X[13], 8);
III(ddd, eee, aaa, bbb, ccc, X[ 5], 9);
III(ccc, ddd, eee, aaa, bbb, X[10], 11);
III(bbb, ccc, ddd, eee, aaa, X[14], 7);
III(aaa, bbb, ccc, ddd, eee, X[15], 7);
III(eee, aaa, bbb, ccc, ddd, X[ 8], 12);
III(ddd, eee, aaa, bbb, ccc, X[12], 7);
III(ccc, ddd, eee, aaa, bbb, X[ 4], 6);
III(bbb, ccc, ddd, eee, aaa, X[ 9], 15);
III(aaa, bbb, ccc, ddd, eee, X[ 1], 13);
III(eee, aaa, bbb, ccc, ddd, X[ 2], 11);
/* parallel round 3 */
HHH(ddd, eee, aaa, bbb, ccc, X[15], 9);
HHH(ccc, ddd, eee, aaa, bbb, X[ 5], 7);
HHH(bbb, ccc, ddd, eee, aaa, X[ 1], 15);
HHH(aaa, bbb, ccc, ddd, eee, X[ 3], 11);
HHH(eee, aaa, bbb, ccc, ddd, X[ 7], 8);
HHH(ddd, eee, aaa, bbb, ccc, X[14], 6);
HHH(ccc, ddd, eee, aaa, bbb, X[ 6], 6);
HHH(bbb, ccc, ddd, eee, aaa, X[ 9], 14);
HHH(aaa, bbb, ccc, ddd, eee, X[11], 12);
HHH(eee, aaa, bbb, ccc, ddd, X[ 8], 13);
HHH(ddd, eee, aaa, bbb, ccc, X[12], 5);
HHH(ccc, ddd, eee, aaa, bbb, X[ 2], 14);
HHH(bbb, ccc, ddd, eee, aaa, X[10], 13);
HHH(aaa, bbb, ccc, ddd, eee, X[ 0], 13);
HHH(eee, aaa, bbb, ccc, ddd, X[ 4], 7);
HHH(ddd, eee, aaa, bbb, ccc, X[13], 5);
/* parallel round 4 */
GGG(ccc, ddd, eee, aaa, bbb, X[ 8], 15);
GGG(bbb, ccc, ddd, eee, aaa, X[ 6], 5);
GGG(aaa, bbb, ccc, ddd, eee, X[ 4], 8);
GGG(eee, aaa, bbb, ccc, ddd, X[ 1], 11);
GGG(ddd, eee, aaa, bbb, ccc, X[ 3], 14);
GGG(ccc, ddd, eee, aaa, bbb, X[11], 14);
GGG(bbb, ccc, ddd, eee, aaa, X[15], 6);
GGG(aaa, bbb, ccc, ddd, eee, X[ 0], 14);
GGG(eee, aaa, bbb, ccc, ddd, X[ 5], 6);
GGG(ddd, eee, aaa, bbb, ccc, X[12], 9);
GGG(ccc, ddd, eee, aaa, bbb, X[ 2], 12);
GGG(bbb, ccc, ddd, eee, aaa, X[13], 9);
GGG(aaa, bbb, ccc, ddd, eee, X[ 9], 12);
GGG(eee, aaa, bbb, ccc, ddd, X[ 7], 5);
GGG(ddd, eee, aaa, bbb, ccc, X[10], 15);
GGG(ccc, ddd, eee, aaa, bbb, X[14], 8);
/* parallel round 5 */
FFF(bbb, ccc, ddd, eee, aaa, X[12] , 8);
FFF(aaa, bbb, ccc, ddd, eee, X[15] , 5);
FFF(eee, aaa, bbb, ccc, ddd, X[10] , 12);
FFF(ddd, eee, aaa, bbb, ccc, X[ 4] , 9);
FFF(ccc, ddd, eee, aaa, bbb, X[ 1] , 12);
FFF(bbb, ccc, ddd, eee, aaa, X[ 5] , 5);
FFF(aaa, bbb, ccc, ddd, eee, X[ 8] , 14);
FFF(eee, aaa, bbb, ccc, ddd, X[ 7] , 6);
FFF(ddd, eee, aaa, bbb, ccc, X[ 6] , 8);
FFF(ccc, ddd, eee, aaa, bbb, X[ 2] , 13);
FFF(bbb, ccc, ddd, eee, aaa, X[13] , 6);
FFF(aaa, bbb, ccc, ddd, eee, X[14] , 5);
FFF(eee, aaa, bbb, ccc, ddd, X[ 0] , 15);
FFF(ddd, eee, aaa, bbb, ccc, X[ 3] , 13);
FFF(ccc, ddd, eee, aaa, bbb, X[ 9] , 11);
FFF(bbb, ccc, ddd, eee, aaa, X[11] , 11);
/* combine results */
ddd += cc + md->rmd160.state[1]; /* final result for md->rmd160.state[0] */
md->rmd160.state[1] = md->rmd160.state[2] + dd + eee;
md->rmd160.state[2] = md->rmd160.state[3] + ee + aaa;
md->rmd160.state[3] = md->rmd160.state[4] + aa + bbb;
md->rmd160.state[4] = md->rmd160.state[0] + bb + ccc;
md->rmd160.state[0] = ddd;
return CRYPT_OK;
}
#ifdef LTC_CLEAN_STACK
static int s_rmd160_compress(hash_state *md, const unsigned char *buf)
{
int err;
err = ss_rmd160_compress(md, buf);
burn_stack(sizeof(ulong32) * 26 + sizeof(int));
return err;
}
#endif
/**
Initialize the hash state
@param md The hash state you wish to initialize
@return CRYPT_OK if successful
*/
int rmd160_init(hash_state * md)
{
LTC_ARGCHK(md != NULL);
md->rmd160.state[0] = 0x67452301UL;
md->rmd160.state[1] = 0xefcdab89UL;
md->rmd160.state[2] = 0x98badcfeUL;
md->rmd160.state[3] = 0x10325476UL;
md->rmd160.state[4] = 0xc3d2e1f0UL;
md->rmd160.curlen = 0;
md->rmd160.length = 0;
return CRYPT_OK;
}
/**
Process a block of memory though the hash
@param md The hash state
@param in The data to hash
@param inlen The length of the data (octets)
@return CRYPT_OK if successful
*/
HASH_PROCESS(rmd160_process, s_rmd160_compress, rmd160, 64)
/**
Terminate the hash to get the digest
@param md The hash state
@param out [out] The destination of the hash (20 bytes)
@return CRYPT_OK if successful
*/
int rmd160_done(hash_state * md, unsigned char *out)
{
int i;
LTC_ARGCHK(md != NULL);
LTC_ARGCHK(out != NULL);
if (md->rmd160.curlen >= sizeof(md->rmd160.buf)) {
return CRYPT_INVALID_ARG;
}
/* increase the length of the message */
md->rmd160.length += md->rmd160.curlen * 8;
/* append the '1' bit */
md->rmd160.buf[md->rmd160.curlen++] = (unsigned char)0x80;
/* if the length is currently above 56 bytes we append zeros
* then compress. Then we can fall back to padding zeros and length
* encoding like normal.
*/
if (md->rmd160.curlen > 56) {
while (md->rmd160.curlen < 64) {
md->rmd160.buf[md->rmd160.curlen++] = (unsigned char)0;
}
s_rmd160_compress(md, md->rmd160.buf);
md->rmd160.curlen = 0;
}
/* pad upto 56 bytes of zeroes */
while (md->rmd160.curlen < 56) {
md->rmd160.buf[md->rmd160.curlen++] = (unsigned char)0;
}
/* store length */
STORE64L(md->rmd160.length, md->rmd160.buf+56);
s_rmd160_compress(md, md->rmd160.buf);
/* copy output */
for (i = 0; i < 5; i++) {
STORE32L(md->rmd160.state[i], out+(4*i));
}
#ifdef LTC_CLEAN_STACK
zeromem(md, sizeof(hash_state));
#endif
return CRYPT_OK;
}
/**
Self-test the hash
@return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled
*/
int rmd160_test(void)
{
#ifndef LTC_TEST
return CRYPT_NOP;
#else
static const struct {
const char *msg;
unsigned char hash[20];
} tests[] = {
{ "",
{ 0x9c, 0x11, 0x85, 0xa5, 0xc5, 0xe9, 0xfc, 0x54, 0x61, 0x28,
0x08, 0x97, 0x7e, 0xe8, 0xf5, 0x48, 0xb2, 0x25, 0x8d, 0x31 }
},
{ "a",
{ 0x0b, 0xdc, 0x9d, 0x2d, 0x25, 0x6b, 0x3e, 0xe9, 0xda, 0xae,
0x34, 0x7b, 0xe6, 0xf4, 0xdc, 0x83, 0x5a, 0x46, 0x7f, 0xfe }
},
{ "abc",
{ 0x8e, 0xb2, 0x08, 0xf7, 0xe0, 0x5d, 0x98, 0x7a, 0x9b, 0x04,
0x4a, 0x8e, 0x98, 0xc6, 0xb0, 0x87, 0xf1, 0x5a, 0x0b, 0xfc }
},
{ "message digest",
{ 0x5d, 0x06, 0x89, 0xef, 0x49, 0xd2, 0xfa, 0xe5, 0x72, 0xb8,
0x81, 0xb1, 0x23, 0xa8, 0x5f, 0xfa, 0x21, 0x59, 0x5f, 0x36 }
},
{ "abcdefghijklmnopqrstuvwxyz",
{ 0xf7, 0x1c, 0x27, 0x10, 0x9c, 0x69, 0x2c, 0x1b, 0x56, 0xbb,
0xdc, 0xeb, 0x5b, 0x9d, 0x28, 0x65, 0xb3, 0x70, 0x8d, 0xbc }
},
{ "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
{ 0x12, 0xa0, 0x53, 0x38, 0x4a, 0x9c, 0x0c, 0x88, 0xe4, 0x05,
0xa0, 0x6c, 0x27, 0xdc, 0xf4, 0x9a, 0xda, 0x62, 0xeb, 0x2b }
}
};
int i;
unsigned char tmp[20];
hash_state md;
for (i = 0; i < (int)(sizeof(tests)/sizeof(tests[0])); i++) {
rmd160_init(&md);
rmd160_process(&md, (unsigned char *)tests[i].msg, XSTRLEN(tests[i].msg));
rmd160_done(&md, tmp);
if (compare_testvector(tmp, sizeof(tmp), tests[i].hash, sizeof(tests[i].hash), "RIPEMD160", i)) {
return CRYPT_FAIL_TESTVECTOR;
}
}
return CRYPT_OK;
#endif
}
#undef F
#undef G
#undef H
#undef I
#undef J
#undef FF
#undef GG
#undef HH
#undef II
#undef JJ
#undef FFF
#undef GGG
#undef HHH
#undef III
#undef JJJ
#endif

View File

@@ -0,0 +1,433 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
/* SPDX-License-Identifier: Unlicense */
#include "tomcrypt_private.h"
/**
@param rmd256.c
RLTC_MD256 Hash function
*/
#ifdef LTC_RIPEMD256
const struct ltc_hash_descriptor rmd256_desc =
{
"rmd256",
13,
32,
64,
/* OID */
{ 1, 3, 36, 3, 2, 3 },
6,
&rmd256_init,
&rmd256_process,
&rmd256_done,
&rmd256_test,
NULL
};
/* the four basic functions F(), G() and H() */
#define F(x, y, z) ((x) ^ (y) ^ (z))
#define G(x, y, z) (((x) & (y)) | (~(x) & (z)))
#define H(x, y, z) (((x) | ~(y)) ^ (z))
#define I(x, y, z) (((x) & (z)) | ((y) & ~(z)))
/* the eight basic operations FF() through III() */
#define FF(a, b, c, d, x, s) \
(a) += F((b), (c), (d)) + (x);\
(a) = ROLc((a), (s));
#define GG(a, b, c, d, x, s) \
(a) += G((b), (c), (d)) + (x) + 0x5a827999UL;\
(a) = ROLc((a), (s));
#define HH(a, b, c, d, x, s) \
(a) += H((b), (c), (d)) + (x) + 0x6ed9eba1UL;\
(a) = ROLc((a), (s));
#define II(a, b, c, d, x, s) \
(a) += I((b), (c), (d)) + (x) + 0x8f1bbcdcUL;\
(a) = ROLc((a), (s));
#define FFF(a, b, c, d, x, s) \
(a) += F((b), (c), (d)) + (x);\
(a) = ROLc((a), (s));
#define GGG(a, b, c, d, x, s) \
(a) += G((b), (c), (d)) + (x) + 0x6d703ef3UL;\
(a) = ROLc((a), (s));
#define HHH(a, b, c, d, x, s) \
(a) += H((b), (c), (d)) + (x) + 0x5c4dd124UL;\
(a) = ROLc((a), (s));
#define III(a, b, c, d, x, s) \
(a) += I((b), (c), (d)) + (x) + 0x50a28be6UL;\
(a) = ROLc((a), (s));
#ifdef LTC_CLEAN_STACK
static int ss_rmd256_compress(hash_state *md, const unsigned char *buf)
#else
static int s_rmd256_compress(hash_state *md, const unsigned char *buf)
#endif
{
ulong32 aa,bb,cc,dd,aaa,bbb,ccc,ddd,tmp,X[16];
int i;
/* load words X */
for (i = 0; i < 16; i++){
LOAD32L(X[i], buf + (4 * i));
}
/* load state */
aa = md->rmd256.state[0];
bb = md->rmd256.state[1];
cc = md->rmd256.state[2];
dd = md->rmd256.state[3];
aaa = md->rmd256.state[4];
bbb = md->rmd256.state[5];
ccc = md->rmd256.state[6];
ddd = md->rmd256.state[7];
/* round 1 */
FF(aa, bb, cc, dd, X[ 0], 11);
FF(dd, aa, bb, cc, X[ 1], 14);
FF(cc, dd, aa, bb, X[ 2], 15);
FF(bb, cc, dd, aa, X[ 3], 12);
FF(aa, bb, cc, dd, X[ 4], 5);
FF(dd, aa, bb, cc, X[ 5], 8);
FF(cc, dd, aa, bb, X[ 6], 7);
FF(bb, cc, dd, aa, X[ 7], 9);
FF(aa, bb, cc, dd, X[ 8], 11);
FF(dd, aa, bb, cc, X[ 9], 13);
FF(cc, dd, aa, bb, X[10], 14);
FF(bb, cc, dd, aa, X[11], 15);
FF(aa, bb, cc, dd, X[12], 6);
FF(dd, aa, bb, cc, X[13], 7);
FF(cc, dd, aa, bb, X[14], 9);
FF(bb, cc, dd, aa, X[15], 8);
/* parallel round 1 */
III(aaa, bbb, ccc, ddd, X[ 5], 8);
III(ddd, aaa, bbb, ccc, X[14], 9);
III(ccc, ddd, aaa, bbb, X[ 7], 9);
III(bbb, ccc, ddd, aaa, X[ 0], 11);
III(aaa, bbb, ccc, ddd, X[ 9], 13);
III(ddd, aaa, bbb, ccc, X[ 2], 15);
III(ccc, ddd, aaa, bbb, X[11], 15);
III(bbb, ccc, ddd, aaa, X[ 4], 5);
III(aaa, bbb, ccc, ddd, X[13], 7);
III(ddd, aaa, bbb, ccc, X[ 6], 7);
III(ccc, ddd, aaa, bbb, X[15], 8);
III(bbb, ccc, ddd, aaa, X[ 8], 11);
III(aaa, bbb, ccc, ddd, X[ 1], 14);
III(ddd, aaa, bbb, ccc, X[10], 14);
III(ccc, ddd, aaa, bbb, X[ 3], 12);
III(bbb, ccc, ddd, aaa, X[12], 6);
tmp = aa; aa = aaa; aaa = tmp;
/* round 2 */
GG(aa, bb, cc, dd, X[ 7], 7);
GG(dd, aa, bb, cc, X[ 4], 6);
GG(cc, dd, aa, bb, X[13], 8);
GG(bb, cc, dd, aa, X[ 1], 13);
GG(aa, bb, cc, dd, X[10], 11);
GG(dd, aa, bb, cc, X[ 6], 9);
GG(cc, dd, aa, bb, X[15], 7);
GG(bb, cc, dd, aa, X[ 3], 15);
GG(aa, bb, cc, dd, X[12], 7);
GG(dd, aa, bb, cc, X[ 0], 12);
GG(cc, dd, aa, bb, X[ 9], 15);
GG(bb, cc, dd, aa, X[ 5], 9);
GG(aa, bb, cc, dd, X[ 2], 11);
GG(dd, aa, bb, cc, X[14], 7);
GG(cc, dd, aa, bb, X[11], 13);
GG(bb, cc, dd, aa, X[ 8], 12);
/* parallel round 2 */
HHH(aaa, bbb, ccc, ddd, X[ 6], 9);
HHH(ddd, aaa, bbb, ccc, X[11], 13);
HHH(ccc, ddd, aaa, bbb, X[ 3], 15);
HHH(bbb, ccc, ddd, aaa, X[ 7], 7);
HHH(aaa, bbb, ccc, ddd, X[ 0], 12);
HHH(ddd, aaa, bbb, ccc, X[13], 8);
HHH(ccc, ddd, aaa, bbb, X[ 5], 9);
HHH(bbb, ccc, ddd, aaa, X[10], 11);
HHH(aaa, bbb, ccc, ddd, X[14], 7);
HHH(ddd, aaa, bbb, ccc, X[15], 7);
HHH(ccc, ddd, aaa, bbb, X[ 8], 12);
HHH(bbb, ccc, ddd, aaa, X[12], 7);
HHH(aaa, bbb, ccc, ddd, X[ 4], 6);
HHH(ddd, aaa, bbb, ccc, X[ 9], 15);
HHH(ccc, ddd, aaa, bbb, X[ 1], 13);
HHH(bbb, ccc, ddd, aaa, X[ 2], 11);
tmp = bb; bb = bbb; bbb = tmp;
/* round 3 */
HH(aa, bb, cc, dd, X[ 3], 11);
HH(dd, aa, bb, cc, X[10], 13);
HH(cc, dd, aa, bb, X[14], 6);
HH(bb, cc, dd, aa, X[ 4], 7);
HH(aa, bb, cc, dd, X[ 9], 14);
HH(dd, aa, bb, cc, X[15], 9);
HH(cc, dd, aa, bb, X[ 8], 13);
HH(bb, cc, dd, aa, X[ 1], 15);
HH(aa, bb, cc, dd, X[ 2], 14);
HH(dd, aa, bb, cc, X[ 7], 8);
HH(cc, dd, aa, bb, X[ 0], 13);
HH(bb, cc, dd, aa, X[ 6], 6);
HH(aa, bb, cc, dd, X[13], 5);
HH(dd, aa, bb, cc, X[11], 12);
HH(cc, dd, aa, bb, X[ 5], 7);
HH(bb, cc, dd, aa, X[12], 5);
/* parallel round 3 */
GGG(aaa, bbb, ccc, ddd, X[15], 9);
GGG(ddd, aaa, bbb, ccc, X[ 5], 7);
GGG(ccc, ddd, aaa, bbb, X[ 1], 15);
GGG(bbb, ccc, ddd, aaa, X[ 3], 11);
GGG(aaa, bbb, ccc, ddd, X[ 7], 8);
GGG(ddd, aaa, bbb, ccc, X[14], 6);
GGG(ccc, ddd, aaa, bbb, X[ 6], 6);
GGG(bbb, ccc, ddd, aaa, X[ 9], 14);
GGG(aaa, bbb, ccc, ddd, X[11], 12);
GGG(ddd, aaa, bbb, ccc, X[ 8], 13);
GGG(ccc, ddd, aaa, bbb, X[12], 5);
GGG(bbb, ccc, ddd, aaa, X[ 2], 14);
GGG(aaa, bbb, ccc, ddd, X[10], 13);
GGG(ddd, aaa, bbb, ccc, X[ 0], 13);
GGG(ccc, ddd, aaa, bbb, X[ 4], 7);
GGG(bbb, ccc, ddd, aaa, X[13], 5);
tmp = cc; cc = ccc; ccc = tmp;
/* round 4 */
II(aa, bb, cc, dd, X[ 1], 11);
II(dd, aa, bb, cc, X[ 9], 12);
II(cc, dd, aa, bb, X[11], 14);
II(bb, cc, dd, aa, X[10], 15);
II(aa, bb, cc, dd, X[ 0], 14);
II(dd, aa, bb, cc, X[ 8], 15);
II(cc, dd, aa, bb, X[12], 9);
II(bb, cc, dd, aa, X[ 4], 8);
II(aa, bb, cc, dd, X[13], 9);
II(dd, aa, bb, cc, X[ 3], 14);
II(cc, dd, aa, bb, X[ 7], 5);
II(bb, cc, dd, aa, X[15], 6);
II(aa, bb, cc, dd, X[14], 8);
II(dd, aa, bb, cc, X[ 5], 6);
II(cc, dd, aa, bb, X[ 6], 5);
II(bb, cc, dd, aa, X[ 2], 12);
/* parallel round 4 */
FFF(aaa, bbb, ccc, ddd, X[ 8], 15);
FFF(ddd, aaa, bbb, ccc, X[ 6], 5);
FFF(ccc, ddd, aaa, bbb, X[ 4], 8);
FFF(bbb, ccc, ddd, aaa, X[ 1], 11);
FFF(aaa, bbb, ccc, ddd, X[ 3], 14);
FFF(ddd, aaa, bbb, ccc, X[11], 14);
FFF(ccc, ddd, aaa, bbb, X[15], 6);
FFF(bbb, ccc, ddd, aaa, X[ 0], 14);
FFF(aaa, bbb, ccc, ddd, X[ 5], 6);
FFF(ddd, aaa, bbb, ccc, X[12], 9);
FFF(ccc, ddd, aaa, bbb, X[ 2], 12);
FFF(bbb, ccc, ddd, aaa, X[13], 9);
FFF(aaa, bbb, ccc, ddd, X[ 9], 12);
FFF(ddd, aaa, bbb, ccc, X[ 7], 5);
FFF(ccc, ddd, aaa, bbb, X[10], 15);
FFF(bbb, ccc, ddd, aaa, X[14], 8);
tmp = dd; dd = ddd; ddd = tmp;
/* combine results */
md->rmd256.state[0] += aa;
md->rmd256.state[1] += bb;
md->rmd256.state[2] += cc;
md->rmd256.state[3] += dd;
md->rmd256.state[4] += aaa;
md->rmd256.state[5] += bbb;
md->rmd256.state[6] += ccc;
md->rmd256.state[7] += ddd;
return CRYPT_OK;
}
#ifdef LTC_CLEAN_STACK
static int s_rmd256_compress(hash_state *md, const unsigned char *buf)
{
int err;
err = ss_rmd256_compress(md, buf);
burn_stack(sizeof(ulong32) * 25 + sizeof(int));
return err;
}
#endif
/**
Initialize the hash state
@param md The hash state you wish to initialize
@return CRYPT_OK if successful
*/
int rmd256_init(hash_state * md)
{
LTC_ARGCHK(md != NULL);
md->rmd256.state[0] = 0x67452301UL;
md->rmd256.state[1] = 0xefcdab89UL;
md->rmd256.state[2] = 0x98badcfeUL;
md->rmd256.state[3] = 0x10325476UL;
md->rmd256.state[4] = 0x76543210UL;
md->rmd256.state[5] = 0xfedcba98UL;
md->rmd256.state[6] = 0x89abcdefUL;
md->rmd256.state[7] = 0x01234567UL;
md->rmd256.curlen = 0;
md->rmd256.length = 0;
return CRYPT_OK;
}
/**
Process a block of memory though the hash
@param md The hash state
@param in The data to hash
@param inlen The length of the data (octets)
@return CRYPT_OK if successful
*/
HASH_PROCESS(rmd256_process, s_rmd256_compress, rmd256, 64)
/**
Terminate the hash to get the digest
@param md The hash state
@param out [out] The destination of the hash (16 bytes)
@return CRYPT_OK if successful
*/
int rmd256_done(hash_state * md, unsigned char *out)
{
int i;
LTC_ARGCHK(md != NULL);
LTC_ARGCHK(out != NULL);
if (md->rmd256.curlen >= sizeof(md->rmd256.buf)) {
return CRYPT_INVALID_ARG;
}
/* increase the length of the message */
md->rmd256.length += md->rmd256.curlen * 8;
/* append the '1' bit */
md->rmd256.buf[md->rmd256.curlen++] = (unsigned char)0x80;
/* if the length is currently above 56 bytes we append zeros
* then compress. Then we can fall back to padding zeros and length
* encoding like normal.
*/
if (md->rmd256.curlen > 56) {
while (md->rmd256.curlen < 64) {
md->rmd256.buf[md->rmd256.curlen++] = (unsigned char)0;
}
s_rmd256_compress(md, md->rmd256.buf);
md->rmd256.curlen = 0;
}
/* pad upto 56 bytes of zeroes */
while (md->rmd256.curlen < 56) {
md->rmd256.buf[md->rmd256.curlen++] = (unsigned char)0;
}
/* store length */
STORE64L(md->rmd256.length, md->rmd256.buf+56);
s_rmd256_compress(md, md->rmd256.buf);
/* copy output */
for (i = 0; i < 8; i++) {
STORE32L(md->rmd256.state[i], out+(4*i));
}
#ifdef LTC_CLEAN_STACK
zeromem(md, sizeof(hash_state));
#endif
return CRYPT_OK;
}
/**
Self-test the hash
@return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled
*/
int rmd256_test(void)
{
#ifndef LTC_TEST
return CRYPT_NOP;
#else
static const struct {
const char *msg;
unsigned char hash[32];
} tests[] = {
{ "",
{ 0x02, 0xba, 0x4c, 0x4e, 0x5f, 0x8e, 0xcd, 0x18,
0x77, 0xfc, 0x52, 0xd6, 0x4d, 0x30, 0xe3, 0x7a,
0x2d, 0x97, 0x74, 0xfb, 0x1e, 0x5d, 0x02, 0x63,
0x80, 0xae, 0x01, 0x68, 0xe3, 0xc5, 0x52, 0x2d }
},
{ "a",
{ 0xf9, 0x33, 0x3e, 0x45, 0xd8, 0x57, 0xf5, 0xd9,
0x0a, 0x91, 0xba, 0xb7, 0x0a, 0x1e, 0xba, 0x0c,
0xfb, 0x1b, 0xe4, 0xb0, 0x78, 0x3c, 0x9a, 0xcf,
0xcd, 0x88, 0x3a, 0x91, 0x34, 0x69, 0x29, 0x25 }
},
{ "abc",
{ 0xaf, 0xbd, 0x6e, 0x22, 0x8b, 0x9d, 0x8c, 0xbb,
0xce, 0xf5, 0xca, 0x2d, 0x03, 0xe6, 0xdb, 0xa1,
0x0a, 0xc0, 0xbc, 0x7d, 0xcb, 0xe4, 0x68, 0x0e,
0x1e, 0x42, 0xd2, 0xe9, 0x75, 0x45, 0x9b, 0x65 }
},
{ "message digest",
{ 0x87, 0xe9, 0x71, 0x75, 0x9a, 0x1c, 0xe4, 0x7a,
0x51, 0x4d, 0x5c, 0x91, 0x4c, 0x39, 0x2c, 0x90,
0x18, 0xc7, 0xc4, 0x6b, 0xc1, 0x44, 0x65, 0x55,
0x4a, 0xfc, 0xdf, 0x54, 0xa5, 0x07, 0x0c, 0x0e }
},
{ "abcdefghijklmnopqrstuvwxyz",
{ 0x64, 0x9d, 0x30, 0x34, 0x75, 0x1e, 0xa2, 0x16,
0x77, 0x6b, 0xf9, 0xa1, 0x8a, 0xcc, 0x81, 0xbc,
0x78, 0x96, 0x11, 0x8a, 0x51, 0x97, 0x96, 0x87,
0x82, 0xdd, 0x1f, 0xd9, 0x7d, 0x8d, 0x51, 0x33 }
},
{ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
{ 0x57, 0x40, 0xa4, 0x08, 0xac, 0x16, 0xb7, 0x20,
0xb8, 0x44, 0x24, 0xae, 0x93, 0x1c, 0xbb, 0x1f,
0xe3, 0x63, 0xd1, 0xd0, 0xbf, 0x40, 0x17, 0xf1,
0xa8, 0x9f, 0x7e, 0xa6, 0xde, 0x77, 0xa0, 0xb8 }
}
};
int i;
unsigned char tmp[32];
hash_state md;
for (i = 0; i < (int)(sizeof(tests)/sizeof(tests[0])); i++) {
rmd256_init(&md);
rmd256_process(&md, (unsigned char *)tests[i].msg, XSTRLEN(tests[i].msg));
rmd256_done(&md, tmp);
if (compare_testvector(tmp, sizeof(tmp), tests[i].hash, sizeof(tests[i].hash), "RIPEMD256", i)) {
return CRYPT_FAIL_TESTVECTOR;
}
}
return CRYPT_OK;
#endif
}
#undef F
#undef G
#undef H
#undef I
#undef FF
#undef GG
#undef HH
#undef II
#undef FFF
#undef GGG
#undef HHH
#undef III
#endif

View File

@@ -0,0 +1,501 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
/* SPDX-License-Identifier: Unlicense */
#include "tomcrypt_private.h"
/**
@file rmd320.c
RMD320 hash function
*/
#ifdef LTC_RIPEMD320
const struct ltc_hash_descriptor rmd320_desc =
{
"rmd320",
14,
40,
64,
/* OID ... does not exist
* http://oid-info.com/get/1.3.36.3.2 */
{ 0 },
0,
&rmd320_init,
&rmd320_process,
&rmd320_done,
&rmd320_test,
NULL
};
/* the five basic functions F(), G() and H() */
#define F(x, y, z) ((x) ^ (y) ^ (z))
#define G(x, y, z) (((x) & (y)) | (~(x) & (z)))
#define H(x, y, z) (((x) | ~(y)) ^ (z))
#define I(x, y, z) (((x) & (z)) | ((y) & ~(z)))
#define J(x, y, z) ((x) ^ ((y) | ~(z)))
/* the ten basic operations FF() through III() */
#define FF(a, b, c, d, e, x, s) \
(a) += F((b), (c), (d)) + (x);\
(a) = ROLc((a), (s)) + (e);\
(c) = ROLc((c), 10);
#define GG(a, b, c, d, e, x, s) \
(a) += G((b), (c), (d)) + (x) + 0x5a827999UL;\
(a) = ROLc((a), (s)) + (e);\
(c) = ROLc((c), 10);
#define HH(a, b, c, d, e, x, s) \
(a) += H((b), (c), (d)) + (x) + 0x6ed9eba1UL;\
(a) = ROLc((a), (s)) + (e);\
(c) = ROLc((c), 10);
#define II(a, b, c, d, e, x, s) \
(a) += I((b), (c), (d)) + (x) + 0x8f1bbcdcUL;\
(a) = ROLc((a), (s)) + (e);\
(c) = ROLc((c), 10);
#define JJ(a, b, c, d, e, x, s) \
(a) += J((b), (c), (d)) + (x) + 0xa953fd4eUL;\
(a) = ROLc((a), (s)) + (e);\
(c) = ROLc((c), 10);
#define FFF(a, b, c, d, e, x, s) \
(a) += F((b), (c), (d)) + (x);\
(a) = ROLc((a), (s)) + (e);\
(c) = ROLc((c), 10);
#define GGG(a, b, c, d, e, x, s) \
(a) += G((b), (c), (d)) + (x) + 0x7a6d76e9UL;\
(a) = ROLc((a), (s)) + (e);\
(c) = ROLc((c), 10);
#define HHH(a, b, c, d, e, x, s) \
(a) += H((b), (c), (d)) + (x) + 0x6d703ef3UL;\
(a) = ROLc((a), (s)) + (e);\
(c) = ROLc((c), 10);
#define III(a, b, c, d, e, x, s) \
(a) += I((b), (c), (d)) + (x) + 0x5c4dd124UL;\
(a) = ROLc((a), (s)) + (e);\
(c) = ROLc((c), 10);
#define JJJ(a, b, c, d, e, x, s) \
(a) += J((b), (c), (d)) + (x) + 0x50a28be6UL;\
(a) = ROLc((a), (s)) + (e);\
(c) = ROLc((c), 10);
#ifdef LTC_CLEAN_STACK
static int ss_rmd320_compress(hash_state *md, const unsigned char *buf)
#else
static int s_rmd320_compress(hash_state *md, const unsigned char *buf)
#endif
{
ulong32 aa,bb,cc,dd,ee,aaa,bbb,ccc,ddd,eee,tmp,X[16];
int i;
/* load words X */
for (i = 0; i < 16; i++){
LOAD32L(X[i], buf + (4 * i));
}
/* load state */
aa = md->rmd320.state[0];
bb = md->rmd320.state[1];
cc = md->rmd320.state[2];
dd = md->rmd320.state[3];
ee = md->rmd320.state[4];
aaa = md->rmd320.state[5];
bbb = md->rmd320.state[6];
ccc = md->rmd320.state[7];
ddd = md->rmd320.state[8];
eee = md->rmd320.state[9];
/* round 1 */
FF(aa, bb, cc, dd, ee, X[ 0], 11);
FF(ee, aa, bb, cc, dd, X[ 1], 14);
FF(dd, ee, aa, bb, cc, X[ 2], 15);
FF(cc, dd, ee, aa, bb, X[ 3], 12);
FF(bb, cc, dd, ee, aa, X[ 4], 5);
FF(aa, bb, cc, dd, ee, X[ 5], 8);
FF(ee, aa, bb, cc, dd, X[ 6], 7);
FF(dd, ee, aa, bb, cc, X[ 7], 9);
FF(cc, dd, ee, aa, bb, X[ 8], 11);
FF(bb, cc, dd, ee, aa, X[ 9], 13);
FF(aa, bb, cc, dd, ee, X[10], 14);
FF(ee, aa, bb, cc, dd, X[11], 15);
FF(dd, ee, aa, bb, cc, X[12], 6);
FF(cc, dd, ee, aa, bb, X[13], 7);
FF(bb, cc, dd, ee, aa, X[14], 9);
FF(aa, bb, cc, dd, ee, X[15], 8);
/* parallel round 1 */
JJJ(aaa, bbb, ccc, ddd, eee, X[ 5], 8);
JJJ(eee, aaa, bbb, ccc, ddd, X[14], 9);
JJJ(ddd, eee, aaa, bbb, ccc, X[ 7], 9);
JJJ(ccc, ddd, eee, aaa, bbb, X[ 0], 11);
JJJ(bbb, ccc, ddd, eee, aaa, X[ 9], 13);
JJJ(aaa, bbb, ccc, ddd, eee, X[ 2], 15);
JJJ(eee, aaa, bbb, ccc, ddd, X[11], 15);
JJJ(ddd, eee, aaa, bbb, ccc, X[ 4], 5);
JJJ(ccc, ddd, eee, aaa, bbb, X[13], 7);
JJJ(bbb, ccc, ddd, eee, aaa, X[ 6], 7);
JJJ(aaa, bbb, ccc, ddd, eee, X[15], 8);
JJJ(eee, aaa, bbb, ccc, ddd, X[ 8], 11);
JJJ(ddd, eee, aaa, bbb, ccc, X[ 1], 14);
JJJ(ccc, ddd, eee, aaa, bbb, X[10], 14);
JJJ(bbb, ccc, ddd, eee, aaa, X[ 3], 12);
JJJ(aaa, bbb, ccc, ddd, eee, X[12], 6);
tmp = aa; aa = aaa; aaa = tmp;
/* round 2 */
GG(ee, aa, bb, cc, dd, X[ 7], 7);
GG(dd, ee, aa, bb, cc, X[ 4], 6);
GG(cc, dd, ee, aa, bb, X[13], 8);
GG(bb, cc, dd, ee, aa, X[ 1], 13);
GG(aa, bb, cc, dd, ee, X[10], 11);
GG(ee, aa, bb, cc, dd, X[ 6], 9);
GG(dd, ee, aa, bb, cc, X[15], 7);
GG(cc, dd, ee, aa, bb, X[ 3], 15);
GG(bb, cc, dd, ee, aa, X[12], 7);
GG(aa, bb, cc, dd, ee, X[ 0], 12);
GG(ee, aa, bb, cc, dd, X[ 9], 15);
GG(dd, ee, aa, bb, cc, X[ 5], 9);
GG(cc, dd, ee, aa, bb, X[ 2], 11);
GG(bb, cc, dd, ee, aa, X[14], 7);
GG(aa, bb, cc, dd, ee, X[11], 13);
GG(ee, aa, bb, cc, dd, X[ 8], 12);
/* parallel round 2 */
III(eee, aaa, bbb, ccc, ddd, X[ 6], 9);
III(ddd, eee, aaa, bbb, ccc, X[11], 13);
III(ccc, ddd, eee, aaa, bbb, X[ 3], 15);
III(bbb, ccc, ddd, eee, aaa, X[ 7], 7);
III(aaa, bbb, ccc, ddd, eee, X[ 0], 12);
III(eee, aaa, bbb, ccc, ddd, X[13], 8);
III(ddd, eee, aaa, bbb, ccc, X[ 5], 9);
III(ccc, ddd, eee, aaa, bbb, X[10], 11);
III(bbb, ccc, ddd, eee, aaa, X[14], 7);
III(aaa, bbb, ccc, ddd, eee, X[15], 7);
III(eee, aaa, bbb, ccc, ddd, X[ 8], 12);
III(ddd, eee, aaa, bbb, ccc, X[12], 7);
III(ccc, ddd, eee, aaa, bbb, X[ 4], 6);
III(bbb, ccc, ddd, eee, aaa, X[ 9], 15);
III(aaa, bbb, ccc, ddd, eee, X[ 1], 13);
III(eee, aaa, bbb, ccc, ddd, X[ 2], 11);
tmp = bb; bb = bbb; bbb = tmp;
/* round 3 */
HH(dd, ee, aa, bb, cc, X[ 3], 11);
HH(cc, dd, ee, aa, bb, X[10], 13);
HH(bb, cc, dd, ee, aa, X[14], 6);
HH(aa, bb, cc, dd, ee, X[ 4], 7);
HH(ee, aa, bb, cc, dd, X[ 9], 14);
HH(dd, ee, aa, bb, cc, X[15], 9);
HH(cc, dd, ee, aa, bb, X[ 8], 13);
HH(bb, cc, dd, ee, aa, X[ 1], 15);
HH(aa, bb, cc, dd, ee, X[ 2], 14);
HH(ee, aa, bb, cc, dd, X[ 7], 8);
HH(dd, ee, aa, bb, cc, X[ 0], 13);
HH(cc, dd, ee, aa, bb, X[ 6], 6);
HH(bb, cc, dd, ee, aa, X[13], 5);
HH(aa, bb, cc, dd, ee, X[11], 12);
HH(ee, aa, bb, cc, dd, X[ 5], 7);
HH(dd, ee, aa, bb, cc, X[12], 5);
/* parallel round 3 */
HHH(ddd, eee, aaa, bbb, ccc, X[15], 9);
HHH(ccc, ddd, eee, aaa, bbb, X[ 5], 7);
HHH(bbb, ccc, ddd, eee, aaa, X[ 1], 15);
HHH(aaa, bbb, ccc, ddd, eee, X[ 3], 11);
HHH(eee, aaa, bbb, ccc, ddd, X[ 7], 8);
HHH(ddd, eee, aaa, bbb, ccc, X[14], 6);
HHH(ccc, ddd, eee, aaa, bbb, X[ 6], 6);
HHH(bbb, ccc, ddd, eee, aaa, X[ 9], 14);
HHH(aaa, bbb, ccc, ddd, eee, X[11], 12);
HHH(eee, aaa, bbb, ccc, ddd, X[ 8], 13);
HHH(ddd, eee, aaa, bbb, ccc, X[12], 5);
HHH(ccc, ddd, eee, aaa, bbb, X[ 2], 14);
HHH(bbb, ccc, ddd, eee, aaa, X[10], 13);
HHH(aaa, bbb, ccc, ddd, eee, X[ 0], 13);
HHH(eee, aaa, bbb, ccc, ddd, X[ 4], 7);
HHH(ddd, eee, aaa, bbb, ccc, X[13], 5);
tmp = cc; cc = ccc; ccc = tmp;
/* round 4 */
II(cc, dd, ee, aa, bb, X[ 1], 11);
II(bb, cc, dd, ee, aa, X[ 9], 12);
II(aa, bb, cc, dd, ee, X[11], 14);
II(ee, aa, bb, cc, dd, X[10], 15);
II(dd, ee, aa, bb, cc, X[ 0], 14);
II(cc, dd, ee, aa, bb, X[ 8], 15);
II(bb, cc, dd, ee, aa, X[12], 9);
II(aa, bb, cc, dd, ee, X[ 4], 8);
II(ee, aa, bb, cc, dd, X[13], 9);
II(dd, ee, aa, bb, cc, X[ 3], 14);
II(cc, dd, ee, aa, bb, X[ 7], 5);
II(bb, cc, dd, ee, aa, X[15], 6);
II(aa, bb, cc, dd, ee, X[14], 8);
II(ee, aa, bb, cc, dd, X[ 5], 6);
II(dd, ee, aa, bb, cc, X[ 6], 5);
II(cc, dd, ee, aa, bb, X[ 2], 12);
/* parallel round 4 */
GGG(ccc, ddd, eee, aaa, bbb, X[ 8], 15);
GGG(bbb, ccc, ddd, eee, aaa, X[ 6], 5);
GGG(aaa, bbb, ccc, ddd, eee, X[ 4], 8);
GGG(eee, aaa, bbb, ccc, ddd, X[ 1], 11);
GGG(ddd, eee, aaa, bbb, ccc, X[ 3], 14);
GGG(ccc, ddd, eee, aaa, bbb, X[11], 14);
GGG(bbb, ccc, ddd, eee, aaa, X[15], 6);
GGG(aaa, bbb, ccc, ddd, eee, X[ 0], 14);
GGG(eee, aaa, bbb, ccc, ddd, X[ 5], 6);
GGG(ddd, eee, aaa, bbb, ccc, X[12], 9);
GGG(ccc, ddd, eee, aaa, bbb, X[ 2], 12);
GGG(bbb, ccc, ddd, eee, aaa, X[13], 9);
GGG(aaa, bbb, ccc, ddd, eee, X[ 9], 12);
GGG(eee, aaa, bbb, ccc, ddd, X[ 7], 5);
GGG(ddd, eee, aaa, bbb, ccc, X[10], 15);
GGG(ccc, ddd, eee, aaa, bbb, X[14], 8);
tmp = dd; dd = ddd; ddd = tmp;
/* round 5 */
JJ(bb, cc, dd, ee, aa, X[ 4], 9);
JJ(aa, bb, cc, dd, ee, X[ 0], 15);
JJ(ee, aa, bb, cc, dd, X[ 5], 5);
JJ(dd, ee, aa, bb, cc, X[ 9], 11);
JJ(cc, dd, ee, aa, bb, X[ 7], 6);
JJ(bb, cc, dd, ee, aa, X[12], 8);
JJ(aa, bb, cc, dd, ee, X[ 2], 13);
JJ(ee, aa, bb, cc, dd, X[10], 12);
JJ(dd, ee, aa, bb, cc, X[14], 5);
JJ(cc, dd, ee, aa, bb, X[ 1], 12);
JJ(bb, cc, dd, ee, aa, X[ 3], 13);
JJ(aa, bb, cc, dd, ee, X[ 8], 14);
JJ(ee, aa, bb, cc, dd, X[11], 11);
JJ(dd, ee, aa, bb, cc, X[ 6], 8);
JJ(cc, dd, ee, aa, bb, X[15], 5);
JJ(bb, cc, dd, ee, aa, X[13], 6);
/* parallel round 5 */
FFF(bbb, ccc, ddd, eee, aaa, X[12] , 8);
FFF(aaa, bbb, ccc, ddd, eee, X[15] , 5);
FFF(eee, aaa, bbb, ccc, ddd, X[10] , 12);
FFF(ddd, eee, aaa, bbb, ccc, X[ 4] , 9);
FFF(ccc, ddd, eee, aaa, bbb, X[ 1] , 12);
FFF(bbb, ccc, ddd, eee, aaa, X[ 5] , 5);
FFF(aaa, bbb, ccc, ddd, eee, X[ 8] , 14);
FFF(eee, aaa, bbb, ccc, ddd, X[ 7] , 6);
FFF(ddd, eee, aaa, bbb, ccc, X[ 6] , 8);
FFF(ccc, ddd, eee, aaa, bbb, X[ 2] , 13);
FFF(bbb, ccc, ddd, eee, aaa, X[13] , 6);
FFF(aaa, bbb, ccc, ddd, eee, X[14] , 5);
FFF(eee, aaa, bbb, ccc, ddd, X[ 0] , 15);
FFF(ddd, eee, aaa, bbb, ccc, X[ 3] , 13);
FFF(ccc, ddd, eee, aaa, bbb, X[ 9] , 11);
FFF(bbb, ccc, ddd, eee, aaa, X[11] , 11);
tmp = ee; ee = eee; eee = tmp;
/* combine results */
md->rmd320.state[0] += aa;
md->rmd320.state[1] += bb;
md->rmd320.state[2] += cc;
md->rmd320.state[3] += dd;
md->rmd320.state[4] += ee;
md->rmd320.state[5] += aaa;
md->rmd320.state[6] += bbb;
md->rmd320.state[7] += ccc;
md->rmd320.state[8] += ddd;
md->rmd320.state[9] += eee;
return CRYPT_OK;
}
#ifdef LTC_CLEAN_STACK
static int s_rmd320_compress(hash_state *md, const unsigned char *buf)
{
int err;
err = ss_rmd320_compress(md, buf);
burn_stack(sizeof(ulong32) * 27 + sizeof(int));
return err;
}
#endif
/**
Initialize the hash state
@param md The hash state you wish to initialize
@return CRYPT_OK if successful
*/
int rmd320_init(hash_state * md)
{
LTC_ARGCHK(md != NULL);
md->rmd320.state[0] = 0x67452301UL;
md->rmd320.state[1] = 0xefcdab89UL;
md->rmd320.state[2] = 0x98badcfeUL;
md->rmd320.state[3] = 0x10325476UL;
md->rmd320.state[4] = 0xc3d2e1f0UL;
md->rmd320.state[5] = 0x76543210UL;
md->rmd320.state[6] = 0xfedcba98UL;
md->rmd320.state[7] = 0x89abcdefUL;
md->rmd320.state[8] = 0x01234567UL;
md->rmd320.state[9] = 0x3c2d1e0fUL;
md->rmd320.curlen = 0;
md->rmd320.length = 0;
return CRYPT_OK;
}
/**
Process a block of memory though the hash
@param md The hash state
@param in The data to hash
@param inlen The length of the data (octets)
@return CRYPT_OK if successful
*/
HASH_PROCESS(rmd320_process, s_rmd320_compress, rmd320, 64)
/**
Terminate the hash to get the digest
@param md The hash state
@param out [out] The destination of the hash (20 bytes)
@return CRYPT_OK if successful
*/
int rmd320_done(hash_state * md, unsigned char *out)
{
int i;
LTC_ARGCHK(md != NULL);
LTC_ARGCHK(out != NULL);
if (md->rmd320.curlen >= sizeof(md->rmd320.buf)) {
return CRYPT_INVALID_ARG;
}
/* increase the length of the message */
md->rmd320.length += md->rmd320.curlen * 8;
/* append the '1' bit */
md->rmd320.buf[md->rmd320.curlen++] = (unsigned char)0x80;
/* if the length is currently above 56 bytes we append zeros
* then compress. Then we can fall back to padding zeros and length
* encoding like normal.
*/
if (md->rmd320.curlen > 56) {
while (md->rmd320.curlen < 64) {
md->rmd320.buf[md->rmd320.curlen++] = (unsigned char)0;
}
s_rmd320_compress(md, md->rmd320.buf);
md->rmd320.curlen = 0;
}
/* pad upto 56 bytes of zeroes */
while (md->rmd320.curlen < 56) {
md->rmd320.buf[md->rmd320.curlen++] = (unsigned char)0;
}
/* store length */
STORE64L(md->rmd320.length, md->rmd320.buf+56);
s_rmd320_compress(md, md->rmd320.buf);
/* copy output */
for (i = 0; i < 10; i++) {
STORE32L(md->rmd320.state[i], out+(4*i));
}
#ifdef LTC_CLEAN_STACK
zeromem(md, sizeof(hash_state));
#endif
return CRYPT_OK;
}
/**
Self-test the hash
@return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled
*/
int rmd320_test(void)
{
#ifndef LTC_TEST
return CRYPT_NOP;
#else
static const struct {
const char *msg;
unsigned char hash[40];
} tests[] = {
{ "",
{ 0x22, 0xd6, 0x5d, 0x56, 0x61, 0x53, 0x6c, 0xdc, 0x75, 0xc1,
0xfd, 0xf5, 0xc6, 0xde, 0x7b, 0x41, 0xb9, 0xf2, 0x73, 0x25,
0xeb, 0xc6, 0x1e, 0x85, 0x57, 0x17, 0x7d, 0x70, 0x5a, 0x0e,
0xc8, 0x80, 0x15, 0x1c, 0x3a, 0x32, 0xa0, 0x08, 0x99, 0xb8 }
},
{ "a",
{ 0xce, 0x78, 0x85, 0x06, 0x38, 0xf9, 0x26, 0x58, 0xa5, 0xa5,
0x85, 0x09, 0x75, 0x79, 0x92, 0x6d, 0xda, 0x66, 0x7a, 0x57,
0x16, 0x56, 0x2c, 0xfc, 0xf6, 0xfb, 0xe7, 0x7f, 0x63, 0x54,
0x2f, 0x99, 0xb0, 0x47, 0x05, 0xd6, 0x97, 0x0d, 0xff, 0x5d }
},
{ "abc",
{ 0xde, 0x4c, 0x01, 0xb3, 0x05, 0x4f, 0x89, 0x30, 0xa7, 0x9d,
0x09, 0xae, 0x73, 0x8e, 0x92, 0x30, 0x1e, 0x5a, 0x17, 0x08,
0x5b, 0xef, 0xfd, 0xc1, 0xb8, 0xd1, 0x16, 0x71, 0x3e, 0x74,
0xf8, 0x2f, 0xa9, 0x42, 0xd6, 0x4c, 0xdb, 0xc4, 0x68, 0x2d }
},
{ "message digest",
{ 0x3a, 0x8e, 0x28, 0x50, 0x2e, 0xd4, 0x5d, 0x42, 0x2f, 0x68,
0x84, 0x4f, 0x9d, 0xd3, 0x16, 0xe7, 0xb9, 0x85, 0x33, 0xfa,
0x3f, 0x2a, 0x91, 0xd2, 0x9f, 0x84, 0xd4, 0x25, 0xc8, 0x8d,
0x6b, 0x4e, 0xff, 0x72, 0x7d, 0xf6, 0x6a, 0x7c, 0x01, 0x97 }
},
{ "abcdefghijklmnopqrstuvwxyz",
{ 0xca, 0xbd, 0xb1, 0x81, 0x0b, 0x92, 0x47, 0x0a, 0x20, 0x93,
0xaa, 0x6b, 0xce, 0x05, 0x95, 0x2c, 0x28, 0x34, 0x8c, 0xf4,
0x3f, 0xf6, 0x08, 0x41, 0x97, 0x51, 0x66, 0xbb, 0x40, 0xed,
0x23, 0x40, 0x04, 0xb8, 0x82, 0x44, 0x63, 0xe6, 0xb0, 0x09 }
},
{ "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
{ 0xd0, 0x34, 0xa7, 0x95, 0x0c, 0xf7, 0x22, 0x02, 0x1b, 0xa4,
0xb8, 0x4d, 0xf7, 0x69, 0xa5, 0xde, 0x20, 0x60, 0xe2, 0x59,
0xdf, 0x4c, 0x9b, 0xb4, 0xa4, 0x26, 0x8c, 0x0e, 0x93, 0x5b,
0xbc, 0x74, 0x70, 0xa9, 0x69, 0xc9, 0xd0, 0x72, 0xa1, 0xac }
}
};
int i;
unsigned char tmp[40];
hash_state md;
for (i = 0; i < (int)(sizeof(tests)/sizeof(tests[0])); i++) {
rmd320_init(&md);
rmd320_process(&md, (unsigned char *)tests[i].msg, XSTRLEN(tests[i].msg));
rmd320_done(&md, tmp);
if (compare_testvector(tmp, sizeof(tmp), tests[i].hash, sizeof(tests[i].hash), "RIPEMD320", i)) {
return CRYPT_FAIL_TESTVECTOR;
}
}
return CRYPT_OK;
#endif
}
#undef F
#undef G
#undef H
#undef I
#undef J
#undef FF
#undef GG
#undef HH
#undef II
#undef JJ
#undef FFF
#undef GGG
#undef HHH
#undef III
#undef JJJ
#endif

View File

@@ -0,0 +1,285 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
/* SPDX-License-Identifier: Unlicense */
#include "tomcrypt_private.h"
/**
@file sha1.c
LTC_SHA1 code by Tom St Denis
*/
#ifdef LTC_SHA1
const struct ltc_hash_descriptor sha1_desc =
{
"sha1",
2,
20,
64,
/* OID */
{ 1, 3, 14, 3, 2, 26, },
6,
&sha1_init,
&sha1_process,
&sha1_done,
&sha1_test,
NULL
};
#define F0(x,y,z) (z ^ (x & (y ^ z)))
#define F1(x,y,z) (x ^ y ^ z)
#define F2(x,y,z) ((x & y) | (z & (x | y)))
#define F3(x,y,z) (x ^ y ^ z)
#ifdef LTC_CLEAN_STACK
static int ss_sha1_compress(hash_state *md, const unsigned char *buf)
#else
static int s_sha1_compress(hash_state *md, const unsigned char *buf)
#endif
{
ulong32 a,b,c,d,e,W[80],i;
#ifdef LTC_SMALL_CODE
ulong32 t;
#endif
/* copy the state into 512-bits into W[0..15] */
for (i = 0; i < 16; i++) {
LOAD32H(W[i], buf + (4*i));
}
/* copy state */
a = md->sha1.state[0];
b = md->sha1.state[1];
c = md->sha1.state[2];
d = md->sha1.state[3];
e = md->sha1.state[4];
/* expand it */
for (i = 16; i < 80; i++) {
W[i] = ROL(W[i-3] ^ W[i-8] ^ W[i-14] ^ W[i-16], 1);
}
/* compress */
/* round one */
#define FF0(a,b,c,d,e,i) e = (ROLc(a, 5) + F0(b,c,d) + e + W[i] + 0x5a827999UL); b = ROLc(b, 30);
#define FF1(a,b,c,d,e,i) e = (ROLc(a, 5) + F1(b,c,d) + e + W[i] + 0x6ed9eba1UL); b = ROLc(b, 30);
#define FF2(a,b,c,d,e,i) e = (ROLc(a, 5) + F2(b,c,d) + e + W[i] + 0x8f1bbcdcUL); b = ROLc(b, 30);
#define FF3(a,b,c,d,e,i) e = (ROLc(a, 5) + F3(b,c,d) + e + W[i] + 0xca62c1d6UL); b = ROLc(b, 30);
#ifdef LTC_SMALL_CODE
for (i = 0; i < 20; ) {
FF0(a,b,c,d,e,i++); t = e; e = d; d = c; c = b; b = a; a = t;
}
for (; i < 40; ) {
FF1(a,b,c,d,e,i++); t = e; e = d; d = c; c = b; b = a; a = t;
}
for (; i < 60; ) {
FF2(a,b,c,d,e,i++); t = e; e = d; d = c; c = b; b = a; a = t;
}
for (; i < 80; ) {
FF3(a,b,c,d,e,i++); t = e; e = d; d = c; c = b; b = a; a = t;
}
#else
for (i = 0; i < 20; ) {
FF0(a,b,c,d,e,i++);
FF0(e,a,b,c,d,i++);
FF0(d,e,a,b,c,i++);
FF0(c,d,e,a,b,i++);
FF0(b,c,d,e,a,i++);
}
/* round two */
for (; i < 40; ) {
FF1(a,b,c,d,e,i++);
FF1(e,a,b,c,d,i++);
FF1(d,e,a,b,c,i++);
FF1(c,d,e,a,b,i++);
FF1(b,c,d,e,a,i++);
}
/* round three */
for (; i < 60; ) {
FF2(a,b,c,d,e,i++);
FF2(e,a,b,c,d,i++);
FF2(d,e,a,b,c,i++);
FF2(c,d,e,a,b,i++);
FF2(b,c,d,e,a,i++);
}
/* round four */
for (; i < 80; ) {
FF3(a,b,c,d,e,i++);
FF3(e,a,b,c,d,i++);
FF3(d,e,a,b,c,i++);
FF3(c,d,e,a,b,i++);
FF3(b,c,d,e,a,i++);
}
#endif
#undef FF0
#undef FF1
#undef FF2
#undef FF3
/* store */
md->sha1.state[0] = md->sha1.state[0] + a;
md->sha1.state[1] = md->sha1.state[1] + b;
md->sha1.state[2] = md->sha1.state[2] + c;
md->sha1.state[3] = md->sha1.state[3] + d;
md->sha1.state[4] = md->sha1.state[4] + e;
return CRYPT_OK;
}
#ifdef LTC_CLEAN_STACK
static int s_sha1_compress(hash_state *md, const unsigned char *buf)
{
int err;
err = ss_sha1_compress(md, buf);
burn_stack(sizeof(ulong32) * 87);
return err;
}
#endif
/**
Initialize the hash state
@param md The hash state you wish to initialize
@return CRYPT_OK if successful
*/
int sha1_init(hash_state * md)
{
LTC_ARGCHK(md != NULL);
md->sha1.state[0] = 0x67452301UL;
md->sha1.state[1] = 0xefcdab89UL;
md->sha1.state[2] = 0x98badcfeUL;
md->sha1.state[3] = 0x10325476UL;
md->sha1.state[4] = 0xc3d2e1f0UL;
md->sha1.curlen = 0;
md->sha1.length = 0;
return CRYPT_OK;
}
/**
Process a block of memory though the hash
@param md The hash state
@param in The data to hash
@param inlen The length of the data (octets)
@return CRYPT_OK if successful
*/
HASH_PROCESS(sha1_process, s_sha1_compress, sha1, 64)
/**
Terminate the hash to get the digest
@param md The hash state
@param out [out] The destination of the hash (20 bytes)
@return CRYPT_OK if successful
*/
int sha1_done(hash_state * md, unsigned char *out)
{
int i;
LTC_ARGCHK(md != NULL);
LTC_ARGCHK(out != NULL);
if (md->sha1.curlen >= sizeof(md->sha1.buf)) {
return CRYPT_INVALID_ARG;
}
/* increase the length of the message */
md->sha1.length += md->sha1.curlen * 8;
/* append the '1' bit */
md->sha1.buf[md->sha1.curlen++] = (unsigned char)0x80;
/* if the length is currently above 56 bytes we append zeros
* then compress. Then we can fall back to padding zeros and length
* encoding like normal.
*/
if (md->sha1.curlen > 56) {
while (md->sha1.curlen < 64) {
md->sha1.buf[md->sha1.curlen++] = (unsigned char)0;
}
s_sha1_compress(md, md->sha1.buf);
md->sha1.curlen = 0;
}
/* pad upto 56 bytes of zeroes */
while (md->sha1.curlen < 56) {
md->sha1.buf[md->sha1.curlen++] = (unsigned char)0;
}
/* store length */
STORE64H(md->sha1.length, md->sha1.buf+56);
s_sha1_compress(md, md->sha1.buf);
/* copy output */
for (i = 0; i < 5; i++) {
STORE32H(md->sha1.state[i], out+(4*i));
}
#ifdef LTC_CLEAN_STACK
zeromem(md, sizeof(hash_state));
#endif
return CRYPT_OK;
}
/**
Self-test the hash
@return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled
*/
int sha1_test(void)
{
#ifndef LTC_TEST
return CRYPT_NOP;
#else
static const struct {
const char *msg;
unsigned char hash[20];
} tests[] = {
{ "abc",
{ 0xa9, 0x99, 0x3e, 0x36, 0x47, 0x06, 0x81, 0x6a,
0xba, 0x3e, 0x25, 0x71, 0x78, 0x50, 0xc2, 0x6c,
0x9c, 0xd0, 0xd8, 0x9d }
},
{ "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
{ 0x84, 0x98, 0x3E, 0x44, 0x1C, 0x3B, 0xD2, 0x6E,
0xBA, 0xAE, 0x4A, 0xA1, 0xF9, 0x51, 0x29, 0xE5,
0xE5, 0x46, 0x70, 0xF1 }
}
};
int i;
unsigned char tmp[20];
hash_state md;
for (i = 0; i < (int)(sizeof(tests) / sizeof(tests[0])); i++) {
sha1_init(&md);
sha1_process(&md, (unsigned char*)tests[i].msg, (unsigned long)XSTRLEN(tests[i].msg));
sha1_done(&md, tmp);
if (compare_testvector(tmp, sizeof(tmp), tests[i].hash, sizeof(tests[i].hash), "SHA1", i)) {
return CRYPT_FAIL_TESTVECTOR;
}
}
return CRYPT_OK;
#endif
}
#undef F0
#undef F1
#undef F2
#undef F3
#undef FF0
#undef FF1
#undef FF2
#undef FF3
#endif

View File

@@ -0,0 +1,119 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
/* SPDX-License-Identifier: Unlicense */
/**
@param sha224.c
LTC_SHA-224 new NIST standard based off of LTC_SHA-256 truncated to 224 bits (Tom St Denis)
*/
#include "tomcrypt_private.h"
#if defined(LTC_SHA224) && defined(LTC_SHA256)
const struct ltc_hash_descriptor sha224_desc =
{
"sha224",
10,
28,
64,
/* OID */
{ 2, 16, 840, 1, 101, 3, 4, 2, 4, },
9,
&sha224_init,
&sha256_process,
&sha224_done,
&sha224_test,
NULL
};
/* init the sha256 er... sha224 state ;-) */
/**
Initialize the hash state
@param md The hash state you wish to initialize
@return CRYPT_OK if successful
*/
int sha224_init(hash_state * md)
{
LTC_ARGCHK(md != NULL);
md->sha256.curlen = 0;
md->sha256.length = 0;
md->sha256.state[0] = 0xc1059ed8UL;
md->sha256.state[1] = 0x367cd507UL;
md->sha256.state[2] = 0x3070dd17UL;
md->sha256.state[3] = 0xf70e5939UL;
md->sha256.state[4] = 0xffc00b31UL;
md->sha256.state[5] = 0x68581511UL;
md->sha256.state[6] = 0x64f98fa7UL;
md->sha256.state[7] = 0xbefa4fa4UL;
return CRYPT_OK;
}
/**
Terminate the hash to get the digest
@param md The hash state
@param out [out] The destination of the hash (28 bytes)
@return CRYPT_OK if successful
*/
int sha224_done(hash_state * md, unsigned char *out)
{
unsigned char buf[32];
int err;
LTC_ARGCHK(md != NULL);
LTC_ARGCHK(out != NULL);
err = sha256_done(md, buf);
XMEMCPY(out, buf, 28);
#ifdef LTC_CLEAN_STACK
zeromem(buf, sizeof(buf));
#endif
return err;
}
/**
Self-test the hash
@return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled
*/
int sha224_test(void)
{
#ifndef LTC_TEST
return CRYPT_NOP;
#else
static const struct {
const char *msg;
unsigned char hash[28];
} tests[] = {
{ "abc",
{ 0x23, 0x09, 0x7d, 0x22, 0x34, 0x05, 0xd8,
0x22, 0x86, 0x42, 0xa4, 0x77, 0xbd, 0xa2,
0x55, 0xb3, 0x2a, 0xad, 0xbc, 0xe4, 0xbd,
0xa0, 0xb3, 0xf7, 0xe3, 0x6c, 0x9d, 0xa7 }
},
{ "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
{ 0x75, 0x38, 0x8b, 0x16, 0x51, 0x27, 0x76,
0xcc, 0x5d, 0xba, 0x5d, 0xa1, 0xfd, 0x89,
0x01, 0x50, 0xb0, 0xc6, 0x45, 0x5c, 0xb4,
0xf5, 0x8b, 0x19, 0x52, 0x52, 0x25, 0x25 }
},
};
int i;
unsigned char tmp[28];
hash_state md;
for (i = 0; i < (int)(sizeof(tests) / sizeof(tests[0])); i++) {
sha224_init(&md);
sha224_process(&md, (unsigned char*)tests[i].msg, (unsigned long)XSTRLEN(tests[i].msg));
sha224_done(&md, tmp);
if (compare_testvector(tmp, sizeof(tmp), tests[i].hash, sizeof(tests[i].hash), "SHA224", i)) {
return CRYPT_FAIL_TESTVECTOR;
}
}
return CRYPT_OK;
#endif
}
#endif /* defined(LTC_SHA224) && defined(LTC_SHA256) */

View File

@@ -0,0 +1,331 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
/* SPDX-License-Identifier: Unlicense */
#include "tomcrypt_private.h"
/**
@file sha256.c
LTC_SHA256 by Tom St Denis
*/
#ifdef LTC_SHA256
const struct ltc_hash_descriptor sha256_desc =
{
"sha256",
0,
32,
64,
/* OID */
{ 2, 16, 840, 1, 101, 3, 4, 2, 1, },
9,
&sha256_init,
&sha256_process,
&sha256_done,
&sha256_test,
NULL
};
#ifdef LTC_SMALL_CODE
/* the K array */
static const ulong32 K[64] = {
0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL, 0x3956c25bUL,
0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL, 0xd807aa98UL, 0x12835b01UL,
0x243185beUL, 0x550c7dc3UL, 0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL,
0xc19bf174UL, 0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL,
0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL, 0x983e5152UL,
0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL, 0xc6e00bf3UL, 0xd5a79147UL,
0x06ca6351UL, 0x14292967UL, 0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL,
0x53380d13UL, 0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL,
0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL, 0xd192e819UL,
0xd6990624UL, 0xf40e3585UL, 0x106aa070UL, 0x19a4c116UL, 0x1e376c08UL,
0x2748774cUL, 0x34b0bcb5UL, 0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL,
0x682e6ff3UL, 0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL,
0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL
};
#endif
/* Various logical functions */
#define Ch(x,y,z) (z ^ (x & (y ^ z)))
#define Maj(x,y,z) (((x | y) & z) | (x & y))
#define S(x, n) RORc((x),(n))
#define R(x, n) (((x)&0xFFFFFFFFUL)>>(n))
#define Sigma0(x) (S(x, 2) ^ S(x, 13) ^ S(x, 22))
#define Sigma1(x) (S(x, 6) ^ S(x, 11) ^ S(x, 25))
#define Gamma0(x) (S(x, 7) ^ S(x, 18) ^ R(x, 3))
#define Gamma1(x) (S(x, 17) ^ S(x, 19) ^ R(x, 10))
/* compress 512-bits */
#ifdef LTC_CLEAN_STACK
static int ss_sha256_compress(hash_state * md, const unsigned char *buf)
#else
static int s_sha256_compress(hash_state * md, const unsigned char *buf)
#endif
{
ulong32 S[8], W[64], t0, t1;
#ifdef LTC_SMALL_CODE
ulong32 t;
#endif
int i;
/* copy state into S */
for (i = 0; i < 8; i++) {
S[i] = md->sha256.state[i];
}
/* copy the state into 512-bits into W[0..15] */
for (i = 0; i < 16; i++) {
LOAD32H(W[i], buf + (4*i));
}
/* fill W[16..63] */
for (i = 16; i < 64; i++) {
W[i] = Gamma1(W[i - 2]) + W[i - 7] + Gamma0(W[i - 15]) + W[i - 16];
}
/* Compress */
#ifdef LTC_SMALL_CODE
#define RND(a,b,c,d,e,f,g,h,i) \
t0 = h + Sigma1(e) + Ch(e, f, g) + K[i] + W[i]; \
t1 = Sigma0(a) + Maj(a, b, c); \
d += t0; \
h = t0 + t1;
for (i = 0; i < 64; ++i) {
RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],i);
t = S[7]; S[7] = S[6]; S[6] = S[5]; S[5] = S[4];
S[4] = S[3]; S[3] = S[2]; S[2] = S[1]; S[1] = S[0]; S[0] = t;
}
#else
#define RND(a,b,c,d,e,f,g,h,i,ki) \
t0 = h + Sigma1(e) + Ch(e, f, g) + ki + W[i]; \
t1 = Sigma0(a) + Maj(a, b, c); \
d += t0; \
h = t0 + t1;
RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],0,0x428a2f98);
RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],1,0x71374491);
RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],2,0xb5c0fbcf);
RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],3,0xe9b5dba5);
RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],4,0x3956c25b);
RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],5,0x59f111f1);
RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],6,0x923f82a4);
RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],7,0xab1c5ed5);
RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],8,0xd807aa98);
RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],9,0x12835b01);
RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],10,0x243185be);
RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],11,0x550c7dc3);
RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],12,0x72be5d74);
RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],13,0x80deb1fe);
RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],14,0x9bdc06a7);
RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],15,0xc19bf174);
RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],16,0xe49b69c1);
RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],17,0xefbe4786);
RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],18,0x0fc19dc6);
RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],19,0x240ca1cc);
RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],20,0x2de92c6f);
RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],21,0x4a7484aa);
RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],22,0x5cb0a9dc);
RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],23,0x76f988da);
RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],24,0x983e5152);
RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],25,0xa831c66d);
RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],26,0xb00327c8);
RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],27,0xbf597fc7);
RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],28,0xc6e00bf3);
RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],29,0xd5a79147);
RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],30,0x06ca6351);
RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],31,0x14292967);
RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],32,0x27b70a85);
RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],33,0x2e1b2138);
RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],34,0x4d2c6dfc);
RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],35,0x53380d13);
RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],36,0x650a7354);
RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],37,0x766a0abb);
RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],38,0x81c2c92e);
RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],39,0x92722c85);
RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],40,0xa2bfe8a1);
RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],41,0xa81a664b);
RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],42,0xc24b8b70);
RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],43,0xc76c51a3);
RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],44,0xd192e819);
RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],45,0xd6990624);
RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],46,0xf40e3585);
RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],47,0x106aa070);
RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],48,0x19a4c116);
RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],49,0x1e376c08);
RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],50,0x2748774c);
RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],51,0x34b0bcb5);
RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],52,0x391c0cb3);
RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],53,0x4ed8aa4a);
RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],54,0x5b9cca4f);
RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],55,0x682e6ff3);
RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],56,0x748f82ee);
RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],57,0x78a5636f);
RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],58,0x84c87814);
RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],59,0x8cc70208);
RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],60,0x90befffa);
RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],61,0xa4506ceb);
RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],62,0xbef9a3f7);
RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],63,0xc67178f2);
#endif
#undef RND
/* feedback */
for (i = 0; i < 8; i++) {
md->sha256.state[i] = md->sha256.state[i] + S[i];
}
return CRYPT_OK;
}
#ifdef LTC_CLEAN_STACK
static int s_sha256_compress(hash_state * md, const unsigned char *buf)
{
int err;
err = ss_sha256_compress(md, buf);
burn_stack(sizeof(ulong32) * 74);
return err;
}
#endif
/**
Initialize the hash state
@param md The hash state you wish to initialize
@return CRYPT_OK if successful
*/
int sha256_init(hash_state * md)
{
LTC_ARGCHK(md != NULL);
md->sha256.curlen = 0;
md->sha256.length = 0;
md->sha256.state[0] = 0x6A09E667UL;
md->sha256.state[1] = 0xBB67AE85UL;
md->sha256.state[2] = 0x3C6EF372UL;
md->sha256.state[3] = 0xA54FF53AUL;
md->sha256.state[4] = 0x510E527FUL;
md->sha256.state[5] = 0x9B05688CUL;
md->sha256.state[6] = 0x1F83D9ABUL;
md->sha256.state[7] = 0x5BE0CD19UL;
return CRYPT_OK;
}
/**
Process a block of memory though the hash
@param md The hash state
@param in The data to hash
@param inlen The length of the data (octets)
@return CRYPT_OK if successful
*/
HASH_PROCESS(sha256_process,s_sha256_compress, sha256, 64)
/**
Terminate the hash to get the digest
@param md The hash state
@param out [out] The destination of the hash (32 bytes)
@return CRYPT_OK if successful
*/
int sha256_done(hash_state * md, unsigned char *out)
{
int i;
LTC_ARGCHK(md != NULL);
LTC_ARGCHK(out != NULL);
if (md->sha256.curlen >= sizeof(md->sha256.buf)) {
return CRYPT_INVALID_ARG;
}
/* increase the length of the message */
md->sha256.length += md->sha256.curlen * 8;
/* append the '1' bit */
md->sha256.buf[md->sha256.curlen++] = (unsigned char)0x80;
/* if the length is currently above 56 bytes we append zeros
* then compress. Then we can fall back to padding zeros and length
* encoding like normal.
*/
if (md->sha256.curlen > 56) {
while (md->sha256.curlen < 64) {
md->sha256.buf[md->sha256.curlen++] = (unsigned char)0;
}
s_sha256_compress(md, md->sha256.buf);
md->sha256.curlen = 0;
}
/* pad upto 56 bytes of zeroes */
while (md->sha256.curlen < 56) {
md->sha256.buf[md->sha256.curlen++] = (unsigned char)0;
}
/* store length */
STORE64H(md->sha256.length, md->sha256.buf+56);
s_sha256_compress(md, md->sha256.buf);
/* copy output */
for (i = 0; i < 8; i++) {
STORE32H(md->sha256.state[i], out+(4*i));
}
#ifdef LTC_CLEAN_STACK
zeromem(md, sizeof(hash_state));
#endif
return CRYPT_OK;
}
/**
Self-test the hash
@return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled
*/
int sha256_test(void)
{
#ifndef LTC_TEST
return CRYPT_NOP;
#else
static const struct {
const char *msg;
unsigned char hash[32];
} tests[] = {
{ "abc",
{ 0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea,
0x41, 0x41, 0x40, 0xde, 0x5d, 0xae, 0x22, 0x23,
0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, 0x7a, 0x9c,
0xb4, 0x10, 0xff, 0x61, 0xf2, 0x00, 0x15, 0xad }
},
{ "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
{ 0x24, 0x8d, 0x6a, 0x61, 0xd2, 0x06, 0x38, 0xb8,
0xe5, 0xc0, 0x26, 0x93, 0x0c, 0x3e, 0x60, 0x39,
0xa3, 0x3c, 0xe4, 0x59, 0x64, 0xff, 0x21, 0x67,
0xf6, 0xec, 0xed, 0xd4, 0x19, 0xdb, 0x06, 0xc1 }
},
};
int i;
unsigned char tmp[32];
hash_state md;
for (i = 0; i < (int)(sizeof(tests) / sizeof(tests[0])); i++) {
sha256_init(&md);
sha256_process(&md, (unsigned char*)tests[i].msg, (unsigned long)XSTRLEN(tests[i].msg));
sha256_done(&md, tmp);
if (compare_testvector(tmp, sizeof(tmp), tests[i].hash, sizeof(tests[i].hash), "SHA256", i)) {
return CRYPT_FAIL_TESTVECTOR;
}
}
return CRYPT_OK;
#endif
}
#undef Ch
#undef Maj
#undef S
#undef R
#undef Sigma0
#undef Sigma1
#undef Gamma0
#undef Gamma1
#endif

View File

@@ -0,0 +1,124 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
/* SPDX-License-Identifier: Unlicense */
/**
@param sha384.c
LTC_SHA384 hash included in sha512.c, Tom St Denis
*/
#include "tomcrypt_private.h"
#if defined(LTC_SHA384) && defined(LTC_SHA512)
const struct ltc_hash_descriptor sha384_desc =
{
"sha384",
4,
48,
128,
/* OID */
{ 2, 16, 840, 1, 101, 3, 4, 2, 2, },
9,
&sha384_init,
&sha512_process,
&sha384_done,
&sha384_test,
NULL
};
/**
Initialize the hash state
@param md The hash state you wish to initialize
@return CRYPT_OK if successful
*/
int sha384_init(hash_state * md)
{
LTC_ARGCHK(md != NULL);
md->sha512.curlen = 0;
md->sha512.length = 0;
md->sha512.state[0] = CONST64(0xcbbb9d5dc1059ed8);
md->sha512.state[1] = CONST64(0x629a292a367cd507);
md->sha512.state[2] = CONST64(0x9159015a3070dd17);
md->sha512.state[3] = CONST64(0x152fecd8f70e5939);
md->sha512.state[4] = CONST64(0x67332667ffc00b31);
md->sha512.state[5] = CONST64(0x8eb44a8768581511);
md->sha512.state[6] = CONST64(0xdb0c2e0d64f98fa7);
md->sha512.state[7] = CONST64(0x47b5481dbefa4fa4);
return CRYPT_OK;
}
/**
Terminate the hash to get the digest
@param md The hash state
@param out [out] The destination of the hash (48 bytes)
@return CRYPT_OK if successful
*/
int sha384_done(hash_state * md, unsigned char *out)
{
unsigned char buf[64];
LTC_ARGCHK(md != NULL);
LTC_ARGCHK(out != NULL);
if (md->sha512.curlen >= sizeof(md->sha512.buf)) {
return CRYPT_INVALID_ARG;
}
sha512_done(md, buf);
XMEMCPY(out, buf, 48);
#ifdef LTC_CLEAN_STACK
zeromem(buf, sizeof(buf));
#endif
return CRYPT_OK;
}
/**
Self-test the hash
@return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled
*/
int sha384_test(void)
{
#ifndef LTC_TEST
return CRYPT_NOP;
#else
static const struct {
const char *msg;
unsigned char hash[48];
} tests[] = {
{ "abc",
{ 0xcb, 0x00, 0x75, 0x3f, 0x45, 0xa3, 0x5e, 0x8b,
0xb5, 0xa0, 0x3d, 0x69, 0x9a, 0xc6, 0x50, 0x07,
0x27, 0x2c, 0x32, 0xab, 0x0e, 0xde, 0xd1, 0x63,
0x1a, 0x8b, 0x60, 0x5a, 0x43, 0xff, 0x5b, 0xed,
0x80, 0x86, 0x07, 0x2b, 0xa1, 0xe7, 0xcc, 0x23,
0x58, 0xba, 0xec, 0xa1, 0x34, 0xc8, 0x25, 0xa7 }
},
{ "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu",
{ 0x09, 0x33, 0x0c, 0x33, 0xf7, 0x11, 0x47, 0xe8,
0x3d, 0x19, 0x2f, 0xc7, 0x82, 0xcd, 0x1b, 0x47,
0x53, 0x11, 0x1b, 0x17, 0x3b, 0x3b, 0x05, 0xd2,
0x2f, 0xa0, 0x80, 0x86, 0xe3, 0xb0, 0xf7, 0x12,
0xfc, 0xc7, 0xc7, 0x1a, 0x55, 0x7e, 0x2d, 0xb9,
0x66, 0xc3, 0xe9, 0xfa, 0x91, 0x74, 0x60, 0x39 }
},
};
int i;
unsigned char tmp[48];
hash_state md;
for (i = 0; i < (int)(sizeof(tests) / sizeof(tests[0])); i++) {
sha384_init(&md);
sha384_process(&md, (unsigned char*)tests[i].msg, (unsigned long)XSTRLEN(tests[i].msg));
sha384_done(&md, tmp);
if (compare_testvector(tmp, sizeof(tmp), tests[i].hash, sizeof(tests[i].hash), "SHA384", i)) {
return CRYPT_FAIL_TESTVECTOR;
}
}
return CRYPT_OK;
#endif
}
#endif /* defined(LTC_SHA384) && defined(LTC_SHA512) */

View File

@@ -0,0 +1,309 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
/* SPDX-License-Identifier: Unlicense */
#include "tomcrypt_private.h"
/**
@param sha512.c
LTC_SHA512 by Tom St Denis
*/
#ifdef LTC_SHA512
const struct ltc_hash_descriptor sha512_desc =
{
"sha512",
5,
64,
128,
/* OID */
{ 2, 16, 840, 1, 101, 3, 4, 2, 3, },
9,
&sha512_init,
&sha512_process,
&sha512_done,
&sha512_test,
NULL
};
/* the K array */
static const ulong64 K[80] = {
CONST64(0x428a2f98d728ae22), CONST64(0x7137449123ef65cd),
CONST64(0xb5c0fbcfec4d3b2f), CONST64(0xe9b5dba58189dbbc),
CONST64(0x3956c25bf348b538), CONST64(0x59f111f1b605d019),
CONST64(0x923f82a4af194f9b), CONST64(0xab1c5ed5da6d8118),
CONST64(0xd807aa98a3030242), CONST64(0x12835b0145706fbe),
CONST64(0x243185be4ee4b28c), CONST64(0x550c7dc3d5ffb4e2),
CONST64(0x72be5d74f27b896f), CONST64(0x80deb1fe3b1696b1),
CONST64(0x9bdc06a725c71235), CONST64(0xc19bf174cf692694),
CONST64(0xe49b69c19ef14ad2), CONST64(0xefbe4786384f25e3),
CONST64(0x0fc19dc68b8cd5b5), CONST64(0x240ca1cc77ac9c65),
CONST64(0x2de92c6f592b0275), CONST64(0x4a7484aa6ea6e483),
CONST64(0x5cb0a9dcbd41fbd4), CONST64(0x76f988da831153b5),
CONST64(0x983e5152ee66dfab), CONST64(0xa831c66d2db43210),
CONST64(0xb00327c898fb213f), CONST64(0xbf597fc7beef0ee4),
CONST64(0xc6e00bf33da88fc2), CONST64(0xd5a79147930aa725),
CONST64(0x06ca6351e003826f), CONST64(0x142929670a0e6e70),
CONST64(0x27b70a8546d22ffc), CONST64(0x2e1b21385c26c926),
CONST64(0x4d2c6dfc5ac42aed), CONST64(0x53380d139d95b3df),
CONST64(0x650a73548baf63de), CONST64(0x766a0abb3c77b2a8),
CONST64(0x81c2c92e47edaee6), CONST64(0x92722c851482353b),
CONST64(0xa2bfe8a14cf10364), CONST64(0xa81a664bbc423001),
CONST64(0xc24b8b70d0f89791), CONST64(0xc76c51a30654be30),
CONST64(0xd192e819d6ef5218), CONST64(0xd69906245565a910),
CONST64(0xf40e35855771202a), CONST64(0x106aa07032bbd1b8),
CONST64(0x19a4c116b8d2d0c8), CONST64(0x1e376c085141ab53),
CONST64(0x2748774cdf8eeb99), CONST64(0x34b0bcb5e19b48a8),
CONST64(0x391c0cb3c5c95a63), CONST64(0x4ed8aa4ae3418acb),
CONST64(0x5b9cca4f7763e373), CONST64(0x682e6ff3d6b2b8a3),
CONST64(0x748f82ee5defb2fc), CONST64(0x78a5636f43172f60),
CONST64(0x84c87814a1f0ab72), CONST64(0x8cc702081a6439ec),
CONST64(0x90befffa23631e28), CONST64(0xa4506cebde82bde9),
CONST64(0xbef9a3f7b2c67915), CONST64(0xc67178f2e372532b),
CONST64(0xca273eceea26619c), CONST64(0xd186b8c721c0c207),
CONST64(0xeada7dd6cde0eb1e), CONST64(0xf57d4f7fee6ed178),
CONST64(0x06f067aa72176fba), CONST64(0x0a637dc5a2c898a6),
CONST64(0x113f9804bef90dae), CONST64(0x1b710b35131c471b),
CONST64(0x28db77f523047d84), CONST64(0x32caab7b40c72493),
CONST64(0x3c9ebe0a15c9bebc), CONST64(0x431d67c49c100d4c),
CONST64(0x4cc5d4becb3e42b6), CONST64(0x597f299cfc657e2a),
CONST64(0x5fcb6fab3ad6faec), CONST64(0x6c44198c4a475817)
};
/* Various logical functions */
#define Ch(x,y,z) (z ^ (x & (y ^ z)))
#define Maj(x,y,z) (((x | y) & z) | (x & y))
#define S(x, n) ROR64c(x, n)
#define R(x, n) (((x)&CONST64(0xFFFFFFFFFFFFFFFF))>>((ulong64)n))
#define Sigma0(x) (S(x, 28) ^ S(x, 34) ^ S(x, 39))
#define Sigma1(x) (S(x, 14) ^ S(x, 18) ^ S(x, 41))
#define Gamma0(x) (S(x, 1) ^ S(x, 8) ^ R(x, 7))
#define Gamma1(x) (S(x, 19) ^ S(x, 61) ^ R(x, 6))
/* compress 1024-bits */
#ifdef LTC_CLEAN_STACK
static int ss_sha512_compress(hash_state * md, const unsigned char *buf)
#else
static int s_sha512_compress(hash_state * md, const unsigned char *buf)
#endif
{
ulong64 S[8], W[80], t0, t1;
int i;
/* copy state into S */
for (i = 0; i < 8; i++) {
S[i] = md->sha512.state[i];
}
/* copy the state into 1024-bits into W[0..15] */
for (i = 0; i < 16; i++) {
LOAD64H(W[i], buf + (8*i));
}
/* fill W[16..79] */
for (i = 16; i < 80; i++) {
W[i] = Gamma1(W[i - 2]) + W[i - 7] + Gamma0(W[i - 15]) + W[i - 16];
}
/* Compress */
#ifdef LTC_SMALL_CODE
for (i = 0; i < 80; i++) {
t0 = S[7] + Sigma1(S[4]) + Ch(S[4], S[5], S[6]) + K[i] + W[i];
t1 = Sigma0(S[0]) + Maj(S[0], S[1], S[2]);
S[7] = S[6];
S[6] = S[5];
S[5] = S[4];
S[4] = S[3] + t0;
S[3] = S[2];
S[2] = S[1];
S[1] = S[0];
S[0] = t0 + t1;
}
#else
#define RND(a,b,c,d,e,f,g,h,i) \
t0 = h + Sigma1(e) + Ch(e, f, g) + K[i] + W[i]; \
t1 = Sigma0(a) + Maj(a, b, c); \
d += t0; \
h = t0 + t1;
for (i = 0; i < 80; i += 8) {
RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],i+0);
RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],i+1);
RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],i+2);
RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],i+3);
RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],i+4);
RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],i+5);
RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],i+6);
RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],i+7);
}
#endif
/* feedback */
for (i = 0; i < 8; i++) {
md->sha512.state[i] = md->sha512.state[i] + S[i];
}
return CRYPT_OK;
}
/* compress 1024-bits */
#ifdef LTC_CLEAN_STACK
static int s_sha512_compress(hash_state * md, const unsigned char *buf)
{
int err;
err = ss_sha512_compress(md, buf);
burn_stack(sizeof(ulong64) * 90 + sizeof(int));
return err;
}
#endif
/**
Initialize the hash state
@param md The hash state you wish to initialize
@return CRYPT_OK if successful
*/
int sha512_init(hash_state * md)
{
LTC_ARGCHK(md != NULL);
md->sha512.curlen = 0;
md->sha512.length = 0;
md->sha512.state[0] = CONST64(0x6a09e667f3bcc908);
md->sha512.state[1] = CONST64(0xbb67ae8584caa73b);
md->sha512.state[2] = CONST64(0x3c6ef372fe94f82b);
md->sha512.state[3] = CONST64(0xa54ff53a5f1d36f1);
md->sha512.state[4] = CONST64(0x510e527fade682d1);
md->sha512.state[5] = CONST64(0x9b05688c2b3e6c1f);
md->sha512.state[6] = CONST64(0x1f83d9abfb41bd6b);
md->sha512.state[7] = CONST64(0x5be0cd19137e2179);
return CRYPT_OK;
}
/**
Process a block of memory though the hash
@param md The hash state
@param in The data to hash
@param inlen The length of the data (octets)
@return CRYPT_OK if successful
*/
HASH_PROCESS(sha512_process, s_sha512_compress, sha512, 128)
/**
Terminate the hash to get the digest
@param md The hash state
@param out [out] The destination of the hash (64 bytes)
@return CRYPT_OK if successful
*/
int sha512_done(hash_state * md, unsigned char *out)
{
int i;
LTC_ARGCHK(md != NULL);
LTC_ARGCHK(out != NULL);
if (md->sha512.curlen >= sizeof(md->sha512.buf)) {
return CRYPT_INVALID_ARG;
}
/* increase the length of the message */
md->sha512.length += md->sha512.curlen * CONST64(8);
/* append the '1' bit */
md->sha512.buf[md->sha512.curlen++] = (unsigned char)0x80;
/* if the length is currently above 112 bytes we append zeros
* then compress. Then we can fall back to padding zeros and length
* encoding like normal.
*/
if (md->sha512.curlen > 112) {
while (md->sha512.curlen < 128) {
md->sha512.buf[md->sha512.curlen++] = (unsigned char)0;
}
s_sha512_compress(md, md->sha512.buf);
md->sha512.curlen = 0;
}
/* pad upto 120 bytes of zeroes
* note: that from 112 to 120 is the 64 MSB of the length. We assume that you won't hash
* > 2^64 bits of data... :-)
*/
while (md->sha512.curlen < 120) {
md->sha512.buf[md->sha512.curlen++] = (unsigned char)0;
}
/* store length */
STORE64H(md->sha512.length, md->sha512.buf+120);
s_sha512_compress(md, md->sha512.buf);
/* copy output */
for (i = 0; i < 8; i++) {
STORE64H(md->sha512.state[i], out+(8*i));
}
#ifdef LTC_CLEAN_STACK
zeromem(md, sizeof(hash_state));
#endif
return CRYPT_OK;
}
/**
Self-test the hash
@return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled
*/
int sha512_test(void)
{
#ifndef LTC_TEST
return CRYPT_NOP;
#else
static const struct {
const char *msg;
unsigned char hash[64];
} tests[] = {
{ "abc",
{ 0xdd, 0xaf, 0x35, 0xa1, 0x93, 0x61, 0x7a, 0xba,
0xcc, 0x41, 0x73, 0x49, 0xae, 0x20, 0x41, 0x31,
0x12, 0xe6, 0xfa, 0x4e, 0x89, 0xa9, 0x7e, 0xa2,
0x0a, 0x9e, 0xee, 0xe6, 0x4b, 0x55, 0xd3, 0x9a,
0x21, 0x92, 0x99, 0x2a, 0x27, 0x4f, 0xc1, 0xa8,
0x36, 0xba, 0x3c, 0x23, 0xa3, 0xfe, 0xeb, 0xbd,
0x45, 0x4d, 0x44, 0x23, 0x64, 0x3c, 0xe8, 0x0e,
0x2a, 0x9a, 0xc9, 0x4f, 0xa5, 0x4c, 0xa4, 0x9f }
},
{ "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu",
{ 0x8e, 0x95, 0x9b, 0x75, 0xda, 0xe3, 0x13, 0xda,
0x8c, 0xf4, 0xf7, 0x28, 0x14, 0xfc, 0x14, 0x3f,
0x8f, 0x77, 0x79, 0xc6, 0xeb, 0x9f, 0x7f, 0xa1,
0x72, 0x99, 0xae, 0xad, 0xb6, 0x88, 0x90, 0x18,
0x50, 0x1d, 0x28, 0x9e, 0x49, 0x00, 0xf7, 0xe4,
0x33, 0x1b, 0x99, 0xde, 0xc4, 0xb5, 0x43, 0x3a,
0xc7, 0xd3, 0x29, 0xee, 0xb6, 0xdd, 0x26, 0x54,
0x5e, 0x96, 0xe5, 0x5b, 0x87, 0x4b, 0xe9, 0x09 }
},
};
int i;
unsigned char tmp[64];
hash_state md;
for (i = 0; i < (int)(sizeof(tests) / sizeof(tests[0])); i++) {
sha512_init(&md);
sha512_process(&md, (unsigned char *)tests[i].msg, (unsigned long)XSTRLEN(tests[i].msg));
sha512_done(&md, tmp);
if (compare_testvector(tmp, sizeof(tmp), tests[i].hash, sizeof(tests[i].hash), "SHA512", i)) {
return CRYPT_FAIL_TESTVECTOR;
}
}
return CRYPT_OK;
#endif
}
#undef Ch
#undef Maj
#undef S
#undef R
#undef Sigma0
#undef Sigma1
#undef Gamma0
#undef Gamma1
#endif

View File

@@ -0,0 +1,120 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
/* SPDX-License-Identifier: Unlicense */
/**
@param sha512_224.c
SHA512/224 hash included in sha512.c
*/
#include "tomcrypt_private.h"
#if defined(LTC_SHA512_224) && defined(LTC_SHA512)
const struct ltc_hash_descriptor sha512_224_desc =
{
"sha512-224",
15,
28,
128,
/* OID */
{ 2, 16, 840, 1, 101, 3, 4, 2, 5, },
9,
&sha512_224_init,
&sha512_process,
&sha512_224_done,
&sha512_224_test,
NULL
};
/**
Initialize the hash state
@param md The hash state you wish to initialize
@return CRYPT_OK if successful
*/
int sha512_224_init(hash_state * md)
{
LTC_ARGCHK(md != NULL);
md->sha512.curlen = 0;
md->sha512.length = 0;
md->sha512.state[0] = CONST64(0x8C3D37C819544DA2);
md->sha512.state[1] = CONST64(0x73E1996689DCD4D6);
md->sha512.state[2] = CONST64(0x1DFAB7AE32FF9C82);
md->sha512.state[3] = CONST64(0x679DD514582F9FCF);
md->sha512.state[4] = CONST64(0x0F6D2B697BD44DA8);
md->sha512.state[5] = CONST64(0x77E36F7304C48942);
md->sha512.state[6] = CONST64(0x3F9D85A86A1D36C8);
md->sha512.state[7] = CONST64(0x1112E6AD91D692A1);
return CRYPT_OK;
}
/**
Terminate the hash to get the digest
@param md The hash state
@param out [out] The destination of the hash (48 bytes)
@return CRYPT_OK if successful
*/
int sha512_224_done(hash_state * md, unsigned char *out)
{
unsigned char buf[64];
LTC_ARGCHK(md != NULL);
LTC_ARGCHK(out != NULL);
if (md->sha512.curlen >= sizeof(md->sha512.buf)) {
return CRYPT_INVALID_ARG;
}
sha512_done(md, buf);
XMEMCPY(out, buf, 28);
#ifdef LTC_CLEAN_STACK
zeromem(buf, sizeof(buf));
#endif
return CRYPT_OK;
}
/**
Self-test the hash
@return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled
*/
int sha512_224_test(void)
{
#ifndef LTC_TEST
return CRYPT_NOP;
#else
static const struct {
const char *msg;
unsigned char hash[28];
} tests[] = {
{ "abc",
{ 0x46, 0x34, 0x27, 0x0F, 0x70, 0x7B, 0x6A, 0x54,
0xDA, 0xAE, 0x75, 0x30, 0x46, 0x08, 0x42, 0xE2,
0x0E, 0x37, 0xED, 0x26, 0x5C, 0xEE, 0xE9, 0xA4,
0x3E, 0x89, 0x24, 0xAA }
},
{ "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu",
{ 0x23, 0xFE, 0xC5, 0xBB, 0x94, 0xD6, 0x0B, 0x23,
0x30, 0x81, 0x92, 0x64, 0x0B, 0x0C, 0x45, 0x33,
0x35, 0xD6, 0x64, 0x73, 0x4F, 0xE4, 0x0E, 0x72,
0x68, 0x67, 0x4A, 0xF9 }
},
};
int i;
unsigned char tmp[28];
hash_state md;
for (i = 0; i < (int)(sizeof(tests) / sizeof(tests[0])); i++) {
sha512_224_init(&md);
sha512_224_process(&md, (unsigned char*)tests[i].msg, (unsigned long)XSTRLEN(tests[i].msg));
sha512_224_done(&md, tmp);
if (compare_testvector(tmp, sizeof(tmp), tests[i].hash, sizeof(tests[i].hash), "SHA512-224", i)) {
return CRYPT_FAIL_TESTVECTOR;
}
}
return CRYPT_OK;
#endif
}
#endif /* defined(LTC_SHA384) && defined(LTC_SHA512) */

View File

@@ -0,0 +1,120 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
/* SPDX-License-Identifier: Unlicense */
/**
@param sha512_256.c
SHA512/256 hash included in sha512.c
*/
#include "tomcrypt_private.h"
#if defined(LTC_SHA512_256) && defined(LTC_SHA512)
const struct ltc_hash_descriptor sha512_256_desc =
{
"sha512-256",
16,
32,
128,
/* OID */
{ 2, 16, 840, 1, 101, 3, 4, 2, 6, },
9,
&sha512_256_init,
&sha512_process,
&sha512_256_done,
&sha512_256_test,
NULL
};
/**
Initialize the hash state
@param md The hash state you wish to initialize
@return CRYPT_OK if successful
*/
int sha512_256_init(hash_state * md)
{
LTC_ARGCHK(md != NULL);
md->sha512.curlen = 0;
md->sha512.length = 0;
md->sha512.state[0] = CONST64(0x22312194FC2BF72C);
md->sha512.state[1] = CONST64(0x9F555FA3C84C64C2);
md->sha512.state[2] = CONST64(0x2393B86B6F53B151);
md->sha512.state[3] = CONST64(0x963877195940EABD);
md->sha512.state[4] = CONST64(0x96283EE2A88EFFE3);
md->sha512.state[5] = CONST64(0xBE5E1E2553863992);
md->sha512.state[6] = CONST64(0x2B0199FC2C85B8AA);
md->sha512.state[7] = CONST64(0x0EB72DDC81C52CA2);
return CRYPT_OK;
}
/**
Terminate the hash to get the digest
@param md The hash state
@param out [out] The destination of the hash (48 bytes)
@return CRYPT_OK if successful
*/
int sha512_256_done(hash_state * md, unsigned char *out)
{
unsigned char buf[64];
LTC_ARGCHK(md != NULL);
LTC_ARGCHK(out != NULL);
if (md->sha512.curlen >= sizeof(md->sha512.buf)) {
return CRYPT_INVALID_ARG;
}
sha512_done(md, buf);
XMEMCPY(out, buf, 32);
#ifdef LTC_CLEAN_STACK
zeromem(buf, sizeof(buf));
#endif
return CRYPT_OK;
}
/**
Self-test the hash
@return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled
*/
int sha512_256_test(void)
{
#ifndef LTC_TEST
return CRYPT_NOP;
#else
static const struct {
const char *msg;
unsigned char hash[32];
} tests[] = {
{ "abc",
{ 0x53, 0x04, 0x8E, 0x26, 0x81, 0x94, 0x1E, 0xF9,
0x9B, 0x2E, 0x29, 0xB7, 0x6B, 0x4C, 0x7D, 0xAB,
0xE4, 0xC2, 0xD0, 0xC6, 0x34, 0xFC, 0x6D, 0x46,
0xE0, 0xE2, 0xF1, 0x31, 0x07, 0xE7, 0xAF, 0x23 }
},
{ "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu",
{ 0x39, 0x28, 0xE1, 0x84, 0xFB, 0x86, 0x90, 0xF8,
0x40, 0xDA, 0x39, 0x88, 0x12, 0x1D, 0x31, 0xBE,
0x65, 0xCB, 0x9D, 0x3E, 0xF8, 0x3E, 0xE6, 0x14,
0x6F, 0xEA, 0xC8, 0x61, 0xE1, 0x9B, 0x56, 0x3A }
},
};
int i;
unsigned char tmp[32];
hash_state md;
for (i = 0; i < (int)(sizeof(tests) / sizeof(tests[0])); i++) {
sha512_256_init(&md);
sha512_256_process(&md, (unsigned char*)tests[i].msg, (unsigned long)XSTRLEN(tests[i].msg));
sha512_256_done(&md, tmp);
if (compare_testvector(tmp, sizeof(tmp), tests[i].hash, sizeof(tests[i].hash), "SHA512-265", i)) {
return CRYPT_FAIL_TESTVECTOR;
}
}
return CRYPT_OK;
#endif
}
#endif /* defined(LTC_SHA384) && defined(LTC_SHA512) */

View File

@@ -0,0 +1,384 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
/* SPDX-License-Identifier: Unlicense */
/* based on https://github.com/brainhub/SHA3IUF (public domain) */
#include "tomcrypt_private.h"
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wconversion"
#pragma clang diagnostic ignored "-Wshorten-64-to-32"
#ifdef LTC_SHA3
const struct ltc_hash_descriptor sha3_224_desc =
{
"sha3-224", /* name of hash */
17, /* internal ID */
28, /* Size of digest in octets */
144, /* Input block size in octets */
{ 2,16,840,1,101,3,4,2,7 }, /* ASN.1 OID */
9, /* Length OID */
&sha3_224_init,
&sha3_process,
&sha3_done,
&sha3_224_test,
NULL
};
const struct ltc_hash_descriptor sha3_256_desc =
{
"sha3-256", /* name of hash */
18, /* internal ID */
32, /* Size of digest in octets */
136, /* Input block size in octets */
{ 2,16,840,1,101,3,4,2,8 }, /* ASN.1 OID */
9, /* Length OID */
&sha3_256_init,
&sha3_process,
&sha3_done,
&sha3_256_test,
NULL
};
const struct ltc_hash_descriptor sha3_384_desc =
{
"sha3-384", /* name of hash */
19, /* internal ID */
48, /* Size of digest in octets */
104, /* Input block size in octets */
{ 2,16,840,1,101,3,4,2,9 }, /* ASN.1 OID */
9, /* Length OID */
&sha3_384_init,
&sha3_process,
&sha3_done,
&sha3_384_test,
NULL
};
const struct ltc_hash_descriptor sha3_512_desc =
{
"sha3-512", /* name of hash */
20, /* internal ID */
64, /* Size of digest in octets */
72, /* Input block size in octets */
{ 2,16,840,1,101,3,4,2,10 }, /* ASN.1 OID */
9, /* Length OID */
&sha3_512_init,
&sha3_process,
&sha3_done,
&sha3_512_test,
NULL
};
#endif
#ifdef LTC_KECCAK
const struct ltc_hash_descriptor keccak_224_desc =
{
"keccak224", /* name of hash */
29, /* internal ID */
28, /* Size of digest in octets */
144, /* Input block size in octets */
{ 0 }, 0, /* no ASN.1 OID */
&sha3_224_init,
&sha3_process,
&keccak_done,
&keccak_224_test,
NULL
};
const struct ltc_hash_descriptor keccak_256_desc =
{
"keccak256", /* name of hash */
30, /* internal ID */
32, /* Size of digest in octets */
136, /* Input block size in octets */
{ 0 }, 0, /* no ASN.1 OID */
&sha3_256_init,
&sha3_process,
&keccak_done,
&keccak_256_test,
NULL
};
const struct ltc_hash_descriptor keccak_384_desc =
{
"keccak384", /* name of hash */
31, /* internal ID */
48, /* Size of digest in octets */
104, /* Input block size in octets */
{ 0 }, 0, /* no ASN.1 OID */
&sha3_384_init,
&sha3_process,
&keccak_done,
&keccak_384_test,
NULL
};
const struct ltc_hash_descriptor keccak_512_desc =
{
"keccak512", /* name of hash */
32, /* internal ID */
64, /* Size of digest in octets */
72, /* Input block size in octets */
{ 0 }, 0, /* no ASN.1 OID */
&sha3_512_init,
&sha3_process,
&keccak_done,
&keccak_512_test,
NULL
};
#endif
#if defined(LTC_SHA3) || defined(LTC_KECCAK)
#define SHA3_KECCAK_SPONGE_WORDS 25 /* 1600 bits > 200 bytes > 25 x ulong64 */
#define SHA3_KECCAK_ROUNDS 24
static const ulong64 s_keccakf_rndc[24] = {
CONST64(0x0000000000000001), CONST64(0x0000000000008082),
CONST64(0x800000000000808a), CONST64(0x8000000080008000),
CONST64(0x000000000000808b), CONST64(0x0000000080000001),
CONST64(0x8000000080008081), CONST64(0x8000000000008009),
CONST64(0x000000000000008a), CONST64(0x0000000000000088),
CONST64(0x0000000080008009), CONST64(0x000000008000000a),
CONST64(0x000000008000808b), CONST64(0x800000000000008b),
CONST64(0x8000000000008089), CONST64(0x8000000000008003),
CONST64(0x8000000000008002), CONST64(0x8000000000000080),
CONST64(0x000000000000800a), CONST64(0x800000008000000a),
CONST64(0x8000000080008081), CONST64(0x8000000000008080),
CONST64(0x0000000080000001), CONST64(0x8000000080008008)
};
static const unsigned s_keccakf_rotc[24] = {
1, 3, 6, 10, 15, 21, 28, 36, 45, 55, 2, 14, 27, 41, 56, 8, 25, 43, 62, 18, 39, 61, 20, 44
};
static const unsigned s_keccakf_piln[24] = {
10, 7, 11, 17, 18, 3, 5, 16, 8, 21, 24, 4, 15, 23, 19, 13, 12, 2, 20, 14, 22, 9, 6, 1
};
static void s_keccakf(ulong64 s[25])
{
int i, j, round;
ulong64 t, bc[5];
for(round = 0; round < SHA3_KECCAK_ROUNDS; round++) {
/* Theta */
for(i = 0; i < 5; i++) {
bc[i] = s[i] ^ s[i + 5] ^ s[i + 10] ^ s[i + 15] ^ s[i + 20];
}
for(i = 0; i < 5; i++) {
t = bc[(i + 4) % 5] ^ ROL64(bc[(i + 1) % 5], 1);
for(j = 0; j < 25; j += 5) {
s[j + i] ^= t;
}
}
/* Rho Pi */
t = s[1];
for(i = 0; i < 24; i++) {
j = s_keccakf_piln[i];
bc[0] = s[j];
s[j] = ROL64(t, s_keccakf_rotc[i]);
t = bc[0];
}
/* Chi */
for(j = 0; j < 25; j += 5) {
for(i = 0; i < 5; i++) {
bc[i] = s[j + i];
}
for(i = 0; i < 5; i++) {
s[j + i] ^= (~bc[(i + 1) % 5]) & bc[(i + 2) % 5];
}
}
/* Iota */
s[0] ^= s_keccakf_rndc[round];
}
}
static LTC_INLINE int ss_done(hash_state *md, unsigned char *hash, ulong64 pad)
{
unsigned i;
LTC_ARGCHK(md != NULL);
LTC_ARGCHK(hash != NULL);
md->sha3.s[md->sha3.word_index] ^= (md->sha3.saved ^ (pad << (md->sha3.byte_index * 8)));
md->sha3.s[SHA3_KECCAK_SPONGE_WORDS - md->sha3.capacity_words - 1] ^= CONST64(0x8000000000000000);
s_keccakf(md->sha3.s);
/* store sha3.s[] as little-endian bytes into sha3.sb */
for(i = 0; i < SHA3_KECCAK_SPONGE_WORDS; i++) {
STORE64L(md->sha3.s[i], md->sha3.sb + i * 8);
}
XMEMCPY(hash, md->sha3.sb, md->sha3.capacity_words * 4);
return CRYPT_OK;
}
/* Public Inteface */
int sha3_224_init(hash_state *md)
{
LTC_ARGCHK(md != NULL);
XMEMSET(&md->sha3, 0, sizeof(md->sha3));
md->sha3.capacity_words = 2 * 224 / (8 * sizeof(ulong64));
return CRYPT_OK;
}
int sha3_256_init(hash_state *md)
{
LTC_ARGCHK(md != NULL);
XMEMSET(&md->sha3, 0, sizeof(md->sha3));
md->sha3.capacity_words = 2 * 256 / (8 * sizeof(ulong64));
return CRYPT_OK;
}
int sha3_384_init(hash_state *md)
{
LTC_ARGCHK(md != NULL);
XMEMSET(&md->sha3, 0, sizeof(md->sha3));
md->sha3.capacity_words = 2 * 384 / (8 * sizeof(ulong64));
return CRYPT_OK;
}
int sha3_512_init(hash_state *md)
{
LTC_ARGCHK(md != NULL);
XMEMSET(&md->sha3, 0, sizeof(md->sha3));
md->sha3.capacity_words = 2 * 512 / (8 * sizeof(ulong64));
return CRYPT_OK;
}
#ifdef LTC_SHA3
int sha3_shake_init(hash_state *md, int num)
{
LTC_ARGCHK(md != NULL);
if (num != 128 && num != 256) return CRYPT_INVALID_ARG;
XMEMSET(&md->sha3, 0, sizeof(md->sha3));
md->sha3.capacity_words = (unsigned short)(2 * num / (8 * sizeof(ulong64)));
return CRYPT_OK;
}
#endif
int sha3_process(hash_state *md, const unsigned char *in, unsigned long inlen)
{
/* 0...7 -- how much is needed to have a word */
unsigned old_tail = (8 - md->sha3.byte_index) & 7;
unsigned long words;
unsigned tail;
unsigned long i;
if (inlen == 0) return CRYPT_OK; /* nothing to do */
LTC_ARGCHK(md != NULL);
LTC_ARGCHK(in != NULL);
if(inlen < old_tail) { /* have no complete word or haven't started the word yet */
while (inlen--) md->sha3.saved |= (ulong64) (*(in++)) << ((md->sha3.byte_index++) * 8);
return CRYPT_OK;
}
if(old_tail) { /* will have one word to process */
inlen -= old_tail;
while (old_tail--) md->sha3.saved |= (ulong64) (*(in++)) << ((md->sha3.byte_index++) * 8);
/* now ready to add saved to the sponge */
md->sha3.s[md->sha3.word_index] ^= md->sha3.saved;
md->sha3.byte_index = 0;
md->sha3.saved = 0;
if(++md->sha3.word_index == (SHA3_KECCAK_SPONGE_WORDS - md->sha3.capacity_words)) {
s_keccakf(md->sha3.s);
md->sha3.word_index = 0;
}
}
/* now work in full words directly from input */
words = inlen / sizeof(ulong64);
tail = inlen - words * sizeof(ulong64);
for(i = 0; i < words; i++, in += sizeof(ulong64)) {
ulong64 t;
LOAD64L(t, in);
md->sha3.s[md->sha3.word_index] ^= t;
if(++md->sha3.word_index == (SHA3_KECCAK_SPONGE_WORDS - md->sha3.capacity_words)) {
s_keccakf(md->sha3.s);
md->sha3.word_index = 0;
}
}
/* finally, save the partial word */
while (tail--) {
md->sha3.saved |= (ulong64) (*(in++)) << ((md->sha3.byte_index++) * 8);
}
return CRYPT_OK;
}
#ifdef LTC_SHA3
int sha3_done(hash_state *md, unsigned char *out)
{
return ss_done(md, out, CONST64(0x06));
}
#endif
#ifdef LTC_KECCAK
int keccak_done(hash_state *md, unsigned char *out)
{
return ss_done(md, out, CONST64(0x01));
}
#endif
#ifdef LTC_SHA3
int sha3_shake_done(hash_state *md, unsigned char *out, unsigned long outlen)
{
/* IMPORTANT NOTE: sha3_shake_done can be called many times */
unsigned long idx;
unsigned i;
if (outlen == 0) return CRYPT_OK; /* nothing to do */
LTC_ARGCHK(md != NULL);
LTC_ARGCHK(out != NULL);
if (!md->sha3.xof_flag) {
/* shake_xof operation must be done only once */
md->sha3.s[md->sha3.word_index] ^= (md->sha3.saved ^ (CONST64(0x1F) << (md->sha3.byte_index * 8)));
md->sha3.s[SHA3_KECCAK_SPONGE_WORDS - md->sha3.capacity_words - 1] ^= CONST64(0x8000000000000000);
s_keccakf(md->sha3.s);
/* store sha3.s[] as little-endian bytes into sha3.sb */
for(i = 0; i < SHA3_KECCAK_SPONGE_WORDS; i++) {
STORE64L(md->sha3.s[i], md->sha3.sb + i * 8);
}
md->sha3.byte_index = 0;
md->sha3.xof_flag = 1;
}
for (idx = 0; idx < outlen; idx++) {
if(md->sha3.byte_index >= (SHA3_KECCAK_SPONGE_WORDS - md->sha3.capacity_words) * 8) {
s_keccakf(md->sha3.s);
/* store sha3.s[] as little-endian bytes into sha3.sb */
for(i = 0; i < SHA3_KECCAK_SPONGE_WORDS; i++) {
STORE64L(md->sha3.s[i], md->sha3.sb + i * 8);
}
md->sha3.byte_index = 0;
}
out[idx] = md->sha3.sb[md->sha3.byte_index++];
}
return CRYPT_OK;
}
int sha3_shake_memory(int num, const unsigned char *in, unsigned long inlen, unsigned char *out, const unsigned long *outlen)
{
hash_state md;
int err;
LTC_ARGCHK(in != NULL);
LTC_ARGCHK(out != NULL);
LTC_ARGCHK(outlen != NULL);
if ((err = sha3_shake_init(&md, num)) != CRYPT_OK) return err;
if ((err = sha3_shake_process(&md, in, inlen)) != CRYPT_OK) return err;
if ((err = sha3_shake_done(&md, out, *outlen)) != CRYPT_OK) return err;
return CRYPT_OK;
}
#endif
#endif
#pragma clang diagnostic pop

View File

@@ -0,0 +1,719 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
/* SPDX-License-Identifier: Unlicense */
/* based on https://github.com/brainhub/SHA3IUF (public domain) */
#include "tomcrypt_private.h"
#ifdef LTC_SHA3
int sha3_224_test(void)
{
#ifndef LTC_TEST
return CRYPT_NOP;
#else
unsigned char buf[200], hash[224 / 8];
int i;
hash_state c;
const unsigned char c1 = 0xa3;
const unsigned char sha3_224_empty[224 / 8] = {
0x6b, 0x4e, 0x03, 0x42, 0x36, 0x67, 0xdb, 0xb7,
0x3b, 0x6e, 0x15, 0x45, 0x4f, 0x0e, 0xb1, 0xab,
0xd4, 0x59, 0x7f, 0x9a, 0x1b, 0x07, 0x8e, 0x3f,
0x5b, 0x5a, 0x6b, 0xc7
};
const unsigned char sha3_224_0xa3_200_times[224 / 8] = {
0x93, 0x76, 0x81, 0x6a, 0xba, 0x50, 0x3f, 0x72,
0xf9, 0x6c, 0xe7, 0xeb, 0x65, 0xac, 0x09, 0x5d,
0xee, 0xe3, 0xbe, 0x4b, 0xf9, 0xbb, 0xc2, 0xa1,
0xcb, 0x7e, 0x11, 0xe0
};
XMEMSET(buf, c1, sizeof(buf));
/* SHA3-224 on an empty buffer */
sha3_224_init(&c);
sha3_done(&c, hash);
if (compare_testvector(hash, sizeof(hash), sha3_224_empty, sizeof(sha3_224_empty), "SHA3-224", 0)) {
return CRYPT_FAIL_TESTVECTOR;
}
/* SHA3-224 in two steps. [FIPS 202] */
sha3_224_init(&c);
sha3_process(&c, buf, sizeof(buf) / 2);
sha3_process(&c, buf + sizeof(buf) / 2, sizeof(buf) / 2);
sha3_done(&c, hash);
if (compare_testvector(hash, sizeof(hash), sha3_224_0xa3_200_times, sizeof(sha3_224_0xa3_200_times), "SHA3-224", 1)) {
return CRYPT_FAIL_TESTVECTOR;
}
/* SHA3-224 byte-by-byte: 200 steps. [FIPS 202] */
i = 200;
sha3_224_init(&c);
while (i--) {
sha3_process(&c, &c1, 1);
}
sha3_done(&c, hash);
if (compare_testvector(hash, sizeof(hash), sha3_224_0xa3_200_times, sizeof(sha3_224_0xa3_200_times), "SHA3-224", 2)) {
return CRYPT_FAIL_TESTVECTOR;
}
return CRYPT_OK;
#endif
}
int sha3_256_test(void)
{
#ifndef LTC_TEST
return CRYPT_NOP;
#else
unsigned char buf[200], hash[256 / 8];
int i;
hash_state c;
const unsigned char c1 = 0xa3;
const unsigned char sha3_256_empty[256 / 8] = {
0xa7, 0xff, 0xc6, 0xf8, 0xbf, 0x1e, 0xd7, 0x66,
0x51, 0xc1, 0x47, 0x56, 0xa0, 0x61, 0xd6, 0x62,
0xf5, 0x80, 0xff, 0x4d, 0xe4, 0x3b, 0x49, 0xfa,
0x82, 0xd8, 0x0a, 0x4b, 0x80, 0xf8, 0x43, 0x4a
};
const unsigned char sha3_256_0xa3_200_times[256 / 8] = {
0x79, 0xf3, 0x8a, 0xde, 0xc5, 0xc2, 0x03, 0x07,
0xa9, 0x8e, 0xf7, 0x6e, 0x83, 0x24, 0xaf, 0xbf,
0xd4, 0x6c, 0xfd, 0x81, 0xb2, 0x2e, 0x39, 0x73,
0xc6, 0x5f, 0xa1, 0xbd, 0x9d, 0xe3, 0x17, 0x87
};
XMEMSET(buf, c1, sizeof(buf));
/* SHA3-256 on an empty buffer */
sha3_256_init(&c);
sha3_done(&c, hash);
if (compare_testvector(hash, sizeof(hash), sha3_256_empty, sizeof(sha3_256_empty), "SHA3-256", 0)) {
return CRYPT_FAIL_TESTVECTOR;
}
/* SHA3-256 as a single buffer. [FIPS 202] */
sha3_256_init(&c);
sha3_process(&c, buf, sizeof(buf));
sha3_done(&c, hash);
if (compare_testvector(hash, sizeof(hash), sha3_256_0xa3_200_times, sizeof(sha3_256_0xa3_200_times), "SHA3-256", 1)) {
return CRYPT_FAIL_TESTVECTOR;
}
/* SHA3-256 in two steps. [FIPS 202] */
sha3_256_init(&c);
sha3_process(&c, buf, sizeof(buf) / 2);
sha3_process(&c, buf + sizeof(buf) / 2, sizeof(buf) / 2);
sha3_done(&c, hash);
if (compare_testvector(hash, sizeof(hash), sha3_256_0xa3_200_times, sizeof(sha3_256_0xa3_200_times), "SHA3-256", 2)) {
return CRYPT_FAIL_TESTVECTOR;
}
/* SHA3-256 byte-by-byte: 200 steps. [FIPS 202] */
i = 200;
sha3_256_init(&c);
while (i--) {
sha3_process(&c, &c1, 1);
}
sha3_done(&c, hash);
if (compare_testvector(hash, sizeof(hash), sha3_256_0xa3_200_times, sizeof(sha3_256_0xa3_200_times), "SHA3-256", 3)) {
return CRYPT_FAIL_TESTVECTOR;
}
/* SHA3-256 byte-by-byte: 135 bytes. Input from [Keccak]. Output
* matched with sha3sum. */
sha3_256_init(&c);
sha3_process(&c, (unsigned char*)
"\xb7\x71\xd5\xce\xf5\xd1\xa4\x1a"
"\x93\xd1\x56\x43\xd7\x18\x1d\x2a"
"\x2e\xf0\xa8\xe8\x4d\x91\x81\x2f"
"\x20\xed\x21\xf1\x47\xbe\xf7\x32"
"\xbf\x3a\x60\xef\x40\x67\xc3\x73"
"\x4b\x85\xbc\x8c\xd4\x71\x78\x0f"
"\x10\xdc\x9e\x82\x91\xb5\x83\x39"
"\xa6\x77\xb9\x60\x21\x8f\x71\xe7"
"\x93\xf2\x79\x7a\xea\x34\x94\x06"
"\x51\x28\x29\x06\x5d\x37\xbb\x55"
"\xea\x79\x6f\xa4\xf5\x6f\xd8\x89"
"\x6b\x49\xb2\xcd\x19\xb4\x32\x15"
"\xad\x96\x7c\x71\x2b\x24\xe5\x03"
"\x2d\x06\x52\x32\xe0\x2c\x12\x74"
"\x09\xd2\xed\x41\x46\xb9\xd7\x5d"
"\x76\x3d\x52\xdb\x98\xd9\x49\xd3"
"\xb0\xfe\xd6\xa8\x05\x2f\xbb", 1080 / 8);
sha3_done(&c, hash);
if(compare_testvector(hash, sizeof(hash),
"\xa1\x9e\xee\x92\xbb\x20\x97\xb6"
"\x4e\x82\x3d\x59\x77\x98\xaa\x18"
"\xbe\x9b\x7c\x73\x6b\x80\x59\xab"
"\xfd\x67\x79\xac\x35\xac\x81\xb5", 256 / 8, "SHA3-256", 4)) {
return CRYPT_FAIL_TESTVECTOR;
}
return CRYPT_OK;
#endif
}
int sha3_384_test(void)
{
#ifndef LTC_TEST
return CRYPT_NOP;
#else
unsigned char buf[200], hash[384 / 8];
int i;
hash_state c;
const unsigned char c1 = 0xa3;
const unsigned char sha3_384_0xa3_200_times[384 / 8] = {
0x18, 0x81, 0xde, 0x2c, 0xa7, 0xe4, 0x1e, 0xf9,
0x5d, 0xc4, 0x73, 0x2b, 0x8f, 0x5f, 0x00, 0x2b,
0x18, 0x9c, 0xc1, 0xe4, 0x2b, 0x74, 0x16, 0x8e,
0xd1, 0x73, 0x26, 0x49, 0xce, 0x1d, 0xbc, 0xdd,
0x76, 0x19, 0x7a, 0x31, 0xfd, 0x55, 0xee, 0x98,
0x9f, 0x2d, 0x70, 0x50, 0xdd, 0x47, 0x3e, 0x8f
};
XMEMSET(buf, c1, sizeof(buf));
/* SHA3-384 as a single buffer. [FIPS 202] */
sha3_384_init(&c);
sha3_process(&c, buf, sizeof(buf));
sha3_done(&c, hash);
if (compare_testvector(hash, sizeof(hash), sha3_384_0xa3_200_times, sizeof(sha3_384_0xa3_200_times), "SHA3-384", 0)) {
return CRYPT_FAIL_TESTVECTOR;
}
/* SHA3-384 in two steps. [FIPS 202] */
sha3_384_init(&c);
sha3_process(&c, buf, sizeof(buf) / 2);
sha3_process(&c, buf + sizeof(buf) / 2, sizeof(buf) / 2);
sha3_done(&c, hash);
if (compare_testvector(hash, sizeof(hash), sha3_384_0xa3_200_times, sizeof(sha3_384_0xa3_200_times), "SHA3-384", 1)) {
return CRYPT_FAIL_TESTVECTOR;
}
/* SHA3-384 byte-by-byte: 200 steps. [FIPS 202] */
i = 200;
sha3_384_init(&c);
while (i--) {
sha3_process(&c, &c1, 1);
}
sha3_done(&c, hash);
if (compare_testvector(hash, sizeof(hash), sha3_384_0xa3_200_times, sizeof(sha3_384_0xa3_200_times), "SHA3-384", 2)) {
return CRYPT_FAIL_TESTVECTOR;
}
return CRYPT_OK;
#endif
}
int sha3_512_test(void)
{
#ifndef LTC_TEST
return CRYPT_NOP;
#else
unsigned char buf[200], hash[512 / 8];
int i;
hash_state c;
const unsigned char c1 = 0xa3;
const unsigned char sha3_512_0xa3_200_times[512 / 8] = {
0xe7, 0x6d, 0xfa, 0xd2, 0x20, 0x84, 0xa8, 0xb1,
0x46, 0x7f, 0xcf, 0x2f, 0xfa, 0x58, 0x36, 0x1b,
0xec, 0x76, 0x28, 0xed, 0xf5, 0xf3, 0xfd, 0xc0,
0xe4, 0x80, 0x5d, 0xc4, 0x8c, 0xae, 0xec, 0xa8,
0x1b, 0x7c, 0x13, 0xc3, 0x0a, 0xdf, 0x52, 0xa3,
0x65, 0x95, 0x84, 0x73, 0x9a, 0x2d, 0xf4, 0x6b,
0xe5, 0x89, 0xc5, 0x1c, 0xa1, 0xa4, 0xa8, 0x41,
0x6d, 0xf6, 0x54, 0x5a, 0x1c, 0xe8, 0xba, 0x00
};
XMEMSET(buf, c1, sizeof(buf));
/* SHA3-512 as a single buffer. [FIPS 202] */
sha3_512_init(&c);
sha3_process(&c, buf, sizeof(buf));
sha3_done(&c, hash);
if (compare_testvector(hash, sizeof(hash), sha3_512_0xa3_200_times, sizeof(sha3_512_0xa3_200_times), "SHA3-512", 0)) {
return CRYPT_FAIL_TESTVECTOR;
}
/* SHA3-512 in two steps. [FIPS 202] */
sha3_512_init(&c);
sha3_process(&c, buf, sizeof(buf) / 2);
sha3_process(&c, buf + sizeof(buf) / 2, sizeof(buf) / 2);
sha3_done(&c, hash);
if (compare_testvector(hash, sizeof(hash), sha3_512_0xa3_200_times, sizeof(sha3_512_0xa3_200_times), "SHA3-512", 1)) {
return CRYPT_FAIL_TESTVECTOR;
}
/* SHA3-512 byte-by-byte: 200 steps. [FIPS 202] */
i = 200;
sha3_512_init(&c);
while (i--) {
sha3_process(&c, &c1, 1);
}
sha3_done(&c, hash);
if (compare_testvector(hash, sizeof(hash), sha3_512_0xa3_200_times, sizeof(sha3_512_0xa3_200_times), "SHA3-512", 2)) {
return CRYPT_FAIL_TESTVECTOR;
}
return CRYPT_OK;
#endif
}
int sha3_shake_test(void)
{
#ifndef LTC_TEST
return CRYPT_NOP;
#else
unsigned char buf[200], hash[512];
int i;
hash_state c;
const unsigned char c1 = 0xa3;
unsigned long len;
const unsigned char shake256_empty[32] = {
0xab, 0x0b, 0xae, 0x31, 0x63, 0x39, 0x89, 0x43,
0x04, 0xe3, 0x58, 0x77, 0xb0, 0xc2, 0x8a, 0x9b,
0x1f, 0xd1, 0x66, 0xc7, 0x96, 0xb9, 0xcc, 0x25,
0x8a, 0x06, 0x4a, 0x8f, 0x57, 0xe2, 0x7f, 0x2a
};
const unsigned char shake256_0xa3_200_times[32] = {
0x6a, 0x1a, 0x9d, 0x78, 0x46, 0x43, 0x6e, 0x4d,
0xca, 0x57, 0x28, 0xb6, 0xf7, 0x60, 0xee, 0xf0,
0xca, 0x92, 0xbf, 0x0b, 0xe5, 0x61, 0x5e, 0x96,
0x95, 0x9d, 0x76, 0x71, 0x97, 0xa0, 0xbe, 0xeb
};
const unsigned char shake128_empty[32] = {
0x43, 0xe4, 0x1b, 0x45, 0xa6, 0x53, 0xf2, 0xa5,
0xc4, 0x49, 0x2c, 0x1a, 0xdd, 0x54, 0x45, 0x12,
0xdd, 0xa2, 0x52, 0x98, 0x33, 0x46, 0x2b, 0x71,
0xa4, 0x1a, 0x45, 0xbe, 0x97, 0x29, 0x0b, 0x6f
};
const unsigned char shake128_0xa3_200_times[32] = {
0x44, 0xc9, 0xfb, 0x35, 0x9f, 0xd5, 0x6a, 0xc0,
0xa9, 0xa7, 0x5a, 0x74, 0x3c, 0xff, 0x68, 0x62,
0xf1, 0x7d, 0x72, 0x59, 0xab, 0x07, 0x52, 0x16,
0xc0, 0x69, 0x95, 0x11, 0x64, 0x3b, 0x64, 0x39
};
XMEMSET(buf, c1, sizeof(buf));
/* SHAKE256 on an empty buffer */
sha3_shake_init(&c, 256);
for (i = 0; i < 16; i++) sha3_shake_done(&c, hash, 32); /* get 512 bytes, keep in hash the last 32 */
if (compare_testvector(hash, sizeof(shake256_empty), shake256_empty, sizeof(shake256_empty), "SHAKE256", 0)) {
return CRYPT_FAIL_TESTVECTOR;
}
/* SHAKE256 via sha3_shake_memory [FIPS 202] */
len = 512;
sha3_shake_memory(256, buf, sizeof(buf), hash, &len);
if (compare_testvector(hash + 480, sizeof(shake256_0xa3_200_times), shake256_0xa3_200_times, sizeof(shake256_0xa3_200_times), "SHAKE256", 1)) {
return CRYPT_FAIL_TESTVECTOR;
}
/* SHAKE256 as a single buffer. [FIPS 202] */
sha3_shake_init(&c, 256);
sha3_shake_process(&c, buf, sizeof(buf));
for (i = 0; i < 16; i++) sha3_shake_done(&c, hash, 32); /* get 512 bytes, keep in hash the last 32 */
if (compare_testvector(hash, sizeof(shake256_0xa3_200_times), shake256_0xa3_200_times, sizeof(shake256_0xa3_200_times), "SHAKE256", 2)) {
return CRYPT_FAIL_TESTVECTOR;
}
/* SHAKE256 in two steps. [FIPS 202] */
sha3_shake_init(&c, 256);
sha3_shake_process(&c, buf, sizeof(buf) / 2);
sha3_shake_process(&c, buf + sizeof(buf) / 2, sizeof(buf) / 2);
for (i = 0; i < 16; i++) sha3_shake_done(&c, hash, 32); /* get 512 bytes, keep in hash the last 32 */
if (compare_testvector(hash, sizeof(shake256_0xa3_200_times), shake256_0xa3_200_times, sizeof(shake256_0xa3_200_times), "SHAKE256", 3)) {
return CRYPT_FAIL_TESTVECTOR;
}
/* SHAKE256 byte-by-byte: 200 steps. [FIPS 202] */
i = 200;
sha3_shake_init(&c, 256);
while (i--) sha3_shake_process(&c, &c1, 1);
for (i = 0; i < 16; i++) sha3_shake_done(&c, hash, 32); /* get 512 bytes, keep in hash the last 32 */
if (compare_testvector(hash, sizeof(shake256_0xa3_200_times), shake256_0xa3_200_times, sizeof(shake256_0xa3_200_times), "SHAKE256", 4)) {
return CRYPT_FAIL_TESTVECTOR;
}
/* SHAKE128 on an empty buffer */
sha3_shake_init(&c, 128);
for (i = 0; i < 16; i++) sha3_shake_done(&c, hash, 32); /* get 512 bytes, keep in hash the last 32 */
if (compare_testvector(hash, sizeof(shake128_empty), shake128_empty, sizeof(shake128_empty), "SHAKE128", 0)) {
return CRYPT_FAIL_TESTVECTOR;
}
/* SHAKE128 via sha3_shake_memory [FIPS 202] */
len = 512;
sha3_shake_memory(128, buf, sizeof(buf), hash, &len);
if (compare_testvector(hash + 480, sizeof(shake128_0xa3_200_times), shake128_0xa3_200_times, sizeof(shake128_0xa3_200_times), "SHAKE128", 1)) {
return CRYPT_FAIL_TESTVECTOR;
}
/* SHAKE128 as a single buffer. [FIPS 202] */
sha3_shake_init(&c, 128);
sha3_shake_process(&c, buf, sizeof(buf));
for (i = 0; i < 16; i++) sha3_shake_done(&c, hash, 32); /* get 512 bytes, keep in hash the last 32 */
if (compare_testvector(hash, sizeof(shake128_0xa3_200_times), shake128_0xa3_200_times, sizeof(shake128_0xa3_200_times), "SHAKE128", 2)) {
return CRYPT_FAIL_TESTVECTOR;
}
/* SHAKE128 in two steps. [FIPS 202] */
sha3_shake_init(&c, 128);
sha3_shake_process(&c, buf, sizeof(buf) / 2);
sha3_shake_process(&c, buf + sizeof(buf) / 2, sizeof(buf) / 2);
for (i = 0; i < 16; i++) sha3_shake_done(&c, hash, 32); /* get 512 bytes, keep in hash the last 32 */
if (compare_testvector(hash, sizeof(shake128_0xa3_200_times), shake128_0xa3_200_times, sizeof(shake128_0xa3_200_times), "SHAKE128", 3)) {
return CRYPT_FAIL_TESTVECTOR;
}
/* SHAKE128 byte-by-byte: 200 steps. [FIPS 202] */
i = 200;
sha3_shake_init(&c, 128);
while (i--) sha3_shake_process(&c, &c1, 1);
for (i = 0; i < 16; i++) sha3_shake_done(&c, hash, 32); /* get 512 bytes, keep in hash the last 32 */
if (compare_testvector(hash, sizeof(shake128_0xa3_200_times), shake128_0xa3_200_times, sizeof(shake128_0xa3_200_times), "SHAKE128", 4)) {
return CRYPT_FAIL_TESTVECTOR;
}
return CRYPT_OK;
#endif
}
#endif
#ifdef LTC_KECCAK
int keccak_224_test(void)
{
#ifndef LTC_TEST
return CRYPT_NOP;
#else
hash_state c;
unsigned char hash[MAXBLOCKSIZE];
keccak_224_init(&c);
keccak_process(&c, (unsigned char*) "\xcc", 1);
keccak_done(&c, hash);
if(compare_testvector(hash, 28,
"\xa9\xca\xb5\x9e\xb4\x0a\x10\xb2"
"\x46\x29\x0f\x2d\x60\x86\xe3\x2e"
"\x36\x89\xfa\xf1\xd2\x6b\x47\x0c"
"\x89\x9f\x28\x02", 28,
"KECCAK-224", 0) != 0) {
return CRYPT_FAIL_TESTVECTOR;
}
keccak_224_init(&c);
keccak_process(&c, (unsigned char*)"\x41\xfb", 2);
keccak_done(&c, hash);
if(compare_testvector(hash, 28,
"\x61\x5b\xa3\x67\xaf\xdc\x35\xaa"
"\xc3\x97\xbc\x7e\xb5\xd5\x8d\x10"
"\x6a\x73\x4b\x24\x98\x6d\x5d\x97"
"\x8f\xef\xd6\x2c", 28,
"KECCAK-224", 1) != 0) {
return CRYPT_FAIL_TESTVECTOR;
}
keccak_224_init(&c);
keccak_process(&c, (unsigned char*)
"\x52\xa6\x08\xab\x21\xcc\xdd\x8a"
"\x44\x57\xa5\x7e\xde\x78\x21\x76", 16);
keccak_done(&c, hash);
if(compare_testvector(hash, 28,
"\x56\x79\xcd\x50\x9c\x51\x20\xaf"
"\x54\x79\x5c\xf4\x77\x14\x96\x41"
"\xcf\x27\xb2\xeb\xb6\xa5\xf9\x03"
"\x40\x70\x4e\x57", 28,
"KECCAK-224", 2) != 0) {
return CRYPT_FAIL_TESTVECTOR;
}
keccak_224_init(&c);
keccak_process(&c, (unsigned char*)
"\x43\x3c\x53\x03\x13\x16\x24\xc0"
"\x02\x1d\x86\x8a\x30\x82\x54\x75"
"\xe8\xd0\xbd\x30\x52\xa0\x22\x18"
"\x03\x98\xf4\xca\x44\x23\xb9\x82"
"\x14\xb6\xbe\xaa\xc2\x1c\x88\x07"
"\xa2\xc3\x3f\x8c\x93\xbd\x42\xb0"
"\x92\xcc\x1b\x06\xce\xdf\x32\x24"
"\xd5\xed\x1e\xc2\x97\x84\x44\x4f"
"\x22\xe0\x8a\x55\xaa\x58\x54\x2b"
"\x52\x4b\x02\xcd\x3d\x5d\x5f\x69"
"\x07\xaf\xe7\x1c\x5d\x74\x62\x22"
"\x4a\x3f\x9d\x9e\x53\xe7\xe0\x84"
"\x6d\xcb\xb4\xce", 100);
keccak_done(&c, hash);
if(compare_testvector(hash, 28,
"\x62\xb1\x0f\x1b\x62\x36\xeb\xc2"
"\xda\x72\x95\x77\x42\xa8\xd4\xe4"
"\x8e\x21\x3b\x5f\x89\x34\x60\x4b"
"\xfd\x4d\x2c\x3a", 28,
"KECCAK-224", 3) != 0) {
return CRYPT_FAIL_TESTVECTOR;
}
return CRYPT_OK;
#endif
}
int keccak_256_test(void)
{
#ifndef LTC_TEST
return CRYPT_NOP;
#else
hash_state c;
unsigned char hash[MAXBLOCKSIZE];
keccak_256_init(&c);
keccak_process(&c, (unsigned char*) "\xcc", 1);
keccak_done(&c, hash);
if(compare_testvector(hash, 32,
"\xee\xad\x6d\xbf\xc7\x34\x0a\x56"
"\xca\xed\xc0\x44\x69\x6a\x16\x88"
"\x70\x54\x9a\x6a\x7f\x6f\x56\x96"
"\x1e\x84\xa5\x4b\xd9\x97\x0b\x8a", 32,
"KECCAK-256", 0) != 0) {
return CRYPT_FAIL_TESTVECTOR;
}
keccak_256_init(&c);
keccak_process(&c, (unsigned char*)"\x41\xfb", 2);
keccak_done(&c, hash);
if(compare_testvector(hash, 32,
"\xa8\xea\xce\xda\x4d\x47\xb3\x28"
"\x1a\x79\x5a\xd9\xe1\xea\x21\x22"
"\xb4\x07\xba\xf9\xaa\xbc\xb9\xe1"
"\x8b\x57\x17\xb7\x87\x35\x37\xd2", 32,
"KECCAK-256", 1) != 0) {
return CRYPT_FAIL_TESTVECTOR;
}
keccak_256_init(&c);
keccak_process(&c, (unsigned char*)
"\x52\xa6\x08\xab\x21\xcc\xdd\x8a"
"\x44\x57\xa5\x7e\xde\x78\x21\x76", 16);
keccak_done(&c, hash);
if(compare_testvector(hash, 32,
"\x0e\x32\xde\xfa\x20\x71\xf0\xb5"
"\xac\x0e\x6a\x10\x8b\x84\x2e\xd0"
"\xf1\xd3\x24\x97\x12\xf5\x8e\xe0"
"\xdd\xf9\x56\xfe\x33\x2a\x5f\x95", 32,
"KECCAK-256", 2) != 0) {
return CRYPT_FAIL_TESTVECTOR;
}
keccak_256_init(&c);
keccak_process(&c, (unsigned char*)
"\x43\x3c\x53\x03\x13\x16\x24\xc0"
"\x02\x1d\x86\x8a\x30\x82\x54\x75"
"\xe8\xd0\xbd\x30\x52\xa0\x22\x18"
"\x03\x98\xf4\xca\x44\x23\xb9\x82"
"\x14\xb6\xbe\xaa\xc2\x1c\x88\x07"
"\xa2\xc3\x3f\x8c\x93\xbd\x42\xb0"
"\x92\xcc\x1b\x06\xce\xdf\x32\x24"
"\xd5\xed\x1e\xc2\x97\x84\x44\x4f"
"\x22\xe0\x8a\x55\xaa\x58\x54\x2b"
"\x52\x4b\x02\xcd\x3d\x5d\x5f\x69"
"\x07\xaf\xe7\x1c\x5d\x74\x62\x22"
"\x4a\x3f\x9d\x9e\x53\xe7\xe0\x84"
"\x6d\xcb\xb4\xce", 100);
keccak_done(&c, hash);
if(compare_testvector(hash, 32,
"\xce\x87\xa5\x17\x3b\xff\xd9\x23"
"\x99\x22\x16\x58\xf8\x01\xd4\x5c"
"\x29\x4d\x90\x06\xee\x9f\x3f\x9d"
"\x41\x9c\x8d\x42\x77\x48\xdc\x41", 32,
"KECCAK-256", 3) != 0) {
return CRYPT_FAIL_TESTVECTOR;
}
return CRYPT_OK;
#endif
}
int keccak_384_test(void)
{
#ifndef LTC_TEST
return CRYPT_NOP;
#else
hash_state c;
unsigned char hash[MAXBLOCKSIZE];
keccak_384_init(&c);
keccak_process(&c, (unsigned char*) "\xcc", 1);
keccak_done(&c, hash);
if(compare_testvector(hash, 48,
"\x1b\x84\xe6\x2a\x46\xe5\xa2\x01"
"\x86\x17\x54\xaf\x5d\xc9\x5c\x4a"
"\x1a\x69\xca\xf4\xa7\x96\xae\x40"
"\x56\x80\x16\x1e\x29\x57\x26\x41"
"\xf5\xfa\x1e\x86\x41\xd7\x95\x83"
"\x36\xee\x7b\x11\xc5\x8f\x73\xe9", 48,
"KECCAK-384", 0) != 0) {
return CRYPT_FAIL_TESTVECTOR;
}
keccak_384_init(&c);
keccak_process(&c, (unsigned char*)"\x41\xfb", 2);
keccak_done(&c, hash);
if(compare_testvector(hash, 48,
"\x49\x5c\xce\x27\x14\xcd\x72\xc8"
"\xc5\x3c\x33\x63\xd2\x2c\x58\xb5"
"\x59\x60\xfe\x26\xbe\x0b\xf3\xbb"
"\xc7\xa3\x31\x6d\xd5\x63\xad\x1d"
"\xb8\x41\x0e\x75\xee\xfe\xa6\x55"
"\xe3\x9d\x46\x70\xec\x0b\x17\x92", 48,
"KECCAK-384", 1) != 0) {
return CRYPT_FAIL_TESTVECTOR;
}
keccak_384_init(&c);
keccak_process(&c, (unsigned char*)
"\x52\xa6\x08\xab\x21\xcc\xdd\x8a"
"\x44\x57\xa5\x7e\xde\x78\x21\x76", 16);
keccak_done(&c, hash);
if(compare_testvector(hash, 48,
"\x18\x42\x2a\xc1\xd3\xa1\xe5\x4b"
"\xad\x87\x68\x83\xd2\xd6\xdd\x65"
"\xf6\x5c\x1d\x5f\x33\xa7\x12\x5c"
"\xc4\xc1\x86\x40\x5a\x12\xed\x64"
"\xba\x96\x67\x2e\xed\xda\x8c\x5a"
"\x63\x31\xd2\x86\x83\xf4\x88\xeb", 48,
"KECCAK-384", 2) != 0) {
return CRYPT_FAIL_TESTVECTOR;
}
keccak_384_init(&c);
keccak_process(&c, (unsigned char*)
"\x43\x3c\x53\x03\x13\x16\x24\xc0"
"\x02\x1d\x86\x8a\x30\x82\x54\x75"
"\xe8\xd0\xbd\x30\x52\xa0\x22\x18"
"\x03\x98\xf4\xca\x44\x23\xb9\x82"
"\x14\xb6\xbe\xaa\xc2\x1c\x88\x07"
"\xa2\xc3\x3f\x8c\x93\xbd\x42\xb0"
"\x92\xcc\x1b\x06\xce\xdf\x32\x24"
"\xd5\xed\x1e\xc2\x97\x84\x44\x4f"
"\x22\xe0\x8a\x55\xaa\x58\x54\x2b"
"\x52\x4b\x02\xcd\x3d\x5d\x5f\x69"
"\x07\xaf\xe7\x1c\x5d\x74\x62\x22"
"\x4a\x3f\x9d\x9e\x53\xe7\xe0\x84"
"\x6d\xcb\xb4\xce", 100);
keccak_done(&c, hash);
if(compare_testvector(hash, 48,
"\x13\x51\x14\x50\x8d\xd6\x3e\x27"
"\x9e\x70\x9c\x26\xf7\x81\x7c\x04"
"\x82\x76\x6c\xde\x49\x13\x2e\x3e"
"\xdf\x2e\xed\xd8\x99\x6f\x4e\x35"
"\x96\xd1\x84\x10\x0b\x38\x48\x68"
"\x24\x9f\x1d\x8b\x8f\xda\xa2\xc9", 48,
"KECCAK-384", 3) != 0) {
return CRYPT_FAIL_TESTVECTOR;
}
return CRYPT_OK;
#endif
}
int keccak_512_test(void)
{
#ifndef LTC_TEST
return CRYPT_NOP;
#else
hash_state c;
unsigned char hash[MAXBLOCKSIZE];
keccak_512_init(&c);
keccak_process(&c, (unsigned char*) "\xcc", 1);
keccak_done(&c, hash);
if(compare_testvector(hash, 64,
"\x86\x30\xc1\x3c\xbd\x06\x6e\xa7"
"\x4b\xbe\x7f\xe4\x68\xfe\xc1\xde"
"\xe1\x0e\xdc\x12\x54\xfb\x4c\x1b"
"\x7c\x5f\xd6\x9b\x64\x6e\x44\x16"
"\x0b\x8c\xe0\x1d\x05\xa0\x90\x8c"
"\xa7\x90\xdf\xb0\x80\xf4\xb5\x13"
"\xbc\x3b\x62\x25\xec\xe7\xa8\x10"
"\x37\x14\x41\xa5\xac\x66\x6e\xb9", 64,
"KECCAK-512", 0) != 0) {
return CRYPT_FAIL_TESTVECTOR;
}
keccak_512_init(&c);
keccak_process(&c, (unsigned char*)"\x41\xfb", 2);
keccak_done(&c, hash);
if(compare_testvector(hash, 64,
"\x55\x1d\xa6\x23\x6f\x8b\x96\xfc"
"\xe9\xf9\x7f\x11\x90\xe9\x01\x32"
"\x4f\x0b\x45\xe0\x6d\xbb\xb5\xcd"
"\xb8\x35\x5d\x6e\xd1\xdc\x34\xb3"
"\xf0\xea\xe7\xdc\xb6\x86\x22\xff"
"\x23\x2f\xa3\xce\xce\x0d\x46\x16"
"\xcd\xeb\x39\x31\xf9\x38\x03\x66"
"\x2a\x28\xdf\x1c\xd5\x35\xb7\x31", 64,
"KECCAK-512", 1) != 0) {
return CRYPT_FAIL_TESTVECTOR;
}
keccak_512_init(&c);
keccak_process(&c, (unsigned char*)
"\x52\xa6\x08\xab\x21\xcc\xdd\x8a"
"\x44\x57\xa5\x7e\xde\x78\x21\x76", 16);
keccak_done(&c, hash);
if(compare_testvector(hash, 64,
"\x4b\x39\xd3\xda\x5b\xcd\xf4\xd9"
"\xb7\x69\x01\x59\x95\x64\x43\x11"
"\xc1\x4c\x43\x5b\xf7\x2b\x10\x09"
"\xd6\xdd\x71\xb0\x1a\x63\xb9\x7c"
"\xfb\x59\x64\x18\xe8\xe4\x23\x42"
"\xd1\x17\xe0\x74\x71\xa8\x91\x43"
"\x14\xba\x7b\x0e\x26\x4d\xad\xf0"
"\xce\xa3\x81\x86\x8c\xbd\x43\xd1", 64,
"KECCAK-512", 2) != 0) {
return CRYPT_FAIL_TESTVECTOR;
}
keccak_512_init(&c);
keccak_process(&c, (unsigned char*)
"\x43\x3c\x53\x03\x13\x16\x24\xc0"
"\x02\x1d\x86\x8a\x30\x82\x54\x75"
"\xe8\xd0\xbd\x30\x52\xa0\x22\x18"
"\x03\x98\xf4\xca\x44\x23\xb9\x82"
"\x14\xb6\xbe\xaa\xc2\x1c\x88\x07"
"\xa2\xc3\x3f\x8c\x93\xbd\x42\xb0"
"\x92\xcc\x1b\x06\xce\xdf\x32\x24"
"\xd5\xed\x1e\xc2\x97\x84\x44\x4f"
"\x22\xe0\x8a\x55\xaa\x58\x54\x2b"
"\x52\x4b\x02\xcd\x3d\x5d\x5f\x69"
"\x07\xaf\xe7\x1c\x5d\x74\x62\x22"
"\x4a\x3f\x9d\x9e\x53\xe7\xe0\x84"
"\x6d\xcb\xb4\xce", 100);
keccak_done(&c, hash);
if(compare_testvector(hash, 64,
"\x52\x7d\x28\xe3\x41\xe6\xb1\x4f"
"\x46\x84\xad\xb4\xb8\x24\xc4\x96"
"\xc6\x48\x2e\x51\x14\x95\x65\xd3"
"\xd1\x72\x26\x82\x88\x84\x30\x6b"
"\x51\xd6\x14\x8a\x72\x62\x2c\x2b"
"\x75\xf5\xd3\x51\x0b\x79\x9d\x8b"
"\xdc\x03\xea\xed\xe4\x53\x67\x6a"
"\x6e\xc8\xfe\x03\xa1\xad\x0e\xab", 64,
"KECCAK-512", 3) != 0) {
return CRYPT_FAIL_TESTVECTOR;
}
return CRYPT_OK;
#endif
}
#endif

View File

@@ -0,0 +1,920 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
/* SPDX-License-Identifier: Unlicense */
#include "tomcrypt_private.h"
/**
@file tiger.c
Tiger hash function, Tom St Denis
*/
#ifdef LTC_TIGER
const struct ltc_hash_descriptor tiger_desc =
{
"tiger",
1,
24,
64,
/* OID */
{ 1, 3, 6, 1, 4, 1, 11591, 12, 2, },
9,
&tiger_init,
&tiger_process,
&tiger_done,
&tiger_test,
NULL
};
const struct ltc_hash_descriptor tiger2_desc =
{
"tiger2",
33,
24,
64,
/* OID ... does not exist */
{ 0 },
0,
&tiger2_init,
&tiger_process,
&tiger_done,
&tiger2_test,
NULL
};
#define t1 (table)
#define t2 (table+256)
#define t3 (table+256*2)
#define t4 (table+256*3)
static const ulong64 table[4*256] = {
CONST64(0x02AAB17CF7E90C5E) /* 0 */, CONST64(0xAC424B03E243A8EC) /* 1 */,
CONST64(0x72CD5BE30DD5FCD3) /* 2 */, CONST64(0x6D019B93F6F97F3A) /* 3 */,
CONST64(0xCD9978FFD21F9193) /* 4 */, CONST64(0x7573A1C9708029E2) /* 5 */,
CONST64(0xB164326B922A83C3) /* 6 */, CONST64(0x46883EEE04915870) /* 7 */,
CONST64(0xEAACE3057103ECE6) /* 8 */, CONST64(0xC54169B808A3535C) /* 9 */,
CONST64(0x4CE754918DDEC47C) /* 10 */, CONST64(0x0AA2F4DFDC0DF40C) /* 11 */,
CONST64(0x10B76F18A74DBEFA) /* 12 */, CONST64(0xC6CCB6235AD1AB6A) /* 13 */,
CONST64(0x13726121572FE2FF) /* 14 */, CONST64(0x1A488C6F199D921E) /* 15 */,
CONST64(0x4BC9F9F4DA0007CA) /* 16 */, CONST64(0x26F5E6F6E85241C7) /* 17 */,
CONST64(0x859079DBEA5947B6) /* 18 */, CONST64(0x4F1885C5C99E8C92) /* 19 */,
CONST64(0xD78E761EA96F864B) /* 20 */, CONST64(0x8E36428C52B5C17D) /* 21 */,
CONST64(0x69CF6827373063C1) /* 22 */, CONST64(0xB607C93D9BB4C56E) /* 23 */,
CONST64(0x7D820E760E76B5EA) /* 24 */, CONST64(0x645C9CC6F07FDC42) /* 25 */,
CONST64(0xBF38A078243342E0) /* 26 */, CONST64(0x5F6B343C9D2E7D04) /* 27 */,
CONST64(0xF2C28AEB600B0EC6) /* 28 */, CONST64(0x6C0ED85F7254BCAC) /* 29 */,
CONST64(0x71592281A4DB4FE5) /* 30 */, CONST64(0x1967FA69CE0FED9F) /* 31 */,
CONST64(0xFD5293F8B96545DB) /* 32 */, CONST64(0xC879E9D7F2A7600B) /* 33 */,
CONST64(0x860248920193194E) /* 34 */, CONST64(0xA4F9533B2D9CC0B3) /* 35 */,
CONST64(0x9053836C15957613) /* 36 */, CONST64(0xDB6DCF8AFC357BF1) /* 37 */,
CONST64(0x18BEEA7A7A370F57) /* 38 */, CONST64(0x037117CA50B99066) /* 39 */,
CONST64(0x6AB30A9774424A35) /* 40 */, CONST64(0xF4E92F02E325249B) /* 41 */,
CONST64(0x7739DB07061CCAE1) /* 42 */, CONST64(0xD8F3B49CECA42A05) /* 43 */,
CONST64(0xBD56BE3F51382F73) /* 44 */, CONST64(0x45FAED5843B0BB28) /* 45 */,
CONST64(0x1C813D5C11BF1F83) /* 46 */, CONST64(0x8AF0E4B6D75FA169) /* 47 */,
CONST64(0x33EE18A487AD9999) /* 48 */, CONST64(0x3C26E8EAB1C94410) /* 49 */,
CONST64(0xB510102BC0A822F9) /* 50 */, CONST64(0x141EEF310CE6123B) /* 51 */,
CONST64(0xFC65B90059DDB154) /* 52 */, CONST64(0xE0158640C5E0E607) /* 53 */,
CONST64(0x884E079826C3A3CF) /* 54 */, CONST64(0x930D0D9523C535FD) /* 55 */,
CONST64(0x35638D754E9A2B00) /* 56 */, CONST64(0x4085FCCF40469DD5) /* 57 */,
CONST64(0xC4B17AD28BE23A4C) /* 58 */, CONST64(0xCAB2F0FC6A3E6A2E) /* 59 */,
CONST64(0x2860971A6B943FCD) /* 60 */, CONST64(0x3DDE6EE212E30446) /* 61 */,
CONST64(0x6222F32AE01765AE) /* 62 */, CONST64(0x5D550BB5478308FE) /* 63 */,
CONST64(0xA9EFA98DA0EDA22A) /* 64 */, CONST64(0xC351A71686C40DA7) /* 65 */,
CONST64(0x1105586D9C867C84) /* 66 */, CONST64(0xDCFFEE85FDA22853) /* 67 */,
CONST64(0xCCFBD0262C5EEF76) /* 68 */, CONST64(0xBAF294CB8990D201) /* 69 */,
CONST64(0xE69464F52AFAD975) /* 70 */, CONST64(0x94B013AFDF133E14) /* 71 */,
CONST64(0x06A7D1A32823C958) /* 72 */, CONST64(0x6F95FE5130F61119) /* 73 */,
CONST64(0xD92AB34E462C06C0) /* 74 */, CONST64(0xED7BDE33887C71D2) /* 75 */,
CONST64(0x79746D6E6518393E) /* 76 */, CONST64(0x5BA419385D713329) /* 77 */,
CONST64(0x7C1BA6B948A97564) /* 78 */, CONST64(0x31987C197BFDAC67) /* 79 */,
CONST64(0xDE6C23C44B053D02) /* 80 */, CONST64(0x581C49FED002D64D) /* 81 */,
CONST64(0xDD474D6338261571) /* 82 */, CONST64(0xAA4546C3E473D062) /* 83 */,
CONST64(0x928FCE349455F860) /* 84 */, CONST64(0x48161BBACAAB94D9) /* 85 */,
CONST64(0x63912430770E6F68) /* 86 */, CONST64(0x6EC8A5E602C6641C) /* 87 */,
CONST64(0x87282515337DDD2B) /* 88 */, CONST64(0x2CDA6B42034B701B) /* 89 */,
CONST64(0xB03D37C181CB096D) /* 90 */, CONST64(0xE108438266C71C6F) /* 91 */,
CONST64(0x2B3180C7EB51B255) /* 92 */, CONST64(0xDF92B82F96C08BBC) /* 93 */,
CONST64(0x5C68C8C0A632F3BA) /* 94 */, CONST64(0x5504CC861C3D0556) /* 95 */,
CONST64(0xABBFA4E55FB26B8F) /* 96 */, CONST64(0x41848B0AB3BACEB4) /* 97 */,
CONST64(0xB334A273AA445D32) /* 98 */, CONST64(0xBCA696F0A85AD881) /* 99 */,
CONST64(0x24F6EC65B528D56C) /* 100 */, CONST64(0x0CE1512E90F4524A) /* 101 */,
CONST64(0x4E9DD79D5506D35A) /* 102 */, CONST64(0x258905FAC6CE9779) /* 103 */,
CONST64(0x2019295B3E109B33) /* 104 */, CONST64(0xF8A9478B73A054CC) /* 105 */,
CONST64(0x2924F2F934417EB0) /* 106 */, CONST64(0x3993357D536D1BC4) /* 107 */,
CONST64(0x38A81AC21DB6FF8B) /* 108 */, CONST64(0x47C4FBF17D6016BF) /* 109 */,
CONST64(0x1E0FAADD7667E3F5) /* 110 */, CONST64(0x7ABCFF62938BEB96) /* 111 */,
CONST64(0xA78DAD948FC179C9) /* 112 */, CONST64(0x8F1F98B72911E50D) /* 113 */,
CONST64(0x61E48EAE27121A91) /* 114 */, CONST64(0x4D62F7AD31859808) /* 115 */,
CONST64(0xECEBA345EF5CEAEB) /* 116 */, CONST64(0xF5CEB25EBC9684CE) /* 117 */,
CONST64(0xF633E20CB7F76221) /* 118 */, CONST64(0xA32CDF06AB8293E4) /* 119 */,
CONST64(0x985A202CA5EE2CA4) /* 120 */, CONST64(0xCF0B8447CC8A8FB1) /* 121 */,
CONST64(0x9F765244979859A3) /* 122 */, CONST64(0xA8D516B1A1240017) /* 123 */,
CONST64(0x0BD7BA3EBB5DC726) /* 124 */, CONST64(0xE54BCA55B86ADB39) /* 125 */,
CONST64(0x1D7A3AFD6C478063) /* 126 */, CONST64(0x519EC608E7669EDD) /* 127 */,
CONST64(0x0E5715A2D149AA23) /* 128 */, CONST64(0x177D4571848FF194) /* 129 */,
CONST64(0xEEB55F3241014C22) /* 130 */, CONST64(0x0F5E5CA13A6E2EC2) /* 131 */,
CONST64(0x8029927B75F5C361) /* 132 */, CONST64(0xAD139FABC3D6E436) /* 133 */,
CONST64(0x0D5DF1A94CCF402F) /* 134 */, CONST64(0x3E8BD948BEA5DFC8) /* 135 */,
CONST64(0xA5A0D357BD3FF77E) /* 136 */, CONST64(0xA2D12E251F74F645) /* 137 */,
CONST64(0x66FD9E525E81A082) /* 138 */, CONST64(0x2E0C90CE7F687A49) /* 139 */,
CONST64(0xC2E8BCBEBA973BC5) /* 140 */, CONST64(0x000001BCE509745F) /* 141 */,
CONST64(0x423777BBE6DAB3D6) /* 142 */, CONST64(0xD1661C7EAEF06EB5) /* 143 */,
CONST64(0xA1781F354DAACFD8) /* 144 */, CONST64(0x2D11284A2B16AFFC) /* 145 */,
CONST64(0xF1FC4F67FA891D1F) /* 146 */, CONST64(0x73ECC25DCB920ADA) /* 147 */,
CONST64(0xAE610C22C2A12651) /* 148 */, CONST64(0x96E0A810D356B78A) /* 149 */,
CONST64(0x5A9A381F2FE7870F) /* 150 */, CONST64(0xD5AD62EDE94E5530) /* 151 */,
CONST64(0xD225E5E8368D1427) /* 152 */, CONST64(0x65977B70C7AF4631) /* 153 */,
CONST64(0x99F889B2DE39D74F) /* 154 */, CONST64(0x233F30BF54E1D143) /* 155 */,
CONST64(0x9A9675D3D9A63C97) /* 156 */, CONST64(0x5470554FF334F9A8) /* 157 */,
CONST64(0x166ACB744A4F5688) /* 158 */, CONST64(0x70C74CAAB2E4AEAD) /* 159 */,
CONST64(0xF0D091646F294D12) /* 160 */, CONST64(0x57B82A89684031D1) /* 161 */,
CONST64(0xEFD95A5A61BE0B6B) /* 162 */, CONST64(0x2FBD12E969F2F29A) /* 163 */,
CONST64(0x9BD37013FEFF9FE8) /* 164 */, CONST64(0x3F9B0404D6085A06) /* 165 */,
CONST64(0x4940C1F3166CFE15) /* 166 */, CONST64(0x09542C4DCDF3DEFB) /* 167 */,
CONST64(0xB4C5218385CD5CE3) /* 168 */, CONST64(0xC935B7DC4462A641) /* 169 */,
CONST64(0x3417F8A68ED3B63F) /* 170 */, CONST64(0xB80959295B215B40) /* 171 */,
CONST64(0xF99CDAEF3B8C8572) /* 172 */, CONST64(0x018C0614F8FCB95D) /* 173 */,
CONST64(0x1B14ACCD1A3ACDF3) /* 174 */, CONST64(0x84D471F200BB732D) /* 175 */,
CONST64(0xC1A3110E95E8DA16) /* 176 */, CONST64(0x430A7220BF1A82B8) /* 177 */,
CONST64(0xB77E090D39DF210E) /* 178 */, CONST64(0x5EF4BD9F3CD05E9D) /* 179 */,
CONST64(0x9D4FF6DA7E57A444) /* 180 */, CONST64(0xDA1D60E183D4A5F8) /* 181 */,
CONST64(0xB287C38417998E47) /* 182 */, CONST64(0xFE3EDC121BB31886) /* 183 */,
CONST64(0xC7FE3CCC980CCBEF) /* 184 */, CONST64(0xE46FB590189BFD03) /* 185 */,
CONST64(0x3732FD469A4C57DC) /* 186 */, CONST64(0x7EF700A07CF1AD65) /* 187 */,
CONST64(0x59C64468A31D8859) /* 188 */, CONST64(0x762FB0B4D45B61F6) /* 189 */,
CONST64(0x155BAED099047718) /* 190 */, CONST64(0x68755E4C3D50BAA6) /* 191 */,
CONST64(0xE9214E7F22D8B4DF) /* 192 */, CONST64(0x2ADDBF532EAC95F4) /* 193 */,
CONST64(0x32AE3909B4BD0109) /* 194 */, CONST64(0x834DF537B08E3450) /* 195 */,
CONST64(0xFA209DA84220728D) /* 196 */, CONST64(0x9E691D9B9EFE23F7) /* 197 */,
CONST64(0x0446D288C4AE8D7F) /* 198 */, CONST64(0x7B4CC524E169785B) /* 199 */,
CONST64(0x21D87F0135CA1385) /* 200 */, CONST64(0xCEBB400F137B8AA5) /* 201 */,
CONST64(0x272E2B66580796BE) /* 202 */, CONST64(0x3612264125C2B0DE) /* 203 */,
CONST64(0x057702BDAD1EFBB2) /* 204 */, CONST64(0xD4BABB8EACF84BE9) /* 205 */,
CONST64(0x91583139641BC67B) /* 206 */, CONST64(0x8BDC2DE08036E024) /* 207 */,
CONST64(0x603C8156F49F68ED) /* 208 */, CONST64(0xF7D236F7DBEF5111) /* 209 */,
CONST64(0x9727C4598AD21E80) /* 210 */, CONST64(0xA08A0896670A5FD7) /* 211 */,
CONST64(0xCB4A8F4309EBA9CB) /* 212 */, CONST64(0x81AF564B0F7036A1) /* 213 */,
CONST64(0xC0B99AA778199ABD) /* 214 */, CONST64(0x959F1EC83FC8E952) /* 215 */,
CONST64(0x8C505077794A81B9) /* 216 */, CONST64(0x3ACAAF8F056338F0) /* 217 */,
CONST64(0x07B43F50627A6778) /* 218 */, CONST64(0x4A44AB49F5ECCC77) /* 219 */,
CONST64(0x3BC3D6E4B679EE98) /* 220 */, CONST64(0x9CC0D4D1CF14108C) /* 221 */,
CONST64(0x4406C00B206BC8A0) /* 222 */, CONST64(0x82A18854C8D72D89) /* 223 */,
CONST64(0x67E366B35C3C432C) /* 224 */, CONST64(0xB923DD61102B37F2) /* 225 */,
CONST64(0x56AB2779D884271D) /* 226 */, CONST64(0xBE83E1B0FF1525AF) /* 227 */,
CONST64(0xFB7C65D4217E49A9) /* 228 */, CONST64(0x6BDBE0E76D48E7D4) /* 229 */,
CONST64(0x08DF828745D9179E) /* 230 */, CONST64(0x22EA6A9ADD53BD34) /* 231 */,
CONST64(0xE36E141C5622200A) /* 232 */, CONST64(0x7F805D1B8CB750EE) /* 233 */,
CONST64(0xAFE5C7A59F58E837) /* 234 */, CONST64(0xE27F996A4FB1C23C) /* 235 */,
CONST64(0xD3867DFB0775F0D0) /* 236 */, CONST64(0xD0E673DE6E88891A) /* 237 */,
CONST64(0x123AEB9EAFB86C25) /* 238 */, CONST64(0x30F1D5D5C145B895) /* 239 */,
CONST64(0xBB434A2DEE7269E7) /* 240 */, CONST64(0x78CB67ECF931FA38) /* 241 */,
CONST64(0xF33B0372323BBF9C) /* 242 */, CONST64(0x52D66336FB279C74) /* 243 */,
CONST64(0x505F33AC0AFB4EAA) /* 244 */, CONST64(0xE8A5CD99A2CCE187) /* 245 */,
CONST64(0x534974801E2D30BB) /* 246 */, CONST64(0x8D2D5711D5876D90) /* 247 */,
CONST64(0x1F1A412891BC038E) /* 248 */, CONST64(0xD6E2E71D82E56648) /* 249 */,
CONST64(0x74036C3A497732B7) /* 250 */, CONST64(0x89B67ED96361F5AB) /* 251 */,
CONST64(0xFFED95D8F1EA02A2) /* 252 */, CONST64(0xE72B3BD61464D43D) /* 253 */,
CONST64(0xA6300F170BDC4820) /* 254 */, CONST64(0xEBC18760ED78A77A) /* 255 */,
CONST64(0xE6A6BE5A05A12138) /* 256 */, CONST64(0xB5A122A5B4F87C98) /* 257 */,
CONST64(0x563C6089140B6990) /* 258 */, CONST64(0x4C46CB2E391F5DD5) /* 259 */,
CONST64(0xD932ADDBC9B79434) /* 260 */, CONST64(0x08EA70E42015AFF5) /* 261 */,
CONST64(0xD765A6673E478CF1) /* 262 */, CONST64(0xC4FB757EAB278D99) /* 263 */,
CONST64(0xDF11C6862D6E0692) /* 264 */, CONST64(0xDDEB84F10D7F3B16) /* 265 */,
CONST64(0x6F2EF604A665EA04) /* 266 */, CONST64(0x4A8E0F0FF0E0DFB3) /* 267 */,
CONST64(0xA5EDEEF83DBCBA51) /* 268 */, CONST64(0xFC4F0A2A0EA4371E) /* 269 */,
CONST64(0xE83E1DA85CB38429) /* 270 */, CONST64(0xDC8FF882BA1B1CE2) /* 271 */,
CONST64(0xCD45505E8353E80D) /* 272 */, CONST64(0x18D19A00D4DB0717) /* 273 */,
CONST64(0x34A0CFEDA5F38101) /* 274 */, CONST64(0x0BE77E518887CAF2) /* 275 */,
CONST64(0x1E341438B3C45136) /* 276 */, CONST64(0xE05797F49089CCF9) /* 277 */,
CONST64(0xFFD23F9DF2591D14) /* 278 */, CONST64(0x543DDA228595C5CD) /* 279 */,
CONST64(0x661F81FD99052A33) /* 280 */, CONST64(0x8736E641DB0F7B76) /* 281 */,
CONST64(0x15227725418E5307) /* 282 */, CONST64(0xE25F7F46162EB2FA) /* 283 */,
CONST64(0x48A8B2126C13D9FE) /* 284 */, CONST64(0xAFDC541792E76EEA) /* 285 */,
CONST64(0x03D912BFC6D1898F) /* 286 */, CONST64(0x31B1AAFA1B83F51B) /* 287 */,
CONST64(0xF1AC2796E42AB7D9) /* 288 */, CONST64(0x40A3A7D7FCD2EBAC) /* 289 */,
CONST64(0x1056136D0AFBBCC5) /* 290 */, CONST64(0x7889E1DD9A6D0C85) /* 291 */,
CONST64(0xD33525782A7974AA) /* 292 */, CONST64(0xA7E25D09078AC09B) /* 293 */,
CONST64(0xBD4138B3EAC6EDD0) /* 294 */, CONST64(0x920ABFBE71EB9E70) /* 295 */,
CONST64(0xA2A5D0F54FC2625C) /* 296 */, CONST64(0xC054E36B0B1290A3) /* 297 */,
CONST64(0xF6DD59FF62FE932B) /* 298 */, CONST64(0x3537354511A8AC7D) /* 299 */,
CONST64(0xCA845E9172FADCD4) /* 300 */, CONST64(0x84F82B60329D20DC) /* 301 */,
CONST64(0x79C62CE1CD672F18) /* 302 */, CONST64(0x8B09A2ADD124642C) /* 303 */,
CONST64(0xD0C1E96A19D9E726) /* 304 */, CONST64(0x5A786A9B4BA9500C) /* 305 */,
CONST64(0x0E020336634C43F3) /* 306 */, CONST64(0xC17B474AEB66D822) /* 307 */,
CONST64(0x6A731AE3EC9BAAC2) /* 308 */, CONST64(0x8226667AE0840258) /* 309 */,
CONST64(0x67D4567691CAECA5) /* 310 */, CONST64(0x1D94155C4875ADB5) /* 311 */,
CONST64(0x6D00FD985B813FDF) /* 312 */, CONST64(0x51286EFCB774CD06) /* 313 */,
CONST64(0x5E8834471FA744AF) /* 314 */, CONST64(0xF72CA0AEE761AE2E) /* 315 */,
CONST64(0xBE40E4CDAEE8E09A) /* 316 */, CONST64(0xE9970BBB5118F665) /* 317 */,
CONST64(0x726E4BEB33DF1964) /* 318 */, CONST64(0x703B000729199762) /* 319 */,
CONST64(0x4631D816F5EF30A7) /* 320 */, CONST64(0xB880B5B51504A6BE) /* 321 */,
CONST64(0x641793C37ED84B6C) /* 322 */, CONST64(0x7B21ED77F6E97D96) /* 323 */,
CONST64(0x776306312EF96B73) /* 324 */, CONST64(0xAE528948E86FF3F4) /* 325 */,
CONST64(0x53DBD7F286A3F8F8) /* 326 */, CONST64(0x16CADCE74CFC1063) /* 327 */,
CONST64(0x005C19BDFA52C6DD) /* 328 */, CONST64(0x68868F5D64D46AD3) /* 329 */,
CONST64(0x3A9D512CCF1E186A) /* 330 */, CONST64(0x367E62C2385660AE) /* 331 */,
CONST64(0xE359E7EA77DCB1D7) /* 332 */, CONST64(0x526C0773749ABE6E) /* 333 */,
CONST64(0x735AE5F9D09F734B) /* 334 */, CONST64(0x493FC7CC8A558BA8) /* 335 */,
CONST64(0xB0B9C1533041AB45) /* 336 */, CONST64(0x321958BA470A59BD) /* 337 */,
CONST64(0x852DB00B5F46C393) /* 338 */, CONST64(0x91209B2BD336B0E5) /* 339 */,
CONST64(0x6E604F7D659EF19F) /* 340 */, CONST64(0xB99A8AE2782CCB24) /* 341 */,
CONST64(0xCCF52AB6C814C4C7) /* 342 */, CONST64(0x4727D9AFBE11727B) /* 343 */,
CONST64(0x7E950D0C0121B34D) /* 344 */, CONST64(0x756F435670AD471F) /* 345 */,
CONST64(0xF5ADD442615A6849) /* 346 */, CONST64(0x4E87E09980B9957A) /* 347 */,
CONST64(0x2ACFA1DF50AEE355) /* 348 */, CONST64(0xD898263AFD2FD556) /* 349 */,
CONST64(0xC8F4924DD80C8FD6) /* 350 */, CONST64(0xCF99CA3D754A173A) /* 351 */,
CONST64(0xFE477BACAF91BF3C) /* 352 */, CONST64(0xED5371F6D690C12D) /* 353 */,
CONST64(0x831A5C285E687094) /* 354 */, CONST64(0xC5D3C90A3708A0A4) /* 355 */,
CONST64(0x0F7F903717D06580) /* 356 */, CONST64(0x19F9BB13B8FDF27F) /* 357 */,
CONST64(0xB1BD6F1B4D502843) /* 358 */, CONST64(0x1C761BA38FFF4012) /* 359 */,
CONST64(0x0D1530C4E2E21F3B) /* 360 */, CONST64(0x8943CE69A7372C8A) /* 361 */,
CONST64(0xE5184E11FEB5CE66) /* 362 */, CONST64(0x618BDB80BD736621) /* 363 */,
CONST64(0x7D29BAD68B574D0B) /* 364 */, CONST64(0x81BB613E25E6FE5B) /* 365 */,
CONST64(0x071C9C10BC07913F) /* 366 */, CONST64(0xC7BEEB7909AC2D97) /* 367 */,
CONST64(0xC3E58D353BC5D757) /* 368 */, CONST64(0xEB017892F38F61E8) /* 369 */,
CONST64(0xD4EFFB9C9B1CC21A) /* 370 */, CONST64(0x99727D26F494F7AB) /* 371 */,
CONST64(0xA3E063A2956B3E03) /* 372 */, CONST64(0x9D4A8B9A4AA09C30) /* 373 */,
CONST64(0x3F6AB7D500090FB4) /* 374 */, CONST64(0x9CC0F2A057268AC0) /* 375 */,
CONST64(0x3DEE9D2DEDBF42D1) /* 376 */, CONST64(0x330F49C87960A972) /* 377 */,
CONST64(0xC6B2720287421B41) /* 378 */, CONST64(0x0AC59EC07C00369C) /* 379 */,
CONST64(0xEF4EAC49CB353425) /* 380 */, CONST64(0xF450244EEF0129D8) /* 381 */,
CONST64(0x8ACC46E5CAF4DEB6) /* 382 */, CONST64(0x2FFEAB63989263F7) /* 383 */,
CONST64(0x8F7CB9FE5D7A4578) /* 384 */, CONST64(0x5BD8F7644E634635) /* 385 */,
CONST64(0x427A7315BF2DC900) /* 386 */, CONST64(0x17D0C4AA2125261C) /* 387 */,
CONST64(0x3992486C93518E50) /* 388 */, CONST64(0xB4CBFEE0A2D7D4C3) /* 389 */,
CONST64(0x7C75D6202C5DDD8D) /* 390 */, CONST64(0xDBC295D8E35B6C61) /* 391 */,
CONST64(0x60B369D302032B19) /* 392 */, CONST64(0xCE42685FDCE44132) /* 393 */,
CONST64(0x06F3DDB9DDF65610) /* 394 */, CONST64(0x8EA4D21DB5E148F0) /* 395 */,
CONST64(0x20B0FCE62FCD496F) /* 396 */, CONST64(0x2C1B912358B0EE31) /* 397 */,
CONST64(0xB28317B818F5A308) /* 398 */, CONST64(0xA89C1E189CA6D2CF) /* 399 */,
CONST64(0x0C6B18576AAADBC8) /* 400 */, CONST64(0xB65DEAA91299FAE3) /* 401 */,
CONST64(0xFB2B794B7F1027E7) /* 402 */, CONST64(0x04E4317F443B5BEB) /* 403 */,
CONST64(0x4B852D325939D0A6) /* 404 */, CONST64(0xD5AE6BEEFB207FFC) /* 405 */,
CONST64(0x309682B281C7D374) /* 406 */, CONST64(0xBAE309A194C3B475) /* 407 */,
CONST64(0x8CC3F97B13B49F05) /* 408 */, CONST64(0x98A9422FF8293967) /* 409 */,
CONST64(0x244B16B01076FF7C) /* 410 */, CONST64(0xF8BF571C663D67EE) /* 411 */,
CONST64(0x1F0D6758EEE30DA1) /* 412 */, CONST64(0xC9B611D97ADEB9B7) /* 413 */,
CONST64(0xB7AFD5887B6C57A2) /* 414 */, CONST64(0x6290AE846B984FE1) /* 415 */,
CONST64(0x94DF4CDEACC1A5FD) /* 416 */, CONST64(0x058A5BD1C5483AFF) /* 417 */,
CONST64(0x63166CC142BA3C37) /* 418 */, CONST64(0x8DB8526EB2F76F40) /* 419 */,
CONST64(0xE10880036F0D6D4E) /* 420 */, CONST64(0x9E0523C9971D311D) /* 421 */,
CONST64(0x45EC2824CC7CD691) /* 422 */, CONST64(0x575B8359E62382C9) /* 423 */,
CONST64(0xFA9E400DC4889995) /* 424 */, CONST64(0xD1823ECB45721568) /* 425 */,
CONST64(0xDAFD983B8206082F) /* 426 */, CONST64(0xAA7D29082386A8CB) /* 427 */,
CONST64(0x269FCD4403B87588) /* 428 */, CONST64(0x1B91F5F728BDD1E0) /* 429 */,
CONST64(0xE4669F39040201F6) /* 430 */, CONST64(0x7A1D7C218CF04ADE) /* 431 */,
CONST64(0x65623C29D79CE5CE) /* 432 */, CONST64(0x2368449096C00BB1) /* 433 */,
CONST64(0xAB9BF1879DA503BA) /* 434 */, CONST64(0xBC23ECB1A458058E) /* 435 */,
CONST64(0x9A58DF01BB401ECC) /* 436 */, CONST64(0xA070E868A85F143D) /* 437 */,
CONST64(0x4FF188307DF2239E) /* 438 */, CONST64(0x14D565B41A641183) /* 439 */,
CONST64(0xEE13337452701602) /* 440 */, CONST64(0x950E3DCF3F285E09) /* 441 */,
CONST64(0x59930254B9C80953) /* 442 */, CONST64(0x3BF299408930DA6D) /* 443 */,
CONST64(0xA955943F53691387) /* 444 */, CONST64(0xA15EDECAA9CB8784) /* 445 */,
CONST64(0x29142127352BE9A0) /* 446 */, CONST64(0x76F0371FFF4E7AFB) /* 447 */,
CONST64(0x0239F450274F2228) /* 448 */, CONST64(0xBB073AF01D5E868B) /* 449 */,
CONST64(0xBFC80571C10E96C1) /* 450 */, CONST64(0xD267088568222E23) /* 451 */,
CONST64(0x9671A3D48E80B5B0) /* 452 */, CONST64(0x55B5D38AE193BB81) /* 453 */,
CONST64(0x693AE2D0A18B04B8) /* 454 */, CONST64(0x5C48B4ECADD5335F) /* 455 */,
CONST64(0xFD743B194916A1CA) /* 456 */, CONST64(0x2577018134BE98C4) /* 457 */,
CONST64(0xE77987E83C54A4AD) /* 458 */, CONST64(0x28E11014DA33E1B9) /* 459 */,
CONST64(0x270CC59E226AA213) /* 460 */, CONST64(0x71495F756D1A5F60) /* 461 */,
CONST64(0x9BE853FB60AFEF77) /* 462 */, CONST64(0xADC786A7F7443DBF) /* 463 */,
CONST64(0x0904456173B29A82) /* 464 */, CONST64(0x58BC7A66C232BD5E) /* 465 */,
CONST64(0xF306558C673AC8B2) /* 466 */, CONST64(0x41F639C6B6C9772A) /* 467 */,
CONST64(0x216DEFE99FDA35DA) /* 468 */, CONST64(0x11640CC71C7BE615) /* 469 */,
CONST64(0x93C43694565C5527) /* 470 */, CONST64(0xEA038E6246777839) /* 471 */,
CONST64(0xF9ABF3CE5A3E2469) /* 472 */, CONST64(0x741E768D0FD312D2) /* 473 */,
CONST64(0x0144B883CED652C6) /* 474 */, CONST64(0xC20B5A5BA33F8552) /* 475 */,
CONST64(0x1AE69633C3435A9D) /* 476 */, CONST64(0x97A28CA4088CFDEC) /* 477 */,
CONST64(0x8824A43C1E96F420) /* 478 */, CONST64(0x37612FA66EEEA746) /* 479 */,
CONST64(0x6B4CB165F9CF0E5A) /* 480 */, CONST64(0x43AA1C06A0ABFB4A) /* 481 */,
CONST64(0x7F4DC26FF162796B) /* 482 */, CONST64(0x6CBACC8E54ED9B0F) /* 483 */,
CONST64(0xA6B7FFEFD2BB253E) /* 484 */, CONST64(0x2E25BC95B0A29D4F) /* 485 */,
CONST64(0x86D6A58BDEF1388C) /* 486 */, CONST64(0xDED74AC576B6F054) /* 487 */,
CONST64(0x8030BDBC2B45805D) /* 488 */, CONST64(0x3C81AF70E94D9289) /* 489 */,
CONST64(0x3EFF6DDA9E3100DB) /* 490 */, CONST64(0xB38DC39FDFCC8847) /* 491 */,
CONST64(0x123885528D17B87E) /* 492 */, CONST64(0xF2DA0ED240B1B642) /* 493 */,
CONST64(0x44CEFADCD54BF9A9) /* 494 */, CONST64(0x1312200E433C7EE6) /* 495 */,
CONST64(0x9FFCC84F3A78C748) /* 496 */, CONST64(0xF0CD1F72248576BB) /* 497 */,
CONST64(0xEC6974053638CFE4) /* 498 */, CONST64(0x2BA7B67C0CEC4E4C) /* 499 */,
CONST64(0xAC2F4DF3E5CE32ED) /* 500 */, CONST64(0xCB33D14326EA4C11) /* 501 */,
CONST64(0xA4E9044CC77E58BC) /* 502 */, CONST64(0x5F513293D934FCEF) /* 503 */,
CONST64(0x5DC9645506E55444) /* 504 */, CONST64(0x50DE418F317DE40A) /* 505 */,
CONST64(0x388CB31A69DDE259) /* 506 */, CONST64(0x2DB4A83455820A86) /* 507 */,
CONST64(0x9010A91E84711AE9) /* 508 */, CONST64(0x4DF7F0B7B1498371) /* 509 */,
CONST64(0xD62A2EABC0977179) /* 510 */, CONST64(0x22FAC097AA8D5C0E) /* 511 */,
CONST64(0xF49FCC2FF1DAF39B) /* 512 */, CONST64(0x487FD5C66FF29281) /* 513 */,
CONST64(0xE8A30667FCDCA83F) /* 514 */, CONST64(0x2C9B4BE3D2FCCE63) /* 515 */,
CONST64(0xDA3FF74B93FBBBC2) /* 516 */, CONST64(0x2FA165D2FE70BA66) /* 517 */,
CONST64(0xA103E279970E93D4) /* 518 */, CONST64(0xBECDEC77B0E45E71) /* 519 */,
CONST64(0xCFB41E723985E497) /* 520 */, CONST64(0xB70AAA025EF75017) /* 521 */,
CONST64(0xD42309F03840B8E0) /* 522 */, CONST64(0x8EFC1AD035898579) /* 523 */,
CONST64(0x96C6920BE2B2ABC5) /* 524 */, CONST64(0x66AF4163375A9172) /* 525 */,
CONST64(0x2174ABDCCA7127FB) /* 526 */, CONST64(0xB33CCEA64A72FF41) /* 527 */,
CONST64(0xF04A4933083066A5) /* 528 */, CONST64(0x8D970ACDD7289AF5) /* 529 */,
CONST64(0x8F96E8E031C8C25E) /* 530 */, CONST64(0xF3FEC02276875D47) /* 531 */,
CONST64(0xEC7BF310056190DD) /* 532 */, CONST64(0xF5ADB0AEBB0F1491) /* 533 */,
CONST64(0x9B50F8850FD58892) /* 534 */, CONST64(0x4975488358B74DE8) /* 535 */,
CONST64(0xA3354FF691531C61) /* 536 */, CONST64(0x0702BBE481D2C6EE) /* 537 */,
CONST64(0x89FB24057DEDED98) /* 538 */, CONST64(0xAC3075138596E902) /* 539 */,
CONST64(0x1D2D3580172772ED) /* 540 */, CONST64(0xEB738FC28E6BC30D) /* 541 */,
CONST64(0x5854EF8F63044326) /* 542 */, CONST64(0x9E5C52325ADD3BBE) /* 543 */,
CONST64(0x90AA53CF325C4623) /* 544 */, CONST64(0xC1D24D51349DD067) /* 545 */,
CONST64(0x2051CFEEA69EA624) /* 546 */, CONST64(0x13220F0A862E7E4F) /* 547 */,
CONST64(0xCE39399404E04864) /* 548 */, CONST64(0xD9C42CA47086FCB7) /* 549 */,
CONST64(0x685AD2238A03E7CC) /* 550 */, CONST64(0x066484B2AB2FF1DB) /* 551 */,
CONST64(0xFE9D5D70EFBF79EC) /* 552 */, CONST64(0x5B13B9DD9C481854) /* 553 */,
CONST64(0x15F0D475ED1509AD) /* 554 */, CONST64(0x0BEBCD060EC79851) /* 555 */,
CONST64(0xD58C6791183AB7F8) /* 556 */, CONST64(0xD1187C5052F3EEE4) /* 557 */,
CONST64(0xC95D1192E54E82FF) /* 558 */, CONST64(0x86EEA14CB9AC6CA2) /* 559 */,
CONST64(0x3485BEB153677D5D) /* 560 */, CONST64(0xDD191D781F8C492A) /* 561 */,
CONST64(0xF60866BAA784EBF9) /* 562 */, CONST64(0x518F643BA2D08C74) /* 563 */,
CONST64(0x8852E956E1087C22) /* 564 */, CONST64(0xA768CB8DC410AE8D) /* 565 */,
CONST64(0x38047726BFEC8E1A) /* 566 */, CONST64(0xA67738B4CD3B45AA) /* 567 */,
CONST64(0xAD16691CEC0DDE19) /* 568 */, CONST64(0xC6D4319380462E07) /* 569 */,
CONST64(0xC5A5876D0BA61938) /* 570 */, CONST64(0x16B9FA1FA58FD840) /* 571 */,
CONST64(0x188AB1173CA74F18) /* 572 */, CONST64(0xABDA2F98C99C021F) /* 573 */,
CONST64(0x3E0580AB134AE816) /* 574 */, CONST64(0x5F3B05B773645ABB) /* 575 */,
CONST64(0x2501A2BE5575F2F6) /* 576 */, CONST64(0x1B2F74004E7E8BA9) /* 577 */,
CONST64(0x1CD7580371E8D953) /* 578 */, CONST64(0x7F6ED89562764E30) /* 579 */,
CONST64(0xB15926FF596F003D) /* 580 */, CONST64(0x9F65293DA8C5D6B9) /* 581 */,
CONST64(0x6ECEF04DD690F84C) /* 582 */, CONST64(0x4782275FFF33AF88) /* 583 */,
CONST64(0xE41433083F820801) /* 584 */, CONST64(0xFD0DFE409A1AF9B5) /* 585 */,
CONST64(0x4325A3342CDB396B) /* 586 */, CONST64(0x8AE77E62B301B252) /* 587 */,
CONST64(0xC36F9E9F6655615A) /* 588 */, CONST64(0x85455A2D92D32C09) /* 589 */,
CONST64(0xF2C7DEA949477485) /* 590 */, CONST64(0x63CFB4C133A39EBA) /* 591 */,
CONST64(0x83B040CC6EBC5462) /* 592 */, CONST64(0x3B9454C8FDB326B0) /* 593 */,
CONST64(0x56F56A9E87FFD78C) /* 594 */, CONST64(0x2DC2940D99F42BC6) /* 595 */,
CONST64(0x98F7DF096B096E2D) /* 596 */, CONST64(0x19A6E01E3AD852BF) /* 597 */,
CONST64(0x42A99CCBDBD4B40B) /* 598 */, CONST64(0xA59998AF45E9C559) /* 599 */,
CONST64(0x366295E807D93186) /* 600 */, CONST64(0x6B48181BFAA1F773) /* 601 */,
CONST64(0x1FEC57E2157A0A1D) /* 602 */, CONST64(0x4667446AF6201AD5) /* 603 */,
CONST64(0xE615EBCACFB0F075) /* 604 */, CONST64(0xB8F31F4F68290778) /* 605 */,
CONST64(0x22713ED6CE22D11E) /* 606 */, CONST64(0x3057C1A72EC3C93B) /* 607 */,
CONST64(0xCB46ACC37C3F1F2F) /* 608 */, CONST64(0xDBB893FD02AAF50E) /* 609 */,
CONST64(0x331FD92E600B9FCF) /* 610 */, CONST64(0xA498F96148EA3AD6) /* 611 */,
CONST64(0xA8D8426E8B6A83EA) /* 612 */, CONST64(0xA089B274B7735CDC) /* 613 */,
CONST64(0x87F6B3731E524A11) /* 614 */, CONST64(0x118808E5CBC96749) /* 615 */,
CONST64(0x9906E4C7B19BD394) /* 616 */, CONST64(0xAFED7F7E9B24A20C) /* 617 */,
CONST64(0x6509EADEEB3644A7) /* 618 */, CONST64(0x6C1EF1D3E8EF0EDE) /* 619 */,
CONST64(0xB9C97D43E9798FB4) /* 620 */, CONST64(0xA2F2D784740C28A3) /* 621 */,
CONST64(0x7B8496476197566F) /* 622 */, CONST64(0x7A5BE3E6B65F069D) /* 623 */,
CONST64(0xF96330ED78BE6F10) /* 624 */, CONST64(0xEEE60DE77A076A15) /* 625 */,
CONST64(0x2B4BEE4AA08B9BD0) /* 626 */, CONST64(0x6A56A63EC7B8894E) /* 627 */,
CONST64(0x02121359BA34FEF4) /* 628 */, CONST64(0x4CBF99F8283703FC) /* 629 */,
CONST64(0x398071350CAF30C8) /* 630 */, CONST64(0xD0A77A89F017687A) /* 631 */,
CONST64(0xF1C1A9EB9E423569) /* 632 */, CONST64(0x8C7976282DEE8199) /* 633 */,
CONST64(0x5D1737A5DD1F7ABD) /* 634 */, CONST64(0x4F53433C09A9FA80) /* 635 */,
CONST64(0xFA8B0C53DF7CA1D9) /* 636 */, CONST64(0x3FD9DCBC886CCB77) /* 637 */,
CONST64(0xC040917CA91B4720) /* 638 */, CONST64(0x7DD00142F9D1DCDF) /* 639 */,
CONST64(0x8476FC1D4F387B58) /* 640 */, CONST64(0x23F8E7C5F3316503) /* 641 */,
CONST64(0x032A2244E7E37339) /* 642 */, CONST64(0x5C87A5D750F5A74B) /* 643 */,
CONST64(0x082B4CC43698992E) /* 644 */, CONST64(0xDF917BECB858F63C) /* 645 */,
CONST64(0x3270B8FC5BF86DDA) /* 646 */, CONST64(0x10AE72BB29B5DD76) /* 647 */,
CONST64(0x576AC94E7700362B) /* 648 */, CONST64(0x1AD112DAC61EFB8F) /* 649 */,
CONST64(0x691BC30EC5FAA427) /* 650 */, CONST64(0xFF246311CC327143) /* 651 */,
CONST64(0x3142368E30E53206) /* 652 */, CONST64(0x71380E31E02CA396) /* 653 */,
CONST64(0x958D5C960AAD76F1) /* 654 */, CONST64(0xF8D6F430C16DA536) /* 655 */,
CONST64(0xC8FFD13F1BE7E1D2) /* 656 */, CONST64(0x7578AE66004DDBE1) /* 657 */,
CONST64(0x05833F01067BE646) /* 658 */, CONST64(0xBB34B5AD3BFE586D) /* 659 */,
CONST64(0x095F34C9A12B97F0) /* 660 */, CONST64(0x247AB64525D60CA8) /* 661 */,
CONST64(0xDCDBC6F3017477D1) /* 662 */, CONST64(0x4A2E14D4DECAD24D) /* 663 */,
CONST64(0xBDB5E6D9BE0A1EEB) /* 664 */, CONST64(0x2A7E70F7794301AB) /* 665 */,
CONST64(0xDEF42D8A270540FD) /* 666 */, CONST64(0x01078EC0A34C22C1) /* 667 */,
CONST64(0xE5DE511AF4C16387) /* 668 */, CONST64(0x7EBB3A52BD9A330A) /* 669 */,
CONST64(0x77697857AA7D6435) /* 670 */, CONST64(0x004E831603AE4C32) /* 671 */,
CONST64(0xE7A21020AD78E312) /* 672 */, CONST64(0x9D41A70C6AB420F2) /* 673 */,
CONST64(0x28E06C18EA1141E6) /* 674 */, CONST64(0xD2B28CBD984F6B28) /* 675 */,
CONST64(0x26B75F6C446E9D83) /* 676 */, CONST64(0xBA47568C4D418D7F) /* 677 */,
CONST64(0xD80BADBFE6183D8E) /* 678 */, CONST64(0x0E206D7F5F166044) /* 679 */,
CONST64(0xE258A43911CBCA3E) /* 680 */, CONST64(0x723A1746B21DC0BC) /* 681 */,
CONST64(0xC7CAA854F5D7CDD3) /* 682 */, CONST64(0x7CAC32883D261D9C) /* 683 */,
CONST64(0x7690C26423BA942C) /* 684 */, CONST64(0x17E55524478042B8) /* 685 */,
CONST64(0xE0BE477656A2389F) /* 686 */, CONST64(0x4D289B5E67AB2DA0) /* 687 */,
CONST64(0x44862B9C8FBBFD31) /* 688 */, CONST64(0xB47CC8049D141365) /* 689 */,
CONST64(0x822C1B362B91C793) /* 690 */, CONST64(0x4EB14655FB13DFD8) /* 691 */,
CONST64(0x1ECBBA0714E2A97B) /* 692 */, CONST64(0x6143459D5CDE5F14) /* 693 */,
CONST64(0x53A8FBF1D5F0AC89) /* 694 */, CONST64(0x97EA04D81C5E5B00) /* 695 */,
CONST64(0x622181A8D4FDB3F3) /* 696 */, CONST64(0xE9BCD341572A1208) /* 697 */,
CONST64(0x1411258643CCE58A) /* 698 */, CONST64(0x9144C5FEA4C6E0A4) /* 699 */,
CONST64(0x0D33D06565CF620F) /* 700 */, CONST64(0x54A48D489F219CA1) /* 701 */,
CONST64(0xC43E5EAC6D63C821) /* 702 */, CONST64(0xA9728B3A72770DAF) /* 703 */,
CONST64(0xD7934E7B20DF87EF) /* 704 */, CONST64(0xE35503B61A3E86E5) /* 705 */,
CONST64(0xCAE321FBC819D504) /* 706 */, CONST64(0x129A50B3AC60BFA6) /* 707 */,
CONST64(0xCD5E68EA7E9FB6C3) /* 708 */, CONST64(0xB01C90199483B1C7) /* 709 */,
CONST64(0x3DE93CD5C295376C) /* 710 */, CONST64(0xAED52EDF2AB9AD13) /* 711 */,
CONST64(0x2E60F512C0A07884) /* 712 */, CONST64(0xBC3D86A3E36210C9) /* 713 */,
CONST64(0x35269D9B163951CE) /* 714 */, CONST64(0x0C7D6E2AD0CDB5FA) /* 715 */,
CONST64(0x59E86297D87F5733) /* 716 */, CONST64(0x298EF221898DB0E7) /* 717 */,
CONST64(0x55000029D1A5AA7E) /* 718 */, CONST64(0x8BC08AE1B5061B45) /* 719 */,
CONST64(0xC2C31C2B6C92703A) /* 720 */, CONST64(0x94CC596BAF25EF42) /* 721 */,
CONST64(0x0A1D73DB22540456) /* 722 */, CONST64(0x04B6A0F9D9C4179A) /* 723 */,
CONST64(0xEFFDAFA2AE3D3C60) /* 724 */, CONST64(0xF7C8075BB49496C4) /* 725 */,
CONST64(0x9CC5C7141D1CD4E3) /* 726 */, CONST64(0x78BD1638218E5534) /* 727 */,
CONST64(0xB2F11568F850246A) /* 728 */, CONST64(0xEDFABCFA9502BC29) /* 729 */,
CONST64(0x796CE5F2DA23051B) /* 730 */, CONST64(0xAAE128B0DC93537C) /* 731 */,
CONST64(0x3A493DA0EE4B29AE) /* 732 */, CONST64(0xB5DF6B2C416895D7) /* 733 */,
CONST64(0xFCABBD25122D7F37) /* 734 */, CONST64(0x70810B58105DC4B1) /* 735 */,
CONST64(0xE10FDD37F7882A90) /* 736 */, CONST64(0x524DCAB5518A3F5C) /* 737 */,
CONST64(0x3C9E85878451255B) /* 738 */, CONST64(0x4029828119BD34E2) /* 739 */,
CONST64(0x74A05B6F5D3CECCB) /* 740 */, CONST64(0xB610021542E13ECA) /* 741 */,
CONST64(0x0FF979D12F59E2AC) /* 742 */, CONST64(0x6037DA27E4F9CC50) /* 743 */,
CONST64(0x5E92975A0DF1847D) /* 744 */, CONST64(0xD66DE190D3E623FE) /* 745 */,
CONST64(0x5032D6B87B568048) /* 746 */, CONST64(0x9A36B7CE8235216E) /* 747 */,
CONST64(0x80272A7A24F64B4A) /* 748 */, CONST64(0x93EFED8B8C6916F7) /* 749 */,
CONST64(0x37DDBFF44CCE1555) /* 750 */, CONST64(0x4B95DB5D4B99BD25) /* 751 */,
CONST64(0x92D3FDA169812FC0) /* 752 */, CONST64(0xFB1A4A9A90660BB6) /* 753 */,
CONST64(0x730C196946A4B9B2) /* 754 */, CONST64(0x81E289AA7F49DA68) /* 755 */,
CONST64(0x64669A0F83B1A05F) /* 756 */, CONST64(0x27B3FF7D9644F48B) /* 757 */,
CONST64(0xCC6B615C8DB675B3) /* 758 */, CONST64(0x674F20B9BCEBBE95) /* 759 */,
CONST64(0x6F31238275655982) /* 760 */, CONST64(0x5AE488713E45CF05) /* 761 */,
CONST64(0xBF619F9954C21157) /* 762 */, CONST64(0xEABAC46040A8EAE9) /* 763 */,
CONST64(0x454C6FE9F2C0C1CD) /* 764 */, CONST64(0x419CF6496412691C) /* 765 */,
CONST64(0xD3DC3BEF265B0F70) /* 766 */, CONST64(0x6D0E60F5C3578A9E) /* 767 */,
CONST64(0x5B0E608526323C55) /* 768 */, CONST64(0x1A46C1A9FA1B59F5) /* 769 */,
CONST64(0xA9E245A17C4C8FFA) /* 770 */, CONST64(0x65CA5159DB2955D7) /* 771 */,
CONST64(0x05DB0A76CE35AFC2) /* 772 */, CONST64(0x81EAC77EA9113D45) /* 773 */,
CONST64(0x528EF88AB6AC0A0D) /* 774 */, CONST64(0xA09EA253597BE3FF) /* 775 */,
CONST64(0x430DDFB3AC48CD56) /* 776 */, CONST64(0xC4B3A67AF45CE46F) /* 777 */,
CONST64(0x4ECECFD8FBE2D05E) /* 778 */, CONST64(0x3EF56F10B39935F0) /* 779 */,
CONST64(0x0B22D6829CD619C6) /* 780 */, CONST64(0x17FD460A74DF2069) /* 781 */,
CONST64(0x6CF8CC8E8510ED40) /* 782 */, CONST64(0xD6C824BF3A6ECAA7) /* 783 */,
CONST64(0x61243D581A817049) /* 784 */, CONST64(0x048BACB6BBC163A2) /* 785 */,
CONST64(0xD9A38AC27D44CC32) /* 786 */, CONST64(0x7FDDFF5BAAF410AB) /* 787 */,
CONST64(0xAD6D495AA804824B) /* 788 */, CONST64(0xE1A6A74F2D8C9F94) /* 789 */,
CONST64(0xD4F7851235DEE8E3) /* 790 */, CONST64(0xFD4B7F886540D893) /* 791 */,
CONST64(0x247C20042AA4BFDA) /* 792 */, CONST64(0x096EA1C517D1327C) /* 793 */,
CONST64(0xD56966B4361A6685) /* 794 */, CONST64(0x277DA5C31221057D) /* 795 */,
CONST64(0x94D59893A43ACFF7) /* 796 */, CONST64(0x64F0C51CCDC02281) /* 797 */,
CONST64(0x3D33BCC4FF6189DB) /* 798 */, CONST64(0xE005CB184CE66AF1) /* 799 */,
CONST64(0xFF5CCD1D1DB99BEA) /* 800 */, CONST64(0xB0B854A7FE42980F) /* 801 */,
CONST64(0x7BD46A6A718D4B9F) /* 802 */, CONST64(0xD10FA8CC22A5FD8C) /* 803 */,
CONST64(0xD31484952BE4BD31) /* 804 */, CONST64(0xC7FA975FCB243847) /* 805 */,
CONST64(0x4886ED1E5846C407) /* 806 */, CONST64(0x28CDDB791EB70B04) /* 807 */,
CONST64(0xC2B00BE2F573417F) /* 808 */, CONST64(0x5C9590452180F877) /* 809 */,
CONST64(0x7A6BDDFFF370EB00) /* 810 */, CONST64(0xCE509E38D6D9D6A4) /* 811 */,
CONST64(0xEBEB0F00647FA702) /* 812 */, CONST64(0x1DCC06CF76606F06) /* 813 */,
CONST64(0xE4D9F28BA286FF0A) /* 814 */, CONST64(0xD85A305DC918C262) /* 815 */,
CONST64(0x475B1D8732225F54) /* 816 */, CONST64(0x2D4FB51668CCB5FE) /* 817 */,
CONST64(0xA679B9D9D72BBA20) /* 818 */, CONST64(0x53841C0D912D43A5) /* 819 */,
CONST64(0x3B7EAA48BF12A4E8) /* 820 */, CONST64(0x781E0E47F22F1DDF) /* 821 */,
CONST64(0xEFF20CE60AB50973) /* 822 */, CONST64(0x20D261D19DFFB742) /* 823 */,
CONST64(0x16A12B03062A2E39) /* 824 */, CONST64(0x1960EB2239650495) /* 825 */,
CONST64(0x251C16FED50EB8B8) /* 826 */, CONST64(0x9AC0C330F826016E) /* 827 */,
CONST64(0xED152665953E7671) /* 828 */, CONST64(0x02D63194A6369570) /* 829 */,
CONST64(0x5074F08394B1C987) /* 830 */, CONST64(0x70BA598C90B25CE1) /* 831 */,
CONST64(0x794A15810B9742F6) /* 832 */, CONST64(0x0D5925E9FCAF8C6C) /* 833 */,
CONST64(0x3067716CD868744E) /* 834 */, CONST64(0x910AB077E8D7731B) /* 835 */,
CONST64(0x6A61BBDB5AC42F61) /* 836 */, CONST64(0x93513EFBF0851567) /* 837 */,
CONST64(0xF494724B9E83E9D5) /* 838 */, CONST64(0xE887E1985C09648D) /* 839 */,
CONST64(0x34B1D3C675370CFD) /* 840 */, CONST64(0xDC35E433BC0D255D) /* 841 */,
CONST64(0xD0AAB84234131BE0) /* 842 */, CONST64(0x08042A50B48B7EAF) /* 843 */,
CONST64(0x9997C4EE44A3AB35) /* 844 */, CONST64(0x829A7B49201799D0) /* 845 */,
CONST64(0x263B8307B7C54441) /* 846 */, CONST64(0x752F95F4FD6A6CA6) /* 847 */,
CONST64(0x927217402C08C6E5) /* 848 */, CONST64(0x2A8AB754A795D9EE) /* 849 */,
CONST64(0xA442F7552F72943D) /* 850 */, CONST64(0x2C31334E19781208) /* 851 */,
CONST64(0x4FA98D7CEAEE6291) /* 852 */, CONST64(0x55C3862F665DB309) /* 853 */,
CONST64(0xBD0610175D53B1F3) /* 854 */, CONST64(0x46FE6CB840413F27) /* 855 */,
CONST64(0x3FE03792DF0CFA59) /* 856 */, CONST64(0xCFE700372EB85E8F) /* 857 */,
CONST64(0xA7BE29E7ADBCE118) /* 858 */, CONST64(0xE544EE5CDE8431DD) /* 859 */,
CONST64(0x8A781B1B41F1873E) /* 860 */, CONST64(0xA5C94C78A0D2F0E7) /* 861 */,
CONST64(0x39412E2877B60728) /* 862 */, CONST64(0xA1265EF3AFC9A62C) /* 863 */,
CONST64(0xBCC2770C6A2506C5) /* 864 */, CONST64(0x3AB66DD5DCE1CE12) /* 865 */,
CONST64(0xE65499D04A675B37) /* 866 */, CONST64(0x7D8F523481BFD216) /* 867 */,
CONST64(0x0F6F64FCEC15F389) /* 868 */, CONST64(0x74EFBE618B5B13C8) /* 869 */,
CONST64(0xACDC82B714273E1D) /* 870 */, CONST64(0xDD40BFE003199D17) /* 871 */,
CONST64(0x37E99257E7E061F8) /* 872 */, CONST64(0xFA52626904775AAA) /* 873 */,
CONST64(0x8BBBF63A463D56F9) /* 874 */, CONST64(0xF0013F1543A26E64) /* 875 */,
CONST64(0xA8307E9F879EC898) /* 876 */, CONST64(0xCC4C27A4150177CC) /* 877 */,
CONST64(0x1B432F2CCA1D3348) /* 878 */, CONST64(0xDE1D1F8F9F6FA013) /* 879 */,
CONST64(0x606602A047A7DDD6) /* 880 */, CONST64(0xD237AB64CC1CB2C7) /* 881 */,
CONST64(0x9B938E7225FCD1D3) /* 882 */, CONST64(0xEC4E03708E0FF476) /* 883 */,
CONST64(0xFEB2FBDA3D03C12D) /* 884 */, CONST64(0xAE0BCED2EE43889A) /* 885 */,
CONST64(0x22CB8923EBFB4F43) /* 886 */, CONST64(0x69360D013CF7396D) /* 887 */,
CONST64(0x855E3602D2D4E022) /* 888 */, CONST64(0x073805BAD01F784C) /* 889 */,
CONST64(0x33E17A133852F546) /* 890 */, CONST64(0xDF4874058AC7B638) /* 891 */,
CONST64(0xBA92B29C678AA14A) /* 892 */, CONST64(0x0CE89FC76CFAADCD) /* 893 */,
CONST64(0x5F9D4E0908339E34) /* 894 */, CONST64(0xF1AFE9291F5923B9) /* 895 */,
CONST64(0x6E3480F60F4A265F) /* 896 */, CONST64(0xEEBF3A2AB29B841C) /* 897 */,
CONST64(0xE21938A88F91B4AD) /* 898 */, CONST64(0x57DFEFF845C6D3C3) /* 899 */,
CONST64(0x2F006B0BF62CAAF2) /* 900 */, CONST64(0x62F479EF6F75EE78) /* 901 */,
CONST64(0x11A55AD41C8916A9) /* 902 */, CONST64(0xF229D29084FED453) /* 903 */,
CONST64(0x42F1C27B16B000E6) /* 904 */, CONST64(0x2B1F76749823C074) /* 905 */,
CONST64(0x4B76ECA3C2745360) /* 906 */, CONST64(0x8C98F463B91691BD) /* 907 */,
CONST64(0x14BCC93CF1ADE66A) /* 908 */, CONST64(0x8885213E6D458397) /* 909 */,
CONST64(0x8E177DF0274D4711) /* 910 */, CONST64(0xB49B73B5503F2951) /* 911 */,
CONST64(0x10168168C3F96B6B) /* 912 */, CONST64(0x0E3D963B63CAB0AE) /* 913 */,
CONST64(0x8DFC4B5655A1DB14) /* 914 */, CONST64(0xF789F1356E14DE5C) /* 915 */,
CONST64(0x683E68AF4E51DAC1) /* 916 */, CONST64(0xC9A84F9D8D4B0FD9) /* 917 */,
CONST64(0x3691E03F52A0F9D1) /* 918 */, CONST64(0x5ED86E46E1878E80) /* 919 */,
CONST64(0x3C711A0E99D07150) /* 920 */, CONST64(0x5A0865B20C4E9310) /* 921 */,
CONST64(0x56FBFC1FE4F0682E) /* 922 */, CONST64(0xEA8D5DE3105EDF9B) /* 923 */,
CONST64(0x71ABFDB12379187A) /* 924 */, CONST64(0x2EB99DE1BEE77B9C) /* 925 */,
CONST64(0x21ECC0EA33CF4523) /* 926 */, CONST64(0x59A4D7521805C7A1) /* 927 */,
CONST64(0x3896F5EB56AE7C72) /* 928 */, CONST64(0xAA638F3DB18F75DC) /* 929 */,
CONST64(0x9F39358DABE9808E) /* 930 */, CONST64(0xB7DEFA91C00B72AC) /* 931 */,
CONST64(0x6B5541FD62492D92) /* 932 */, CONST64(0x6DC6DEE8F92E4D5B) /* 933 */,
CONST64(0x353F57ABC4BEEA7E) /* 934 */, CONST64(0x735769D6DA5690CE) /* 935 */,
CONST64(0x0A234AA642391484) /* 936 */, CONST64(0xF6F9508028F80D9D) /* 937 */,
CONST64(0xB8E319A27AB3F215) /* 938 */, CONST64(0x31AD9C1151341A4D) /* 939 */,
CONST64(0x773C22A57BEF5805) /* 940 */, CONST64(0x45C7561A07968633) /* 941 */,
CONST64(0xF913DA9E249DBE36) /* 942 */, CONST64(0xDA652D9B78A64C68) /* 943 */,
CONST64(0x4C27A97F3BC334EF) /* 944 */, CONST64(0x76621220E66B17F4) /* 945 */,
CONST64(0x967743899ACD7D0B) /* 946 */, CONST64(0xF3EE5BCAE0ED6782) /* 947 */,
CONST64(0x409F753600C879FC) /* 948 */, CONST64(0x06D09A39B5926DB6) /* 949 */,
CONST64(0x6F83AEB0317AC588) /* 950 */, CONST64(0x01E6CA4A86381F21) /* 951 */,
CONST64(0x66FF3462D19F3025) /* 952 */, CONST64(0x72207C24DDFD3BFB) /* 953 */,
CONST64(0x4AF6B6D3E2ECE2EB) /* 954 */, CONST64(0x9C994DBEC7EA08DE) /* 955 */,
CONST64(0x49ACE597B09A8BC4) /* 956 */, CONST64(0xB38C4766CF0797BA) /* 957 */,
CONST64(0x131B9373C57C2A75) /* 958 */, CONST64(0xB1822CCE61931E58) /* 959 */,
CONST64(0x9D7555B909BA1C0C) /* 960 */, CONST64(0x127FAFDD937D11D2) /* 961 */,
CONST64(0x29DA3BADC66D92E4) /* 962 */, CONST64(0xA2C1D57154C2ECBC) /* 963 */,
CONST64(0x58C5134D82F6FE24) /* 964 */, CONST64(0x1C3AE3515B62274F) /* 965 */,
CONST64(0xE907C82E01CB8126) /* 966 */, CONST64(0xF8ED091913E37FCB) /* 967 */,
CONST64(0x3249D8F9C80046C9) /* 968 */, CONST64(0x80CF9BEDE388FB63) /* 969 */,
CONST64(0x1881539A116CF19E) /* 970 */, CONST64(0x5103F3F76BD52457) /* 971 */,
CONST64(0x15B7E6F5AE47F7A8) /* 972 */, CONST64(0xDBD7C6DED47E9CCF) /* 973 */,
CONST64(0x44E55C410228BB1A) /* 974 */, CONST64(0xB647D4255EDB4E99) /* 975 */,
CONST64(0x5D11882BB8AAFC30) /* 976 */, CONST64(0xF5098BBB29D3212A) /* 977 */,
CONST64(0x8FB5EA14E90296B3) /* 978 */, CONST64(0x677B942157DD025A) /* 979 */,
CONST64(0xFB58E7C0A390ACB5) /* 980 */, CONST64(0x89D3674C83BD4A01) /* 981 */,
CONST64(0x9E2DA4DF4BF3B93B) /* 982 */, CONST64(0xFCC41E328CAB4829) /* 983 */,
CONST64(0x03F38C96BA582C52) /* 984 */, CONST64(0xCAD1BDBD7FD85DB2) /* 985 */,
CONST64(0xBBB442C16082AE83) /* 986 */, CONST64(0xB95FE86BA5DA9AB0) /* 987 */,
CONST64(0xB22E04673771A93F) /* 988 */, CONST64(0x845358C9493152D8) /* 989 */,
CONST64(0xBE2A488697B4541E) /* 990 */, CONST64(0x95A2DC2DD38E6966) /* 991 */,
CONST64(0xC02C11AC923C852B) /* 992 */, CONST64(0x2388B1990DF2A87B) /* 993 */,
CONST64(0x7C8008FA1B4F37BE) /* 994 */, CONST64(0x1F70D0C84D54E503) /* 995 */,
CONST64(0x5490ADEC7ECE57D4) /* 996 */, CONST64(0x002B3C27D9063A3A) /* 997 */,
CONST64(0x7EAEA3848030A2BF) /* 998 */, CONST64(0xC602326DED2003C0) /* 999 */,
CONST64(0x83A7287D69A94086) /* 1000 */, CONST64(0xC57A5FCB30F57A8A) /* 1001 */,
CONST64(0xB56844E479EBE779) /* 1002 */, CONST64(0xA373B40F05DCBCE9) /* 1003 */,
CONST64(0xD71A786E88570EE2) /* 1004 */, CONST64(0x879CBACDBDE8F6A0) /* 1005 */,
CONST64(0x976AD1BCC164A32F) /* 1006 */, CONST64(0xAB21E25E9666D78B) /* 1007 */,
CONST64(0x901063AAE5E5C33C) /* 1008 */, CONST64(0x9818B34448698D90) /* 1009 */,
CONST64(0xE36487AE3E1E8ABB) /* 1010 */, CONST64(0xAFBDF931893BDCB4) /* 1011 */,
CONST64(0x6345A0DC5FBBD519) /* 1012 */, CONST64(0x8628FE269B9465CA) /* 1013 */,
CONST64(0x1E5D01603F9C51EC) /* 1014 */, CONST64(0x4DE44006A15049B7) /* 1015 */,
CONST64(0xBF6C70E5F776CBB1) /* 1016 */, CONST64(0x411218F2EF552BED) /* 1017 */,
CONST64(0xCB0C0708705A36A3) /* 1018 */, CONST64(0xE74D14754F986044) /* 1019 */,
CONST64(0xCD56D9430EA8280E) /* 1020 */, CONST64(0xC12591D7535F5065) /* 1021 */,
CONST64(0xC83223F1720AEF96) /* 1022 */, CONST64(0xC3A0396F7363A51F) /* 1023 */};
/* one round of the hash function */
LTC_INLINE static void tiger_round(ulong64 *a, ulong64 *b, ulong64 *c, ulong64 x, int mul)
{
ulong64 tmp;
tmp = (*c ^= x);
*a -= t1[LTC_BYTE(tmp, 0)] ^ t2[LTC_BYTE(tmp, 2)] ^ t3[LTC_BYTE(tmp, 4)] ^ t4[LTC_BYTE(tmp, 6)];
tmp = (*b += t4[LTC_BYTE(tmp, 1)] ^ t3[LTC_BYTE(tmp, 3)] ^ t2[LTC_BYTE(tmp,5)] ^ t1[LTC_BYTE(tmp,7)]);
switch (mul) {
case 5: *b = (tmp << 2) + tmp; break;
case 7: *b = (tmp << 3) - tmp; break;
case 9: *b = (tmp << 3) + tmp; break;
}
}
/* one complete pass */
static void s_pass(ulong64 *a, ulong64 *b, ulong64 *c, const ulong64 *x, int mul)
{
tiger_round(a,b,c,x[0],mul);
tiger_round(b,c,a,x[1],mul);
tiger_round(c,a,b,x[2],mul);
tiger_round(a,b,c,x[3],mul);
tiger_round(b,c,a,x[4],mul);
tiger_round(c,a,b,x[5],mul);
tiger_round(a,b,c,x[6],mul);
tiger_round(b,c,a,x[7],mul);
}
/* The key mixing schedule */
static void s_key_schedule(ulong64 *x)
{
x[0] -= x[7] ^ CONST64(0xA5A5A5A5A5A5A5A5);
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] ^ CONST64(0x0123456789ABCDEF);
}
#ifdef LTC_CLEAN_STACK
static int ss_tiger_compress(hash_state *md, const unsigned char *buf)
#else
static int s_tiger_compress(hash_state *md, const unsigned char *buf)
#endif
{
ulong64 a, b, c, x[8], t;
unsigned long i;
/* load words */
for (i = 0; i < 8; i++) {
LOAD64L(x[i],&buf[8*i]);
}
a = md->tiger.state[0];
b = md->tiger.state[1];
c = md->tiger.state[2];
s_pass(&a,&b,&c,x,5);
s_key_schedule(x);
s_pass(&c,&a,&b,x,7);
s_key_schedule(x);
s_pass(&b,&c,&a,x,9);
for (i = 3; i < md->tiger.passes; ++i) {
s_key_schedule(x);
s_pass(&a,&b,&c,x,9);
t = a; a = c; c = b; b = t;
}
/* store state */
md->tiger.state[0] = a ^ md->tiger.state[0];
md->tiger.state[1] = b - md->tiger.state[1];
md->tiger.state[2] = c + md->tiger.state[2];
return CRYPT_OK;
}
#ifdef LTC_CLEAN_STACK
static int s_tiger_compress(hash_state *md, const unsigned char *buf)
{
int err;
err = ss_tiger_compress(md, buf);
burn_stack(sizeof(ulong64) * 11 + sizeof(unsigned long));
return err;
}
#endif
/**
Initialize the hash state
@param md The hash state you wish to initialize
@return CRYPT_OK if successful
*/
int tiger_init(hash_state *md)
{
LTC_ARGCHK(md != NULL);
md->tiger.state[0] = CONST64(0x0123456789ABCDEF);
md->tiger.state[1] = CONST64(0xFEDCBA9876543210);
md->tiger.state[2] = CONST64(0xF096A5B4C3B2E187);
md->tiger.curlen = 0;
md->tiger.length = 0;
md->tiger.passes = 3;
md->tiger.pad = 0x01u;
return CRYPT_OK;
}
/**
Initialize the hash state (extended version)
@param md The hash state you wish to initialize
@param passes The number of passes that should be executed
when the compress function is called.
@return CRYPT_OK if successful
*/
int tiger_init_ex(hash_state *md, unsigned long passes)
{
int err;
if ((err = tiger_init(md) != CRYPT_OK)) {
return err;
}
md->tiger.passes = passes;
return CRYPT_OK;
}
/**
Initialize the hash state (extended version)
@param md The hash state you wish to initialize
@return CRYPT_OK if successful
*/
int tiger2_init(hash_state *md)
{
int err;
if ((err = tiger_init(md) != CRYPT_OK)) {
return err;
}
md->tiger.pad = 0x80u;
return CRYPT_OK;
}
/**
Initialize the hash state (extended version)
@param md The hash state you wish to initialize
@param passes The number of passes that should be executed
when the compress function is called.
@return CRYPT_OK if successful
*/
int tiger2_init_ex(hash_state *md, unsigned long passes)
{
int err;
if ((err = tiger2_init(md) != CRYPT_OK)) {
return err;
}
md->tiger.passes = passes;
return CRYPT_OK;
}
/**
Process a block of memory though the hash
@param md The hash state
@param in The data to hash
@param inlen The length of the data (octets)
@return CRYPT_OK if successful
*/
HASH_PROCESS(tiger_process, s_tiger_compress, tiger, 64)
/**
Terminate the hash to get the digest
@param md The hash state
@param out [out] The destination of the hash (24 bytes)
@return CRYPT_OK if successful
*/
int tiger_done(hash_state * md, unsigned char *out)
{
LTC_ARGCHK(md != NULL);
LTC_ARGCHK(out != NULL);
if (md->tiger.curlen >= sizeof(md->tiger.buf)) {
return CRYPT_INVALID_ARG;
}
/* increase the length of the message */
md->tiger.length += md->tiger.curlen * 8;
/* append the padding bit */
md->tiger.buf[md->tiger.curlen++] = md->tiger.pad;
/* if the length is currently above 56 bytes we append zeros
* then compress. Then we can fall back to padding zeros and length
* encoding like normal. */
if (md->tiger.curlen > 56) {
while (md->tiger.curlen < 64) {
md->tiger.buf[md->tiger.curlen++] = (unsigned char)0;
}
s_tiger_compress(md, md->tiger.buf);
md->tiger.curlen = 0;
}
/* pad upto 56 bytes of zeroes */
while (md->tiger.curlen < 56) {
md->tiger.buf[md->tiger.curlen++] = (unsigned char)0;
}
/* store length */
STORE64L(md->tiger.length, md->tiger.buf+56);
s_tiger_compress(md, md->tiger.buf);
/* copy output */
STORE64L(md->tiger.state[0], &out[0]);
STORE64L(md->tiger.state[1], &out[8]);
STORE64L(md->tiger.state[2], &out[16]);
#ifdef LTC_CLEAN_STACK
zeromem(md, sizeof(hash_state));
#endif
return CRYPT_OK;
}
/**
Self-test the hash
@return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled
*/
static int s_tiger_test(unsigned int idx)
{
#ifndef LTC_TEST
LTC_UNUSED_PARAM(idx);
return CRYPT_NOP;
#else
static const struct {
const char *msg;
unsigned char hash[2][24];
} tests[] = {
{ "",
{
{ 0x32, 0x93, 0xac, 0x63, 0x0c, 0x13, 0xf0, 0x24,
0x5f, 0x92, 0xbb, 0xb1, 0x76, 0x6e, 0x16, 0x16,
0x7a, 0x4e, 0x58, 0x49, 0x2d, 0xde, 0x73, 0xf3 },
{ 0x44, 0x41, 0xbe, 0x75, 0xf6, 0x01, 0x87, 0x73,
0xc2, 0x06, 0xc2, 0x27, 0x45, 0x37, 0x4b, 0x92,
0x4a, 0xa8, 0x31, 0x3f, 0xef, 0x91, 0x9f, 0x41 },
},
},
{ "abc",
{
{ 0x2a, 0xab, 0x14, 0x84, 0xe8, 0xc1, 0x58, 0xf2,
0xbf, 0xb8, 0xc5, 0xff, 0x41, 0xb5, 0x7a, 0x52,
0x51, 0x29, 0x13, 0x1c, 0x95, 0x7b, 0x5f, 0x93 },
{ 0xf6, 0x8d, 0x7b, 0xc5, 0xaf, 0x4b, 0x43, 0xa0,
0x6e, 0x04, 0x8d, 0x78, 0x29, 0x56, 0x0d, 0x4a,
0x94, 0x15, 0x65, 0x8b, 0xb0, 0xb1, 0xf3, 0xbf },
},
},
{ "Tiger",
{
{ 0xdd, 0x00, 0x23, 0x07, 0x99, 0xf5, 0x00, 0x9f,
0xec, 0x6d, 0xeb, 0xc8, 0x38, 0xbb, 0x6a, 0x27,
0xdf, 0x2b, 0x9d, 0x6f, 0x11, 0x0c, 0x79, 0x37 },
{ 0xfe, 0x40, 0x79, 0x8b, 0x8e, 0xb9, 0x37, 0xfd,
0x97, 0x76, 0x08, 0x93, 0x05, 0x48, 0xd6, 0xa8,
0x94, 0xc2, 0x0b, 0x04, 0xcb, 0xef, 0x7a, 0x42 },
},
},
{ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-",
{
{ 0xf7, 0x1c, 0x85, 0x83, 0x90, 0x2a, 0xfb, 0x87,
0x9e, 0xdf, 0xe6, 0x10, 0xf8, 0x2c, 0x0d, 0x47,
0x86, 0xa3, 0xa5, 0x34, 0x50, 0x44, 0x86, 0xb5 },
{ 0x15, 0x9b, 0x38, 0x0a, 0xb7, 0x92, 0x94, 0xe0,
0xda, 0x19, 0xf1, 0x62, 0x82, 0xce, 0x6d, 0xce,
0x0f, 0x84, 0xd3, 0x4f, 0x72, 0x9d, 0xbe, 0xa3 },
},
},
{ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-",
{
{ 0xc5, 0x40, 0x34, 0xe5, 0xb4, 0x3e, 0xb8, 0x00,
0x58, 0x48, 0xa7, 0xe0, 0xae, 0x6a, 0xac, 0x76,
0xe4, 0xff, 0x59, 0x0a, 0xe7, 0x15, 0xfd, 0x25 },
{ 0x01, 0xef, 0x91, 0x0b, 0x9b, 0xb2, 0xcb, 0x4c,
0x6c, 0x47, 0x49, 0x5c, 0x86, 0xb3, 0x64, 0x1a,
0xff, 0x14, 0xfb, 0xf7, 0x79, 0x40, 0x9c, 0x0e },
},
},
};
int (*init[2])(hash_state *hash) = { tiger_init, tiger2_init };
int i;
unsigned char tmp[24];
hash_state md;
for (i = 0; i < (int)(sizeof(tests) / sizeof(tests[0])); i++) {
init[idx](&md);
tiger_process(&md, (unsigned char *)tests[i].msg, (unsigned long)XSTRLEN(tests[i].msg));
tiger_done(&md, tmp);
if (compare_testvector(tmp, sizeof(tmp), tests[i].hash[idx], sizeof(tests[i].hash[idx]), !idx ? "TIGER": "TIGER2", i)) {
return CRYPT_FAIL_TESTVECTOR;
}
}
return CRYPT_OK;
#endif
}
/**
Self-test the hash
@return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled
*/
int tiger_test(void)
{
return s_tiger_test(0);
}
/**
Self-test the hash
@return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled
*/
int tiger2_test(void)
{
return s_tiger_test(1);
}
#undef t1
#undef t2
#undef t3
#undef t4
#endif
/*
Hash of "":
24F0130C63AC9332 16166E76B1BB925F F373DE2D49584E7A
Hash of "abc":
F258C1E88414AB2A 527AB541FFC5B8BF 935F7B951C132951
Hash of "Tiger":
9F00F599072300DD 276ABB38C8EB6DEC 37790C116F9D2BDF
Hash of "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-":
87FB2A9083851CF7 470D2CF810E6DF9E B586445034A5A386
Hash of "ABCDEFGHIJKLMNOPQRSTUVWXYZ=abcdefghijklmnopqrstuvwxyz+0123456789":
467DB80863EBCE48 8DF1CD1261655DE9 57896565975F9197
Hash of "Tiger - A Fast New Hash Function, by Ross Anderson and Eli Biham":
0C410A042968868A 1671DA5A3FD29A72 5EC1E457D3CDB303
Hash of "Tiger - A Fast New Hash Function, by Ross Anderson and Eli Biham, proceedings of Fast Software Encryption 3, Cambridge.":
EBF591D5AFA655CE 7F22894FF87F54AC 89C811B6B0DA3193
Hash of "Tiger - A Fast New Hash Function, by Ross Anderson and Eli Biham, proceedings of Fast Software Encryption 3, Cambridge, 1996.":
3D9AEB03D1BD1A63 57B2774DFD6D5B24 DD68151D503974FC
Hash of "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-":
00B83EB4E53440C5 76AC6AAEE0A74858 25FD15E70A59FFE4
*/

View File

@@ -0,0 +1,300 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
/* SPDX-License-Identifier: Unlicense */
/**
@file whirl.c
LTC_WHIRLPOOL (using their new sbox) hash function by Tom St Denis
*/
#include "tomcrypt_private.h"
#ifdef LTC_WHIRLPOOL
const struct ltc_hash_descriptor whirlpool_desc =
{
"whirlpool",
11,
64,
64,
/* OID */
{ 1, 0, 10118, 3, 0, 55 },
6,
&whirlpool_init,
&whirlpool_process,
&whirlpool_done,
&whirlpool_test,
NULL
};
/* the sboxes */
#ifndef LTC_WHIRLTAB_C
#define LTC_WHIRLTAB_C
#include "whirltab.c"
#endif
/* get a_{i,j} */
#define GB(a,i,j) ((a[(i) & 7] >> (8 * (j))) & 255)
/* shortcut macro to perform three functions at once */
#define theta_pi_gamma(a, i) \
(SB0(GB(a, i-0, 7)) ^ \
SB1(GB(a, i-1, 6)) ^ \
SB2(GB(a, i-2, 5)) ^ \
SB3(GB(a, i-3, 4)) ^ \
SB4(GB(a, i-4, 3)) ^ \
SB5(GB(a, i-5, 2)) ^ \
SB6(GB(a, i-6, 1)) ^ \
SB7(GB(a, i-7, 0)))
#ifdef LTC_CLEAN_STACK
static int ss_whirlpool_compress(hash_state *md, const unsigned char *buf)
#else
static int s_whirlpool_compress(hash_state *md, const unsigned char *buf)
#endif
{
ulong64 K[2][8], T[3][8];
int x, y;
/* load the block/state */
for (x = 0; x < 8; x++) {
K[0][x] = md->whirlpool.state[x];
LOAD64H(T[0][x], buf + (8 * x));
T[2][x] = T[0][x];
T[0][x] ^= K[0][x];
}
/* do rounds 1..10 */
for (x = 0; x < 10; x += 2) {
/* odd round */
/* apply main transform to K[0] into K[1] */
for (y = 0; y < 8; y++) {
K[1][y] = theta_pi_gamma(K[0], y);
}
/* xor the constant */
K[1][0] ^= cont[x];
/* apply main transform to T[0] into T[1] */
for (y = 0; y < 8; y++) {
T[1][y] = theta_pi_gamma(T[0], y) ^ K[1][y];
}
/* even round */
/* apply main transform to K[1] into K[0] */
for (y = 0; y < 8; y++) {
K[0][y] = theta_pi_gamma(K[1], y);
}
/* xor the constant */
K[0][0] ^= cont[x+1];
/* apply main transform to T[1] into T[0] */
for (y = 0; y < 8; y++) {
T[0][y] = theta_pi_gamma(T[1], y) ^ K[0][y];
}
}
/* store state */
for (x = 0; x < 8; x++) {
md->whirlpool.state[x] ^= T[0][x] ^ T[2][x];
}
return CRYPT_OK;
}
#ifdef LTC_CLEAN_STACK
static int s_whirlpool_compress(hash_state *md, const unsigned char *buf)
{
int err;
err = ss_whirlpool_compress(md, buf);
burn_stack((5 * 8 * sizeof(ulong64)) + (2 * sizeof(int)));
return err;
}
#endif
/**
Initialize the hash state
@param md The hash state you wish to initialize
@return CRYPT_OK if successful
*/
int whirlpool_init(hash_state * md)
{
LTC_ARGCHK(md != NULL);
zeromem(&md->whirlpool, sizeof(md->whirlpool));
return CRYPT_OK;
}
/**
Process a block of memory though the hash
@param md The hash state
@param in The data to hash
@param inlen The length of the data (octets)
@return CRYPT_OK if successful
*/
HASH_PROCESS(whirlpool_process, s_whirlpool_compress, whirlpool, 64)
/**
Terminate the hash to get the digest
@param md The hash state
@param out [out] The destination of the hash (64 bytes)
@return CRYPT_OK if successful
*/
int whirlpool_done(hash_state * md, unsigned char *out)
{
int i;
LTC_ARGCHK(md != NULL);
LTC_ARGCHK(out != NULL);
if (md->whirlpool.curlen >= sizeof(md->whirlpool.buf)) {
return CRYPT_INVALID_ARG;
}
/* increase the length of the message */
md->whirlpool.length += md->whirlpool.curlen * 8;
/* append the '1' bit */
md->whirlpool.buf[md->whirlpool.curlen++] = (unsigned char)0x80;
/* if the length is currently above 32 bytes we append zeros
* then compress. Then we can fall back to padding zeros and length
* encoding like normal.
*/
if (md->whirlpool.curlen > 32) {
while (md->whirlpool.curlen < 64) {
md->whirlpool.buf[md->whirlpool.curlen++] = (unsigned char)0;
}
s_whirlpool_compress(md, md->whirlpool.buf);
md->whirlpool.curlen = 0;
}
/* pad upto 56 bytes of zeroes (should be 32 but we only support 64-bit lengths) */
while (md->whirlpool.curlen < 56) {
md->whirlpool.buf[md->whirlpool.curlen++] = (unsigned char)0;
}
/* store length */
STORE64H(md->whirlpool.length, md->whirlpool.buf+56);
s_whirlpool_compress(md, md->whirlpool.buf);
/* copy output */
for (i = 0; i < 8; i++) {
STORE64H(md->whirlpool.state[i], out+(8*i));
}
#ifdef LTC_CLEAN_STACK
zeromem(md, sizeof(*md));
#endif
return CRYPT_OK;
}
/**
Self-test the hash
@return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled
*/
int whirlpool_test(void)
{
#ifndef LTC_TEST
return CRYPT_NOP;
#else
static const struct {
int len;
unsigned char msg[128], hash[64];
} tests[] = {
/* NULL Message */
{
0,
{ 0x00 },
{ 0x19, 0xFA, 0x61, 0xD7, 0x55, 0x22, 0xA4, 0x66, 0x9B, 0x44, 0xE3, 0x9C, 0x1D, 0x2E, 0x17, 0x26,
0xC5, 0x30, 0x23, 0x21, 0x30, 0xD4, 0x07, 0xF8, 0x9A, 0xFE, 0xE0, 0x96, 0x49, 0x97, 0xF7, 0xA7,
0x3E, 0x83, 0xBE, 0x69, 0x8B, 0x28, 0x8F, 0xEB, 0xCF, 0x88, 0xE3, 0xE0, 0x3C, 0x4F, 0x07, 0x57,
0xEA, 0x89, 0x64, 0xE5, 0x9B, 0x63, 0xD9, 0x37, 0x08, 0xB1, 0x38, 0xCC, 0x42, 0xA6, 0x6E, 0xB3 }
},
/* 448-bits of 0 bits */
{
56,
{ 0x00 },
{ 0x0B, 0x3F, 0x53, 0x78, 0xEB, 0xED, 0x2B, 0xF4, 0xD7, 0xBE, 0x3C, 0xFD, 0x81, 0x8C, 0x1B, 0x03,
0xB6, 0xBB, 0x03, 0xD3, 0x46, 0x94, 0x8B, 0x04, 0xF4, 0xF4, 0x0C, 0x72, 0x6F, 0x07, 0x58, 0x70,
0x2A, 0x0F, 0x1E, 0x22, 0x58, 0x80, 0xE3, 0x8D, 0xD5, 0xF6, 0xED, 0x6D, 0xE9, 0xB1, 0xE9, 0x61,
0xE4, 0x9F, 0xC1, 0x31, 0x8D, 0x7C, 0xB7, 0x48, 0x22, 0xF3, 0xD0, 0xE2, 0xE9, 0xA7, 0xE7, 0xB0 }
},
/* 520-bits of 0 bits */
{
65,
{ 0x00 },
{ 0x85, 0xE1, 0x24, 0xC4, 0x41, 0x5B, 0xCF, 0x43, 0x19, 0x54, 0x3E, 0x3A, 0x63, 0xFF, 0x57, 0x1D,
0x09, 0x35, 0x4C, 0xEE, 0xBE, 0xE1, 0xE3, 0x25, 0x30, 0x8C, 0x90, 0x69, 0xF4, 0x3E, 0x2A, 0xE4,
0xD0, 0xE5, 0x1D, 0x4E, 0xB1, 0xE8, 0x64, 0x28, 0x70, 0x19, 0x4E, 0x95, 0x30, 0xD8, 0xD8, 0xAF,
0x65, 0x89, 0xD1, 0xBF, 0x69, 0x49, 0xDD, 0xF9, 0x0A, 0x7F, 0x12, 0x08, 0x62, 0x37, 0x95, 0xB9 }
},
/* 512-bits, leading set */
{
64,
{ 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0x10, 0x3E, 0x00, 0x55, 0xA9, 0xB0, 0x90, 0xE1, 0x1C, 0x8F, 0xDD, 0xEB, 0xBA, 0x06, 0xC0, 0x5A,
0xCE, 0x8B, 0x64, 0xB8, 0x96, 0x12, 0x8F, 0x6E, 0xED, 0x30, 0x71, 0xFC, 0xF3, 0xDC, 0x16, 0x94,
0x67, 0x78, 0xE0, 0x72, 0x23, 0x23, 0x3F, 0xD1, 0x80, 0xFC, 0x40, 0xCC, 0xDB, 0x84, 0x30, 0xA6,
0x40, 0xE3, 0x76, 0x34, 0x27, 0x1E, 0x65, 0x5C, 0xA1, 0x67, 0x4E, 0xBF, 0xF5, 0x07, 0xF8, 0xCB }
},
/* 512-bits, leading set of second byte */
{
64,
{ 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0x35, 0x7B, 0x42, 0xEA, 0x79, 0xBC, 0x97, 0x86, 0x97, 0x5A, 0x3C, 0x44, 0x70, 0xAA, 0xB2, 0x3E,
0x62, 0x29, 0x79, 0x7B, 0xAD, 0xBD, 0x54, 0x36, 0x5B, 0x54, 0x96, 0xE5, 0x5D, 0x9D, 0xD7, 0x9F,
0xE9, 0x62, 0x4F, 0xB4, 0x22, 0x66, 0x93, 0x0A, 0x62, 0x8E, 0xD4, 0xDB, 0x08, 0xF9, 0xDD, 0x35,
0xEF, 0x1B, 0xE1, 0x04, 0x53, 0xFC, 0x18, 0xF4, 0x2C, 0x7F, 0x5E, 0x1F, 0x9B, 0xAE, 0x55, 0xE0 }
},
/* 512-bits, leading set of last byte */
{
64,
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80 },
{ 0x8B, 0x39, 0x04, 0xDD, 0x19, 0x81, 0x41, 0x26, 0xFD, 0x02, 0x74, 0xAB, 0x49, 0xC5, 0x97, 0xF6,
0xD7, 0x75, 0x33, 0x52, 0xA2, 0xDD, 0x91, 0xFD, 0x8F, 0x9F, 0x54, 0x05, 0x4C, 0x54, 0xBF, 0x0F,
0x06, 0xDB, 0x4F, 0xF7, 0x08, 0xA3, 0xA2, 0x8B, 0xC3, 0x7A, 0x92, 0x1E, 0xEE, 0x11, 0xED, 0x7B,
0x6A, 0x53, 0x79, 0x32, 0xCC, 0x5E, 0x94, 0xEE, 0x1E, 0xA6, 0x57, 0x60, 0x7E, 0x36, 0xC9, 0xF7 }
},
};
int i;
unsigned char tmp[64];
hash_state md;
for (i = 0; i < (int)(sizeof(tests)/sizeof(tests[0])); i++) {
whirlpool_init(&md);
whirlpool_process(&md, (unsigned char *)tests[i].msg, tests[i].len);
whirlpool_done(&md, tmp);
if (compare_testvector(tmp, sizeof(tmp), tests[i].hash, sizeof(tests[i].hash), "WHIRLPOOL", i)) {
return CRYPT_FAIL_TESTVECTOR;
}
}
return CRYPT_OK;
#endif
}
#undef GB
#undef theta_pi_gamma
#endif

View File

@@ -0,0 +1,586 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
/* SPDX-License-Identifier: Unlicense */
/**
@file whirltab.c
LTC_WHIRLPOOL tables, Tom St Denis
*/
#ifdef LTC_WHIRLTAB_C
static const ulong64 sbox0[] = {
CONST64(0x18186018c07830d8), CONST64(0x23238c2305af4626), CONST64(0xc6c63fc67ef991b8), CONST64(0xe8e887e8136fcdfb),
CONST64(0x878726874ca113cb), CONST64(0xb8b8dab8a9626d11), CONST64(0x0101040108050209), CONST64(0x4f4f214f426e9e0d),
CONST64(0x3636d836adee6c9b), CONST64(0xa6a6a2a6590451ff), CONST64(0xd2d26fd2debdb90c), CONST64(0xf5f5f3f5fb06f70e),
CONST64(0x7979f979ef80f296), CONST64(0x6f6fa16f5fcede30), CONST64(0x91917e91fcef3f6d), CONST64(0x52525552aa07a4f8),
CONST64(0x60609d6027fdc047), CONST64(0xbcbccabc89766535), CONST64(0x9b9b569baccd2b37), CONST64(0x8e8e028e048c018a),
CONST64(0xa3a3b6a371155bd2), CONST64(0x0c0c300c603c186c), CONST64(0x7b7bf17bff8af684), CONST64(0x3535d435b5e16a80),
CONST64(0x1d1d741de8693af5), CONST64(0xe0e0a7e05347ddb3), CONST64(0xd7d77bd7f6acb321), CONST64(0xc2c22fc25eed999c),
CONST64(0x2e2eb82e6d965c43), CONST64(0x4b4b314b627a9629), CONST64(0xfefedffea321e15d), CONST64(0x575741578216aed5),
CONST64(0x15155415a8412abd), CONST64(0x7777c1779fb6eee8), CONST64(0x3737dc37a5eb6e92), CONST64(0xe5e5b3e57b56d79e),
CONST64(0x9f9f469f8cd92313), CONST64(0xf0f0e7f0d317fd23), CONST64(0x4a4a354a6a7f9420), CONST64(0xdada4fda9e95a944),
CONST64(0x58587d58fa25b0a2), CONST64(0xc9c903c906ca8fcf), CONST64(0x2929a429558d527c), CONST64(0x0a0a280a5022145a),
CONST64(0xb1b1feb1e14f7f50), CONST64(0xa0a0baa0691a5dc9), CONST64(0x6b6bb16b7fdad614), CONST64(0x85852e855cab17d9),
CONST64(0xbdbdcebd8173673c), CONST64(0x5d5d695dd234ba8f), CONST64(0x1010401080502090), CONST64(0xf4f4f7f4f303f507),
CONST64(0xcbcb0bcb16c08bdd), CONST64(0x3e3ef83eedc67cd3), CONST64(0x0505140528110a2d), CONST64(0x676781671fe6ce78),
CONST64(0xe4e4b7e47353d597), CONST64(0x27279c2725bb4e02), CONST64(0x4141194132588273), CONST64(0x8b8b168b2c9d0ba7),
CONST64(0xa7a7a6a7510153f6), CONST64(0x7d7de97dcf94fab2), CONST64(0x95956e95dcfb3749), CONST64(0xd8d847d88e9fad56),
CONST64(0xfbfbcbfb8b30eb70), CONST64(0xeeee9fee2371c1cd), CONST64(0x7c7ced7cc791f8bb), CONST64(0x6666856617e3cc71),
CONST64(0xdddd53dda68ea77b), CONST64(0x17175c17b84b2eaf), CONST64(0x4747014702468e45), CONST64(0x9e9e429e84dc211a),
CONST64(0xcaca0fca1ec589d4), CONST64(0x2d2db42d75995a58), CONST64(0xbfbfc6bf9179632e), CONST64(0x07071c07381b0e3f),
CONST64(0xadad8ead012347ac), CONST64(0x5a5a755aea2fb4b0), CONST64(0x838336836cb51bef), CONST64(0x3333cc3385ff66b6),
CONST64(0x636391633ff2c65c), CONST64(0x02020802100a0412), CONST64(0xaaaa92aa39384993), CONST64(0x7171d971afa8e2de),
CONST64(0xc8c807c80ecf8dc6), CONST64(0x19196419c87d32d1), CONST64(0x494939497270923b), CONST64(0xd9d943d9869aaf5f),
CONST64(0xf2f2eff2c31df931), CONST64(0xe3e3abe34b48dba8), CONST64(0x5b5b715be22ab6b9), CONST64(0x88881a8834920dbc),
CONST64(0x9a9a529aa4c8293e), CONST64(0x262698262dbe4c0b), CONST64(0x3232c8328dfa64bf), CONST64(0xb0b0fab0e94a7d59),
CONST64(0xe9e983e91b6acff2), CONST64(0x0f0f3c0f78331e77), CONST64(0xd5d573d5e6a6b733), CONST64(0x80803a8074ba1df4),
CONST64(0xbebec2be997c6127), CONST64(0xcdcd13cd26de87eb), CONST64(0x3434d034bde46889), CONST64(0x48483d487a759032),
CONST64(0xffffdbffab24e354), CONST64(0x7a7af57af78ff48d), CONST64(0x90907a90f4ea3d64), CONST64(0x5f5f615fc23ebe9d),
CONST64(0x202080201da0403d), CONST64(0x6868bd6867d5d00f), CONST64(0x1a1a681ad07234ca), CONST64(0xaeae82ae192c41b7),
CONST64(0xb4b4eab4c95e757d), CONST64(0x54544d549a19a8ce), CONST64(0x93937693ece53b7f), CONST64(0x222288220daa442f),
CONST64(0x64648d6407e9c863), CONST64(0xf1f1e3f1db12ff2a), CONST64(0x7373d173bfa2e6cc), CONST64(0x12124812905a2482),
CONST64(0x40401d403a5d807a), CONST64(0x0808200840281048), CONST64(0xc3c32bc356e89b95), CONST64(0xecec97ec337bc5df),
CONST64(0xdbdb4bdb9690ab4d), CONST64(0xa1a1bea1611f5fc0), CONST64(0x8d8d0e8d1c830791), CONST64(0x3d3df43df5c97ac8),
CONST64(0x97976697ccf1335b), CONST64(0x0000000000000000), CONST64(0xcfcf1bcf36d483f9), CONST64(0x2b2bac2b4587566e),
CONST64(0x7676c57697b3ece1), CONST64(0x8282328264b019e6), CONST64(0xd6d67fd6fea9b128), CONST64(0x1b1b6c1bd87736c3),
CONST64(0xb5b5eeb5c15b7774), CONST64(0xafaf86af112943be), CONST64(0x6a6ab56a77dfd41d), CONST64(0x50505d50ba0da0ea),
CONST64(0x45450945124c8a57), CONST64(0xf3f3ebf3cb18fb38), CONST64(0x3030c0309df060ad), CONST64(0xefef9bef2b74c3c4),
CONST64(0x3f3ffc3fe5c37eda), CONST64(0x55554955921caac7), CONST64(0xa2a2b2a2791059db), CONST64(0xeaea8fea0365c9e9),
CONST64(0x656589650fecca6a), CONST64(0xbabad2bab9686903), CONST64(0x2f2fbc2f65935e4a), CONST64(0xc0c027c04ee79d8e),
CONST64(0xdede5fdebe81a160), CONST64(0x1c1c701ce06c38fc), CONST64(0xfdfdd3fdbb2ee746), CONST64(0x4d4d294d52649a1f),
CONST64(0x92927292e4e03976), CONST64(0x7575c9758fbceafa), CONST64(0x06061806301e0c36), CONST64(0x8a8a128a249809ae),
CONST64(0xb2b2f2b2f940794b), CONST64(0xe6e6bfe66359d185), CONST64(0x0e0e380e70361c7e), CONST64(0x1f1f7c1ff8633ee7),
CONST64(0x6262956237f7c455), CONST64(0xd4d477d4eea3b53a), CONST64(0xa8a89aa829324d81), CONST64(0x96966296c4f43152),
CONST64(0xf9f9c3f99b3aef62), CONST64(0xc5c533c566f697a3), CONST64(0x2525942535b14a10), CONST64(0x59597959f220b2ab),
CONST64(0x84842a8454ae15d0), CONST64(0x7272d572b7a7e4c5), CONST64(0x3939e439d5dd72ec), CONST64(0x4c4c2d4c5a619816),
CONST64(0x5e5e655eca3bbc94), CONST64(0x7878fd78e785f09f), CONST64(0x3838e038ddd870e5), CONST64(0x8c8c0a8c14860598),
CONST64(0xd1d163d1c6b2bf17), CONST64(0xa5a5aea5410b57e4), CONST64(0xe2e2afe2434dd9a1), CONST64(0x616199612ff8c24e),
CONST64(0xb3b3f6b3f1457b42), CONST64(0x2121842115a54234), CONST64(0x9c9c4a9c94d62508), CONST64(0x1e1e781ef0663cee),
CONST64(0x4343114322528661), CONST64(0xc7c73bc776fc93b1), CONST64(0xfcfcd7fcb32be54f), CONST64(0x0404100420140824),
CONST64(0x51515951b208a2e3), CONST64(0x99995e99bcc72f25), CONST64(0x6d6da96d4fc4da22), CONST64(0x0d0d340d68391a65),
CONST64(0xfafacffa8335e979), CONST64(0xdfdf5bdfb684a369), CONST64(0x7e7ee57ed79bfca9), CONST64(0x242490243db44819),
CONST64(0x3b3bec3bc5d776fe), CONST64(0xabab96ab313d4b9a), CONST64(0xcece1fce3ed181f0), CONST64(0x1111441188552299),
CONST64(0x8f8f068f0c890383), CONST64(0x4e4e254e4a6b9c04), CONST64(0xb7b7e6b7d1517366), CONST64(0xebeb8beb0b60cbe0),
CONST64(0x3c3cf03cfdcc78c1), CONST64(0x81813e817cbf1ffd), CONST64(0x94946a94d4fe3540), CONST64(0xf7f7fbf7eb0cf31c),
CONST64(0xb9b9deb9a1676f18), CONST64(0x13134c13985f268b), CONST64(0x2c2cb02c7d9c5851), CONST64(0xd3d36bd3d6b8bb05),
CONST64(0xe7e7bbe76b5cd38c), CONST64(0x6e6ea56e57cbdc39), CONST64(0xc4c437c46ef395aa), CONST64(0x03030c03180f061b),
CONST64(0x565645568a13acdc), CONST64(0x44440d441a49885e), CONST64(0x7f7fe17fdf9efea0), CONST64(0xa9a99ea921374f88),
CONST64(0x2a2aa82a4d825467), CONST64(0xbbbbd6bbb16d6b0a), CONST64(0xc1c123c146e29f87), CONST64(0x53535153a202a6f1),
CONST64(0xdcdc57dcae8ba572), CONST64(0x0b0b2c0b58271653), CONST64(0x9d9d4e9d9cd32701), CONST64(0x6c6cad6c47c1d82b),
CONST64(0x3131c43195f562a4), CONST64(0x7474cd7487b9e8f3), CONST64(0xf6f6fff6e309f115), CONST64(0x464605460a438c4c),
CONST64(0xacac8aac092645a5), CONST64(0x89891e893c970fb5), CONST64(0x14145014a04428b4), CONST64(0xe1e1a3e15b42dfba),
CONST64(0x16165816b04e2ca6), CONST64(0x3a3ae83acdd274f7), CONST64(0x6969b9696fd0d206), CONST64(0x09092409482d1241),
CONST64(0x7070dd70a7ade0d7), CONST64(0xb6b6e2b6d954716f), CONST64(0xd0d067d0ceb7bd1e), CONST64(0xeded93ed3b7ec7d6),
CONST64(0xcccc17cc2edb85e2), CONST64(0x424215422a578468), CONST64(0x98985a98b4c22d2c), CONST64(0xa4a4aaa4490e55ed),
CONST64(0x2828a0285d885075), CONST64(0x5c5c6d5cda31b886), CONST64(0xf8f8c7f8933fed6b), CONST64(0x8686228644a411c2)
};
#ifdef LTC_SMALL_CODE
#define SB0(x) sbox0[x]
#define SB1(x) ROR64c(sbox0[x], 8)
#define SB2(x) ROR64c(sbox0[x], 16)
#define SB3(x) ROR64c(sbox0[x], 24)
#define SB4(x) ROR64c(sbox0[x], 32)
#define SB5(x) ROR64c(sbox0[x], 40)
#define SB6(x) ROR64c(sbox0[x], 48)
#define SB7(x) ROR64c(sbox0[x], 56)
#else
#define SB0(x) sbox0[x]
#define SB1(x) sbox1[x]
#define SB2(x) sbox2[x]
#define SB3(x) sbox3[x]
#define SB4(x) sbox4[x]
#define SB5(x) sbox5[x]
#define SB6(x) sbox6[x]
#define SB7(x) sbox7[x]
static const ulong64 sbox1[] = {
CONST64(0xd818186018c07830), CONST64(0x2623238c2305af46), CONST64(0xb8c6c63fc67ef991), CONST64(0xfbe8e887e8136fcd),
CONST64(0xcb878726874ca113), CONST64(0x11b8b8dab8a9626d), CONST64(0x0901010401080502), CONST64(0x0d4f4f214f426e9e),
CONST64(0x9b3636d836adee6c), CONST64(0xffa6a6a2a6590451), CONST64(0x0cd2d26fd2debdb9), CONST64(0x0ef5f5f3f5fb06f7),
CONST64(0x967979f979ef80f2), CONST64(0x306f6fa16f5fcede), CONST64(0x6d91917e91fcef3f), CONST64(0xf852525552aa07a4),
CONST64(0x4760609d6027fdc0), CONST64(0x35bcbccabc897665), CONST64(0x379b9b569baccd2b), CONST64(0x8a8e8e028e048c01),
CONST64(0xd2a3a3b6a371155b), CONST64(0x6c0c0c300c603c18), CONST64(0x847b7bf17bff8af6), CONST64(0x803535d435b5e16a),
CONST64(0xf51d1d741de8693a), CONST64(0xb3e0e0a7e05347dd), CONST64(0x21d7d77bd7f6acb3), CONST64(0x9cc2c22fc25eed99),
CONST64(0x432e2eb82e6d965c), CONST64(0x294b4b314b627a96), CONST64(0x5dfefedffea321e1), CONST64(0xd5575741578216ae),
CONST64(0xbd15155415a8412a), CONST64(0xe87777c1779fb6ee), CONST64(0x923737dc37a5eb6e), CONST64(0x9ee5e5b3e57b56d7),
CONST64(0x139f9f469f8cd923), CONST64(0x23f0f0e7f0d317fd), CONST64(0x204a4a354a6a7f94), CONST64(0x44dada4fda9e95a9),
CONST64(0xa258587d58fa25b0), CONST64(0xcfc9c903c906ca8f), CONST64(0x7c2929a429558d52), CONST64(0x5a0a0a280a502214),
CONST64(0x50b1b1feb1e14f7f), CONST64(0xc9a0a0baa0691a5d), CONST64(0x146b6bb16b7fdad6), CONST64(0xd985852e855cab17),
CONST64(0x3cbdbdcebd817367), CONST64(0x8f5d5d695dd234ba), CONST64(0x9010104010805020), CONST64(0x07f4f4f7f4f303f5),
CONST64(0xddcbcb0bcb16c08b), CONST64(0xd33e3ef83eedc67c), CONST64(0x2d0505140528110a), CONST64(0x78676781671fe6ce),
CONST64(0x97e4e4b7e47353d5), CONST64(0x0227279c2725bb4e), CONST64(0x7341411941325882), CONST64(0xa78b8b168b2c9d0b),
CONST64(0xf6a7a7a6a7510153), CONST64(0xb27d7de97dcf94fa), CONST64(0x4995956e95dcfb37), CONST64(0x56d8d847d88e9fad),
CONST64(0x70fbfbcbfb8b30eb), CONST64(0xcdeeee9fee2371c1), CONST64(0xbb7c7ced7cc791f8), CONST64(0x716666856617e3cc),
CONST64(0x7bdddd53dda68ea7), CONST64(0xaf17175c17b84b2e), CONST64(0x454747014702468e), CONST64(0x1a9e9e429e84dc21),
CONST64(0xd4caca0fca1ec589), CONST64(0x582d2db42d75995a), CONST64(0x2ebfbfc6bf917963), CONST64(0x3f07071c07381b0e),
CONST64(0xacadad8ead012347), CONST64(0xb05a5a755aea2fb4), CONST64(0xef838336836cb51b), CONST64(0xb63333cc3385ff66),
CONST64(0x5c636391633ff2c6), CONST64(0x1202020802100a04), CONST64(0x93aaaa92aa393849), CONST64(0xde7171d971afa8e2),
CONST64(0xc6c8c807c80ecf8d), CONST64(0xd119196419c87d32), CONST64(0x3b49493949727092), CONST64(0x5fd9d943d9869aaf),
CONST64(0x31f2f2eff2c31df9), CONST64(0xa8e3e3abe34b48db), CONST64(0xb95b5b715be22ab6), CONST64(0xbc88881a8834920d),
CONST64(0x3e9a9a529aa4c829), CONST64(0x0b262698262dbe4c), CONST64(0xbf3232c8328dfa64), CONST64(0x59b0b0fab0e94a7d),
CONST64(0xf2e9e983e91b6acf), CONST64(0x770f0f3c0f78331e), CONST64(0x33d5d573d5e6a6b7), CONST64(0xf480803a8074ba1d),
CONST64(0x27bebec2be997c61), CONST64(0xebcdcd13cd26de87), CONST64(0x893434d034bde468), CONST64(0x3248483d487a7590),
CONST64(0x54ffffdbffab24e3), CONST64(0x8d7a7af57af78ff4), CONST64(0x6490907a90f4ea3d), CONST64(0x9d5f5f615fc23ebe),
CONST64(0x3d202080201da040), CONST64(0x0f6868bd6867d5d0), CONST64(0xca1a1a681ad07234), CONST64(0xb7aeae82ae192c41),
CONST64(0x7db4b4eab4c95e75), CONST64(0xce54544d549a19a8), CONST64(0x7f93937693ece53b), CONST64(0x2f222288220daa44),
CONST64(0x6364648d6407e9c8), CONST64(0x2af1f1e3f1db12ff), CONST64(0xcc7373d173bfa2e6), CONST64(0x8212124812905a24),
CONST64(0x7a40401d403a5d80), CONST64(0x4808082008402810), CONST64(0x95c3c32bc356e89b), CONST64(0xdfecec97ec337bc5),
CONST64(0x4ddbdb4bdb9690ab), CONST64(0xc0a1a1bea1611f5f), CONST64(0x918d8d0e8d1c8307), CONST64(0xc83d3df43df5c97a),
CONST64(0x5b97976697ccf133), CONST64(0x0000000000000000), CONST64(0xf9cfcf1bcf36d483), CONST64(0x6e2b2bac2b458756),
CONST64(0xe17676c57697b3ec), CONST64(0xe68282328264b019), CONST64(0x28d6d67fd6fea9b1), CONST64(0xc31b1b6c1bd87736),
CONST64(0x74b5b5eeb5c15b77), CONST64(0xbeafaf86af112943), CONST64(0x1d6a6ab56a77dfd4), CONST64(0xea50505d50ba0da0),
CONST64(0x5745450945124c8a), CONST64(0x38f3f3ebf3cb18fb), CONST64(0xad3030c0309df060), CONST64(0xc4efef9bef2b74c3),
CONST64(0xda3f3ffc3fe5c37e), CONST64(0xc755554955921caa), CONST64(0xdba2a2b2a2791059), CONST64(0xe9eaea8fea0365c9),
CONST64(0x6a656589650fecca), CONST64(0x03babad2bab96869), CONST64(0x4a2f2fbc2f65935e), CONST64(0x8ec0c027c04ee79d),
CONST64(0x60dede5fdebe81a1), CONST64(0xfc1c1c701ce06c38), CONST64(0x46fdfdd3fdbb2ee7), CONST64(0x1f4d4d294d52649a),
CONST64(0x7692927292e4e039), CONST64(0xfa7575c9758fbcea), CONST64(0x3606061806301e0c), CONST64(0xae8a8a128a249809),
CONST64(0x4bb2b2f2b2f94079), CONST64(0x85e6e6bfe66359d1), CONST64(0x7e0e0e380e70361c), CONST64(0xe71f1f7c1ff8633e),
CONST64(0x556262956237f7c4), CONST64(0x3ad4d477d4eea3b5), CONST64(0x81a8a89aa829324d), CONST64(0x5296966296c4f431),
CONST64(0x62f9f9c3f99b3aef), CONST64(0xa3c5c533c566f697), CONST64(0x102525942535b14a), CONST64(0xab59597959f220b2),
CONST64(0xd084842a8454ae15), CONST64(0xc57272d572b7a7e4), CONST64(0xec3939e439d5dd72), CONST64(0x164c4c2d4c5a6198),
CONST64(0x945e5e655eca3bbc), CONST64(0x9f7878fd78e785f0), CONST64(0xe53838e038ddd870), CONST64(0x988c8c0a8c148605),
CONST64(0x17d1d163d1c6b2bf), CONST64(0xe4a5a5aea5410b57), CONST64(0xa1e2e2afe2434dd9), CONST64(0x4e616199612ff8c2),
CONST64(0x42b3b3f6b3f1457b), CONST64(0x342121842115a542), CONST64(0x089c9c4a9c94d625), CONST64(0xee1e1e781ef0663c),
CONST64(0x6143431143225286), CONST64(0xb1c7c73bc776fc93), CONST64(0x4ffcfcd7fcb32be5), CONST64(0x2404041004201408),
CONST64(0xe351515951b208a2), CONST64(0x2599995e99bcc72f), CONST64(0x226d6da96d4fc4da), CONST64(0x650d0d340d68391a),
CONST64(0x79fafacffa8335e9), CONST64(0x69dfdf5bdfb684a3), CONST64(0xa97e7ee57ed79bfc), CONST64(0x19242490243db448),
CONST64(0xfe3b3bec3bc5d776), CONST64(0x9aabab96ab313d4b), CONST64(0xf0cece1fce3ed181), CONST64(0x9911114411885522),
CONST64(0x838f8f068f0c8903), CONST64(0x044e4e254e4a6b9c), CONST64(0x66b7b7e6b7d15173), CONST64(0xe0ebeb8beb0b60cb),
CONST64(0xc13c3cf03cfdcc78), CONST64(0xfd81813e817cbf1f), CONST64(0x4094946a94d4fe35), CONST64(0x1cf7f7fbf7eb0cf3),
CONST64(0x18b9b9deb9a1676f), CONST64(0x8b13134c13985f26), CONST64(0x512c2cb02c7d9c58), CONST64(0x05d3d36bd3d6b8bb),
CONST64(0x8ce7e7bbe76b5cd3), CONST64(0x396e6ea56e57cbdc), CONST64(0xaac4c437c46ef395), CONST64(0x1b03030c03180f06),
CONST64(0xdc565645568a13ac), CONST64(0x5e44440d441a4988), CONST64(0xa07f7fe17fdf9efe), CONST64(0x88a9a99ea921374f),
CONST64(0x672a2aa82a4d8254), CONST64(0x0abbbbd6bbb16d6b), CONST64(0x87c1c123c146e29f), CONST64(0xf153535153a202a6),
CONST64(0x72dcdc57dcae8ba5), CONST64(0x530b0b2c0b582716), CONST64(0x019d9d4e9d9cd327), CONST64(0x2b6c6cad6c47c1d8),
CONST64(0xa43131c43195f562), CONST64(0xf37474cd7487b9e8), CONST64(0x15f6f6fff6e309f1), CONST64(0x4c464605460a438c),
CONST64(0xa5acac8aac092645), CONST64(0xb589891e893c970f), CONST64(0xb414145014a04428), CONST64(0xbae1e1a3e15b42df),
CONST64(0xa616165816b04e2c), CONST64(0xf73a3ae83acdd274), CONST64(0x066969b9696fd0d2), CONST64(0x4109092409482d12),
CONST64(0xd77070dd70a7ade0), CONST64(0x6fb6b6e2b6d95471), CONST64(0x1ed0d067d0ceb7bd), CONST64(0xd6eded93ed3b7ec7),
CONST64(0xe2cccc17cc2edb85), CONST64(0x68424215422a5784), CONST64(0x2c98985a98b4c22d), CONST64(0xeda4a4aaa4490e55),
CONST64(0x752828a0285d8850), CONST64(0x865c5c6d5cda31b8), CONST64(0x6bf8f8c7f8933fed), CONST64(0xc28686228644a411)
};
static const ulong64 sbox2[] = {
CONST64(0x30d818186018c078), CONST64(0x462623238c2305af), CONST64(0x91b8c6c63fc67ef9), CONST64(0xcdfbe8e887e8136f),
CONST64(0x13cb878726874ca1), CONST64(0x6d11b8b8dab8a962), CONST64(0x0209010104010805), CONST64(0x9e0d4f4f214f426e),
CONST64(0x6c9b3636d836adee), CONST64(0x51ffa6a6a2a65904), CONST64(0xb90cd2d26fd2debd), CONST64(0xf70ef5f5f3f5fb06),
CONST64(0xf2967979f979ef80), CONST64(0xde306f6fa16f5fce), CONST64(0x3f6d91917e91fcef), CONST64(0xa4f852525552aa07),
CONST64(0xc04760609d6027fd), CONST64(0x6535bcbccabc8976), CONST64(0x2b379b9b569baccd), CONST64(0x018a8e8e028e048c),
CONST64(0x5bd2a3a3b6a37115), CONST64(0x186c0c0c300c603c), CONST64(0xf6847b7bf17bff8a), CONST64(0x6a803535d435b5e1),
CONST64(0x3af51d1d741de869), CONST64(0xddb3e0e0a7e05347), CONST64(0xb321d7d77bd7f6ac), CONST64(0x999cc2c22fc25eed),
CONST64(0x5c432e2eb82e6d96), CONST64(0x96294b4b314b627a), CONST64(0xe15dfefedffea321), CONST64(0xaed5575741578216),
CONST64(0x2abd15155415a841), CONST64(0xeee87777c1779fb6), CONST64(0x6e923737dc37a5eb), CONST64(0xd79ee5e5b3e57b56),
CONST64(0x23139f9f469f8cd9), CONST64(0xfd23f0f0e7f0d317), CONST64(0x94204a4a354a6a7f), CONST64(0xa944dada4fda9e95),
CONST64(0xb0a258587d58fa25), CONST64(0x8fcfc9c903c906ca), CONST64(0x527c2929a429558d), CONST64(0x145a0a0a280a5022),
CONST64(0x7f50b1b1feb1e14f), CONST64(0x5dc9a0a0baa0691a), CONST64(0xd6146b6bb16b7fda), CONST64(0x17d985852e855cab),
CONST64(0x673cbdbdcebd8173), CONST64(0xba8f5d5d695dd234), CONST64(0x2090101040108050), CONST64(0xf507f4f4f7f4f303),
CONST64(0x8bddcbcb0bcb16c0), CONST64(0x7cd33e3ef83eedc6), CONST64(0x0a2d050514052811), CONST64(0xce78676781671fe6),
CONST64(0xd597e4e4b7e47353), CONST64(0x4e0227279c2725bb), CONST64(0x8273414119413258), CONST64(0x0ba78b8b168b2c9d),
CONST64(0x53f6a7a7a6a75101), CONST64(0xfab27d7de97dcf94), CONST64(0x374995956e95dcfb), CONST64(0xad56d8d847d88e9f),
CONST64(0xeb70fbfbcbfb8b30), CONST64(0xc1cdeeee9fee2371), CONST64(0xf8bb7c7ced7cc791), CONST64(0xcc716666856617e3),
CONST64(0xa77bdddd53dda68e), CONST64(0x2eaf17175c17b84b), CONST64(0x8e45474701470246), CONST64(0x211a9e9e429e84dc),
CONST64(0x89d4caca0fca1ec5), CONST64(0x5a582d2db42d7599), CONST64(0x632ebfbfc6bf9179), CONST64(0x0e3f07071c07381b),
CONST64(0x47acadad8ead0123), CONST64(0xb4b05a5a755aea2f), CONST64(0x1bef838336836cb5), CONST64(0x66b63333cc3385ff),
CONST64(0xc65c636391633ff2), CONST64(0x041202020802100a), CONST64(0x4993aaaa92aa3938), CONST64(0xe2de7171d971afa8),
CONST64(0x8dc6c8c807c80ecf), CONST64(0x32d119196419c87d), CONST64(0x923b494939497270), CONST64(0xaf5fd9d943d9869a),
CONST64(0xf931f2f2eff2c31d), CONST64(0xdba8e3e3abe34b48), CONST64(0xb6b95b5b715be22a), CONST64(0x0dbc88881a883492),
CONST64(0x293e9a9a529aa4c8), CONST64(0x4c0b262698262dbe), CONST64(0x64bf3232c8328dfa), CONST64(0x7d59b0b0fab0e94a),
CONST64(0xcff2e9e983e91b6a), CONST64(0x1e770f0f3c0f7833), CONST64(0xb733d5d573d5e6a6), CONST64(0x1df480803a8074ba),
CONST64(0x6127bebec2be997c), CONST64(0x87ebcdcd13cd26de), CONST64(0x68893434d034bde4), CONST64(0x903248483d487a75),
CONST64(0xe354ffffdbffab24), CONST64(0xf48d7a7af57af78f), CONST64(0x3d6490907a90f4ea), CONST64(0xbe9d5f5f615fc23e),
CONST64(0x403d202080201da0), CONST64(0xd00f6868bd6867d5), CONST64(0x34ca1a1a681ad072), CONST64(0x41b7aeae82ae192c),
CONST64(0x757db4b4eab4c95e), CONST64(0xa8ce54544d549a19), CONST64(0x3b7f93937693ece5), CONST64(0x442f222288220daa),
CONST64(0xc86364648d6407e9), CONST64(0xff2af1f1e3f1db12), CONST64(0xe6cc7373d173bfa2), CONST64(0x248212124812905a),
CONST64(0x807a40401d403a5d), CONST64(0x1048080820084028), CONST64(0x9b95c3c32bc356e8), CONST64(0xc5dfecec97ec337b),
CONST64(0xab4ddbdb4bdb9690), CONST64(0x5fc0a1a1bea1611f), CONST64(0x07918d8d0e8d1c83), CONST64(0x7ac83d3df43df5c9),
CONST64(0x335b97976697ccf1), CONST64(0x0000000000000000), CONST64(0x83f9cfcf1bcf36d4), CONST64(0x566e2b2bac2b4587),
CONST64(0xece17676c57697b3), CONST64(0x19e68282328264b0), CONST64(0xb128d6d67fd6fea9), CONST64(0x36c31b1b6c1bd877),
CONST64(0x7774b5b5eeb5c15b), CONST64(0x43beafaf86af1129), CONST64(0xd41d6a6ab56a77df), CONST64(0xa0ea50505d50ba0d),
CONST64(0x8a5745450945124c), CONST64(0xfb38f3f3ebf3cb18), CONST64(0x60ad3030c0309df0), CONST64(0xc3c4efef9bef2b74),
CONST64(0x7eda3f3ffc3fe5c3), CONST64(0xaac755554955921c), CONST64(0x59dba2a2b2a27910), CONST64(0xc9e9eaea8fea0365),
CONST64(0xca6a656589650fec), CONST64(0x6903babad2bab968), CONST64(0x5e4a2f2fbc2f6593), CONST64(0x9d8ec0c027c04ee7),
CONST64(0xa160dede5fdebe81), CONST64(0x38fc1c1c701ce06c), CONST64(0xe746fdfdd3fdbb2e), CONST64(0x9a1f4d4d294d5264),
CONST64(0x397692927292e4e0), CONST64(0xeafa7575c9758fbc), CONST64(0x0c3606061806301e), CONST64(0x09ae8a8a128a2498),
CONST64(0x794bb2b2f2b2f940), CONST64(0xd185e6e6bfe66359), CONST64(0x1c7e0e0e380e7036), CONST64(0x3ee71f1f7c1ff863),
CONST64(0xc4556262956237f7), CONST64(0xb53ad4d477d4eea3), CONST64(0x4d81a8a89aa82932), CONST64(0x315296966296c4f4),
CONST64(0xef62f9f9c3f99b3a), CONST64(0x97a3c5c533c566f6), CONST64(0x4a102525942535b1), CONST64(0xb2ab59597959f220),
CONST64(0x15d084842a8454ae), CONST64(0xe4c57272d572b7a7), CONST64(0x72ec3939e439d5dd), CONST64(0x98164c4c2d4c5a61),
CONST64(0xbc945e5e655eca3b), CONST64(0xf09f7878fd78e785), CONST64(0x70e53838e038ddd8), CONST64(0x05988c8c0a8c1486),
CONST64(0xbf17d1d163d1c6b2), CONST64(0x57e4a5a5aea5410b), CONST64(0xd9a1e2e2afe2434d), CONST64(0xc24e616199612ff8),
CONST64(0x7b42b3b3f6b3f145), CONST64(0x42342121842115a5), CONST64(0x25089c9c4a9c94d6), CONST64(0x3cee1e1e781ef066),
CONST64(0x8661434311432252), CONST64(0x93b1c7c73bc776fc), CONST64(0xe54ffcfcd7fcb32b), CONST64(0x0824040410042014),
CONST64(0xa2e351515951b208), CONST64(0x2f2599995e99bcc7), CONST64(0xda226d6da96d4fc4), CONST64(0x1a650d0d340d6839),
CONST64(0xe979fafacffa8335), CONST64(0xa369dfdf5bdfb684), CONST64(0xfca97e7ee57ed79b), CONST64(0x4819242490243db4),
CONST64(0x76fe3b3bec3bc5d7), CONST64(0x4b9aabab96ab313d), CONST64(0x81f0cece1fce3ed1), CONST64(0x2299111144118855),
CONST64(0x03838f8f068f0c89), CONST64(0x9c044e4e254e4a6b), CONST64(0x7366b7b7e6b7d151), CONST64(0xcbe0ebeb8beb0b60),
CONST64(0x78c13c3cf03cfdcc), CONST64(0x1ffd81813e817cbf), CONST64(0x354094946a94d4fe), CONST64(0xf31cf7f7fbf7eb0c),
CONST64(0x6f18b9b9deb9a167), CONST64(0x268b13134c13985f), CONST64(0x58512c2cb02c7d9c), CONST64(0xbb05d3d36bd3d6b8),
CONST64(0xd38ce7e7bbe76b5c), CONST64(0xdc396e6ea56e57cb), CONST64(0x95aac4c437c46ef3), CONST64(0x061b03030c03180f),
CONST64(0xacdc565645568a13), CONST64(0x885e44440d441a49), CONST64(0xfea07f7fe17fdf9e), CONST64(0x4f88a9a99ea92137),
CONST64(0x54672a2aa82a4d82), CONST64(0x6b0abbbbd6bbb16d), CONST64(0x9f87c1c123c146e2), CONST64(0xa6f153535153a202),
CONST64(0xa572dcdc57dcae8b), CONST64(0x16530b0b2c0b5827), CONST64(0x27019d9d4e9d9cd3), CONST64(0xd82b6c6cad6c47c1),
CONST64(0x62a43131c43195f5), CONST64(0xe8f37474cd7487b9), CONST64(0xf115f6f6fff6e309), CONST64(0x8c4c464605460a43),
CONST64(0x45a5acac8aac0926), CONST64(0x0fb589891e893c97), CONST64(0x28b414145014a044), CONST64(0xdfbae1e1a3e15b42),
CONST64(0x2ca616165816b04e), CONST64(0x74f73a3ae83acdd2), CONST64(0xd2066969b9696fd0), CONST64(0x124109092409482d),
CONST64(0xe0d77070dd70a7ad), CONST64(0x716fb6b6e2b6d954), CONST64(0xbd1ed0d067d0ceb7), CONST64(0xc7d6eded93ed3b7e),
CONST64(0x85e2cccc17cc2edb), CONST64(0x8468424215422a57), CONST64(0x2d2c98985a98b4c2), CONST64(0x55eda4a4aaa4490e),
CONST64(0x50752828a0285d88), CONST64(0xb8865c5c6d5cda31), CONST64(0xed6bf8f8c7f8933f), CONST64(0x11c28686228644a4)
};
static const ulong64 sbox3[] = {
CONST64(0x7830d818186018c0), CONST64(0xaf462623238c2305), CONST64(0xf991b8c6c63fc67e), CONST64(0x6fcdfbe8e887e813),
CONST64(0xa113cb878726874c), CONST64(0x626d11b8b8dab8a9), CONST64(0x0502090101040108), CONST64(0x6e9e0d4f4f214f42),
CONST64(0xee6c9b3636d836ad), CONST64(0x0451ffa6a6a2a659), CONST64(0xbdb90cd2d26fd2de), CONST64(0x06f70ef5f5f3f5fb),
CONST64(0x80f2967979f979ef), CONST64(0xcede306f6fa16f5f), CONST64(0xef3f6d91917e91fc), CONST64(0x07a4f852525552aa),
CONST64(0xfdc04760609d6027), CONST64(0x766535bcbccabc89), CONST64(0xcd2b379b9b569bac), CONST64(0x8c018a8e8e028e04),
CONST64(0x155bd2a3a3b6a371), CONST64(0x3c186c0c0c300c60), CONST64(0x8af6847b7bf17bff), CONST64(0xe16a803535d435b5),
CONST64(0x693af51d1d741de8), CONST64(0x47ddb3e0e0a7e053), CONST64(0xacb321d7d77bd7f6), CONST64(0xed999cc2c22fc25e),
CONST64(0x965c432e2eb82e6d), CONST64(0x7a96294b4b314b62), CONST64(0x21e15dfefedffea3), CONST64(0x16aed55757415782),
CONST64(0x412abd15155415a8), CONST64(0xb6eee87777c1779f), CONST64(0xeb6e923737dc37a5), CONST64(0x56d79ee5e5b3e57b),
CONST64(0xd923139f9f469f8c), CONST64(0x17fd23f0f0e7f0d3), CONST64(0x7f94204a4a354a6a), CONST64(0x95a944dada4fda9e),
CONST64(0x25b0a258587d58fa), CONST64(0xca8fcfc9c903c906), CONST64(0x8d527c2929a42955), CONST64(0x22145a0a0a280a50),
CONST64(0x4f7f50b1b1feb1e1), CONST64(0x1a5dc9a0a0baa069), CONST64(0xdad6146b6bb16b7f), CONST64(0xab17d985852e855c),
CONST64(0x73673cbdbdcebd81), CONST64(0x34ba8f5d5d695dd2), CONST64(0x5020901010401080), CONST64(0x03f507f4f4f7f4f3),
CONST64(0xc08bddcbcb0bcb16), CONST64(0xc67cd33e3ef83eed), CONST64(0x110a2d0505140528), CONST64(0xe6ce78676781671f),
CONST64(0x53d597e4e4b7e473), CONST64(0xbb4e0227279c2725), CONST64(0x5882734141194132), CONST64(0x9d0ba78b8b168b2c),
CONST64(0x0153f6a7a7a6a751), CONST64(0x94fab27d7de97dcf), CONST64(0xfb374995956e95dc), CONST64(0x9fad56d8d847d88e),
CONST64(0x30eb70fbfbcbfb8b), CONST64(0x71c1cdeeee9fee23), CONST64(0x91f8bb7c7ced7cc7), CONST64(0xe3cc716666856617),
CONST64(0x8ea77bdddd53dda6), CONST64(0x4b2eaf17175c17b8), CONST64(0x468e454747014702), CONST64(0xdc211a9e9e429e84),
CONST64(0xc589d4caca0fca1e), CONST64(0x995a582d2db42d75), CONST64(0x79632ebfbfc6bf91), CONST64(0x1b0e3f07071c0738),
CONST64(0x2347acadad8ead01), CONST64(0x2fb4b05a5a755aea), CONST64(0xb51bef838336836c), CONST64(0xff66b63333cc3385),
CONST64(0xf2c65c636391633f), CONST64(0x0a04120202080210), CONST64(0x384993aaaa92aa39), CONST64(0xa8e2de7171d971af),
CONST64(0xcf8dc6c8c807c80e), CONST64(0x7d32d119196419c8), CONST64(0x70923b4949394972), CONST64(0x9aaf5fd9d943d986),
CONST64(0x1df931f2f2eff2c3), CONST64(0x48dba8e3e3abe34b), CONST64(0x2ab6b95b5b715be2), CONST64(0x920dbc88881a8834),
CONST64(0xc8293e9a9a529aa4), CONST64(0xbe4c0b262698262d), CONST64(0xfa64bf3232c8328d), CONST64(0x4a7d59b0b0fab0e9),
CONST64(0x6acff2e9e983e91b), CONST64(0x331e770f0f3c0f78), CONST64(0xa6b733d5d573d5e6), CONST64(0xba1df480803a8074),
CONST64(0x7c6127bebec2be99), CONST64(0xde87ebcdcd13cd26), CONST64(0xe468893434d034bd), CONST64(0x75903248483d487a),
CONST64(0x24e354ffffdbffab), CONST64(0x8ff48d7a7af57af7), CONST64(0xea3d6490907a90f4), CONST64(0x3ebe9d5f5f615fc2),
CONST64(0xa0403d202080201d), CONST64(0xd5d00f6868bd6867), CONST64(0x7234ca1a1a681ad0), CONST64(0x2c41b7aeae82ae19),
CONST64(0x5e757db4b4eab4c9), CONST64(0x19a8ce54544d549a), CONST64(0xe53b7f93937693ec), CONST64(0xaa442f222288220d),
CONST64(0xe9c86364648d6407), CONST64(0x12ff2af1f1e3f1db), CONST64(0xa2e6cc7373d173bf), CONST64(0x5a24821212481290),
CONST64(0x5d807a40401d403a), CONST64(0x2810480808200840), CONST64(0xe89b95c3c32bc356), CONST64(0x7bc5dfecec97ec33),
CONST64(0x90ab4ddbdb4bdb96), CONST64(0x1f5fc0a1a1bea161), CONST64(0x8307918d8d0e8d1c), CONST64(0xc97ac83d3df43df5),
CONST64(0xf1335b97976697cc), CONST64(0x0000000000000000), CONST64(0xd483f9cfcf1bcf36), CONST64(0x87566e2b2bac2b45),
CONST64(0xb3ece17676c57697), CONST64(0xb019e68282328264), CONST64(0xa9b128d6d67fd6fe), CONST64(0x7736c31b1b6c1bd8),
CONST64(0x5b7774b5b5eeb5c1), CONST64(0x2943beafaf86af11), CONST64(0xdfd41d6a6ab56a77), CONST64(0x0da0ea50505d50ba),
CONST64(0x4c8a574545094512), CONST64(0x18fb38f3f3ebf3cb), CONST64(0xf060ad3030c0309d), CONST64(0x74c3c4efef9bef2b),
CONST64(0xc37eda3f3ffc3fe5), CONST64(0x1caac75555495592), CONST64(0x1059dba2a2b2a279), CONST64(0x65c9e9eaea8fea03),
CONST64(0xecca6a656589650f), CONST64(0x686903babad2bab9), CONST64(0x935e4a2f2fbc2f65), CONST64(0xe79d8ec0c027c04e),
CONST64(0x81a160dede5fdebe), CONST64(0x6c38fc1c1c701ce0), CONST64(0x2ee746fdfdd3fdbb), CONST64(0x649a1f4d4d294d52),
CONST64(0xe0397692927292e4), CONST64(0xbceafa7575c9758f), CONST64(0x1e0c360606180630), CONST64(0x9809ae8a8a128a24),
CONST64(0x40794bb2b2f2b2f9), CONST64(0x59d185e6e6bfe663), CONST64(0x361c7e0e0e380e70), CONST64(0x633ee71f1f7c1ff8),
CONST64(0xf7c4556262956237), CONST64(0xa3b53ad4d477d4ee), CONST64(0x324d81a8a89aa829), CONST64(0xf4315296966296c4),
CONST64(0x3aef62f9f9c3f99b), CONST64(0xf697a3c5c533c566), CONST64(0xb14a102525942535), CONST64(0x20b2ab59597959f2),
CONST64(0xae15d084842a8454), CONST64(0xa7e4c57272d572b7), CONST64(0xdd72ec3939e439d5), CONST64(0x6198164c4c2d4c5a),
CONST64(0x3bbc945e5e655eca), CONST64(0x85f09f7878fd78e7), CONST64(0xd870e53838e038dd), CONST64(0x8605988c8c0a8c14),
CONST64(0xb2bf17d1d163d1c6), CONST64(0x0b57e4a5a5aea541), CONST64(0x4dd9a1e2e2afe243), CONST64(0xf8c24e616199612f),
CONST64(0x457b42b3b3f6b3f1), CONST64(0xa542342121842115), CONST64(0xd625089c9c4a9c94), CONST64(0x663cee1e1e781ef0),
CONST64(0x5286614343114322), CONST64(0xfc93b1c7c73bc776), CONST64(0x2be54ffcfcd7fcb3), CONST64(0x1408240404100420),
CONST64(0x08a2e351515951b2), CONST64(0xc72f2599995e99bc), CONST64(0xc4da226d6da96d4f), CONST64(0x391a650d0d340d68),
CONST64(0x35e979fafacffa83), CONST64(0x84a369dfdf5bdfb6), CONST64(0x9bfca97e7ee57ed7), CONST64(0xb44819242490243d),
CONST64(0xd776fe3b3bec3bc5), CONST64(0x3d4b9aabab96ab31), CONST64(0xd181f0cece1fce3e), CONST64(0x5522991111441188),
CONST64(0x8903838f8f068f0c), CONST64(0x6b9c044e4e254e4a), CONST64(0x517366b7b7e6b7d1), CONST64(0x60cbe0ebeb8beb0b),
CONST64(0xcc78c13c3cf03cfd), CONST64(0xbf1ffd81813e817c), CONST64(0xfe354094946a94d4), CONST64(0x0cf31cf7f7fbf7eb),
CONST64(0x676f18b9b9deb9a1), CONST64(0x5f268b13134c1398), CONST64(0x9c58512c2cb02c7d), CONST64(0xb8bb05d3d36bd3d6),
CONST64(0x5cd38ce7e7bbe76b), CONST64(0xcbdc396e6ea56e57), CONST64(0xf395aac4c437c46e), CONST64(0x0f061b03030c0318),
CONST64(0x13acdc565645568a), CONST64(0x49885e44440d441a), CONST64(0x9efea07f7fe17fdf), CONST64(0x374f88a9a99ea921),
CONST64(0x8254672a2aa82a4d), CONST64(0x6d6b0abbbbd6bbb1), CONST64(0xe29f87c1c123c146), CONST64(0x02a6f153535153a2),
CONST64(0x8ba572dcdc57dcae), CONST64(0x2716530b0b2c0b58), CONST64(0xd327019d9d4e9d9c), CONST64(0xc1d82b6c6cad6c47),
CONST64(0xf562a43131c43195), CONST64(0xb9e8f37474cd7487), CONST64(0x09f115f6f6fff6e3), CONST64(0x438c4c464605460a),
CONST64(0x2645a5acac8aac09), CONST64(0x970fb589891e893c), CONST64(0x4428b414145014a0), CONST64(0x42dfbae1e1a3e15b),
CONST64(0x4e2ca616165816b0), CONST64(0xd274f73a3ae83acd), CONST64(0xd0d2066969b9696f), CONST64(0x2d12410909240948),
CONST64(0xade0d77070dd70a7), CONST64(0x54716fb6b6e2b6d9), CONST64(0xb7bd1ed0d067d0ce), CONST64(0x7ec7d6eded93ed3b),
CONST64(0xdb85e2cccc17cc2e), CONST64(0x578468424215422a), CONST64(0xc22d2c98985a98b4), CONST64(0x0e55eda4a4aaa449),
CONST64(0x8850752828a0285d), CONST64(0x31b8865c5c6d5cda), CONST64(0x3fed6bf8f8c7f893), CONST64(0xa411c28686228644)
};
static const ulong64 sbox4[] = {
CONST64(0xc07830d818186018), CONST64(0x05af462623238c23), CONST64(0x7ef991b8c6c63fc6), CONST64(0x136fcdfbe8e887e8),
CONST64(0x4ca113cb87872687), CONST64(0xa9626d11b8b8dab8), CONST64(0x0805020901010401), CONST64(0x426e9e0d4f4f214f),
CONST64(0xadee6c9b3636d836), CONST64(0x590451ffa6a6a2a6), CONST64(0xdebdb90cd2d26fd2), CONST64(0xfb06f70ef5f5f3f5),
CONST64(0xef80f2967979f979), CONST64(0x5fcede306f6fa16f), CONST64(0xfcef3f6d91917e91), CONST64(0xaa07a4f852525552),
CONST64(0x27fdc04760609d60), CONST64(0x89766535bcbccabc), CONST64(0xaccd2b379b9b569b), CONST64(0x048c018a8e8e028e),
CONST64(0x71155bd2a3a3b6a3), CONST64(0x603c186c0c0c300c), CONST64(0xff8af6847b7bf17b), CONST64(0xb5e16a803535d435),
CONST64(0xe8693af51d1d741d), CONST64(0x5347ddb3e0e0a7e0), CONST64(0xf6acb321d7d77bd7), CONST64(0x5eed999cc2c22fc2),
CONST64(0x6d965c432e2eb82e), CONST64(0x627a96294b4b314b), CONST64(0xa321e15dfefedffe), CONST64(0x8216aed557574157),
CONST64(0xa8412abd15155415), CONST64(0x9fb6eee87777c177), CONST64(0xa5eb6e923737dc37), CONST64(0x7b56d79ee5e5b3e5),
CONST64(0x8cd923139f9f469f), CONST64(0xd317fd23f0f0e7f0), CONST64(0x6a7f94204a4a354a), CONST64(0x9e95a944dada4fda),
CONST64(0xfa25b0a258587d58), CONST64(0x06ca8fcfc9c903c9), CONST64(0x558d527c2929a429), CONST64(0x5022145a0a0a280a),
CONST64(0xe14f7f50b1b1feb1), CONST64(0x691a5dc9a0a0baa0), CONST64(0x7fdad6146b6bb16b), CONST64(0x5cab17d985852e85),
CONST64(0x8173673cbdbdcebd), CONST64(0xd234ba8f5d5d695d), CONST64(0x8050209010104010), CONST64(0xf303f507f4f4f7f4),
CONST64(0x16c08bddcbcb0bcb), CONST64(0xedc67cd33e3ef83e), CONST64(0x28110a2d05051405), CONST64(0x1fe6ce7867678167),
CONST64(0x7353d597e4e4b7e4), CONST64(0x25bb4e0227279c27), CONST64(0x3258827341411941), CONST64(0x2c9d0ba78b8b168b),
CONST64(0x510153f6a7a7a6a7), CONST64(0xcf94fab27d7de97d), CONST64(0xdcfb374995956e95), CONST64(0x8e9fad56d8d847d8),
CONST64(0x8b30eb70fbfbcbfb), CONST64(0x2371c1cdeeee9fee), CONST64(0xc791f8bb7c7ced7c), CONST64(0x17e3cc7166668566),
CONST64(0xa68ea77bdddd53dd), CONST64(0xb84b2eaf17175c17), CONST64(0x02468e4547470147), CONST64(0x84dc211a9e9e429e),
CONST64(0x1ec589d4caca0fca), CONST64(0x75995a582d2db42d), CONST64(0x9179632ebfbfc6bf), CONST64(0x381b0e3f07071c07),
CONST64(0x012347acadad8ead), CONST64(0xea2fb4b05a5a755a), CONST64(0x6cb51bef83833683), CONST64(0x85ff66b63333cc33),
CONST64(0x3ff2c65c63639163), CONST64(0x100a041202020802), CONST64(0x39384993aaaa92aa), CONST64(0xafa8e2de7171d971),
CONST64(0x0ecf8dc6c8c807c8), CONST64(0xc87d32d119196419), CONST64(0x7270923b49493949), CONST64(0x869aaf5fd9d943d9),
CONST64(0xc31df931f2f2eff2), CONST64(0x4b48dba8e3e3abe3), CONST64(0xe22ab6b95b5b715b), CONST64(0x34920dbc88881a88),
CONST64(0xa4c8293e9a9a529a), CONST64(0x2dbe4c0b26269826), CONST64(0x8dfa64bf3232c832), CONST64(0xe94a7d59b0b0fab0),
CONST64(0x1b6acff2e9e983e9), CONST64(0x78331e770f0f3c0f), CONST64(0xe6a6b733d5d573d5), CONST64(0x74ba1df480803a80),
CONST64(0x997c6127bebec2be), CONST64(0x26de87ebcdcd13cd), CONST64(0xbde468893434d034), CONST64(0x7a75903248483d48),
CONST64(0xab24e354ffffdbff), CONST64(0xf78ff48d7a7af57a), CONST64(0xf4ea3d6490907a90), CONST64(0xc23ebe9d5f5f615f),
CONST64(0x1da0403d20208020), CONST64(0x67d5d00f6868bd68), CONST64(0xd07234ca1a1a681a), CONST64(0x192c41b7aeae82ae),
CONST64(0xc95e757db4b4eab4), CONST64(0x9a19a8ce54544d54), CONST64(0xece53b7f93937693), CONST64(0x0daa442f22228822),
CONST64(0x07e9c86364648d64), CONST64(0xdb12ff2af1f1e3f1), CONST64(0xbfa2e6cc7373d173), CONST64(0x905a248212124812),
CONST64(0x3a5d807a40401d40), CONST64(0x4028104808082008), CONST64(0x56e89b95c3c32bc3), CONST64(0x337bc5dfecec97ec),
CONST64(0x9690ab4ddbdb4bdb), CONST64(0x611f5fc0a1a1bea1), CONST64(0x1c8307918d8d0e8d), CONST64(0xf5c97ac83d3df43d),
CONST64(0xccf1335b97976697), CONST64(0x0000000000000000), CONST64(0x36d483f9cfcf1bcf), CONST64(0x4587566e2b2bac2b),
CONST64(0x97b3ece17676c576), CONST64(0x64b019e682823282), CONST64(0xfea9b128d6d67fd6), CONST64(0xd87736c31b1b6c1b),
CONST64(0xc15b7774b5b5eeb5), CONST64(0x112943beafaf86af), CONST64(0x77dfd41d6a6ab56a), CONST64(0xba0da0ea50505d50),
CONST64(0x124c8a5745450945), CONST64(0xcb18fb38f3f3ebf3), CONST64(0x9df060ad3030c030), CONST64(0x2b74c3c4efef9bef),
CONST64(0xe5c37eda3f3ffc3f), CONST64(0x921caac755554955), CONST64(0x791059dba2a2b2a2), CONST64(0x0365c9e9eaea8fea),
CONST64(0x0fecca6a65658965), CONST64(0xb9686903babad2ba), CONST64(0x65935e4a2f2fbc2f), CONST64(0x4ee79d8ec0c027c0),
CONST64(0xbe81a160dede5fde), CONST64(0xe06c38fc1c1c701c), CONST64(0xbb2ee746fdfdd3fd), CONST64(0x52649a1f4d4d294d),
CONST64(0xe4e0397692927292), CONST64(0x8fbceafa7575c975), CONST64(0x301e0c3606061806), CONST64(0x249809ae8a8a128a),
CONST64(0xf940794bb2b2f2b2), CONST64(0x6359d185e6e6bfe6), CONST64(0x70361c7e0e0e380e), CONST64(0xf8633ee71f1f7c1f),
CONST64(0x37f7c45562629562), CONST64(0xeea3b53ad4d477d4), CONST64(0x29324d81a8a89aa8), CONST64(0xc4f4315296966296),
CONST64(0x9b3aef62f9f9c3f9), CONST64(0x66f697a3c5c533c5), CONST64(0x35b14a1025259425), CONST64(0xf220b2ab59597959),
CONST64(0x54ae15d084842a84), CONST64(0xb7a7e4c57272d572), CONST64(0xd5dd72ec3939e439), CONST64(0x5a6198164c4c2d4c),
CONST64(0xca3bbc945e5e655e), CONST64(0xe785f09f7878fd78), CONST64(0xddd870e53838e038), CONST64(0x148605988c8c0a8c),
CONST64(0xc6b2bf17d1d163d1), CONST64(0x410b57e4a5a5aea5), CONST64(0x434dd9a1e2e2afe2), CONST64(0x2ff8c24e61619961),
CONST64(0xf1457b42b3b3f6b3), CONST64(0x15a5423421218421), CONST64(0x94d625089c9c4a9c), CONST64(0xf0663cee1e1e781e),
CONST64(0x2252866143431143), CONST64(0x76fc93b1c7c73bc7), CONST64(0xb32be54ffcfcd7fc), CONST64(0x2014082404041004),
CONST64(0xb208a2e351515951), CONST64(0xbcc72f2599995e99), CONST64(0x4fc4da226d6da96d), CONST64(0x68391a650d0d340d),
CONST64(0x8335e979fafacffa), CONST64(0xb684a369dfdf5bdf), CONST64(0xd79bfca97e7ee57e), CONST64(0x3db4481924249024),
CONST64(0xc5d776fe3b3bec3b), CONST64(0x313d4b9aabab96ab), CONST64(0x3ed181f0cece1fce), CONST64(0x8855229911114411),
CONST64(0x0c8903838f8f068f), CONST64(0x4a6b9c044e4e254e), CONST64(0xd1517366b7b7e6b7), CONST64(0x0b60cbe0ebeb8beb),
CONST64(0xfdcc78c13c3cf03c), CONST64(0x7cbf1ffd81813e81), CONST64(0xd4fe354094946a94), CONST64(0xeb0cf31cf7f7fbf7),
CONST64(0xa1676f18b9b9deb9), CONST64(0x985f268b13134c13), CONST64(0x7d9c58512c2cb02c), CONST64(0xd6b8bb05d3d36bd3),
CONST64(0x6b5cd38ce7e7bbe7), CONST64(0x57cbdc396e6ea56e), CONST64(0x6ef395aac4c437c4), CONST64(0x180f061b03030c03),
CONST64(0x8a13acdc56564556), CONST64(0x1a49885e44440d44), CONST64(0xdf9efea07f7fe17f), CONST64(0x21374f88a9a99ea9),
CONST64(0x4d8254672a2aa82a), CONST64(0xb16d6b0abbbbd6bb), CONST64(0x46e29f87c1c123c1), CONST64(0xa202a6f153535153),
CONST64(0xae8ba572dcdc57dc), CONST64(0x582716530b0b2c0b), CONST64(0x9cd327019d9d4e9d), CONST64(0x47c1d82b6c6cad6c),
CONST64(0x95f562a43131c431), CONST64(0x87b9e8f37474cd74), CONST64(0xe309f115f6f6fff6), CONST64(0x0a438c4c46460546),
CONST64(0x092645a5acac8aac), CONST64(0x3c970fb589891e89), CONST64(0xa04428b414145014), CONST64(0x5b42dfbae1e1a3e1),
CONST64(0xb04e2ca616165816), CONST64(0xcdd274f73a3ae83a), CONST64(0x6fd0d2066969b969), CONST64(0x482d124109092409),
CONST64(0xa7ade0d77070dd70), CONST64(0xd954716fb6b6e2b6), CONST64(0xceb7bd1ed0d067d0), CONST64(0x3b7ec7d6eded93ed),
CONST64(0x2edb85e2cccc17cc), CONST64(0x2a57846842421542), CONST64(0xb4c22d2c98985a98), CONST64(0x490e55eda4a4aaa4),
CONST64(0x5d8850752828a028), CONST64(0xda31b8865c5c6d5c), CONST64(0x933fed6bf8f8c7f8), CONST64(0x44a411c286862286)
};
static const ulong64 sbox5[] = {
CONST64(0x18c07830d8181860), CONST64(0x2305af462623238c), CONST64(0xc67ef991b8c6c63f), CONST64(0xe8136fcdfbe8e887),
CONST64(0x874ca113cb878726), CONST64(0xb8a9626d11b8b8da), CONST64(0x0108050209010104), CONST64(0x4f426e9e0d4f4f21),
CONST64(0x36adee6c9b3636d8), CONST64(0xa6590451ffa6a6a2), CONST64(0xd2debdb90cd2d26f), CONST64(0xf5fb06f70ef5f5f3),
CONST64(0x79ef80f2967979f9), CONST64(0x6f5fcede306f6fa1), CONST64(0x91fcef3f6d91917e), CONST64(0x52aa07a4f8525255),
CONST64(0x6027fdc04760609d), CONST64(0xbc89766535bcbcca), CONST64(0x9baccd2b379b9b56), CONST64(0x8e048c018a8e8e02),
CONST64(0xa371155bd2a3a3b6), CONST64(0x0c603c186c0c0c30), CONST64(0x7bff8af6847b7bf1), CONST64(0x35b5e16a803535d4),
CONST64(0x1de8693af51d1d74), CONST64(0xe05347ddb3e0e0a7), CONST64(0xd7f6acb321d7d77b), CONST64(0xc25eed999cc2c22f),
CONST64(0x2e6d965c432e2eb8), CONST64(0x4b627a96294b4b31), CONST64(0xfea321e15dfefedf), CONST64(0x578216aed5575741),
CONST64(0x15a8412abd151554), CONST64(0x779fb6eee87777c1), CONST64(0x37a5eb6e923737dc), CONST64(0xe57b56d79ee5e5b3),
CONST64(0x9f8cd923139f9f46), CONST64(0xf0d317fd23f0f0e7), CONST64(0x4a6a7f94204a4a35), CONST64(0xda9e95a944dada4f),
CONST64(0x58fa25b0a258587d), CONST64(0xc906ca8fcfc9c903), CONST64(0x29558d527c2929a4), CONST64(0x0a5022145a0a0a28),
CONST64(0xb1e14f7f50b1b1fe), CONST64(0xa0691a5dc9a0a0ba), CONST64(0x6b7fdad6146b6bb1), CONST64(0x855cab17d985852e),
CONST64(0xbd8173673cbdbdce), CONST64(0x5dd234ba8f5d5d69), CONST64(0x1080502090101040), CONST64(0xf4f303f507f4f4f7),
CONST64(0xcb16c08bddcbcb0b), CONST64(0x3eedc67cd33e3ef8), CONST64(0x0528110a2d050514), CONST64(0x671fe6ce78676781),
CONST64(0xe47353d597e4e4b7), CONST64(0x2725bb4e0227279c), CONST64(0x4132588273414119), CONST64(0x8b2c9d0ba78b8b16),
CONST64(0xa7510153f6a7a7a6), CONST64(0x7dcf94fab27d7de9), CONST64(0x95dcfb374995956e), CONST64(0xd88e9fad56d8d847),
CONST64(0xfb8b30eb70fbfbcb), CONST64(0xee2371c1cdeeee9f), CONST64(0x7cc791f8bb7c7ced), CONST64(0x6617e3cc71666685),
CONST64(0xdda68ea77bdddd53), CONST64(0x17b84b2eaf17175c), CONST64(0x4702468e45474701), CONST64(0x9e84dc211a9e9e42),
CONST64(0xca1ec589d4caca0f), CONST64(0x2d75995a582d2db4), CONST64(0xbf9179632ebfbfc6), CONST64(0x07381b0e3f07071c),
CONST64(0xad012347acadad8e), CONST64(0x5aea2fb4b05a5a75), CONST64(0x836cb51bef838336), CONST64(0x3385ff66b63333cc),
CONST64(0x633ff2c65c636391), CONST64(0x02100a0412020208), CONST64(0xaa39384993aaaa92), CONST64(0x71afa8e2de7171d9),
CONST64(0xc80ecf8dc6c8c807), CONST64(0x19c87d32d1191964), CONST64(0x497270923b494939), CONST64(0xd9869aaf5fd9d943),
CONST64(0xf2c31df931f2f2ef), CONST64(0xe34b48dba8e3e3ab), CONST64(0x5be22ab6b95b5b71), CONST64(0x8834920dbc88881a),
CONST64(0x9aa4c8293e9a9a52), CONST64(0x262dbe4c0b262698), CONST64(0x328dfa64bf3232c8), CONST64(0xb0e94a7d59b0b0fa),
CONST64(0xe91b6acff2e9e983), CONST64(0x0f78331e770f0f3c), CONST64(0xd5e6a6b733d5d573), CONST64(0x8074ba1df480803a),
CONST64(0xbe997c6127bebec2), CONST64(0xcd26de87ebcdcd13), CONST64(0x34bde468893434d0), CONST64(0x487a75903248483d),
CONST64(0xffab24e354ffffdb), CONST64(0x7af78ff48d7a7af5), CONST64(0x90f4ea3d6490907a), CONST64(0x5fc23ebe9d5f5f61),
CONST64(0x201da0403d202080), CONST64(0x6867d5d00f6868bd), CONST64(0x1ad07234ca1a1a68), CONST64(0xae192c41b7aeae82),
CONST64(0xb4c95e757db4b4ea), CONST64(0x549a19a8ce54544d), CONST64(0x93ece53b7f939376), CONST64(0x220daa442f222288),
CONST64(0x6407e9c86364648d), CONST64(0xf1db12ff2af1f1e3), CONST64(0x73bfa2e6cc7373d1), CONST64(0x12905a2482121248),
CONST64(0x403a5d807a40401d), CONST64(0x0840281048080820), CONST64(0xc356e89b95c3c32b), CONST64(0xec337bc5dfecec97),
CONST64(0xdb9690ab4ddbdb4b), CONST64(0xa1611f5fc0a1a1be), CONST64(0x8d1c8307918d8d0e), CONST64(0x3df5c97ac83d3df4),
CONST64(0x97ccf1335b979766), CONST64(0x0000000000000000), CONST64(0xcf36d483f9cfcf1b), CONST64(0x2b4587566e2b2bac),
CONST64(0x7697b3ece17676c5), CONST64(0x8264b019e6828232), CONST64(0xd6fea9b128d6d67f), CONST64(0x1bd87736c31b1b6c),
CONST64(0xb5c15b7774b5b5ee), CONST64(0xaf112943beafaf86), CONST64(0x6a77dfd41d6a6ab5), CONST64(0x50ba0da0ea50505d),
CONST64(0x45124c8a57454509), CONST64(0xf3cb18fb38f3f3eb), CONST64(0x309df060ad3030c0), CONST64(0xef2b74c3c4efef9b),
CONST64(0x3fe5c37eda3f3ffc), CONST64(0x55921caac7555549), CONST64(0xa2791059dba2a2b2), CONST64(0xea0365c9e9eaea8f),
CONST64(0x650fecca6a656589), CONST64(0xbab9686903babad2), CONST64(0x2f65935e4a2f2fbc), CONST64(0xc04ee79d8ec0c027),
CONST64(0xdebe81a160dede5f), CONST64(0x1ce06c38fc1c1c70), CONST64(0xfdbb2ee746fdfdd3), CONST64(0x4d52649a1f4d4d29),
CONST64(0x92e4e03976929272), CONST64(0x758fbceafa7575c9), CONST64(0x06301e0c36060618), CONST64(0x8a249809ae8a8a12),
CONST64(0xb2f940794bb2b2f2), CONST64(0xe66359d185e6e6bf), CONST64(0x0e70361c7e0e0e38), CONST64(0x1ff8633ee71f1f7c),
CONST64(0x6237f7c455626295), CONST64(0xd4eea3b53ad4d477), CONST64(0xa829324d81a8a89a), CONST64(0x96c4f43152969662),
CONST64(0xf99b3aef62f9f9c3), CONST64(0xc566f697a3c5c533), CONST64(0x2535b14a10252594), CONST64(0x59f220b2ab595979),
CONST64(0x8454ae15d084842a), CONST64(0x72b7a7e4c57272d5), CONST64(0x39d5dd72ec3939e4), CONST64(0x4c5a6198164c4c2d),
CONST64(0x5eca3bbc945e5e65), CONST64(0x78e785f09f7878fd), CONST64(0x38ddd870e53838e0), CONST64(0x8c148605988c8c0a),
CONST64(0xd1c6b2bf17d1d163), CONST64(0xa5410b57e4a5a5ae), CONST64(0xe2434dd9a1e2e2af), CONST64(0x612ff8c24e616199),
CONST64(0xb3f1457b42b3b3f6), CONST64(0x2115a54234212184), CONST64(0x9c94d625089c9c4a), CONST64(0x1ef0663cee1e1e78),
CONST64(0x4322528661434311), CONST64(0xc776fc93b1c7c73b), CONST64(0xfcb32be54ffcfcd7), CONST64(0x0420140824040410),
CONST64(0x51b208a2e3515159), CONST64(0x99bcc72f2599995e), CONST64(0x6d4fc4da226d6da9), CONST64(0x0d68391a650d0d34),
CONST64(0xfa8335e979fafacf), CONST64(0xdfb684a369dfdf5b), CONST64(0x7ed79bfca97e7ee5), CONST64(0x243db44819242490),
CONST64(0x3bc5d776fe3b3bec), CONST64(0xab313d4b9aabab96), CONST64(0xce3ed181f0cece1f), CONST64(0x1188552299111144),
CONST64(0x8f0c8903838f8f06), CONST64(0x4e4a6b9c044e4e25), CONST64(0xb7d1517366b7b7e6), CONST64(0xeb0b60cbe0ebeb8b),
CONST64(0x3cfdcc78c13c3cf0), CONST64(0x817cbf1ffd81813e), CONST64(0x94d4fe354094946a), CONST64(0xf7eb0cf31cf7f7fb),
CONST64(0xb9a1676f18b9b9de), CONST64(0x13985f268b13134c), CONST64(0x2c7d9c58512c2cb0), CONST64(0xd3d6b8bb05d3d36b),
CONST64(0xe76b5cd38ce7e7bb), CONST64(0x6e57cbdc396e6ea5), CONST64(0xc46ef395aac4c437), CONST64(0x03180f061b03030c),
CONST64(0x568a13acdc565645), CONST64(0x441a49885e44440d), CONST64(0x7fdf9efea07f7fe1), CONST64(0xa921374f88a9a99e),
CONST64(0x2a4d8254672a2aa8), CONST64(0xbbb16d6b0abbbbd6), CONST64(0xc146e29f87c1c123), CONST64(0x53a202a6f1535351),
CONST64(0xdcae8ba572dcdc57), CONST64(0x0b582716530b0b2c), CONST64(0x9d9cd327019d9d4e), CONST64(0x6c47c1d82b6c6cad),
CONST64(0x3195f562a43131c4), CONST64(0x7487b9e8f37474cd), CONST64(0xf6e309f115f6f6ff), CONST64(0x460a438c4c464605),
CONST64(0xac092645a5acac8a), CONST64(0x893c970fb589891e), CONST64(0x14a04428b4141450), CONST64(0xe15b42dfbae1e1a3),
CONST64(0x16b04e2ca6161658), CONST64(0x3acdd274f73a3ae8), CONST64(0x696fd0d2066969b9), CONST64(0x09482d1241090924),
CONST64(0x70a7ade0d77070dd), CONST64(0xb6d954716fb6b6e2), CONST64(0xd0ceb7bd1ed0d067), CONST64(0xed3b7ec7d6eded93),
CONST64(0xcc2edb85e2cccc17), CONST64(0x422a578468424215), CONST64(0x98b4c22d2c98985a), CONST64(0xa4490e55eda4a4aa),
CONST64(0x285d8850752828a0), CONST64(0x5cda31b8865c5c6d), CONST64(0xf8933fed6bf8f8c7), CONST64(0x8644a411c2868622)
};
static const ulong64 sbox6[] = {
CONST64(0x6018c07830d81818), CONST64(0x8c2305af46262323), CONST64(0x3fc67ef991b8c6c6), CONST64(0x87e8136fcdfbe8e8),
CONST64(0x26874ca113cb8787), CONST64(0xdab8a9626d11b8b8), CONST64(0x0401080502090101), CONST64(0x214f426e9e0d4f4f),
CONST64(0xd836adee6c9b3636), CONST64(0xa2a6590451ffa6a6), CONST64(0x6fd2debdb90cd2d2), CONST64(0xf3f5fb06f70ef5f5),
CONST64(0xf979ef80f2967979), CONST64(0xa16f5fcede306f6f), CONST64(0x7e91fcef3f6d9191), CONST64(0x5552aa07a4f85252),
CONST64(0x9d6027fdc0476060), CONST64(0xcabc89766535bcbc), CONST64(0x569baccd2b379b9b), CONST64(0x028e048c018a8e8e),
CONST64(0xb6a371155bd2a3a3), CONST64(0x300c603c186c0c0c), CONST64(0xf17bff8af6847b7b), CONST64(0xd435b5e16a803535),
CONST64(0x741de8693af51d1d), CONST64(0xa7e05347ddb3e0e0), CONST64(0x7bd7f6acb321d7d7), CONST64(0x2fc25eed999cc2c2),
CONST64(0xb82e6d965c432e2e), CONST64(0x314b627a96294b4b), CONST64(0xdffea321e15dfefe), CONST64(0x41578216aed55757),
CONST64(0x5415a8412abd1515), CONST64(0xc1779fb6eee87777), CONST64(0xdc37a5eb6e923737), CONST64(0xb3e57b56d79ee5e5),
CONST64(0x469f8cd923139f9f), CONST64(0xe7f0d317fd23f0f0), CONST64(0x354a6a7f94204a4a), CONST64(0x4fda9e95a944dada),
CONST64(0x7d58fa25b0a25858), CONST64(0x03c906ca8fcfc9c9), CONST64(0xa429558d527c2929), CONST64(0x280a5022145a0a0a),
CONST64(0xfeb1e14f7f50b1b1), CONST64(0xbaa0691a5dc9a0a0), CONST64(0xb16b7fdad6146b6b), CONST64(0x2e855cab17d98585),
CONST64(0xcebd8173673cbdbd), CONST64(0x695dd234ba8f5d5d), CONST64(0x4010805020901010), CONST64(0xf7f4f303f507f4f4),
CONST64(0x0bcb16c08bddcbcb), CONST64(0xf83eedc67cd33e3e), CONST64(0x140528110a2d0505), CONST64(0x81671fe6ce786767),
CONST64(0xb7e47353d597e4e4), CONST64(0x9c2725bb4e022727), CONST64(0x1941325882734141), CONST64(0x168b2c9d0ba78b8b),
CONST64(0xa6a7510153f6a7a7), CONST64(0xe97dcf94fab27d7d), CONST64(0x6e95dcfb37499595), CONST64(0x47d88e9fad56d8d8),
CONST64(0xcbfb8b30eb70fbfb), CONST64(0x9fee2371c1cdeeee), CONST64(0xed7cc791f8bb7c7c), CONST64(0x856617e3cc716666),
CONST64(0x53dda68ea77bdddd), CONST64(0x5c17b84b2eaf1717), CONST64(0x014702468e454747), CONST64(0x429e84dc211a9e9e),
CONST64(0x0fca1ec589d4caca), CONST64(0xb42d75995a582d2d), CONST64(0xc6bf9179632ebfbf), CONST64(0x1c07381b0e3f0707),
CONST64(0x8ead012347acadad), CONST64(0x755aea2fb4b05a5a), CONST64(0x36836cb51bef8383), CONST64(0xcc3385ff66b63333),
CONST64(0x91633ff2c65c6363), CONST64(0x0802100a04120202), CONST64(0x92aa39384993aaaa), CONST64(0xd971afa8e2de7171),
CONST64(0x07c80ecf8dc6c8c8), CONST64(0x6419c87d32d11919), CONST64(0x39497270923b4949), CONST64(0x43d9869aaf5fd9d9),
CONST64(0xeff2c31df931f2f2), CONST64(0xabe34b48dba8e3e3), CONST64(0x715be22ab6b95b5b), CONST64(0x1a8834920dbc8888),
CONST64(0x529aa4c8293e9a9a), CONST64(0x98262dbe4c0b2626), CONST64(0xc8328dfa64bf3232), CONST64(0xfab0e94a7d59b0b0),
CONST64(0x83e91b6acff2e9e9), CONST64(0x3c0f78331e770f0f), CONST64(0x73d5e6a6b733d5d5), CONST64(0x3a8074ba1df48080),
CONST64(0xc2be997c6127bebe), CONST64(0x13cd26de87ebcdcd), CONST64(0xd034bde468893434), CONST64(0x3d487a7590324848),
CONST64(0xdbffab24e354ffff), CONST64(0xf57af78ff48d7a7a), CONST64(0x7a90f4ea3d649090), CONST64(0x615fc23ebe9d5f5f),
CONST64(0x80201da0403d2020), CONST64(0xbd6867d5d00f6868), CONST64(0x681ad07234ca1a1a), CONST64(0x82ae192c41b7aeae),
CONST64(0xeab4c95e757db4b4), CONST64(0x4d549a19a8ce5454), CONST64(0x7693ece53b7f9393), CONST64(0x88220daa442f2222),
CONST64(0x8d6407e9c8636464), CONST64(0xe3f1db12ff2af1f1), CONST64(0xd173bfa2e6cc7373), CONST64(0x4812905a24821212),
CONST64(0x1d403a5d807a4040), CONST64(0x2008402810480808), CONST64(0x2bc356e89b95c3c3), CONST64(0x97ec337bc5dfecec),
CONST64(0x4bdb9690ab4ddbdb), CONST64(0xbea1611f5fc0a1a1), CONST64(0x0e8d1c8307918d8d), CONST64(0xf43df5c97ac83d3d),
CONST64(0x6697ccf1335b9797), CONST64(0x0000000000000000), CONST64(0x1bcf36d483f9cfcf), CONST64(0xac2b4587566e2b2b),
CONST64(0xc57697b3ece17676), CONST64(0x328264b019e68282), CONST64(0x7fd6fea9b128d6d6), CONST64(0x6c1bd87736c31b1b),
CONST64(0xeeb5c15b7774b5b5), CONST64(0x86af112943beafaf), CONST64(0xb56a77dfd41d6a6a), CONST64(0x5d50ba0da0ea5050),
CONST64(0x0945124c8a574545), CONST64(0xebf3cb18fb38f3f3), CONST64(0xc0309df060ad3030), CONST64(0x9bef2b74c3c4efef),
CONST64(0xfc3fe5c37eda3f3f), CONST64(0x4955921caac75555), CONST64(0xb2a2791059dba2a2), CONST64(0x8fea0365c9e9eaea),
CONST64(0x89650fecca6a6565), CONST64(0xd2bab9686903baba), CONST64(0xbc2f65935e4a2f2f), CONST64(0x27c04ee79d8ec0c0),
CONST64(0x5fdebe81a160dede), CONST64(0x701ce06c38fc1c1c), CONST64(0xd3fdbb2ee746fdfd), CONST64(0x294d52649a1f4d4d),
CONST64(0x7292e4e039769292), CONST64(0xc9758fbceafa7575), CONST64(0x1806301e0c360606), CONST64(0x128a249809ae8a8a),
CONST64(0xf2b2f940794bb2b2), CONST64(0xbfe66359d185e6e6), CONST64(0x380e70361c7e0e0e), CONST64(0x7c1ff8633ee71f1f),
CONST64(0x956237f7c4556262), CONST64(0x77d4eea3b53ad4d4), CONST64(0x9aa829324d81a8a8), CONST64(0x6296c4f431529696),
CONST64(0xc3f99b3aef62f9f9), CONST64(0x33c566f697a3c5c5), CONST64(0x942535b14a102525), CONST64(0x7959f220b2ab5959),
CONST64(0x2a8454ae15d08484), CONST64(0xd572b7a7e4c57272), CONST64(0xe439d5dd72ec3939), CONST64(0x2d4c5a6198164c4c),
CONST64(0x655eca3bbc945e5e), CONST64(0xfd78e785f09f7878), CONST64(0xe038ddd870e53838), CONST64(0x0a8c148605988c8c),
CONST64(0x63d1c6b2bf17d1d1), CONST64(0xaea5410b57e4a5a5), CONST64(0xafe2434dd9a1e2e2), CONST64(0x99612ff8c24e6161),
CONST64(0xf6b3f1457b42b3b3), CONST64(0x842115a542342121), CONST64(0x4a9c94d625089c9c), CONST64(0x781ef0663cee1e1e),
CONST64(0x1143225286614343), CONST64(0x3bc776fc93b1c7c7), CONST64(0xd7fcb32be54ffcfc), CONST64(0x1004201408240404),
CONST64(0x5951b208a2e35151), CONST64(0x5e99bcc72f259999), CONST64(0xa96d4fc4da226d6d), CONST64(0x340d68391a650d0d),
CONST64(0xcffa8335e979fafa), CONST64(0x5bdfb684a369dfdf), CONST64(0xe57ed79bfca97e7e), CONST64(0x90243db448192424),
CONST64(0xec3bc5d776fe3b3b), CONST64(0x96ab313d4b9aabab), CONST64(0x1fce3ed181f0cece), CONST64(0x4411885522991111),
CONST64(0x068f0c8903838f8f), CONST64(0x254e4a6b9c044e4e), CONST64(0xe6b7d1517366b7b7), CONST64(0x8beb0b60cbe0ebeb),
CONST64(0xf03cfdcc78c13c3c), CONST64(0x3e817cbf1ffd8181), CONST64(0x6a94d4fe35409494), CONST64(0xfbf7eb0cf31cf7f7),
CONST64(0xdeb9a1676f18b9b9), CONST64(0x4c13985f268b1313), CONST64(0xb02c7d9c58512c2c), CONST64(0x6bd3d6b8bb05d3d3),
CONST64(0xbbe76b5cd38ce7e7), CONST64(0xa56e57cbdc396e6e), CONST64(0x37c46ef395aac4c4), CONST64(0x0c03180f061b0303),
CONST64(0x45568a13acdc5656), CONST64(0x0d441a49885e4444), CONST64(0xe17fdf9efea07f7f), CONST64(0x9ea921374f88a9a9),
CONST64(0xa82a4d8254672a2a), CONST64(0xd6bbb16d6b0abbbb), CONST64(0x23c146e29f87c1c1), CONST64(0x5153a202a6f15353),
CONST64(0x57dcae8ba572dcdc), CONST64(0x2c0b582716530b0b), CONST64(0x4e9d9cd327019d9d), CONST64(0xad6c47c1d82b6c6c),
CONST64(0xc43195f562a43131), CONST64(0xcd7487b9e8f37474), CONST64(0xfff6e309f115f6f6), CONST64(0x05460a438c4c4646),
CONST64(0x8aac092645a5acac), CONST64(0x1e893c970fb58989), CONST64(0x5014a04428b41414), CONST64(0xa3e15b42dfbae1e1),
CONST64(0x5816b04e2ca61616), CONST64(0xe83acdd274f73a3a), CONST64(0xb9696fd0d2066969), CONST64(0x2409482d12410909),
CONST64(0xdd70a7ade0d77070), CONST64(0xe2b6d954716fb6b6), CONST64(0x67d0ceb7bd1ed0d0), CONST64(0x93ed3b7ec7d6eded),
CONST64(0x17cc2edb85e2cccc), CONST64(0x15422a5784684242), CONST64(0x5a98b4c22d2c9898), CONST64(0xaaa4490e55eda4a4),
CONST64(0xa0285d8850752828), CONST64(0x6d5cda31b8865c5c), CONST64(0xc7f8933fed6bf8f8), CONST64(0x228644a411c28686)
};
static const ulong64 sbox7[] = {
CONST64(0x186018c07830d818), CONST64(0x238c2305af462623), CONST64(0xc63fc67ef991b8c6), CONST64(0xe887e8136fcdfbe8),
CONST64(0x8726874ca113cb87), CONST64(0xb8dab8a9626d11b8), CONST64(0x0104010805020901), CONST64(0x4f214f426e9e0d4f),
CONST64(0x36d836adee6c9b36), CONST64(0xa6a2a6590451ffa6), CONST64(0xd26fd2debdb90cd2), CONST64(0xf5f3f5fb06f70ef5),
CONST64(0x79f979ef80f29679), CONST64(0x6fa16f5fcede306f), CONST64(0x917e91fcef3f6d91), CONST64(0x525552aa07a4f852),
CONST64(0x609d6027fdc04760), CONST64(0xbccabc89766535bc), CONST64(0x9b569baccd2b379b), CONST64(0x8e028e048c018a8e),
CONST64(0xa3b6a371155bd2a3), CONST64(0x0c300c603c186c0c), CONST64(0x7bf17bff8af6847b), CONST64(0x35d435b5e16a8035),
CONST64(0x1d741de8693af51d), CONST64(0xe0a7e05347ddb3e0), CONST64(0xd77bd7f6acb321d7), CONST64(0xc22fc25eed999cc2),
CONST64(0x2eb82e6d965c432e), CONST64(0x4b314b627a96294b), CONST64(0xfedffea321e15dfe), CONST64(0x5741578216aed557),
CONST64(0x155415a8412abd15), CONST64(0x77c1779fb6eee877), CONST64(0x37dc37a5eb6e9237), CONST64(0xe5b3e57b56d79ee5),
CONST64(0x9f469f8cd923139f), CONST64(0xf0e7f0d317fd23f0), CONST64(0x4a354a6a7f94204a), CONST64(0xda4fda9e95a944da),
CONST64(0x587d58fa25b0a258), CONST64(0xc903c906ca8fcfc9), CONST64(0x29a429558d527c29), CONST64(0x0a280a5022145a0a),
CONST64(0xb1feb1e14f7f50b1), CONST64(0xa0baa0691a5dc9a0), CONST64(0x6bb16b7fdad6146b), CONST64(0x852e855cab17d985),
CONST64(0xbdcebd8173673cbd), CONST64(0x5d695dd234ba8f5d), CONST64(0x1040108050209010), CONST64(0xf4f7f4f303f507f4),
CONST64(0xcb0bcb16c08bddcb), CONST64(0x3ef83eedc67cd33e), CONST64(0x05140528110a2d05), CONST64(0x6781671fe6ce7867),
CONST64(0xe4b7e47353d597e4), CONST64(0x279c2725bb4e0227), CONST64(0x4119413258827341), CONST64(0x8b168b2c9d0ba78b),
CONST64(0xa7a6a7510153f6a7), CONST64(0x7de97dcf94fab27d), CONST64(0x956e95dcfb374995), CONST64(0xd847d88e9fad56d8),
CONST64(0xfbcbfb8b30eb70fb), CONST64(0xee9fee2371c1cdee), CONST64(0x7ced7cc791f8bb7c), CONST64(0x66856617e3cc7166),
CONST64(0xdd53dda68ea77bdd), CONST64(0x175c17b84b2eaf17), CONST64(0x47014702468e4547), CONST64(0x9e429e84dc211a9e),
CONST64(0xca0fca1ec589d4ca), CONST64(0x2db42d75995a582d), CONST64(0xbfc6bf9179632ebf), CONST64(0x071c07381b0e3f07),
CONST64(0xad8ead012347acad), CONST64(0x5a755aea2fb4b05a), CONST64(0x8336836cb51bef83), CONST64(0x33cc3385ff66b633),
CONST64(0x6391633ff2c65c63), CONST64(0x020802100a041202), CONST64(0xaa92aa39384993aa), CONST64(0x71d971afa8e2de71),
CONST64(0xc807c80ecf8dc6c8), CONST64(0x196419c87d32d119), CONST64(0x4939497270923b49), CONST64(0xd943d9869aaf5fd9),
CONST64(0xf2eff2c31df931f2), CONST64(0xe3abe34b48dba8e3), CONST64(0x5b715be22ab6b95b), CONST64(0x881a8834920dbc88),
CONST64(0x9a529aa4c8293e9a), CONST64(0x2698262dbe4c0b26), CONST64(0x32c8328dfa64bf32), CONST64(0xb0fab0e94a7d59b0),
CONST64(0xe983e91b6acff2e9), CONST64(0x0f3c0f78331e770f), CONST64(0xd573d5e6a6b733d5), CONST64(0x803a8074ba1df480),
CONST64(0xbec2be997c6127be), CONST64(0xcd13cd26de87ebcd), CONST64(0x34d034bde4688934), CONST64(0x483d487a75903248),
CONST64(0xffdbffab24e354ff), CONST64(0x7af57af78ff48d7a), CONST64(0x907a90f4ea3d6490), CONST64(0x5f615fc23ebe9d5f),
CONST64(0x2080201da0403d20), CONST64(0x68bd6867d5d00f68), CONST64(0x1a681ad07234ca1a), CONST64(0xae82ae192c41b7ae),
CONST64(0xb4eab4c95e757db4), CONST64(0x544d549a19a8ce54), CONST64(0x937693ece53b7f93), CONST64(0x2288220daa442f22),
CONST64(0x648d6407e9c86364), CONST64(0xf1e3f1db12ff2af1), CONST64(0x73d173bfa2e6cc73), CONST64(0x124812905a248212),
CONST64(0x401d403a5d807a40), CONST64(0x0820084028104808), CONST64(0xc32bc356e89b95c3), CONST64(0xec97ec337bc5dfec),
CONST64(0xdb4bdb9690ab4ddb), CONST64(0xa1bea1611f5fc0a1), CONST64(0x8d0e8d1c8307918d), CONST64(0x3df43df5c97ac83d),
CONST64(0x976697ccf1335b97), CONST64(0x0000000000000000), CONST64(0xcf1bcf36d483f9cf), CONST64(0x2bac2b4587566e2b),
CONST64(0x76c57697b3ece176), CONST64(0x82328264b019e682), CONST64(0xd67fd6fea9b128d6), CONST64(0x1b6c1bd87736c31b),
CONST64(0xb5eeb5c15b7774b5), CONST64(0xaf86af112943beaf), CONST64(0x6ab56a77dfd41d6a), CONST64(0x505d50ba0da0ea50),
CONST64(0x450945124c8a5745), CONST64(0xf3ebf3cb18fb38f3), CONST64(0x30c0309df060ad30), CONST64(0xef9bef2b74c3c4ef),
CONST64(0x3ffc3fe5c37eda3f), CONST64(0x554955921caac755), CONST64(0xa2b2a2791059dba2), CONST64(0xea8fea0365c9e9ea),
CONST64(0x6589650fecca6a65), CONST64(0xbad2bab9686903ba), CONST64(0x2fbc2f65935e4a2f), CONST64(0xc027c04ee79d8ec0),
CONST64(0xde5fdebe81a160de), CONST64(0x1c701ce06c38fc1c), CONST64(0xfdd3fdbb2ee746fd), CONST64(0x4d294d52649a1f4d),
CONST64(0x927292e4e0397692), CONST64(0x75c9758fbceafa75), CONST64(0x061806301e0c3606), CONST64(0x8a128a249809ae8a),
CONST64(0xb2f2b2f940794bb2), CONST64(0xe6bfe66359d185e6), CONST64(0x0e380e70361c7e0e), CONST64(0x1f7c1ff8633ee71f),
CONST64(0x62956237f7c45562), CONST64(0xd477d4eea3b53ad4), CONST64(0xa89aa829324d81a8), CONST64(0x966296c4f4315296),
CONST64(0xf9c3f99b3aef62f9), CONST64(0xc533c566f697a3c5), CONST64(0x25942535b14a1025), CONST64(0x597959f220b2ab59),
CONST64(0x842a8454ae15d084), CONST64(0x72d572b7a7e4c572), CONST64(0x39e439d5dd72ec39), CONST64(0x4c2d4c5a6198164c),
CONST64(0x5e655eca3bbc945e), CONST64(0x78fd78e785f09f78), CONST64(0x38e038ddd870e538), CONST64(0x8c0a8c148605988c),
CONST64(0xd163d1c6b2bf17d1), CONST64(0xa5aea5410b57e4a5), CONST64(0xe2afe2434dd9a1e2), CONST64(0x6199612ff8c24e61),
CONST64(0xb3f6b3f1457b42b3), CONST64(0x21842115a5423421), CONST64(0x9c4a9c94d625089c), CONST64(0x1e781ef0663cee1e),
CONST64(0x4311432252866143), CONST64(0xc73bc776fc93b1c7), CONST64(0xfcd7fcb32be54ffc), CONST64(0x0410042014082404),
CONST64(0x515951b208a2e351), CONST64(0x995e99bcc72f2599), CONST64(0x6da96d4fc4da226d), CONST64(0x0d340d68391a650d),
CONST64(0xfacffa8335e979fa), CONST64(0xdf5bdfb684a369df), CONST64(0x7ee57ed79bfca97e), CONST64(0x2490243db4481924),
CONST64(0x3bec3bc5d776fe3b), CONST64(0xab96ab313d4b9aab), CONST64(0xce1fce3ed181f0ce), CONST64(0x1144118855229911),
CONST64(0x8f068f0c8903838f), CONST64(0x4e254e4a6b9c044e), CONST64(0xb7e6b7d1517366b7), CONST64(0xeb8beb0b60cbe0eb),
CONST64(0x3cf03cfdcc78c13c), CONST64(0x813e817cbf1ffd81), CONST64(0x946a94d4fe354094), CONST64(0xf7fbf7eb0cf31cf7),
CONST64(0xb9deb9a1676f18b9), CONST64(0x134c13985f268b13), CONST64(0x2cb02c7d9c58512c), CONST64(0xd36bd3d6b8bb05d3),
CONST64(0xe7bbe76b5cd38ce7), CONST64(0x6ea56e57cbdc396e), CONST64(0xc437c46ef395aac4), CONST64(0x030c03180f061b03),
CONST64(0x5645568a13acdc56), CONST64(0x440d441a49885e44), CONST64(0x7fe17fdf9efea07f), CONST64(0xa99ea921374f88a9),
CONST64(0x2aa82a4d8254672a), CONST64(0xbbd6bbb16d6b0abb), CONST64(0xc123c146e29f87c1), CONST64(0x535153a202a6f153),
CONST64(0xdc57dcae8ba572dc), CONST64(0x0b2c0b582716530b), CONST64(0x9d4e9d9cd327019d), CONST64(0x6cad6c47c1d82b6c),
CONST64(0x31c43195f562a431), CONST64(0x74cd7487b9e8f374), CONST64(0xf6fff6e309f115f6), CONST64(0x4605460a438c4c46),
CONST64(0xac8aac092645a5ac), CONST64(0x891e893c970fb589), CONST64(0x145014a04428b414), CONST64(0xe1a3e15b42dfbae1),
CONST64(0x165816b04e2ca616), CONST64(0x3ae83acdd274f73a), CONST64(0x69b9696fd0d20669), CONST64(0x092409482d124109),
CONST64(0x70dd70a7ade0d770), CONST64(0xb6e2b6d954716fb6), CONST64(0xd067d0ceb7bd1ed0), CONST64(0xed93ed3b7ec7d6ed),
CONST64(0xcc17cc2edb85e2cc), CONST64(0x4215422a57846842), CONST64(0x985a98b4c22d2c98), CONST64(0xa4aaa4490e55eda4),
CONST64(0x28a0285d88507528), CONST64(0x5c6d5cda31b8865c), CONST64(0xf8c7f8933fed6bf8), CONST64(0x86228644a411c286)
};
#endif
static const ulong64 cont[] = {
CONST64(0x1823c6e887b8014f),
CONST64(0x36a6d2f5796f9152),
CONST64(0x60bc9b8ea30c7b35),
CONST64(0x1de0d7c22e4bfe57),
CONST64(0x157737e59ff04ada),
CONST64(0x58c9290ab1a06b85),
CONST64(0xbd5d10f4cb3e0567),
CONST64(0xe427418ba77d95d8),
CONST64(0xfbee7c66dd17479e),
CONST64(0xca2dbf07ad5a8333),
CONST64(0x6302aa71c81949d9),
};
#endif /* LTC_WHIRLTAB_C */