1
0
mirror of https://github.com/VCMP-SqMod/SqMod.git synced 2025-11-04 16:27:18 +01:00

More work on Cmake scripts.

This commit is contained in:
Sandu Liviu Catalin
2020-03-21 22:00:02 +02:00
parent 44b1cb5d96
commit 22c8d84b1e
41 changed files with 49 additions and 5 deletions

View File

@@ -0,0 +1,7 @@
# Create the AES256Lib library
add_library(AES256Lib STATIC include/aes256.h aes256.cpp)
# Configure include folders
target_include_directories(AES256Lib PRIVATE ${CMAKE_CURRENT_LIST_DIR})
target_include_directories(AES256Lib PUBLIC ${CMAKE_CURRENT_LIST_DIR}/include)
# Configure build options
target_compile_definitions(AES256Lib PRIVATE )

View File

@@ -0,0 +1,407 @@
/*
* Byte-oriented AES-256 implementation.
* All lookup tables replaced with 'on the fly' calculations.
*
* Copyright (c) 2007-2011 Ilya O. Levin, http://www.literatecode.com
* Other contributors: Hal Finney
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "aes256.h"
#ifdef __cplusplus
extern "C" {
#endif
#define FD(x) (((x) >> 1) ^ (((x) & 1) ? 0x8d : 0))
#define BACK_TO_TABLES
static uint8_t rj_xtime(uint8_t);
static void aes_subBytes(uint8_t *);
static void aes_subBytes_inv(uint8_t *);
static void aes_addRoundKey(uint8_t *, uint8_t *);
static void aes_addRoundKey_cpy(uint8_t *, uint8_t *, uint8_t *);
static void aes_shiftRows(uint8_t *);
static void aes_shiftRows_inv(uint8_t *);
static void aes_mixColumns(uint8_t *);
static void aes_mixColumns_inv(uint8_t *);
static void aes_expandEncKey(uint8_t *, uint8_t *);
static void aes_expandDecKey(uint8_t *, uint8_t *);
#ifndef BACK_TO_TABLES
static uint8_t gf_alog(uint8_t);
static uint8_t gf_log(uint8_t);
static uint8_t gf_mulinv(uint8_t);
static uint8_t rj_sbox(uint8_t);
static uint8_t rj_sbox_inv(uint8_t);
#endif
#ifdef BACK_TO_TABLES
static const uint8_t sbox[256] =
{
0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5,
0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0,
0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc,
0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a,
0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0,
0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b,
0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85,
0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5,
0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17,
0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88,
0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c,
0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9,
0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6,
0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e,
0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94,
0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68,
0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
};
static const uint8_t sboxinv[256] =
{
0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38,
0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb,
0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87,
0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb,
0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d,
0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e,
0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2,
0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25,
0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16,
0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92,
0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda,
0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84,
0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a,
0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06,
0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02,
0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b,
0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea,
0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73,
0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85,
0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e,
0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89,
0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b,
0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20,
0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4,
0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31,
0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f,
0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d,
0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef,
0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0,
0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61,
0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26,
0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d
};
#define rj_sbox(x) sbox[(x)]
#define rj_sbox_inv(x) sboxinv[(x)]
#else /* tableless subroutines */
/* -------------------------------------------------------------------------- */
static uint8_t gf_alog(uint8_t x) // calculate anti-logarithm gen 3
{
uint8_t y = 1, i;
for (i = 0; i < x; i++) y ^= rj_xtime(y);
return y;
} /* gf_alog */
/* -------------------------------------------------------------------------- */
static uint8_t gf_log(uint8_t x) // calculate logarithm gen 3
{
uint8_t y, i = 0;
if (x)
for (i = 1, y = 1; i > 0; i++ )
{
y ^= rj_xtime(y);
if (y == x) break;
}
return i;
} /* gf_log */
/* -------------------------------------------------------------------------- */
static uint8_t gf_mulinv(uint8_t x) // calculate multiplicative inverse
{
return (x) ? gf_alog(255 - gf_log(x)) : 0;
} /* gf_mulinv */
/* -------------------------------------------------------------------------- */
static uint8_t rj_sbox(uint8_t x)
{
uint8_t y, sb;
sb = y = gf_mulinv(x);
y = (uint8_t)(y << 1) | (y >> 7), sb ^= y;
y = (uint8_t)(y << 1) | (y >> 7), sb ^= y;
y = (uint8_t)(y << 1) | (y >> 7), sb ^= y;
y = (uint8_t)(y << 1) | (y >> 7), sb ^= y;
return (sb ^ 0x63);
} /* rj_sbox */
/* -------------------------------------------------------------------------- */
static uint8_t rj_sbox_inv(uint8_t x)
{
uint8_t y, sb;
y = x ^ 0x63;
sb = y = (uint8_t)(y << 1) | (y >> 7);
y = (uint8_t)(y << 2) | (y >> 6);
sb ^= y;
y = (uint8_t)(y << 3) | (y >> 5);
sb ^= y;
return gf_mulinv(sb);
} /* rj_sbox_inv */
#endif
/* -------------------------------------------------------------------------- */
static uint8_t rj_xtime(uint8_t x)
{
uint8_t y = (uint8_t)(x << 1);
return (x & 0x80) ? (y ^ 0x1b) : y;
} /* rj_xtime */
/* -------------------------------------------------------------------------- */
static void aes_subBytes(uint8_t *buf)
{
register uint8_t i = 16;
while (i--) buf[i] = rj_sbox(buf[i]);
} /* aes_subBytes */
/* -------------------------------------------------------------------------- */
static void aes_subBytes_inv(uint8_t *buf)
{
register uint8_t i = 16;
while (i--) buf[i] = rj_sbox_inv(buf[i]);
} /* aes_subBytes_inv */
/* -------------------------------------------------------------------------- */
static void aes_addRoundKey(uint8_t *buf, uint8_t *key)
{
register uint8_t i = 16;
while (i--) buf[i] ^= key[i];
} /* aes_addRoundKey */
/* -------------------------------------------------------------------------- */
static void aes_addRoundKey_cpy(uint8_t *buf, uint8_t *key, uint8_t *cpk)
{
register uint8_t i = 16;
while (i--) buf[i] ^= (cpk[i] = key[i]), cpk[16 + i] = key[16 + i];
} /* aes_addRoundKey_cpy */
/* -------------------------------------------------------------------------- */
static void aes_shiftRows(uint8_t *buf)
{
register uint8_t i, j; /* to make it potentially parallelable :) */
i = buf[1], buf[1] = buf[5], buf[5] = buf[9], buf[9] = buf[13], buf[13] = i;
i = buf[10], buf[10] = buf[2], buf[2] = i;
j = buf[3], buf[3] = buf[15], buf[15] = buf[11], buf[11] = buf[7], buf[7] = j;
j = buf[14], buf[14] = buf[6], buf[6] = j;
} /* aes_shiftRows */
/* -------------------------------------------------------------------------- */
static void aes_shiftRows_inv(uint8_t *buf)
{
register uint8_t i, j; /* same as above :) */
i = buf[1], buf[1] = buf[13], buf[13] = buf[9], buf[9] = buf[5], buf[5] = i;
i = buf[2], buf[2] = buf[10], buf[10] = i;
j = buf[3], buf[3] = buf[7], buf[7] = buf[11], buf[11] = buf[15], buf[15] = j;
j = buf[6], buf[6] = buf[14], buf[14] = j;
} /* aes_shiftRows_inv */
/* -------------------------------------------------------------------------- */
static void aes_mixColumns(uint8_t *buf)
{
register uint8_t i, a, b, c, d, e;
for (i = 0; i < 16; i += 4)
{
a = buf[i];
b = buf[i + 1];
c = buf[i + 2];
d = buf[i + 3];
e = a ^ b ^ c ^ d;
buf[i] ^= e ^ rj_xtime(a ^ b);
buf[i + 1] ^= e ^ rj_xtime(b ^ c);
buf[i + 2] ^= e ^ rj_xtime(c ^ d);
buf[i + 3] ^= e ^ rj_xtime(d ^ a);
}
} /* aes_mixColumns */
/* -------------------------------------------------------------------------- */
void aes_mixColumns_inv(uint8_t *buf)
{
register uint8_t i, a, b, c, d, e, x, y, z;
for (i = 0; i < 16; i += 4)
{
a = buf[i];
b = buf[i + 1];
c = buf[i + 2];
d = buf[i + 3];
e = a ^ b ^ c ^ d;
z = rj_xtime(e);
x = e ^ rj_xtime(rj_xtime(z ^ a ^ c));
y = e ^ rj_xtime(rj_xtime(z ^ b ^ d));
buf[i] ^= x ^ rj_xtime(a ^ b);
buf[i + 1] ^= y ^ rj_xtime(b ^ c);
buf[i + 2] ^= x ^ rj_xtime(c ^ d);
buf[i + 3] ^= y ^ rj_xtime(d ^ a);
}
} /* aes_mixColumns_inv */
/* -------------------------------------------------------------------------- */
static void aes_expandEncKey(uint8_t *k, uint8_t *rc)
{
register uint8_t i;
k[0] ^= rj_sbox(k[29]) ^ (*rc);
k[1] ^= rj_sbox(k[30]);
k[2] ^= rj_sbox(k[31]);
k[3] ^= rj_sbox(k[28]);
*rc = rj_xtime( *rc);
for(i = 4; i < 16; i += 4) k[i] ^= k[i - 4], k[i + 1] ^= k[i - 3],
k[i + 2] ^= k[i - 2], k[i + 3] ^= k[i - 1];
k[16] ^= rj_sbox(k[12]);
k[17] ^= rj_sbox(k[13]);
k[18] ^= rj_sbox(k[14]);
k[19] ^= rj_sbox(k[15]);
for(i = 20; i < 32; i += 4) k[i] ^= k[i - 4], k[i + 1] ^= k[i - 3],
k[i + 2] ^= k[i - 2], k[i + 3] ^= k[i - 1];
} /* aes_expandEncKey */
/* -------------------------------------------------------------------------- */
void aes_expandDecKey(uint8_t *k, uint8_t *rc)
{
uint8_t i;
for(i = 28; i > 16; i -= 4) k[i + 0] ^= k[i - 4], k[i + 1] ^= k[i - 3],
k[i + 2] ^= k[i - 2], k[i + 3] ^= k[i - 1];
k[16] ^= rj_sbox(k[12]);
k[17] ^= rj_sbox(k[13]);
k[18] ^= rj_sbox(k[14]);
k[19] ^= rj_sbox(k[15]);
for(i = 12; i > 0; i -= 4) k[i + 0] ^= k[i - 4], k[i + 1] ^= k[i - 3],
k[i + 2] ^= k[i - 2], k[i + 3] ^= k[i - 1];
*rc = FD(*rc);
k[0] ^= rj_sbox(k[29]) ^ (*rc);
k[1] ^= rj_sbox(k[30]);
k[2] ^= rj_sbox(k[31]);
k[3] ^= rj_sbox(k[28]);
} /* aes_expandDecKey */
/* -------------------------------------------------------------------------- */
void aes256_init(aes256_context *ctx, uint8_t *k)
{
uint8_t rcon = 1;
register uint8_t i;
for (i = 0; i < sizeof(ctx->key); i++) ctx->enckey[i] = ctx->deckey[i] = k[i];
for (i = 8; --i;) aes_expandEncKey(ctx->deckey, &rcon);
} /* aes256_init */
/* -------------------------------------------------------------------------- */
void aes256_done(aes256_context *ctx)
{
register uint8_t i;
for (i = 0; i < sizeof(ctx->key); i++)
ctx->key[i] = ctx->enckey[i] = ctx->deckey[i] = 0;
} /* aes256_done */
/* -------------------------------------------------------------------------- */
void aes256_encrypt_ecb(aes256_context *ctx, uint8_t *buf)
{
uint8_t i, rcon;
aes_addRoundKey_cpy(buf, ctx->enckey, ctx->key);
for(i = 1, rcon = 1; i < 14; ++i)
{
aes_subBytes(buf);
aes_shiftRows(buf);
aes_mixColumns(buf);
if( i & 1 ) aes_addRoundKey( buf, &ctx->key[16]);
else aes_expandEncKey(ctx->key, &rcon), aes_addRoundKey(buf, ctx->key);
}
aes_subBytes(buf);
aes_shiftRows(buf);
aes_expandEncKey(ctx->key, &rcon);
aes_addRoundKey(buf, ctx->key);
} /* aes256_encrypt */
/* -------------------------------------------------------------------------- */
void aes256_decrypt_ecb(aes256_context *ctx, uint8_t *buf)
{
uint8_t i, rcon;
aes_addRoundKey_cpy(buf, ctx->deckey, ctx->key);
aes_shiftRows_inv(buf);
aes_subBytes_inv(buf);
for (i = 14, rcon = 0x80; --i;)
{
if( ( i & 1 ) )
{
aes_expandDecKey(ctx->key, &rcon);
aes_addRoundKey(buf, &ctx->key[16]);
}
else aes_addRoundKey(buf, ctx->key);
aes_mixColumns_inv(buf);
aes_shiftRows_inv(buf);
aes_subBytes_inv(buf);
}
aes_addRoundKey( buf, ctx->key);
} /* aes256_decrypt */
#ifdef __cplusplus
}
#endif

View File

@@ -0,0 +1,42 @@
/*
* Byte-oriented AES-256 implementation.
* All lookup tables replaced with 'on the fly' calculations.
*
* Copyright (c) 2007-2009 Ilya O. Levin, http://www.literatecode.com
* Other contributors: Hal Finney
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef uint8_t
#define uint8_t unsigned char
#endif
#ifdef __cplusplus
extern "C" {
#endif
typedef struct {
uint8_t key[32];
uint8_t enckey[32];
uint8_t deckey[32];
} aes256_context;
void aes256_init(aes256_context *, uint8_t * /* key */);
void aes256_done(aes256_context *);
void aes256_encrypt_ecb(aes256_context *, uint8_t * /* plaintext */);
void aes256_decrypt_ecb(aes256_context *, uint8_t * /* cipertext */);
#ifdef __cplusplus
}
#endif

View File

@@ -0,0 +1,7 @@
# Create the B64Lib library
add_library(B64Lib STATIC include/b64.h decode.c decode.c)
# Configure include folders
target_include_directories(B64Lib PRIVATE ${CMAKE_CURRENT_LIST_DIR})
target_include_directories(B64Lib PUBLIC ${CMAKE_CURRENT_LIST_DIR}/include)
# Configure build options
target_compile_definitions(B64Lib PRIVATE )

View File

@@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2014 Little Star Media, Inc.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@@ -0,0 +1,123 @@
/**
* `decode.c' - b64
*
* copyright (c) 2014 joseph werle
*/
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <b64.h>
unsigned char *
b64_decode (const char *src, size_t len) {
return b64_decode_ex(src, len, NULL);
}
unsigned char *
b64_decode_ex (const char *src, size_t len, size_t *decsize) {
int i = 0;
int j = 0;
int l = 0;
size_t size = 0;
unsigned char *dec = NULL;
unsigned char buf[3];
unsigned char tmp[4];
// alloc
dec = (unsigned char *) b64_malloc(1);
if (NULL == dec) { return NULL; }
// parse until end of source
while (len--) {
// break if char is `=' or not base64 char
if ('=' == src[j]) { break; }
if (!(isalnum(src[j]) || '+' == src[j] || '/' == src[j])) { break; }
// read up to 4 bytes at a time into `tmp'
tmp[i++] = src[j++];
// if 4 bytes read then decode into `buf'
if (4 == i) {
// translate values in `tmp' from table
for (i = 0; i < 4; ++i) {
// find translation char in `b64_table'
for (l = 0; l < 64; ++l) {
if (tmp[i] == b64_table[l]) {
tmp[i] = l;
break;
}
}
}
// decode
buf[0] = (tmp[0] << 2) + ((tmp[1] & 0x30) >> 4);
buf[1] = ((tmp[1] & 0xf) << 4) + ((tmp[2] & 0x3c) >> 2);
buf[2] = ((tmp[2] & 0x3) << 6) + tmp[3];
// write decoded buffer to `dec'
dec = (unsigned char *) b64_realloc(dec, size + 3);
if (dec != NULL){
for (i = 0; i < 3; ++i) {
dec[size++] = buf[i];
}
} else {
return NULL;
}
// reset
i = 0;
}
}
// remainder
if (i > 0) {
// fill `tmp' with `\0' at most 4 times
for (j = i; j < 4; ++j) {
tmp[j] = '\0';
}
// translate remainder
for (j = 0; j < 4; ++j) {
// find translation char in `b64_table'
for (l = 0; l < 64; ++l) {
if (tmp[j] == b64_table[l]) {
tmp[j] = l;
break;
}
}
}
// decode remainder
buf[0] = (tmp[0] << 2) + ((tmp[1] & 0x30) >> 4);
buf[1] = ((tmp[1] & 0xf) << 4) + ((tmp[2] & 0x3c) >> 2);
buf[2] = ((tmp[2] & 0x3) << 6) + tmp[3];
// write remainer decoded buffer to `dec'
dec = (unsigned char *) b64_realloc(dec, size + (i - 1));
if (dec != NULL){
for (j = 0; (j < i - 1); ++j) {
dec[size++] = buf[j];
}
} else {
return NULL;
}
}
// Make sure we have enough space to add '\0' character at end.
dec = (unsigned char *) b64_realloc(dec, size + 1);
if (dec != NULL){
dec[size] = '\0';
} else {
return NULL;
}
// Return back the size of decoded string if demanded.
if (decsize != NULL) {
*decsize = size;
}
return dec;
}

View File

@@ -0,0 +1,93 @@
/**
* `encode.c' - b64
*
* copyright (c) 2014 joseph werle
*/
#include <stdio.h>
#include <stdlib.h>
#include <b64.h>
char *
b64_encode (const unsigned char *src, size_t len) {
return b64_encode_ex(src, len, NULL);
}
char *
b64_encode_ex (const unsigned char *src, size_t len, size_t *encsize) {
int i = 0;
int j = 0;
char *enc = NULL;
size_t size = 0;
unsigned char buf[4];
unsigned char tmp[3];
// alloc
enc = (char *) b64_malloc(1);
if (NULL == enc) { return NULL; }
// parse until end of source
while (len--) {
// read up to 3 bytes at a time into `tmp'
tmp[i++] = *(src++);
// if 3 bytes read then encode into `buf'
if (3 == i) {
buf[0] = (tmp[0] & 0xfc) >> 2;
buf[1] = ((tmp[0] & 0x03) << 4) + ((tmp[1] & 0xf0) >> 4);
buf[2] = ((tmp[1] & 0x0f) << 2) + ((tmp[2] & 0xc0) >> 6);
buf[3] = tmp[2] & 0x3f;
// allocate 4 new byts for `enc` and
// then translate each encoded buffer
// part by index from the base 64 index table
// into `enc' unsigned char array
enc = (char *) b64_realloc(enc, size + 4);
for (i = 0; i < 4; ++i) {
enc[size++] = b64_table[buf[i]];
}
// reset index
i = 0;
}
}
// remainder
if (i > 0) {
// fill `tmp' with `\0' at most 3 times
for (j = i; j < 3; ++j) {
tmp[j] = '\0';
}
// perform same codec as above
buf[0] = (tmp[0] & 0xfc) >> 2;
buf[1] = ((tmp[0] & 0x03) << 4) + ((tmp[1] & 0xf0) >> 4);
buf[2] = ((tmp[1] & 0x0f) << 2) + ((tmp[2] & 0xc0) >> 6);
buf[3] = tmp[2] & 0x3f;
// perform same write to `enc` with new allocation
for (j = 0; (j < i + 1); ++j) {
enc = (char *) b64_realloc(enc, size + 1);
enc[size++] = b64_table[buf[j]];
}
// while there is still a remainder
// append `=' to `enc'
while ((i++ < 3)) {
enc = (char *) b64_realloc(enc, size + 1);
enc[size++] = '=';
}
}
// Make sure we have enough space to add '\0' character at end.
enc = (char *) b64_realloc(enc, size + 1);
enc[size] = '\0';
// Return back the size of encoded string if demanded.
if (encsize != NULL) {
*encsize = size;
}
return enc;
}

View File

@@ -0,0 +1,76 @@
/**
* `b64.h' - b64
*
* copyright (c) 2014 joseph werle
*/
#ifndef B64_H
#define B64_H 1
/**
* Memory allocation functions to use. You can define b64_malloc and
* b64_realloc to custom functions if you want.
*/
#ifndef b64_malloc
# define b64_malloc(ptr) malloc(ptr)
#endif
#ifndef b64_realloc
# define b64_realloc(ptr, size) realloc(ptr, size)
#endif
/**
* Base64 index table.
*/
static const char b64_table[] = {
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
'w', 'x', 'y', 'z', '0', '1', '2', '3',
'4', '5', '6', '7', '8', '9', '+', '/'
};
#ifdef __cplusplus
extern "C" {
#endif
/**
* Encode `unsigned char *' source with `size_t' size.
* Returns a `char *' base64 encoded string.
*/
char *
b64_encode (const unsigned char *, size_t);
/**
* Encode `unsigned char *' source with `size_t' size.
* Returns a `char *' base64 encoded string + size of encoded string.
*/
char *
b64_encode_ex (const unsigned char *, size_t, size_t *);
/**
* Dencode `char *' source with `size_t' size.
* Returns a `unsigned char *' base64 decoded string.
*/
unsigned char *
b64_decode (const char *, size_t);
/**
* Dencode `char *' source with `size_t' size.
* Returns a `unsigned char *' base64 decoded string + size of decoded string.
*/
unsigned char *
b64_decode_ex (const char *, size_t, size_t *);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,17 @@
# Create the HashLib library
add_library(HashLib STATIC
include/hash.h
include/hmac.h
include/crc32.h crc32.cpp
include/keccak.h keccak.cpp
include/md5.h md5.cpp
include/sha1.h sha1.cpp
include/sha3.h sha3.cpp
include/sha256.h sha256.cpp
digest.cpp
)
# Configure include folders
target_include_directories(HashLib PRIVATE ${CMAKE_CURRENT_LIST_DIR})
target_include_directories(HashLib PUBLIC ${CMAKE_CURRENT_LIST_DIR}/include)
# Configure build options
target_compile_definitions(HashLib PRIVATE )

View File

@@ -0,0 +1,431 @@
// //////////////////////////////////////////////////////////
// crc32.cpp
// Copyright (c) 2014,2015 Stephan Brumme. All rights reserved.
// see http://create.stephan-brumme.com/disclaimer.html
//
#include "crc32.h"
// big endian architectures need #define __BYTE_ORDER __BIG_ENDIAN
#ifndef _MSC_VER
#include <endian.h>
#endif
/// same as reset()
CRC32::CRC32()
{
reset();
}
/// restart
void CRC32::reset()
{
m_hash = 0;
}
namespace
{
/// look-up table
static const uint32_t crc32Lookup[8][256] =
{
// generated by:
//for (uint32_t i = 0; i <= 0xFF; i++)
//{
// uint32_t crc = i;
// for (unsigned int j = 0; j < 8; j++)
// crc = (crc >> 1) ^ ((crc & 1) * Polynomial);
// crc32Lookup[0][i] = crc;
//}
// slicing-by-8 algorithm (from Intel):
// http://www.intel.com/technology/comms/perfnet/download/CRC_generators.pdf
// http://sourceforge.net/projects/slicing-by-8/
//for (unsigned int i = 0; i <= 0xFF; i++)
//{
// crc32Lookup[1][i] = (crc32Lookup[0][i] >> 8) ^ crc32Lookup[0][crc32Lookup[0][i] & 0xFF];
// crc32Lookup[2][i] = (crc32Lookup[1][i] >> 8) ^ crc32Lookup[0][crc32Lookup[1][i] & 0xFF];
// crc32Lookup[3][i] = (crc32Lookup[2][i] >> 8) ^ crc32Lookup[0][crc32Lookup[2][i] & 0xFF];
// crc32Lookup[4][i] = (crc32Lookup[3][i] >> 8) ^ crc32Lookup[0][crc32Lookup[3][i] & 0xFF];
// crc32Lookup[5][i] = (crc32Lookup[4][i] >> 8) ^ crc32Lookup[0][crc32Lookup[4][i] & 0xFF];
// crc32Lookup[6][i] = (crc32Lookup[5][i] >> 8) ^ crc32Lookup[0][crc32Lookup[5][i] & 0xFF];
// crc32Lookup[7][i] = (crc32Lookup[6][i] >> 8) ^ crc32Lookup[0][crc32Lookup[6][i] & 0xFF];
//}
{ 0x00000000,0x77073096,0xEE0E612C,0x990951BA,0x076DC419,0x706AF48F,0xE963A535,0x9E6495A3,
0x0EDB8832,0x79DCB8A4,0xE0D5E91E,0x97D2D988,0x09B64C2B,0x7EB17CBD,0xE7B82D07,0x90BF1D91,
0x1DB71064,0x6AB020F2,0xF3B97148,0x84BE41DE,0x1ADAD47D,0x6DDDE4EB,0xF4D4B551,0x83D385C7,
0x136C9856,0x646BA8C0,0xFD62F97A,0x8A65C9EC,0x14015C4F,0x63066CD9,0xFA0F3D63,0x8D080DF5,
0x3B6E20C8,0x4C69105E,0xD56041E4,0xA2677172,0x3C03E4D1,0x4B04D447,0xD20D85FD,0xA50AB56B,
0x35B5A8FA,0x42B2986C,0xDBBBC9D6,0xACBCF940,0x32D86CE3,0x45DF5C75,0xDCD60DCF,0xABD13D59,
0x26D930AC,0x51DE003A,0xC8D75180,0xBFD06116,0x21B4F4B5,0x56B3C423,0xCFBA9599,0xB8BDA50F,
0x2802B89E,0x5F058808,0xC60CD9B2,0xB10BE924,0x2F6F7C87,0x58684C11,0xC1611DAB,0xB6662D3D,
0x76DC4190,0x01DB7106,0x98D220BC,0xEFD5102A,0x71B18589,0x06B6B51F,0x9FBFE4A5,0xE8B8D433,
0x7807C9A2,0x0F00F934,0x9609A88E,0xE10E9818,0x7F6A0DBB,0x086D3D2D,0x91646C97,0xE6635C01,
0x6B6B51F4,0x1C6C6162,0x856530D8,0xF262004E,0x6C0695ED,0x1B01A57B,0x8208F4C1,0xF50FC457,
0x65B0D9C6,0x12B7E950,0x8BBEB8EA,0xFCB9887C,0x62DD1DDF,0x15DA2D49,0x8CD37CF3,0xFBD44C65,
0x4DB26158,0x3AB551CE,0xA3BC0074,0xD4BB30E2,0x4ADFA541,0x3DD895D7,0xA4D1C46D,0xD3D6F4FB,
0x4369E96A,0x346ED9FC,0xAD678846,0xDA60B8D0,0x44042D73,0x33031DE5,0xAA0A4C5F,0xDD0D7CC9,
0x5005713C,0x270241AA,0xBE0B1010,0xC90C2086,0x5768B525,0x206F85B3,0xB966D409,0xCE61E49F,
0x5EDEF90E,0x29D9C998,0xB0D09822,0xC7D7A8B4,0x59B33D17,0x2EB40D81,0xB7BD5C3B,0xC0BA6CAD,
0xEDB88320,0x9ABFB3B6,0x03B6E20C,0x74B1D29A,0xEAD54739,0x9DD277AF,0x04DB2615,0x73DC1683,
0xE3630B12,0x94643B84,0x0D6D6A3E,0x7A6A5AA8,0xE40ECF0B,0x9309FF9D,0x0A00AE27,0x7D079EB1,
0xF00F9344,0x8708A3D2,0x1E01F268,0x6906C2FE,0xF762575D,0x806567CB,0x196C3671,0x6E6B06E7,
0xFED41B76,0x89D32BE0,0x10DA7A5A,0x67DD4ACC,0xF9B9DF6F,0x8EBEEFF9,0x17B7BE43,0x60B08ED5,
0xD6D6A3E8,0xA1D1937E,0x38D8C2C4,0x4FDFF252,0xD1BB67F1,0xA6BC5767,0x3FB506DD,0x48B2364B,
0xD80D2BDA,0xAF0A1B4C,0x36034AF6,0x41047A60,0xDF60EFC3,0xA867DF55,0x316E8EEF,0x4669BE79,
0xCB61B38C,0xBC66831A,0x256FD2A0,0x5268E236,0xCC0C7795,0xBB0B4703,0x220216B9,0x5505262F,
0xC5BA3BBE,0xB2BD0B28,0x2BB45A92,0x5CB36A04,0xC2D7FFA7,0xB5D0CF31,0x2CD99E8B,0x5BDEAE1D,
0x9B64C2B0,0xEC63F226,0x756AA39C,0x026D930A,0x9C0906A9,0xEB0E363F,0x72076785,0x05005713,
0x95BF4A82,0xE2B87A14,0x7BB12BAE,0x0CB61B38,0x92D28E9B,0xE5D5BE0D,0x7CDCEFB7,0x0BDBDF21,
0x86D3D2D4,0xF1D4E242,0x68DDB3F8,0x1FDA836E,0x81BE16CD,0xF6B9265B,0x6FB077E1,0x18B74777,
0x88085AE6,0xFF0F6A70,0x66063BCA,0x11010B5C,0x8F659EFF,0xF862AE69,0x616BFFD3,0x166CCF45,
0xA00AE278,0xD70DD2EE,0x4E048354,0x3903B3C2,0xA7672661,0xD06016F7,0x4969474D,0x3E6E77DB,
0xAED16A4A,0xD9D65ADC,0x40DF0B66,0x37D83BF0,0xA9BCAE53,0xDEBB9EC5,0x47B2CF7F,0x30B5FFE9,
0xBDBDF21C,0xCABAC28A,0x53B39330,0x24B4A3A6,0xBAD03605,0xCDD70693,0x54DE5729,0x23D967BF,
0xB3667A2E,0xC4614AB8,0x5D681B02,0x2A6F2B94,0xB40BBE37,0xC30C8EA1,0x5A05DF1B,0x2D02EF8D },
{ 0x00000000,0x191B3141,0x32366282,0x2B2D53C3,0x646CC504,0x7D77F445,0x565AA786,0x4F4196C7,
0xC8D98A08,0xD1C2BB49,0xFAEFE88A,0xE3F4D9CB,0xACB54F0C,0xB5AE7E4D,0x9E832D8E,0x87981CCF,
0x4AC21251,0x53D92310,0x78F470D3,0x61EF4192,0x2EAED755,0x37B5E614,0x1C98B5D7,0x05838496,
0x821B9859,0x9B00A918,0xB02DFADB,0xA936CB9A,0xE6775D5D,0xFF6C6C1C,0xD4413FDF,0xCD5A0E9E,
0x958424A2,0x8C9F15E3,0xA7B24620,0xBEA97761,0xF1E8E1A6,0xE8F3D0E7,0xC3DE8324,0xDAC5B265,
0x5D5DAEAA,0x44469FEB,0x6F6BCC28,0x7670FD69,0x39316BAE,0x202A5AEF,0x0B07092C,0x121C386D,
0xDF4636F3,0xC65D07B2,0xED705471,0xF46B6530,0xBB2AF3F7,0xA231C2B6,0x891C9175,0x9007A034,
0x179FBCFB,0x0E848DBA,0x25A9DE79,0x3CB2EF38,0x73F379FF,0x6AE848BE,0x41C51B7D,0x58DE2A3C,
0xF0794F05,0xE9627E44,0xC24F2D87,0xDB541CC6,0x94158A01,0x8D0EBB40,0xA623E883,0xBF38D9C2,
0x38A0C50D,0x21BBF44C,0x0A96A78F,0x138D96CE,0x5CCC0009,0x45D73148,0x6EFA628B,0x77E153CA,
0xBABB5D54,0xA3A06C15,0x888D3FD6,0x91960E97,0xDED79850,0xC7CCA911,0xECE1FAD2,0xF5FACB93,
0x7262D75C,0x6B79E61D,0x4054B5DE,0x594F849F,0x160E1258,0x0F152319,0x243870DA,0x3D23419B,
0x65FD6BA7,0x7CE65AE6,0x57CB0925,0x4ED03864,0x0191AEA3,0x188A9FE2,0x33A7CC21,0x2ABCFD60,
0xAD24E1AF,0xB43FD0EE,0x9F12832D,0x8609B26C,0xC94824AB,0xD05315EA,0xFB7E4629,0xE2657768,
0x2F3F79F6,0x362448B7,0x1D091B74,0x04122A35,0x4B53BCF2,0x52488DB3,0x7965DE70,0x607EEF31,
0xE7E6F3FE,0xFEFDC2BF,0xD5D0917C,0xCCCBA03D,0x838A36FA,0x9A9107BB,0xB1BC5478,0xA8A76539,
0x3B83984B,0x2298A90A,0x09B5FAC9,0x10AECB88,0x5FEF5D4F,0x46F46C0E,0x6DD93FCD,0x74C20E8C,
0xF35A1243,0xEA412302,0xC16C70C1,0xD8774180,0x9736D747,0x8E2DE606,0xA500B5C5,0xBC1B8484,
0x71418A1A,0x685ABB5B,0x4377E898,0x5A6CD9D9,0x152D4F1E,0x0C367E5F,0x271B2D9C,0x3E001CDD,
0xB9980012,0xA0833153,0x8BAE6290,0x92B553D1,0xDDF4C516,0xC4EFF457,0xEFC2A794,0xF6D996D5,
0xAE07BCE9,0xB71C8DA8,0x9C31DE6B,0x852AEF2A,0xCA6B79ED,0xD37048AC,0xF85D1B6F,0xE1462A2E,
0x66DE36E1,0x7FC507A0,0x54E85463,0x4DF36522,0x02B2F3E5,0x1BA9C2A4,0x30849167,0x299FA026,
0xE4C5AEB8,0xFDDE9FF9,0xD6F3CC3A,0xCFE8FD7B,0x80A96BBC,0x99B25AFD,0xB29F093E,0xAB84387F,
0x2C1C24B0,0x350715F1,0x1E2A4632,0x07317773,0x4870E1B4,0x516BD0F5,0x7A468336,0x635DB277,
0xCBFAD74E,0xD2E1E60F,0xF9CCB5CC,0xE0D7848D,0xAF96124A,0xB68D230B,0x9DA070C8,0x84BB4189,
0x03235D46,0x1A386C07,0x31153FC4,0x280E0E85,0x674F9842,0x7E54A903,0x5579FAC0,0x4C62CB81,
0x8138C51F,0x9823F45E,0xB30EA79D,0xAA1596DC,0xE554001B,0xFC4F315A,0xD7626299,0xCE7953D8,
0x49E14F17,0x50FA7E56,0x7BD72D95,0x62CC1CD4,0x2D8D8A13,0x3496BB52,0x1FBBE891,0x06A0D9D0,
0x5E7EF3EC,0x4765C2AD,0x6C48916E,0x7553A02F,0x3A1236E8,0x230907A9,0x0824546A,0x113F652B,
0x96A779E4,0x8FBC48A5,0xA4911B66,0xBD8A2A27,0xF2CBBCE0,0xEBD08DA1,0xC0FDDE62,0xD9E6EF23,
0x14BCE1BD,0x0DA7D0FC,0x268A833F,0x3F91B27E,0x70D024B9,0x69CB15F8,0x42E6463B,0x5BFD777A,
0xDC656BB5,0xC57E5AF4,0xEE530937,0xF7483876,0xB809AEB1,0xA1129FF0,0x8A3FCC33,0x9324FD72 },
{ 0x00000000,0x01C26A37,0x0384D46E,0x0246BE59,0x0709A8DC,0x06CBC2EB,0x048D7CB2,0x054F1685,
0x0E1351B8,0x0FD13B8F,0x0D9785D6,0x0C55EFE1,0x091AF964,0x08D89353,0x0A9E2D0A,0x0B5C473D,
0x1C26A370,0x1DE4C947,0x1FA2771E,0x1E601D29,0x1B2F0BAC,0x1AED619B,0x18ABDFC2,0x1969B5F5,
0x1235F2C8,0x13F798FF,0x11B126A6,0x10734C91,0x153C5A14,0x14FE3023,0x16B88E7A,0x177AE44D,
0x384D46E0,0x398F2CD7,0x3BC9928E,0x3A0BF8B9,0x3F44EE3C,0x3E86840B,0x3CC03A52,0x3D025065,
0x365E1758,0x379C7D6F,0x35DAC336,0x3418A901,0x3157BF84,0x3095D5B3,0x32D36BEA,0x331101DD,
0x246BE590,0x25A98FA7,0x27EF31FE,0x262D5BC9,0x23624D4C,0x22A0277B,0x20E69922,0x2124F315,
0x2A78B428,0x2BBADE1F,0x29FC6046,0x283E0A71,0x2D711CF4,0x2CB376C3,0x2EF5C89A,0x2F37A2AD,
0x709A8DC0,0x7158E7F7,0x731E59AE,0x72DC3399,0x7793251C,0x76514F2B,0x7417F172,0x75D59B45,
0x7E89DC78,0x7F4BB64F,0x7D0D0816,0x7CCF6221,0x798074A4,0x78421E93,0x7A04A0CA,0x7BC6CAFD,
0x6CBC2EB0,0x6D7E4487,0x6F38FADE,0x6EFA90E9,0x6BB5866C,0x6A77EC5B,0x68315202,0x69F33835,
0x62AF7F08,0x636D153F,0x612BAB66,0x60E9C151,0x65A6D7D4,0x6464BDE3,0x662203BA,0x67E0698D,
0x48D7CB20,0x4915A117,0x4B531F4E,0x4A917579,0x4FDE63FC,0x4E1C09CB,0x4C5AB792,0x4D98DDA5,
0x46C49A98,0x4706F0AF,0x45404EF6,0x448224C1,0x41CD3244,0x400F5873,0x4249E62A,0x438B8C1D,
0x54F16850,0x55330267,0x5775BC3E,0x56B7D609,0x53F8C08C,0x523AAABB,0x507C14E2,0x51BE7ED5,
0x5AE239E8,0x5B2053DF,0x5966ED86,0x58A487B1,0x5DEB9134,0x5C29FB03,0x5E6F455A,0x5FAD2F6D,
0xE1351B80,0xE0F771B7,0xE2B1CFEE,0xE373A5D9,0xE63CB35C,0xE7FED96B,0xE5B86732,0xE47A0D05,
0xEF264A38,0xEEE4200F,0xECA29E56,0xED60F461,0xE82FE2E4,0xE9ED88D3,0xEBAB368A,0xEA695CBD,
0xFD13B8F0,0xFCD1D2C7,0xFE976C9E,0xFF5506A9,0xFA1A102C,0xFBD87A1B,0xF99EC442,0xF85CAE75,
0xF300E948,0xF2C2837F,0xF0843D26,0xF1465711,0xF4094194,0xF5CB2BA3,0xF78D95FA,0xF64FFFCD,
0xD9785D60,0xD8BA3757,0xDAFC890E,0xDB3EE339,0xDE71F5BC,0xDFB39F8B,0xDDF521D2,0xDC374BE5,
0xD76B0CD8,0xD6A966EF,0xD4EFD8B6,0xD52DB281,0xD062A404,0xD1A0CE33,0xD3E6706A,0xD2241A5D,
0xC55EFE10,0xC49C9427,0xC6DA2A7E,0xC7184049,0xC25756CC,0xC3953CFB,0xC1D382A2,0xC011E895,
0xCB4DAFA8,0xCA8FC59F,0xC8C97BC6,0xC90B11F1,0xCC440774,0xCD866D43,0xCFC0D31A,0xCE02B92D,
0x91AF9640,0x906DFC77,0x922B422E,0x93E92819,0x96A63E9C,0x976454AB,0x9522EAF2,0x94E080C5,
0x9FBCC7F8,0x9E7EADCF,0x9C381396,0x9DFA79A1,0x98B56F24,0x99770513,0x9B31BB4A,0x9AF3D17D,
0x8D893530,0x8C4B5F07,0x8E0DE15E,0x8FCF8B69,0x8A809DEC,0x8B42F7DB,0x89044982,0x88C623B5,
0x839A6488,0x82580EBF,0x801EB0E6,0x81DCDAD1,0x8493CC54,0x8551A663,0x8717183A,0x86D5720D,
0xA9E2D0A0,0xA820BA97,0xAA6604CE,0xABA46EF9,0xAEEB787C,0xAF29124B,0xAD6FAC12,0xACADC625,
0xA7F18118,0xA633EB2F,0xA4755576,0xA5B73F41,0xA0F829C4,0xA13A43F3,0xA37CFDAA,0xA2BE979D,
0xB5C473D0,0xB40619E7,0xB640A7BE,0xB782CD89,0xB2CDDB0C,0xB30FB13B,0xB1490F62,0xB08B6555,
0xBBD72268,0xBA15485F,0xB853F606,0xB9919C31,0xBCDE8AB4,0xBD1CE083,0xBF5A5EDA,0xBE9834ED },
{ 0x00000000,0xB8BC6765,0xAA09C88B,0x12B5AFEE,0x8F629757,0x37DEF032,0x256B5FDC,0x9DD738B9,
0xC5B428EF,0x7D084F8A,0x6FBDE064,0xD7018701,0x4AD6BFB8,0xF26AD8DD,0xE0DF7733,0x58631056,
0x5019579F,0xE8A530FA,0xFA109F14,0x42ACF871,0xDF7BC0C8,0x67C7A7AD,0x75720843,0xCDCE6F26,
0x95AD7F70,0x2D111815,0x3FA4B7FB,0x8718D09E,0x1ACFE827,0xA2738F42,0xB0C620AC,0x087A47C9,
0xA032AF3E,0x188EC85B,0x0A3B67B5,0xB28700D0,0x2F503869,0x97EC5F0C,0x8559F0E2,0x3DE59787,
0x658687D1,0xDD3AE0B4,0xCF8F4F5A,0x7733283F,0xEAE41086,0x525877E3,0x40EDD80D,0xF851BF68,
0xF02BF8A1,0x48979FC4,0x5A22302A,0xE29E574F,0x7F496FF6,0xC7F50893,0xD540A77D,0x6DFCC018,
0x359FD04E,0x8D23B72B,0x9F9618C5,0x272A7FA0,0xBAFD4719,0x0241207C,0x10F48F92,0xA848E8F7,
0x9B14583D,0x23A83F58,0x311D90B6,0x89A1F7D3,0x1476CF6A,0xACCAA80F,0xBE7F07E1,0x06C36084,
0x5EA070D2,0xE61C17B7,0xF4A9B859,0x4C15DF3C,0xD1C2E785,0x697E80E0,0x7BCB2F0E,0xC377486B,
0xCB0D0FA2,0x73B168C7,0x6104C729,0xD9B8A04C,0x446F98F5,0xFCD3FF90,0xEE66507E,0x56DA371B,
0x0EB9274D,0xB6054028,0xA4B0EFC6,0x1C0C88A3,0x81DBB01A,0x3967D77F,0x2BD27891,0x936E1FF4,
0x3B26F703,0x839A9066,0x912F3F88,0x299358ED,0xB4446054,0x0CF80731,0x1E4DA8DF,0xA6F1CFBA,
0xFE92DFEC,0x462EB889,0x549B1767,0xEC277002,0x71F048BB,0xC94C2FDE,0xDBF98030,0x6345E755,
0x6B3FA09C,0xD383C7F9,0xC1366817,0x798A0F72,0xE45D37CB,0x5CE150AE,0x4E54FF40,0xF6E89825,
0xAE8B8873,0x1637EF16,0x048240F8,0xBC3E279D,0x21E91F24,0x99557841,0x8BE0D7AF,0x335CB0CA,
0xED59B63B,0x55E5D15E,0x47507EB0,0xFFEC19D5,0x623B216C,0xDA874609,0xC832E9E7,0x708E8E82,
0x28ED9ED4,0x9051F9B1,0x82E4565F,0x3A58313A,0xA78F0983,0x1F336EE6,0x0D86C108,0xB53AA66D,
0xBD40E1A4,0x05FC86C1,0x1749292F,0xAFF54E4A,0x322276F3,0x8A9E1196,0x982BBE78,0x2097D91D,
0x78F4C94B,0xC048AE2E,0xD2FD01C0,0x6A4166A5,0xF7965E1C,0x4F2A3979,0x5D9F9697,0xE523F1F2,
0x4D6B1905,0xF5D77E60,0xE762D18E,0x5FDEB6EB,0xC2098E52,0x7AB5E937,0x680046D9,0xD0BC21BC,
0x88DF31EA,0x3063568F,0x22D6F961,0x9A6A9E04,0x07BDA6BD,0xBF01C1D8,0xADB46E36,0x15080953,
0x1D724E9A,0xA5CE29FF,0xB77B8611,0x0FC7E174,0x9210D9CD,0x2AACBEA8,0x38191146,0x80A57623,
0xD8C66675,0x607A0110,0x72CFAEFE,0xCA73C99B,0x57A4F122,0xEF189647,0xFDAD39A9,0x45115ECC,
0x764DEE06,0xCEF18963,0xDC44268D,0x64F841E8,0xF92F7951,0x41931E34,0x5326B1DA,0xEB9AD6BF,
0xB3F9C6E9,0x0B45A18C,0x19F00E62,0xA14C6907,0x3C9B51BE,0x842736DB,0x96929935,0x2E2EFE50,
0x2654B999,0x9EE8DEFC,0x8C5D7112,0x34E11677,0xA9362ECE,0x118A49AB,0x033FE645,0xBB838120,
0xE3E09176,0x5B5CF613,0x49E959FD,0xF1553E98,0x6C820621,0xD43E6144,0xC68BCEAA,0x7E37A9CF,
0xD67F4138,0x6EC3265D,0x7C7689B3,0xC4CAEED6,0x591DD66F,0xE1A1B10A,0xF3141EE4,0x4BA87981,
0x13CB69D7,0xAB770EB2,0xB9C2A15C,0x017EC639,0x9CA9FE80,0x241599E5,0x36A0360B,0x8E1C516E,
0x866616A7,0x3EDA71C2,0x2C6FDE2C,0x94D3B949,0x090481F0,0xB1B8E695,0xA30D497B,0x1BB12E1E,
0x43D23E48,0xFB6E592D,0xE9DBF6C3,0x516791A6,0xCCB0A91F,0x740CCE7A,0x66B96194,0xDE0506F1 },
{ 0x00000000,0x3D6029B0,0x7AC05360,0x47A07AD0,0xF580A6C0,0xC8E08F70,0x8F40F5A0,0xB220DC10,
0x30704BC1,0x0D106271,0x4AB018A1,0x77D03111,0xC5F0ED01,0xF890C4B1,0xBF30BE61,0x825097D1,
0x60E09782,0x5D80BE32,0x1A20C4E2,0x2740ED52,0x95603142,0xA80018F2,0xEFA06222,0xD2C04B92,
0x5090DC43,0x6DF0F5F3,0x2A508F23,0x1730A693,0xA5107A83,0x98705333,0xDFD029E3,0xE2B00053,
0xC1C12F04,0xFCA106B4,0xBB017C64,0x866155D4,0x344189C4,0x0921A074,0x4E81DAA4,0x73E1F314,
0xF1B164C5,0xCCD14D75,0x8B7137A5,0xB6111E15,0x0431C205,0x3951EBB5,0x7EF19165,0x4391B8D5,
0xA121B886,0x9C419136,0xDBE1EBE6,0xE681C256,0x54A11E46,0x69C137F6,0x2E614D26,0x13016496,
0x9151F347,0xAC31DAF7,0xEB91A027,0xD6F18997,0x64D15587,0x59B17C37,0x1E1106E7,0x23712F57,
0x58F35849,0x659371F9,0x22330B29,0x1F532299,0xAD73FE89,0x9013D739,0xD7B3ADE9,0xEAD38459,
0x68831388,0x55E33A38,0x124340E8,0x2F236958,0x9D03B548,0xA0639CF8,0xE7C3E628,0xDAA3CF98,
0x3813CFCB,0x0573E67B,0x42D39CAB,0x7FB3B51B,0xCD93690B,0xF0F340BB,0xB7533A6B,0x8A3313DB,
0x0863840A,0x3503ADBA,0x72A3D76A,0x4FC3FEDA,0xFDE322CA,0xC0830B7A,0x872371AA,0xBA43581A,
0x9932774D,0xA4525EFD,0xE3F2242D,0xDE920D9D,0x6CB2D18D,0x51D2F83D,0x167282ED,0x2B12AB5D,
0xA9423C8C,0x9422153C,0xD3826FEC,0xEEE2465C,0x5CC29A4C,0x61A2B3FC,0x2602C92C,0x1B62E09C,
0xF9D2E0CF,0xC4B2C97F,0x8312B3AF,0xBE729A1F,0x0C52460F,0x31326FBF,0x7692156F,0x4BF23CDF,
0xC9A2AB0E,0xF4C282BE,0xB362F86E,0x8E02D1DE,0x3C220DCE,0x0142247E,0x46E25EAE,0x7B82771E,
0xB1E6B092,0x8C869922,0xCB26E3F2,0xF646CA42,0x44661652,0x79063FE2,0x3EA64532,0x03C66C82,
0x8196FB53,0xBCF6D2E3,0xFB56A833,0xC6368183,0x74165D93,0x49767423,0x0ED60EF3,0x33B62743,
0xD1062710,0xEC660EA0,0xABC67470,0x96A65DC0,0x248681D0,0x19E6A860,0x5E46D2B0,0x6326FB00,
0xE1766CD1,0xDC164561,0x9BB63FB1,0xA6D61601,0x14F6CA11,0x2996E3A1,0x6E369971,0x5356B0C1,
0x70279F96,0x4D47B626,0x0AE7CCF6,0x3787E546,0x85A73956,0xB8C710E6,0xFF676A36,0xC2074386,
0x4057D457,0x7D37FDE7,0x3A978737,0x07F7AE87,0xB5D77297,0x88B75B27,0xCF1721F7,0xF2770847,
0x10C70814,0x2DA721A4,0x6A075B74,0x576772C4,0xE547AED4,0xD8278764,0x9F87FDB4,0xA2E7D404,
0x20B743D5,0x1DD76A65,0x5A7710B5,0x67173905,0xD537E515,0xE857CCA5,0xAFF7B675,0x92979FC5,
0xE915E8DB,0xD475C16B,0x93D5BBBB,0xAEB5920B,0x1C954E1B,0x21F567AB,0x66551D7B,0x5B3534CB,
0xD965A31A,0xE4058AAA,0xA3A5F07A,0x9EC5D9CA,0x2CE505DA,0x11852C6A,0x562556BA,0x6B457F0A,
0x89F57F59,0xB49556E9,0xF3352C39,0xCE550589,0x7C75D999,0x4115F029,0x06B58AF9,0x3BD5A349,
0xB9853498,0x84E51D28,0xC34567F8,0xFE254E48,0x4C059258,0x7165BBE8,0x36C5C138,0x0BA5E888,
0x28D4C7DF,0x15B4EE6F,0x521494BF,0x6F74BD0F,0xDD54611F,0xE03448AF,0xA794327F,0x9AF41BCF,
0x18A48C1E,0x25C4A5AE,0x6264DF7E,0x5F04F6CE,0xED242ADE,0xD044036E,0x97E479BE,0xAA84500E,
0x4834505D,0x755479ED,0x32F4033D,0x0F942A8D,0xBDB4F69D,0x80D4DF2D,0xC774A5FD,0xFA148C4D,
0x78441B9C,0x4524322C,0x028448FC,0x3FE4614C,0x8DC4BD5C,0xB0A494EC,0xF704EE3C,0xCA64C78C },
{ 0x00000000,0xCB5CD3A5,0x4DC8A10B,0x869472AE,0x9B914216,0x50CD91B3,0xD659E31D,0x1D0530B8,
0xEC53826D,0x270F51C8,0xA19B2366,0x6AC7F0C3,0x77C2C07B,0xBC9E13DE,0x3A0A6170,0xF156B2D5,
0x03D6029B,0xC88AD13E,0x4E1EA390,0x85427035,0x9847408D,0x531B9328,0xD58FE186,0x1ED33223,
0xEF8580F6,0x24D95353,0xA24D21FD,0x6911F258,0x7414C2E0,0xBF481145,0x39DC63EB,0xF280B04E,
0x07AC0536,0xCCF0D693,0x4A64A43D,0x81387798,0x9C3D4720,0x57619485,0xD1F5E62B,0x1AA9358E,
0xEBFF875B,0x20A354FE,0xA6372650,0x6D6BF5F5,0x706EC54D,0xBB3216E8,0x3DA66446,0xF6FAB7E3,
0x047A07AD,0xCF26D408,0x49B2A6A6,0x82EE7503,0x9FEB45BB,0x54B7961E,0xD223E4B0,0x197F3715,
0xE82985C0,0x23755665,0xA5E124CB,0x6EBDF76E,0x73B8C7D6,0xB8E41473,0x3E7066DD,0xF52CB578,
0x0F580A6C,0xC404D9C9,0x4290AB67,0x89CC78C2,0x94C9487A,0x5F959BDF,0xD901E971,0x125D3AD4,
0xE30B8801,0x28575BA4,0xAEC3290A,0x659FFAAF,0x789ACA17,0xB3C619B2,0x35526B1C,0xFE0EB8B9,
0x0C8E08F7,0xC7D2DB52,0x4146A9FC,0x8A1A7A59,0x971F4AE1,0x5C439944,0xDAD7EBEA,0x118B384F,
0xE0DD8A9A,0x2B81593F,0xAD152B91,0x6649F834,0x7B4CC88C,0xB0101B29,0x36846987,0xFDD8BA22,
0x08F40F5A,0xC3A8DCFF,0x453CAE51,0x8E607DF4,0x93654D4C,0x58399EE9,0xDEADEC47,0x15F13FE2,
0xE4A78D37,0x2FFB5E92,0xA96F2C3C,0x6233FF99,0x7F36CF21,0xB46A1C84,0x32FE6E2A,0xF9A2BD8F,
0x0B220DC1,0xC07EDE64,0x46EAACCA,0x8DB67F6F,0x90B34FD7,0x5BEF9C72,0xDD7BEEDC,0x16273D79,
0xE7718FAC,0x2C2D5C09,0xAAB92EA7,0x61E5FD02,0x7CE0CDBA,0xB7BC1E1F,0x31286CB1,0xFA74BF14,
0x1EB014D8,0xD5ECC77D,0x5378B5D3,0x98246676,0x852156CE,0x4E7D856B,0xC8E9F7C5,0x03B52460,
0xF2E396B5,0x39BF4510,0xBF2B37BE,0x7477E41B,0x6972D4A3,0xA22E0706,0x24BA75A8,0xEFE6A60D,
0x1D661643,0xD63AC5E6,0x50AEB748,0x9BF264ED,0x86F75455,0x4DAB87F0,0xCB3FF55E,0x006326FB,
0xF135942E,0x3A69478B,0xBCFD3525,0x77A1E680,0x6AA4D638,0xA1F8059D,0x276C7733,0xEC30A496,
0x191C11EE,0xD240C24B,0x54D4B0E5,0x9F886340,0x828D53F8,0x49D1805D,0xCF45F2F3,0x04192156,
0xF54F9383,0x3E134026,0xB8873288,0x73DBE12D,0x6EDED195,0xA5820230,0x2316709E,0xE84AA33B,
0x1ACA1375,0xD196C0D0,0x5702B27E,0x9C5E61DB,0x815B5163,0x4A0782C6,0xCC93F068,0x07CF23CD,
0xF6999118,0x3DC542BD,0xBB513013,0x700DE3B6,0x6D08D30E,0xA65400AB,0x20C07205,0xEB9CA1A0,
0x11E81EB4,0xDAB4CD11,0x5C20BFBF,0x977C6C1A,0x8A795CA2,0x41258F07,0xC7B1FDA9,0x0CED2E0C,
0xFDBB9CD9,0x36E74F7C,0xB0733DD2,0x7B2FEE77,0x662ADECF,0xAD760D6A,0x2BE27FC4,0xE0BEAC61,
0x123E1C2F,0xD962CF8A,0x5FF6BD24,0x94AA6E81,0x89AF5E39,0x42F38D9C,0xC467FF32,0x0F3B2C97,
0xFE6D9E42,0x35314DE7,0xB3A53F49,0x78F9ECEC,0x65FCDC54,0xAEA00FF1,0x28347D5F,0xE368AEFA,
0x16441B82,0xDD18C827,0x5B8CBA89,0x90D0692C,0x8DD55994,0x46898A31,0xC01DF89F,0x0B412B3A,
0xFA1799EF,0x314B4A4A,0xB7DF38E4,0x7C83EB41,0x6186DBF9,0xAADA085C,0x2C4E7AF2,0xE712A957,
0x15921919,0xDECECABC,0x585AB812,0x93066BB7,0x8E035B0F,0x455F88AA,0xC3CBFA04,0x089729A1,
0xF9C19B74,0x329D48D1,0xB4093A7F,0x7F55E9DA,0x6250D962,0xA90C0AC7,0x2F987869,0xE4C4ABCC },
{ 0x00000000,0xA6770BB4,0x979F1129,0x31E81A9D,0xF44F2413,0x52382FA7,0x63D0353A,0xC5A73E8E,
0x33EF4E67,0x959845D3,0xA4705F4E,0x020754FA,0xC7A06A74,0x61D761C0,0x503F7B5D,0xF64870E9,
0x67DE9CCE,0xC1A9977A,0xF0418DE7,0x56368653,0x9391B8DD,0x35E6B369,0x040EA9F4,0xA279A240,
0x5431D2A9,0xF246D91D,0xC3AEC380,0x65D9C834,0xA07EF6BA,0x0609FD0E,0x37E1E793,0x9196EC27,
0xCFBD399C,0x69CA3228,0x582228B5,0xFE552301,0x3BF21D8F,0x9D85163B,0xAC6D0CA6,0x0A1A0712,
0xFC5277FB,0x5A257C4F,0x6BCD66D2,0xCDBA6D66,0x081D53E8,0xAE6A585C,0x9F8242C1,0x39F54975,
0xA863A552,0x0E14AEE6,0x3FFCB47B,0x998BBFCF,0x5C2C8141,0xFA5B8AF5,0xCBB39068,0x6DC49BDC,
0x9B8CEB35,0x3DFBE081,0x0C13FA1C,0xAA64F1A8,0x6FC3CF26,0xC9B4C492,0xF85CDE0F,0x5E2BD5BB,
0x440B7579,0xE27C7ECD,0xD3946450,0x75E36FE4,0xB044516A,0x16335ADE,0x27DB4043,0x81AC4BF7,
0x77E43B1E,0xD19330AA,0xE07B2A37,0x460C2183,0x83AB1F0D,0x25DC14B9,0x14340E24,0xB2430590,
0x23D5E9B7,0x85A2E203,0xB44AF89E,0x123DF32A,0xD79ACDA4,0x71EDC610,0x4005DC8D,0xE672D739,
0x103AA7D0,0xB64DAC64,0x87A5B6F9,0x21D2BD4D,0xE47583C3,0x42028877,0x73EA92EA,0xD59D995E,
0x8BB64CE5,0x2DC14751,0x1C295DCC,0xBA5E5678,0x7FF968F6,0xD98E6342,0xE86679DF,0x4E11726B,
0xB8590282,0x1E2E0936,0x2FC613AB,0x89B1181F,0x4C162691,0xEA612D25,0xDB8937B8,0x7DFE3C0C,
0xEC68D02B,0x4A1FDB9F,0x7BF7C102,0xDD80CAB6,0x1827F438,0xBE50FF8C,0x8FB8E511,0x29CFEEA5,
0xDF879E4C,0x79F095F8,0x48188F65,0xEE6F84D1,0x2BC8BA5F,0x8DBFB1EB,0xBC57AB76,0x1A20A0C2,
0x8816EAF2,0x2E61E146,0x1F89FBDB,0xB9FEF06F,0x7C59CEE1,0xDA2EC555,0xEBC6DFC8,0x4DB1D47C,
0xBBF9A495,0x1D8EAF21,0x2C66B5BC,0x8A11BE08,0x4FB68086,0xE9C18B32,0xD82991AF,0x7E5E9A1B,
0xEFC8763C,0x49BF7D88,0x78576715,0xDE206CA1,0x1B87522F,0xBDF0599B,0x8C184306,0x2A6F48B2,
0xDC27385B,0x7A5033EF,0x4BB82972,0xEDCF22C6,0x28681C48,0x8E1F17FC,0xBFF70D61,0x198006D5,
0x47ABD36E,0xE1DCD8DA,0xD034C247,0x7643C9F3,0xB3E4F77D,0x1593FCC9,0x247BE654,0x820CEDE0,
0x74449D09,0xD23396BD,0xE3DB8C20,0x45AC8794,0x800BB91A,0x267CB2AE,0x1794A833,0xB1E3A387,
0x20754FA0,0x86024414,0xB7EA5E89,0x119D553D,0xD43A6BB3,0x724D6007,0x43A57A9A,0xE5D2712E,
0x139A01C7,0xB5ED0A73,0x840510EE,0x22721B5A,0xE7D525D4,0x41A22E60,0x704A34FD,0xD63D3F49,
0xCC1D9F8B,0x6A6A943F,0x5B828EA2,0xFDF58516,0x3852BB98,0x9E25B02C,0xAFCDAAB1,0x09BAA105,
0xFFF2D1EC,0x5985DA58,0x686DC0C5,0xCE1ACB71,0x0BBDF5FF,0xADCAFE4B,0x9C22E4D6,0x3A55EF62,
0xABC30345,0x0DB408F1,0x3C5C126C,0x9A2B19D8,0x5F8C2756,0xF9FB2CE2,0xC813367F,0x6E643DCB,
0x982C4D22,0x3E5B4696,0x0FB35C0B,0xA9C457BF,0x6C636931,0xCA146285,0xFBFC7818,0x5D8B73AC,
0x03A0A617,0xA5D7ADA3,0x943FB73E,0x3248BC8A,0xF7EF8204,0x519889B0,0x6070932D,0xC6079899,
0x304FE870,0x9638E3C4,0xA7D0F959,0x01A7F2ED,0xC400CC63,0x6277C7D7,0x539FDD4A,0xF5E8D6FE,
0x647E3AD9,0xC209316D,0xF3E12BF0,0x55962044,0x90311ECA,0x3646157E,0x07AE0FE3,0xA1D90457,
0x579174BE,0xF1E67F0A,0xC00E6597,0x66796E23,0xA3DE50AD,0x05A95B19,0x34414184,0x92364A30 },
{ 0x00000000,0xCCAA009E,0x4225077D,0x8E8F07E3,0x844A0EFA,0x48E00E64,0xC66F0987,0x0AC50919,
0xD3E51BB5,0x1F4F1B2B,0x91C01CC8,0x5D6A1C56,0x57AF154F,0x9B0515D1,0x158A1232,0xD92012AC,
0x7CBB312B,0xB01131B5,0x3E9E3656,0xF23436C8,0xF8F13FD1,0x345B3F4F,0xBAD438AC,0x767E3832,
0xAF5E2A9E,0x63F42A00,0xED7B2DE3,0x21D12D7D,0x2B142464,0xE7BE24FA,0x69312319,0xA59B2387,
0xF9766256,0x35DC62C8,0xBB53652B,0x77F965B5,0x7D3C6CAC,0xB1966C32,0x3F196BD1,0xF3B36B4F,
0x2A9379E3,0xE639797D,0x68B67E9E,0xA41C7E00,0xAED97719,0x62737787,0xECFC7064,0x205670FA,
0x85CD537D,0x496753E3,0xC7E85400,0x0B42549E,0x01875D87,0xCD2D5D19,0x43A25AFA,0x8F085A64,
0x562848C8,0x9A824856,0x140D4FB5,0xD8A74F2B,0xD2624632,0x1EC846AC,0x9047414F,0x5CED41D1,
0x299DC2ED,0xE537C273,0x6BB8C590,0xA712C50E,0xADD7CC17,0x617DCC89,0xEFF2CB6A,0x2358CBF4,
0xFA78D958,0x36D2D9C6,0xB85DDE25,0x74F7DEBB,0x7E32D7A2,0xB298D73C,0x3C17D0DF,0xF0BDD041,
0x5526F3C6,0x998CF358,0x1703F4BB,0xDBA9F425,0xD16CFD3C,0x1DC6FDA2,0x9349FA41,0x5FE3FADF,
0x86C3E873,0x4A69E8ED,0xC4E6EF0E,0x084CEF90,0x0289E689,0xCE23E617,0x40ACE1F4,0x8C06E16A,
0xD0EBA0BB,0x1C41A025,0x92CEA7C6,0x5E64A758,0x54A1AE41,0x980BAEDF,0x1684A93C,0xDA2EA9A2,
0x030EBB0E,0xCFA4BB90,0x412BBC73,0x8D81BCED,0x8744B5F4,0x4BEEB56A,0xC561B289,0x09CBB217,
0xAC509190,0x60FA910E,0xEE7596ED,0x22DF9673,0x281A9F6A,0xE4B09FF4,0x6A3F9817,0xA6959889,
0x7FB58A25,0xB31F8ABB,0x3D908D58,0xF13A8DC6,0xFBFF84DF,0x37558441,0xB9DA83A2,0x7570833C,
0x533B85DA,0x9F918544,0x111E82A7,0xDDB48239,0xD7718B20,0x1BDB8BBE,0x95548C5D,0x59FE8CC3,
0x80DE9E6F,0x4C749EF1,0xC2FB9912,0x0E51998C,0x04949095,0xC83E900B,0x46B197E8,0x8A1B9776,
0x2F80B4F1,0xE32AB46F,0x6DA5B38C,0xA10FB312,0xABCABA0B,0x6760BA95,0xE9EFBD76,0x2545BDE8,
0xFC65AF44,0x30CFAFDA,0xBE40A839,0x72EAA8A7,0x782FA1BE,0xB485A120,0x3A0AA6C3,0xF6A0A65D,
0xAA4DE78C,0x66E7E712,0xE868E0F1,0x24C2E06F,0x2E07E976,0xE2ADE9E8,0x6C22EE0B,0xA088EE95,
0x79A8FC39,0xB502FCA7,0x3B8DFB44,0xF727FBDA,0xFDE2F2C3,0x3148F25D,0xBFC7F5BE,0x736DF520,
0xD6F6D6A7,0x1A5CD639,0x94D3D1DA,0x5879D144,0x52BCD85D,0x9E16D8C3,0x1099DF20,0xDC33DFBE,
0x0513CD12,0xC9B9CD8C,0x4736CA6F,0x8B9CCAF1,0x8159C3E8,0x4DF3C376,0xC37CC495,0x0FD6C40B,
0x7AA64737,0xB60C47A9,0x3883404A,0xF42940D4,0xFEEC49CD,0x32464953,0xBCC94EB0,0x70634E2E,
0xA9435C82,0x65E95C1C,0xEB665BFF,0x27CC5B61,0x2D095278,0xE1A352E6,0x6F2C5505,0xA386559B,
0x061D761C,0xCAB77682,0x44387161,0x889271FF,0x825778E6,0x4EFD7878,0xC0727F9B,0x0CD87F05,
0xD5F86DA9,0x19526D37,0x97DD6AD4,0x5B776A4A,0x51B26353,0x9D1863CD,0x1397642E,0xDF3D64B0,
0x83D02561,0x4F7A25FF,0xC1F5221C,0x0D5F2282,0x079A2B9B,0xCB302B05,0x45BF2CE6,0x89152C78,
0x50353ED4,0x9C9F3E4A,0x121039A9,0xDEBA3937,0xD47F302E,0x18D530B0,0x965A3753,0x5AF037CD,
0xFF6B144A,0x33C114D4,0xBD4E1337,0x71E413A9,0x7B211AB0,0xB78B1A2E,0x39041DCD,0xF5AE1D53,
0x2C8E0FFF,0xE0240F61,0x6EAB0882,0xA201081C,0xA8C40105,0x646E019B,0xEAE10678,0x264B06E6 }
};
inline uint32_t swap(uint32_t x)
{
#if defined(__GNUC__) || defined(__clang__)
return __builtin_bswap32(x);
#endif
#ifdef MSC_VER
return _byteswap_ulong(x);
#endif
return (x >> 24) |
((x >> 8) & 0x0000FF00) |
((x << 8) & 0x00FF0000) |
(x << 24);
}
}
/// add arbitrary number of bytes
void CRC32::add(const void* data, size_t numBytes)
{
uint32_t* current = (uint32_t*) data;
uint32_t crc = ~m_hash;
// process eight bytes at once
while (numBytes >= 8)
{
#if defined(__BYTE_ORDER) && (__BYTE_ORDER != 0) && (__BYTE_ORDER == __BIG_ENDIAN)
uint32_t one = *current++ ^ swap(crc);
uint32_t two = *current++;
crc = crc32Lookup[7][ one>>24 ] ^
crc32Lookup[6][(one>>16) & 0xFF] ^
crc32Lookup[5][(one>> 8) & 0xFF] ^
crc32Lookup[4][ one & 0xFF] ^
crc32Lookup[3][ two>>24 ] ^
crc32Lookup[2][(two>>16) & 0xFF] ^
crc32Lookup[1][(two>> 8) & 0xFF] ^
crc32Lookup[0][ two & 0xFF];
#else
uint32_t one = *current++ ^ crc;
uint32_t two = *current++;
crc = crc32Lookup[7][ one & 0xFF] ^
crc32Lookup[6][(one>> 8) & 0xFF] ^
crc32Lookup[5][(one>>16) & 0xFF] ^
crc32Lookup[4][ one>>24 ] ^
crc32Lookup[3][ two & 0xFF] ^
crc32Lookup[2][(two>> 8) & 0xFF] ^
crc32Lookup[1][(two>>16) & 0xFF] ^
crc32Lookup[0][ two>>24 ];
#endif
numBytes -= 8;
}
unsigned char* currentChar = (unsigned char*) current;
// remaining 1 to 7 bytes (standard CRC table-based algorithm)
while (numBytes--)
crc = (crc >> 8) ^ crc32Lookup[0][(crc & 0xFF) ^ *currentChar++];
m_hash = ~crc;
}
/// return latest hash as 8 hex characters
std::string CRC32::getHash()
{
// convert hash to string
static const char dec2hex[16+1] = "0123456789abcdef";
char hashBuffer[8+1];
hashBuffer[0] = dec2hex[ m_hash >> 28 ];
hashBuffer[1] = dec2hex[(m_hash >> 24) & 15];
hashBuffer[2] = dec2hex[(m_hash >> 20) & 15];
hashBuffer[3] = dec2hex[(m_hash >> 16) & 15];
hashBuffer[4] = dec2hex[(m_hash >> 12) & 15];
hashBuffer[5] = dec2hex[(m_hash >> 8) & 15];
hashBuffer[6] = dec2hex[(m_hash >> 4) & 15];
hashBuffer[7] = dec2hex[ m_hash & 15];
// zero-terminated string
hashBuffer[8] = 0;
// convert to std::string
return hashBuffer;
}
/// return latest hash as bytes
void CRC32::getHash(unsigned char buffer[CRC32::HashBytes])
{
buffer[0] = (m_hash >> 24) & 0xFF;
buffer[1] = (m_hash >> 16) & 0xFF;
buffer[2] = (m_hash >> 8) & 0xFF;
buffer[3] = m_hash & 0xFF;
}
/// compute CRC32 of a memory block
std::string CRC32::operator()(const void* data, size_t numBytes)
{
reset();
add(data, numBytes);
return getHash();
}
/// compute CRC32 of a string, excluding final zero
std::string CRC32::operator()(const std::string& text)
{
reset();
add(text.c_str(), text.size());
return getHash();
}

View File

@@ -0,0 +1,109 @@
// //////////////////////////////////////////////////////////
// digest.cpp
// Copyright (c) 2014,2015 Stephan Brumme. All rights reserved.
// see http://create.stephan-brumme.com/disclaimer.html
//
// g++ -O3 digest.cpp crc32.cpp md5.cpp sha1.cpp sha256.cpp keccak.cpp sha3.cpp -o digest
#include "crc32.h"
#include "md5.h"
#include "sha1.h"
#include "sha256.h"
#include "keccak.h"
#include "sha3.h"
#include <iostream>
#include <fstream>
int main(int argc, char** argv)
{
// syntax check
if (argc < 2 || argc > 3)
{
std::cout << "./digest filename [--crc|--md5|--sha1|--sha256|--keccak|--sha3]" << std::endl;
return 1;
}
// parameters
std::string filename = argv[1];
std::string algorithm = argc == 3 ? argv[2] : "";
bool computeCrc32 = algorithm.empty() || algorithm == "--crc";
bool computeMd5 = algorithm.empty() || algorithm == "--md5";
bool computeSha1 = algorithm.empty() || algorithm == "--sha1";
bool computeSha2 = algorithm.empty() || algorithm == "--sha2" || algorithm == "--sha256";
bool computeKeccak = algorithm.empty() || algorithm == "--keccak";
bool computeSha3 = algorithm.empty() || algorithm == "--sha3";
CRC32 digestCrc32;
MD5 digestMd5;
SHA1 digestSha1;
SHA256 digestSha2;
Keccak digestKeccak(Keccak::Keccak256);
SHA3 digestSha3 (SHA3 ::Bits256);
// each cycle processes about 1 MByte (divisible by 144 => improves Keccak/SHA3 performance)
const size_t BufferSize = 144*7*1024;
char* buffer = new char[BufferSize];
// select input source: either file or standard-in
std::ifstream file;
std::istream* input = NULL;
// accept std::cin, syntax will be: "./digest - --sha3 < data"
if (filename == "-")
{
input = &std::cin;
}
else
{
// open file
file.open(filename.c_str(), std::ios::in | std::ios::binary);
if (!file)
{
std::cerr << "Can't open '" << filename << "'" << std::endl;
return 2;
}
input = &file;
}
// process file
while (*input)
{
input->read(buffer, BufferSize);
std::size_t numBytesRead = size_t(input->gcount());
if (computeCrc32)
digestCrc32 .add(buffer, numBytesRead);
if (computeMd5)
digestMd5 .add(buffer, numBytesRead);
if (computeSha1)
digestSha1 .add(buffer, numBytesRead);
if (computeSha2)
digestSha2 .add(buffer, numBytesRead);
if (computeKeccak)
digestKeccak.add(buffer, numBytesRead);
if (computeSha3)
digestSha3 .add(buffer, numBytesRead);
}
// clean up
file.close();
delete[] buffer;
// show results
if (computeCrc32)
std::cout << "CRC32: " << digestCrc32 .getHash() << std::endl;
if (computeMd5)
std::cout << "MD5: " << digestMd5 .getHash() << std::endl;
if (computeSha1)
std::cout << "SHA1: " << digestSha1 .getHash() << std::endl;
if (computeSha2)
std::cout << "SHA2/256: " << digestSha2 .getHash() << std::endl;
if (computeKeccak)
std::cout << "Keccak/256: " << digestKeccak.getHash() << std::endl;
if (computeSha3)
std::cout << "SHA3/256: " << digestSha3 .getHash() << std::endl;
return 0;
}

View File

@@ -0,0 +1,7 @@
All source code published on http://create.stephan-brumme.com and its sub-pages is licensed similar to the zlib license:
This software is provided 'as-is', without any express or implied warranty. In no event will the author be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions:
The origin of this software must not be misrepresented; you must not claim that you wrote the original software.
If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.

View File

@@ -0,0 +1,69 @@
// //////////////////////////////////////////////////////////
// crc32.h
// Copyright (c) 2014,2015 Stephan Brumme. All rights reserved.
// see http://create.stephan-brumme.com/disclaimer.html
//
#pragma once
//#include "hash.h"
#include <string>
// define fixed size integer types
#ifdef _MSC_VER
// Windows
typedef unsigned __int8 uint8_t;
typedef unsigned __int32 uint32_t;
#else
// GCC
#include <stdint.h>
#endif
/// compute CRC32 hash, based on Intel's Slicing-by-8 algorithm
/** Usage:
CRC32 crc32;
std::string myHash = crc32("Hello World"); // std::string
std::string myHash2 = crc32("How are you", 11); // arbitrary data, 11 bytes
// or in a streaming fashion:
CRC32 crc32;
while (more data available)
crc32.add(pointer to fresh data, number of new bytes);
std::string myHash3 = crc32.getHash();
Note:
You can find code for the faster Slicing-by-16 algorithm on my website, too:
http://create.stephan-brumme.com/crc32/
Its unrolled version is about twice as fast but its look-up table doubled in size as well.
*/
class CRC32 //: public Hash
{
public:
/// hash is 4 bytes long
enum { HashBytes = 4 };
/// same as reset()
CRC32();
/// compute CRC32 of a memory block
std::string operator()(const void* data, size_t numBytes);
/// compute CRC32 of a string, excluding final zero
std::string operator()(const std::string& text);
/// add arbitrary number of bytes
void add(const void* data, size_t numBytes);
/// return latest hash as 8 hex characters
std::string getHash();
/// return latest hash as bytes
void getHash(unsigned char buffer[HashBytes]);
/// restart
void reset();
private:
/// hash
uint32_t m_hash;
};

View File

@@ -0,0 +1,28 @@
// //////////////////////////////////////////////////////////
// hash.h
// Copyright (c) 2014,2015 Stephan Brumme. All rights reserved.
// see http://create.stephan-brumme.com/disclaimer.html
//
#pragma once
#include <string>
/// abstract base class
class Hash
{
public:
/// compute hash of a memory block
virtual std::string operator()(const void* data, size_t numBytes) = 0;
/// compute hash of a string, excluding final zero
virtual std::string operator()(const std::string& text) = 0;
/// add arbitrary number of bytes
virtual void add(const void* data, size_t numBytes) = 0;
/// return latest hash as hex characters
virtual std::string getHash() = 0;
/// restart
virtual void reset() = 0;
};

View File

@@ -0,0 +1,83 @@
// //////////////////////////////////////////////////////////
// hmac.h
// Copyright (c) 2015 Stephan Brumme. All rights reserved.
// see http://create.stephan-brumme.com/disclaimer.html
//
#pragma once
// based on http://tools.ietf.org/html/rfc2104
// see also http://en.wikipedia.org/wiki/Hash-based_message_authentication_code
/** Usage:
std::string msg = "The quick brown fox jumps over the lazy dog";
std::string key = "key";
std::string md5hmac = hmac< MD5 >(msg, key);
std::string sha1hmac = hmac< SHA1 >(msg, key);
std::string sha2hmac = hmac<SHA256>(msg, key);
Note:
To keep my code simple, HMAC computation currently needs the whole message at once.
This is in contrast to the hashes MD5, SHA1, etc. where an add() method is available
for incremental computation.
You can use any hash for HMAC as long as it provides:
- constant HashMethod::BlockSize (typically 64)
- constant HashMethod::HashBytes (length of hash in bytes, e.g. 20 for SHA1)
- HashMethod::add(buffer, bufferSize)
- HashMethod::getHash(unsigned char buffer[HashMethod::BlockSize])
*/
#include <string>
#include <cstring> // memcpy
/// compute HMAC hash of data and key using MD5, SHA1 or SHA256
template <typename HashMethod>
std::string hmac(const void* data, size_t numDataBytes, const void* key, size_t numKeyBytes)
{
// initialize key with zeros
unsigned char usedKey[HashMethod::BlockSize] = {0};
// adjust length of key: must contain exactly blockSize bytes
if (numKeyBytes <= HashMethod::BlockSize)
{
// copy key
memcpy(usedKey, key, numKeyBytes);
}
else
{
// shorten key: usedKey = hashed(key)
HashMethod keyHasher;
keyHasher.add(key, numKeyBytes);
keyHasher.getHash(usedKey);
}
// create initial XOR padding
for (size_t i = 0; i < HashMethod::BlockSize; i++)
usedKey[i] ^= 0x36;
// inside = hash((usedKey ^ 0x36) + data)
unsigned char inside[HashMethod::HashBytes];
HashMethod insideHasher;
insideHasher.add(usedKey, HashMethod::BlockSize);
insideHasher.add(data, numDataBytes);
insideHasher.getHash(inside);
// undo usedKey's previous 0x36 XORing and apply a XOR by 0x5C
for (size_t i = 0; i < HashMethod::BlockSize; i++)
usedKey[i] ^= 0x5C ^ 0x36;
// hash((usedKey ^ 0x5C) + hash((usedKey ^ 0x36) + data))
HashMethod finalHasher;
finalHasher.add(usedKey, HashMethod::BlockSize);
finalHasher.add(inside, HashMethod::HashBytes);
return finalHasher.getHash();
}
/// convenience function for std::string
template <typename HashMethod>
std::string hmac(const std::string& data, const std::string& key)
{
return hmac<HashMethod>(data.c_str(), data.size(), key.c_str(), key.size());
}

View File

@@ -0,0 +1,81 @@
// //////////////////////////////////////////////////////////
// keccak.h
// Copyright (c) 2014,2015 Stephan Brumme. All rights reserved.
// see http://create.stephan-brumme.com/disclaimer.html
//
#pragma once
//#include "hash.h"
#include <string>
// define fixed size integer types
#ifdef _MSC_VER
// Windows
typedef unsigned __int8 uint8_t;
typedef unsigned __int64 uint64_t;
#else
// GCC
#include <stdint.h>
#endif
/// compute Keccak hash (designated SHA3)
/** Usage:
Keccak keccak;
std::string myHash = keccak("Hello World"); // std::string
std::string myHash2 = keccak("How are you", 11); // arbitrary data, 11 bytes
// or in a streaming fashion:
Keccak keccak;
while (more data available)
keccak.add(pointer to fresh data, number of new bytes);
std::string myHash3 = keccak.getHash();
*/
class Keccak //: public Hash
{
public:
/// algorithm variants
enum Bits { Keccak224 = 224, Keccak256 = 256, Keccak384 = 384, Keccak512 = 512 };
/// same as reset()
explicit Keccak(Bits bits = Keccak256);
/// compute hash of a memory block
std::string operator()(const void* data, size_t numBytes);
/// compute hash of a string, excluding final zero
std::string operator()(const std::string& text);
/// add arbitrary number of bytes
void add(const void* data, size_t numBytes);
/// return latest hash as hex characters
std::string getHash();
/// restart
void reset();
private:
/// process a full block
void processBlock(const void* data);
/// process everything left in the internal buffer
void processBuffer();
/// 1600 bits, stored as 25x64 bit, BlockSize is no more than 1152 bits (Keccak224)
enum { StateSize = 1600 / (8 * 8),
MaxBlockSize = 200 - 2 * (224 / 8) };
/// hash
uint64_t m_hash[StateSize];
/// size of processed data in bytes
uint64_t m_numBytes;
/// block size (less or equal to MaxBlockSize)
size_t m_blockSize;
/// valid bytes in m_buffer
size_t m_bufferSize;
/// bytes not processed yet
uint8_t m_buffer[MaxBlockSize];
/// variant
Bits m_bits;
};

View File

@@ -0,0 +1,78 @@
// //////////////////////////////////////////////////////////
// md5.h
// Copyright (c) 2014 Stephan Brumme. All rights reserved.
// see http://create.stephan-brumme.com/disclaimer.html
//
#pragma once
//#include "hash.h"
#include <string>
// define fixed size integer types
#ifdef _MSC_VER
// Windows
typedef unsigned __int8 uint8_t;
typedef unsigned __int32 uint32_t;
typedef unsigned __int64 uint64_t;
#else
// GCC
#include <stdint.h>
#endif
/// compute MD5 hash
/** Usage:
MD5 md5;
std::string myHash = md5("Hello World"); // std::string
std::string myHash2 = md5("How are you", 11); // arbitrary data, 11 bytes
// or in a streaming fashion:
MD5 md5;
while (more data available)
md5.add(pointer to fresh data, number of new bytes);
std::string myHash3 = md5.getHash();
*/
class MD5 //: public Hash
{
public:
/// split into 64 byte blocks (=> 512 bits), hash is 16 bytes long
enum { BlockSize = 512 / 8, HashBytes = 16 };
/// same as reset()
MD5();
/// compute MD5 of a memory block
std::string operator()(const void* data, size_t numBytes);
/// compute MD5 of a string, excluding final zero
std::string operator()(const std::string& text);
/// add arbitrary number of bytes
void add(const void* data, size_t numBytes);
/// return latest hash as 32 hex characters
std::string getHash();
/// return latest hash as bytes
void getHash(unsigned char buffer[HashBytes]);
/// restart
void reset();
private:
/// process 64 bytes
void processBlock(const void* data);
/// process everything left in the internal buffer
void processBuffer();
/// size of processed data in bytes
uint64_t m_numBytes;
/// valid bytes in m_buffer
size_t m_bufferSize;
/// bytes not processed yet
uint8_t m_buffer[BlockSize];
enum { HashValues = HashBytes / 4 };
/// hash, stored as integers
uint32_t m_hash[HashValues];
};

View File

@@ -0,0 +1,78 @@
// //////////////////////////////////////////////////////////
// sha1.h
// Copyright (c) 2014,2015 Stephan Brumme. All rights reserved.
// see http://create.stephan-brumme.com/disclaimer.html
//
#pragma once
//#include "hash.h"
#include <string>
// define fixed size integer types
#ifdef _MSC_VER
// Windows
typedef unsigned __int8 uint8_t;
typedef unsigned __int32 uint32_t;
typedef unsigned __int64 uint64_t;
#else
// GCC
#include <stdint.h>
#endif
/// compute SHA1 hash
/** Usage:
SHA1 sha1;
std::string myHash = sha1("Hello World"); // std::string
std::string myHash2 = sha1("How are you", 11); // arbitrary data, 11 bytes
// or in a streaming fashion:
SHA1 sha1;
while (more data available)
sha1.add(pointer to fresh data, number of new bytes);
std::string myHash3 = sha1.getHash();
*/
class SHA1 //: public Hash
{
public:
/// split into 64 byte blocks (=> 512 bits), hash is 20 bytes long
enum { BlockSize = 512 / 8, HashBytes = 20 };
/// same as reset()
SHA1();
/// compute SHA1 of a memory block
std::string operator()(const void* data, size_t numBytes);
/// compute SHA1 of a string, excluding final zero
std::string operator()(const std::string& text);
/// add arbitrary number of bytes
void add(const void* data, size_t numBytes);
/// return latest hash as 40 hex characters
std::string getHash();
/// return latest hash as bytes
void getHash(unsigned char buffer[HashBytes]);
/// restart
void reset();
private:
/// process 64 bytes
void processBlock(const void* data);
/// process everything left in the internal buffer
void processBuffer();
/// size of processed data in bytes
uint64_t m_numBytes;
/// valid bytes in m_buffer
size_t m_bufferSize;
/// bytes not processed yet
uint8_t m_buffer[BlockSize];
enum { HashValues = HashBytes / 4 };
/// hash, stored as integers
uint32_t m_hash[HashValues];
};

View File

@@ -0,0 +1,78 @@
// //////////////////////////////////////////////////////////
// sha256.h
// Copyright (c) 2014,2015 Stephan Brumme. All rights reserved.
// see http://create.stephan-brumme.com/disclaimer.html
//
#pragma once
//#include "hash.h"
#include <string>
// define fixed size integer types
#ifdef _MSC_VER
// Windows
typedef unsigned __int8 uint8_t;
typedef unsigned __int32 uint32_t;
typedef unsigned __int64 uint64_t;
#else
// GCC
#include <stdint.h>
#endif
/// compute SHA256 hash
/** Usage:
SHA256 sha256;
std::string myHash = sha256("Hello World"); // std::string
std::string myHash2 = sha256("How are you", 11); // arbitrary data, 11 bytes
// or in a streaming fashion:
SHA256 sha256;
while (more data available)
sha256.add(pointer to fresh data, number of new bytes);
std::string myHash3 = sha256.getHash();
*/
class SHA256 //: public Hash
{
public:
/// split into 64 byte blocks (=> 512 bits), hash is 32 bytes long
enum { BlockSize = 512 / 8, HashBytes = 32 };
/// same as reset()
SHA256();
/// compute SHA256 of a memory block
std::string operator()(const void* data, size_t numBytes);
/// compute SHA256 of a string, excluding final zero
std::string operator()(const std::string& text);
/// add arbitrary number of bytes
void add(const void* data, size_t numBytes);
/// return latest hash as 64 hex characters
std::string getHash();
/// return latest hash as bytes
void getHash(unsigned char buffer[HashBytes]);
/// restart
void reset();
private:
/// process 64 bytes
void processBlock(const void* data);
/// process everything left in the internal buffer
void processBuffer();
/// size of processed data in bytes
uint64_t m_numBytes;
/// valid bytes in m_buffer
size_t m_bufferSize;
/// bytes not processed yet
uint8_t m_buffer[BlockSize];
enum { HashValues = HashBytes / 4 };
/// hash, stored as integers
uint32_t m_hash[HashValues];
};

View File

@@ -0,0 +1,81 @@
// //////////////////////////////////////////////////////////
// sha3.h
// Copyright (c) 2014,2015 Stephan Brumme. All rights reserved.
// see http://create.stephan-brumme.com/disclaimer.html
//
#pragma once
//#include "hash.h"
#include <string>
// define fixed size integer types
#ifdef _MSC_VER
// Windows
typedef unsigned __int8 uint8_t;
typedef unsigned __int64 uint64_t;
#else
// GCC
#include <stdint.h>
#endif
/// compute SHA3 hash
/** Usage:
SHA3 sha3;
std::string myHash = sha3("Hello World"); // std::string
std::string myHash2 = sha3("How are you", 11); // arbitrary data, 11 bytes
// or in a streaming fashion:
SHA3 sha3;
while (more data available)
sha3.add(pointer to fresh data, number of new bytes);
std::string myHash3 = sha3.getHash();
*/
class SHA3 //: public Hash
{
public:
/// algorithm variants
enum Bits { Bits224 = 224, Bits256 = 256, Bits384 = 384, Bits512 = 512 };
/// same as reset()
explicit SHA3(Bits bits = Bits256);
/// compute hash of a memory block
std::string operator()(const void* data, size_t numBytes);
/// compute hash of a string, excluding final zero
std::string operator()(const std::string& text);
/// add arbitrary number of bytes
void add(const void* data, size_t numBytes);
/// return latest hash as hex characters
std::string getHash();
/// restart
void reset();
private:
/// process a full block
void processBlock(const void* data);
/// process everything left in the internal buffer
void processBuffer();
/// 1600 bits, stored as 25x64 bit, BlockSize is no more than 1152 bits (Keccak224)
enum { StateSize = 1600 / (8 * 8),
MaxBlockSize = 200 - 2 * (224 / 8) };
/// hash
uint64_t m_hash[StateSize];
/// size of processed data in bytes
uint64_t m_numBytes;
/// block size (less or equal to MaxBlockSize)
size_t m_blockSize;
/// valid bytes in m_buffer
size_t m_bufferSize;
/// bytes not processed yet
uint8_t m_buffer[MaxBlockSize];
/// variant
Bits m_bits;
};

View File

@@ -0,0 +1,289 @@
// //////////////////////////////////////////////////////////
// keccak.cpp
// Copyright (c) 2014,2015 Stephan Brumme. All rights reserved.
// see http://create.stephan-brumme.com/disclaimer.html
//
#include "keccak.h"
// big endian architectures need #define __BYTE_ORDER __BIG_ENDIAN
#ifndef _MSC_VER
#include <endian.h>
#endif
/// same as reset()
Keccak::Keccak(Bits bits)
: m_blockSize(200 - 2 * (bits / 8)),
m_bits(bits)
{
reset();
}
/// restart
void Keccak::reset()
{
for (size_t i = 0; i < StateSize; i++)
m_hash[i] = 0;
m_numBytes = 0;
m_bufferSize = 0;
}
/// constants and local helper functions
namespace
{
const unsigned int KeccakRounds = 24;
const uint64_t XorMasks[KeccakRounds] =
{
0x0000000000000001ULL, 0x0000000000008082ULL, 0x800000000000808aULL,
0x8000000080008000ULL, 0x000000000000808bULL, 0x0000000080000001ULL,
0x8000000080008081ULL, 0x8000000000008009ULL, 0x000000000000008aULL,
0x0000000000000088ULL, 0x0000000080008009ULL, 0x000000008000000aULL,
0x000000008000808bULL, 0x800000000000008bULL, 0x8000000000008089ULL,
0x8000000000008003ULL, 0x8000000000008002ULL, 0x8000000000000080ULL,
0x000000000000800aULL, 0x800000008000000aULL, 0x8000000080008081ULL,
0x8000000000008080ULL, 0x0000000080000001ULL, 0x8000000080008008ULL
};
/// rotate left and wrap around to the right
inline uint64_t rotateLeft(uint64_t x, uint8_t numBits)
{
return (x << numBits) | (x >> (64 - numBits));
}
/// convert litte vs big endian
inline uint64_t swap(uint64_t x)
{
#if defined(__GNUC__) || defined(__clang__)
return __builtin_bswap64(x);
#endif
#ifdef _MSC_VER
return _byteswap_uint64(x);
#endif
return (x >> 56) |
((x >> 40) & 0x000000000000FF00ULL) |
((x >> 24) & 0x0000000000FF0000ULL) |
((x >> 8) & 0x00000000FF000000ULL) |
((x << 8) & 0x000000FF00000000ULL) |
((x << 24) & 0x0000FF0000000000ULL) |
((x << 40) & 0x00FF000000000000ULL) |
(x << 56);
}
/// return x % 5 for 0 <= x <= 9
unsigned int mod5(unsigned int x)
{
if (x < 5)
return x;
return x - 5;
}
}
/// process a full block
void Keccak::processBlock(const void* data)
{
#if defined(__BYTE_ORDER) && (__BYTE_ORDER != 0) && (__BYTE_ORDER == __BIG_ENDIAN)
#define LITTLEENDIAN(x) swap(x)
#else
#define LITTLEENDIAN(x) (x)
#endif
const uint64_t* data64 = (const uint64_t*) data;
// mix data into state
for (unsigned int i = 0; i < m_blockSize / 8; i++)
m_hash[i] ^= LITTLEENDIAN(data64[i]);
// re-compute state
for (unsigned int round = 0; round < KeccakRounds; round++)
{
// Theta
uint64_t coefficients[5];
for (unsigned int i = 0; i < 5; i++)
coefficients[i] = m_hash[i] ^ m_hash[i + 5] ^ m_hash[i + 10] ^ m_hash[i + 15] ^ m_hash[i + 20];
for (unsigned int i = 0; i < 5; i++)
{
uint64_t one = coefficients[mod5(i + 4)] ^ rotateLeft(coefficients[mod5(i + 1)], 1);
m_hash[i ] ^= one;
m_hash[i + 5] ^= one;
m_hash[i + 10] ^= one;
m_hash[i + 15] ^= one;
m_hash[i + 20] ^= one;
}
// temporary
uint64_t one;
// Rho Pi
uint64_t last = m_hash[1];
one = m_hash[10]; m_hash[10] = rotateLeft(last, 1); last = one;
one = m_hash[ 7]; m_hash[ 7] = rotateLeft(last, 3); last = one;
one = m_hash[11]; m_hash[11] = rotateLeft(last, 6); last = one;
one = m_hash[17]; m_hash[17] = rotateLeft(last, 10); last = one;
one = m_hash[18]; m_hash[18] = rotateLeft(last, 15); last = one;
one = m_hash[ 3]; m_hash[ 3] = rotateLeft(last, 21); last = one;
one = m_hash[ 5]; m_hash[ 5] = rotateLeft(last, 28); last = one;
one = m_hash[16]; m_hash[16] = rotateLeft(last, 36); last = one;
one = m_hash[ 8]; m_hash[ 8] = rotateLeft(last, 45); last = one;
one = m_hash[21]; m_hash[21] = rotateLeft(last, 55); last = one;
one = m_hash[24]; m_hash[24] = rotateLeft(last, 2); last = one;
one = m_hash[ 4]; m_hash[ 4] = rotateLeft(last, 14); last = one;
one = m_hash[15]; m_hash[15] = rotateLeft(last, 27); last = one;
one = m_hash[23]; m_hash[23] = rotateLeft(last, 41); last = one;
one = m_hash[19]; m_hash[19] = rotateLeft(last, 56); last = one;
one = m_hash[13]; m_hash[13] = rotateLeft(last, 8); last = one;
one = m_hash[12]; m_hash[12] = rotateLeft(last, 25); last = one;
one = m_hash[ 2]; m_hash[ 2] = rotateLeft(last, 43); last = one;
one = m_hash[20]; m_hash[20] = rotateLeft(last, 62); last = one;
one = m_hash[14]; m_hash[14] = rotateLeft(last, 18); last = one;
one = m_hash[22]; m_hash[22] = rotateLeft(last, 39); last = one;
one = m_hash[ 9]; m_hash[ 9] = rotateLeft(last, 61); last = one;
one = m_hash[ 6]; m_hash[ 6] = rotateLeft(last, 20); last = one;
m_hash[ 1] = rotateLeft(last, 44);
// Chi
for (unsigned int j = 0; j < 25; j += 5)
{
// temporaries
uint64_t one = m_hash[j];
uint64_t two = m_hash[j + 1];
m_hash[j] ^= m_hash[j + 2] & ~two;
m_hash[j + 1] ^= m_hash[j + 3] & ~m_hash[j + 2];
m_hash[j + 2] ^= m_hash[j + 4] & ~m_hash[j + 3];
m_hash[j + 3] ^= one & ~m_hash[j + 4];
m_hash[j + 4] ^= two & ~one;
}
// Iota
m_hash[0] ^= XorMasks[round];
}
}
/// add arbitrary number of bytes
void Keccak::add(const void* data, size_t numBytes)
{
const uint8_t* current = (const uint8_t*) data;
if (m_bufferSize > 0)
{
while (numBytes > 0 && m_bufferSize < m_blockSize)
{
m_buffer[m_bufferSize++] = *current++;
numBytes--;
}
}
// full buffer
if (m_bufferSize == m_blockSize)
{
processBlock((void*)m_buffer);
m_numBytes += m_blockSize;
m_bufferSize = 0;
}
// no more data ?
if (numBytes == 0)
return;
// process full blocks
while (numBytes >= m_blockSize)
{
processBlock(current);
current += m_blockSize;
m_numBytes += m_blockSize;
numBytes -= m_blockSize;
}
// keep remaining bytes in buffer
while (numBytes > 0)
{
m_buffer[m_bufferSize++] = *current++;
numBytes--;
}
}
/// process everything left in the internal buffer
void Keccak::processBuffer()
{
unsigned int blockSize = 200 - 2 * (m_bits / 8);
// add padding
size_t offset = m_bufferSize;
// add a "1" byte
m_buffer[offset++] = 1;
// fill with zeros
while (offset < blockSize)
m_buffer[offset++] = 0;
// and add a single set bit
m_buffer[blockSize - 1] |= 0x80;
processBlock(m_buffer);
}
/// return latest hash as 16 hex characters
std::string Keccak::getHash()
{
// process remaining bytes
processBuffer();
// convert hash to string
static const char dec2hex[16 + 1] = "0123456789abcdef";
// number of significant elements in hash (uint64_t)
unsigned int hashLength = m_bits / 64;
std::string result;
for (unsigned int i = 0; i < hashLength; i++)
for (unsigned int j = 0; j < 8; j++) // 64 bits => 8 bytes
{
// convert a byte to hex
unsigned char oneByte = (unsigned char) (m_hash[i] >> (8 * j));
result += dec2hex[oneByte >> 4];
result += dec2hex[oneByte & 15];
}
// Keccak224's last entry in m_hash provides only 32 bits instead of 64 bits
unsigned int remainder = m_bits - hashLength * 64;
unsigned int processed = 0;
while (processed < remainder)
{
// convert a byte to hex
unsigned char oneByte = (unsigned char) (m_hash[hashLength] >> processed);
result += dec2hex[oneByte >> 4];
result += dec2hex[oneByte & 15];
processed += 8;
}
return result;
}
/// compute Keccak hash of a memory block
std::string Keccak::operator()(const void* data, size_t numBytes)
{
reset();
add(data, numBytes);
return getHash();
}
/// compute Keccak hash of a string, excluding final zero
std::string Keccak::operator()(const std::string& text)
{
reset();
add(text.c_str(), text.size());
return getHash();
}

View File

@@ -0,0 +1,380 @@
// //////////////////////////////////////////////////////////
// md5.cpp
// Copyright (c) 2014,2015 Stephan Brumme. All rights reserved.
// see http://create.stephan-brumme.com/disclaimer.html
//
#include "md5.h"
#ifndef _MSC_VER
#include <endian.h>
#endif
/// same as reset()
MD5::MD5()
{
reset();
}
/// restart
void MD5::reset()
{
m_numBytes = 0;
m_bufferSize = 0;
// according to RFC 1321
m_hash[0] = 0x67452301;
m_hash[1] = 0xefcdab89;
m_hash[2] = 0x98badcfe;
m_hash[3] = 0x10325476;
}
namespace
{
// mix functions for processBlock()
inline uint32_t f1(uint32_t b, uint32_t c, uint32_t d)
{
return d ^ (b & (c ^ d)); // original: f = (b & c) | ((~b) & d);
}
inline uint32_t f2(uint32_t b, uint32_t c, uint32_t d)
{
return c ^ (d & (b ^ c)); // original: f = (b & d) | (c & (~d));
}
inline uint32_t f3(uint32_t b, uint32_t c, uint32_t d)
{
return b ^ c ^ d;
}
inline uint32_t f4(uint32_t b, uint32_t c, uint32_t d)
{
return c ^ (b | ~d);
}
inline uint32_t rotate(uint32_t a, uint32_t c)
{
return (a << c) | (a >> (32 - c));
}
#if defined(__BYTE_ORDER) && (__BYTE_ORDER != 0) && (__BYTE_ORDER == __BIG_ENDIAN)
inline uint32_t swap(uint32_t x)
{
#if defined(__GNUC__) || defined(__clang__)
return __builtin_bswap32(x);
#endif
#ifdef MSC_VER
return _byteswap_ulong(x);
#endif
return (x >> 24) |
((x >> 8) & 0x0000FF00) |
((x << 8) & 0x00FF0000) |
(x << 24);
}
#endif
}
/// process 64 bytes
void MD5::processBlock(const void* data)
{
// get last hash
uint32_t a = m_hash[0];
uint32_t b = m_hash[1];
uint32_t c = m_hash[2];
uint32_t d = m_hash[3];
// data represented as 16x 32-bit words
const uint32_t* words = (uint32_t*) data;
// computations are little endian, swap data if necessary
#if defined(__BYTE_ORDER) && (__BYTE_ORDER != 0) && (__BYTE_ORDER == __BIG_ENDIAN)
#define LITTLEENDIAN(x) swap(x)
#else
#define LITTLEENDIAN(x) (x)
#endif
// first round
uint32_t word0 = LITTLEENDIAN(words[ 0]);
a = rotate(a + f1(b,c,d) + word0 + 0xd76aa478, 7) + b;
uint32_t word1 = LITTLEENDIAN(words[ 1]);
d = rotate(d + f1(a,b,c) + word1 + 0xe8c7b756, 12) + a;
uint32_t word2 = LITTLEENDIAN(words[ 2]);
c = rotate(c + f1(d,a,b) + word2 + 0x242070db, 17) + d;
uint32_t word3 = LITTLEENDIAN(words[ 3]);
b = rotate(b + f1(c,d,a) + word3 + 0xc1bdceee, 22) + c;
uint32_t word4 = LITTLEENDIAN(words[ 4]);
a = rotate(a + f1(b,c,d) + word4 + 0xf57c0faf, 7) + b;
uint32_t word5 = LITTLEENDIAN(words[ 5]);
d = rotate(d + f1(a,b,c) + word5 + 0x4787c62a, 12) + a;
uint32_t word6 = LITTLEENDIAN(words[ 6]);
c = rotate(c + f1(d,a,b) + word6 + 0xa8304613, 17) + d;
uint32_t word7 = LITTLEENDIAN(words[ 7]);
b = rotate(b + f1(c,d,a) + word7 + 0xfd469501, 22) + c;
uint32_t word8 = LITTLEENDIAN(words[ 8]);
a = rotate(a + f1(b,c,d) + word8 + 0x698098d8, 7) + b;
uint32_t word9 = LITTLEENDIAN(words[ 9]);
d = rotate(d + f1(a,b,c) + word9 + 0x8b44f7af, 12) + a;
uint32_t word10 = LITTLEENDIAN(words[10]);
c = rotate(c + f1(d,a,b) + word10 + 0xffff5bb1, 17) + d;
uint32_t word11 = LITTLEENDIAN(words[11]);
b = rotate(b + f1(c,d,a) + word11 + 0x895cd7be, 22) + c;
uint32_t word12 = LITTLEENDIAN(words[12]);
a = rotate(a + f1(b,c,d) + word12 + 0x6b901122, 7) + b;
uint32_t word13 = LITTLEENDIAN(words[13]);
d = rotate(d + f1(a,b,c) + word13 + 0xfd987193, 12) + a;
uint32_t word14 = LITTLEENDIAN(words[14]);
c = rotate(c + f1(d,a,b) + word14 + 0xa679438e, 17) + d;
uint32_t word15 = LITTLEENDIAN(words[15]);
b = rotate(b + f1(c,d,a) + word15 + 0x49b40821, 22) + c;
// second round
a = rotate(a + f2(b,c,d) + word1 + 0xf61e2562, 5) + b;
d = rotate(d + f2(a,b,c) + word6 + 0xc040b340, 9) + a;
c = rotate(c + f2(d,a,b) + word11 + 0x265e5a51, 14) + d;
b = rotate(b + f2(c,d,a) + word0 + 0xe9b6c7aa, 20) + c;
a = rotate(a + f2(b,c,d) + word5 + 0xd62f105d, 5) + b;
d = rotate(d + f2(a,b,c) + word10 + 0x02441453, 9) + a;
c = rotate(c + f2(d,a,b) + word15 + 0xd8a1e681, 14) + d;
b = rotate(b + f2(c,d,a) + word4 + 0xe7d3fbc8, 20) + c;
a = rotate(a + f2(b,c,d) + word9 + 0x21e1cde6, 5) + b;
d = rotate(d + f2(a,b,c) + word14 + 0xc33707d6, 9) + a;
c = rotate(c + f2(d,a,b) + word3 + 0xf4d50d87, 14) + d;
b = rotate(b + f2(c,d,a) + word8 + 0x455a14ed, 20) + c;
a = rotate(a + f2(b,c,d) + word13 + 0xa9e3e905, 5) + b;
d = rotate(d + f2(a,b,c) + word2 + 0xfcefa3f8, 9) + a;
c = rotate(c + f2(d,a,b) + word7 + 0x676f02d9, 14) + d;
b = rotate(b + f2(c,d,a) + word12 + 0x8d2a4c8a, 20) + c;
// third round
a = rotate(a + f3(b,c,d) + word5 + 0xfffa3942, 4) + b;
d = rotate(d + f3(a,b,c) + word8 + 0x8771f681, 11) + a;
c = rotate(c + f3(d,a,b) + word11 + 0x6d9d6122, 16) + d;
b = rotate(b + f3(c,d,a) + word14 + 0xfde5380c, 23) + c;
a = rotate(a + f3(b,c,d) + word1 + 0xa4beea44, 4) + b;
d = rotate(d + f3(a,b,c) + word4 + 0x4bdecfa9, 11) + a;
c = rotate(c + f3(d,a,b) + word7 + 0xf6bb4b60, 16) + d;
b = rotate(b + f3(c,d,a) + word10 + 0xbebfbc70, 23) + c;
a = rotate(a + f3(b,c,d) + word13 + 0x289b7ec6, 4) + b;
d = rotate(d + f3(a,b,c) + word0 + 0xeaa127fa, 11) + a;
c = rotate(c + f3(d,a,b) + word3 + 0xd4ef3085, 16) + d;
b = rotate(b + f3(c,d,a) + word6 + 0x04881d05, 23) + c;
a = rotate(a + f3(b,c,d) + word9 + 0xd9d4d039, 4) + b;
d = rotate(d + f3(a,b,c) + word12 + 0xe6db99e5, 11) + a;
c = rotate(c + f3(d,a,b) + word15 + 0x1fa27cf8, 16) + d;
b = rotate(b + f3(c,d,a) + word2 + 0xc4ac5665, 23) + c;
// fourth round
a = rotate(a + f4(b,c,d) + word0 + 0xf4292244, 6) + b;
d = rotate(d + f4(a,b,c) + word7 + 0x432aff97, 10) + a;
c = rotate(c + f4(d,a,b) + word14 + 0xab9423a7, 15) + d;
b = rotate(b + f4(c,d,a) + word5 + 0xfc93a039, 21) + c;
a = rotate(a + f4(b,c,d) + word12 + 0x655b59c3, 6) + b;
d = rotate(d + f4(a,b,c) + word3 + 0x8f0ccc92, 10) + a;
c = rotate(c + f4(d,a,b) + word10 + 0xffeff47d, 15) + d;
b = rotate(b + f4(c,d,a) + word1 + 0x85845dd1, 21) + c;
a = rotate(a + f4(b,c,d) + word8 + 0x6fa87e4f, 6) + b;
d = rotate(d + f4(a,b,c) + word15 + 0xfe2ce6e0, 10) + a;
c = rotate(c + f4(d,a,b) + word6 + 0xa3014314, 15) + d;
b = rotate(b + f4(c,d,a) + word13 + 0x4e0811a1, 21) + c;
a = rotate(a + f4(b,c,d) + word4 + 0xf7537e82, 6) + b;
d = rotate(d + f4(a,b,c) + word11 + 0xbd3af235, 10) + a;
c = rotate(c + f4(d,a,b) + word2 + 0x2ad7d2bb, 15) + d;
b = rotate(b + f4(c,d,a) + word9 + 0xeb86d391, 21) + c;
// update hash
m_hash[0] += a;
m_hash[1] += b;
m_hash[2] += c;
m_hash[3] += d;
}
/// add arbitrary number of bytes
void MD5::add(const void* data, size_t numBytes)
{
const uint8_t* current = (const uint8_t*) data;
if (m_bufferSize > 0)
{
while (numBytes > 0 && m_bufferSize < BlockSize)
{
m_buffer[m_bufferSize++] = *current++;
numBytes--;
}
}
// full buffer
if (m_bufferSize == BlockSize)
{
processBlock(m_buffer);
m_numBytes += BlockSize;
m_bufferSize = 0;
}
// no more data ?
if (numBytes == 0)
return;
// process full blocks
while (numBytes >= BlockSize)
{
processBlock(current);
current += BlockSize;
m_numBytes += BlockSize;
numBytes -= BlockSize;
}
// keep remaining bytes in buffer
while (numBytes > 0)
{
m_buffer[m_bufferSize++] = *current++;
numBytes--;
}
}
/// process final block, less than 64 bytes
void MD5::processBuffer()
{
// the input bytes are considered as bits strings, where the first bit is the most significant bit of the byte
// - append "1" bit to message
// - append "0" bits until message length in bit mod 512 is 448
// - append length as 64 bit integer
// number of bits
size_t paddedLength = m_bufferSize * 8;
// plus one bit set to 1 (always appended)
paddedLength++;
// number of bits must be (numBits % 512) = 448
size_t lower11Bits = paddedLength & 511;
if (lower11Bits <= 448)
paddedLength += 448 - lower11Bits;
else
paddedLength += 512 + 448 - lower11Bits;
// convert from bits to bytes
paddedLength /= 8;
// only needed if additional data flows over into a second block
unsigned char extra[BlockSize];
// append a "1" bit, 128 => binary 10000000
if (m_bufferSize < BlockSize)
m_buffer[m_bufferSize] = 128;
else
extra[0] = 128;
size_t i;
for (i = m_bufferSize + 1; i < BlockSize; i++)
m_buffer[i] = 0;
for (; i < paddedLength; i++)
extra[i - BlockSize] = 0;
// add message length in bits as 64 bit number
uint64_t msgBits = 8 * (m_numBytes + m_bufferSize);
// find right position
unsigned char* addLength;
if (paddedLength < BlockSize)
addLength = m_buffer + paddedLength;
else
addLength = extra + paddedLength - BlockSize;
// must be little endian
*addLength++ = msgBits & 0xFF; msgBits >>= 8;
*addLength++ = msgBits & 0xFF; msgBits >>= 8;
*addLength++ = msgBits & 0xFF; msgBits >>= 8;
*addLength++ = msgBits & 0xFF; msgBits >>= 8;
*addLength++ = msgBits & 0xFF; msgBits >>= 8;
*addLength++ = msgBits & 0xFF; msgBits >>= 8;
*addLength++ = msgBits & 0xFF; msgBits >>= 8;
*addLength++ = msgBits & 0xFF;
// process blocks
processBlock(m_buffer);
// flowed over into a second block ?
if (paddedLength > BlockSize)
processBlock(extra);
}
/// return latest hash as 32 hex characters
std::string MD5::getHash()
{
// compute hash (as raw bytes)
unsigned char rawHash[HashBytes];
getHash(rawHash);
// convert to hex string
std::string result;
result.reserve(2 * HashBytes);
for (int i = 0; i < HashBytes; i++)
{
static const char dec2hex[16+1] = "0123456789abcdef";
result += dec2hex[(rawHash[i] >> 4) & 15];
result += dec2hex[ rawHash[i] & 15];
}
return result;
}
/// return latest hash as bytes
void MD5::getHash(unsigned char buffer[MD5::HashBytes])
{
// save old hash if buffer is partially filled
uint32_t oldHash[HashValues];
for (int i = 0; i < HashValues; i++)
oldHash[i] = m_hash[i];
// process remaining bytes
processBuffer();
unsigned char* current = buffer;
for (int i = 0; i < HashValues; i++)
{
*current++ = m_hash[i] & 0xFF;
*current++ = (m_hash[i] >> 8) & 0xFF;
*current++ = (m_hash[i] >> 16) & 0xFF;
*current++ = (m_hash[i] >> 24) & 0xFF;
// restore old hash
m_hash[i] = oldHash[i];
}
}
/// compute MD5 of a memory block
std::string MD5::operator()(const void* data, size_t numBytes)
{
reset();
add(data, numBytes);
return getHash();
}
/// compute MD5 of a string, excluding final zero
std::string MD5::operator()(const std::string& text)
{
reset();
add(text.c_str(), text.size());
return getHash();
}

View File

@@ -0,0 +1,326 @@
// //////////////////////////////////////////////////////////
// sha1.cpp
// Copyright (c) 2014,2015 Stephan Brumme. All rights reserved.
// see http://create.stephan-brumme.com/disclaimer.html
//
#include "sha1.h"
// big endian architectures need #define __BYTE_ORDER __BIG_ENDIAN
#ifndef _MSC_VER
#include <endian.h>
#endif
/// same as reset()
SHA1::SHA1()
{
reset();
}
/// restart
void SHA1::reset()
{
m_numBytes = 0;
m_bufferSize = 0;
// according to RFC 1321
m_hash[0] = 0x67452301;
m_hash[1] = 0xefcdab89;
m_hash[2] = 0x98badcfe;
m_hash[3] = 0x10325476;
m_hash[4] = 0xc3d2e1f0;
}
namespace
{
// mix functions for processBlock()
inline uint32_t f1(uint32_t b, uint32_t c, uint32_t d)
{
return d ^ (b & (c ^ d)); // original: f = (b & c) | ((~b) & d);
}
inline uint32_t f2(uint32_t b, uint32_t c, uint32_t d)
{
return b ^ c ^ d;
}
inline uint32_t f3(uint32_t b, uint32_t c, uint32_t d)
{
return (b & c) | (b & d) | (c & d);
}
inline uint32_t rotate(uint32_t a, uint32_t c)
{
return (a << c) | (a >> (32 - c));
}
inline uint32_t swap(uint32_t x)
{
#if defined(__GNUC__) || defined(__clang__)
return __builtin_bswap32(x);
#endif
#ifdef MSC_VER
return _byteswap_ulong(x);
#endif
return (x >> 24) |
((x >> 8) & 0x0000FF00) |
((x << 8) & 0x00FF0000) |
(x << 24);
}
}
/// process 64 bytes
void SHA1::processBlock(const void* data)
{
// get last hash
uint32_t a = m_hash[0];
uint32_t b = m_hash[1];
uint32_t c = m_hash[2];
uint32_t d = m_hash[3];
uint32_t e = m_hash[4];
// data represented as 16x 32-bit words
const uint32_t* input = (uint32_t*) data;
// convert to big endian
uint32_t words[80];
for (int i = 0; i < 16; i++)
#if defined(__BYTE_ORDER) && (__BYTE_ORDER != 0) && (__BYTE_ORDER == __BIG_ENDIAN)
words[i] = input[i];
#else
words[i] = swap(input[i]);
#endif
// extend to 80 words
for (int i = 16; i < 80; i++)
words[i] = rotate(words[i-3] ^ words[i-8] ^ words[i-14] ^ words[i-16], 1);
// first round
for (int i = 0; i < 4; i++)
{
int offset = 5*i;
e += rotate(a,5) + f1(b,c,d) + words[offset ] + 0x5a827999; b = rotate(b,30);
d += rotate(e,5) + f1(a,b,c) + words[offset+1] + 0x5a827999; a = rotate(a,30);
c += rotate(d,5) + f1(e,a,b) + words[offset+2] + 0x5a827999; e = rotate(e,30);
b += rotate(c,5) + f1(d,e,a) + words[offset+3] + 0x5a827999; d = rotate(d,30);
a += rotate(b,5) + f1(c,d,e) + words[offset+4] + 0x5a827999; c = rotate(c,30);
}
// second round
for (int i = 4; i < 8; i++)
{
int offset = 5*i;
e += rotate(a,5) + f2(b,c,d) + words[offset ] + 0x6ed9eba1; b = rotate(b,30);
d += rotate(e,5) + f2(a,b,c) + words[offset+1] + 0x6ed9eba1; a = rotate(a,30);
c += rotate(d,5) + f2(e,a,b) + words[offset+2] + 0x6ed9eba1; e = rotate(e,30);
b += rotate(c,5) + f2(d,e,a) + words[offset+3] + 0x6ed9eba1; d = rotate(d,30);
a += rotate(b,5) + f2(c,d,e) + words[offset+4] + 0x6ed9eba1; c = rotate(c,30);
}
// third round
for (int i = 8; i < 12; i++)
{
int offset = 5*i;
e += rotate(a,5) + f3(b,c,d) + words[offset ] + 0x8f1bbcdc; b = rotate(b,30);
d += rotate(e,5) + f3(a,b,c) + words[offset+1] + 0x8f1bbcdc; a = rotate(a,30);
c += rotate(d,5) + f3(e,a,b) + words[offset+2] + 0x8f1bbcdc; e = rotate(e,30);
b += rotate(c,5) + f3(d,e,a) + words[offset+3] + 0x8f1bbcdc; d = rotate(d,30);
a += rotate(b,5) + f3(c,d,e) + words[offset+4] + 0x8f1bbcdc; c = rotate(c,30);
}
// fourth round
for (int i = 12; i < 16; i++)
{
int offset = 5*i;
e += rotate(a,5) + f2(b,c,d) + words[offset ] + 0xca62c1d6; b = rotate(b,30);
d += rotate(e,5) + f2(a,b,c) + words[offset+1] + 0xca62c1d6; a = rotate(a,30);
c += rotate(d,5) + f2(e,a,b) + words[offset+2] + 0xca62c1d6; e = rotate(e,30);
b += rotate(c,5) + f2(d,e,a) + words[offset+3] + 0xca62c1d6; d = rotate(d,30);
a += rotate(b,5) + f2(c,d,e) + words[offset+4] + 0xca62c1d6; c = rotate(c,30);
}
// update hash
m_hash[0] += a;
m_hash[1] += b;
m_hash[2] += c;
m_hash[3] += d;
m_hash[4] += e;
}
/// add arbitrary number of bytes
void SHA1::add(const void* data, size_t numBytes)
{
const uint8_t* current = (const uint8_t*) data;
if (m_bufferSize > 0)
{
while (numBytes > 0 && m_bufferSize < BlockSize)
{
m_buffer[m_bufferSize++] = *current++;
numBytes--;
}
}
// full buffer
if (m_bufferSize == BlockSize)
{
processBlock((void*)m_buffer);
m_numBytes += BlockSize;
m_bufferSize = 0;
}
// no more data ?
if (numBytes == 0)
return;
// process full blocks
while (numBytes >= BlockSize)
{
processBlock(current);
current += BlockSize;
m_numBytes += BlockSize;
numBytes -= BlockSize;
}
// keep remaining bytes in buffer
while (numBytes > 0)
{
m_buffer[m_bufferSize++] = *current++;
numBytes--;
}
}
/// process final block, less than 64 bytes
void SHA1::processBuffer()
{
// the input bytes are considered as bits strings, where the first bit is the most significant bit of the byte
// - append "1" bit to message
// - append "0" bits until message length in bit mod 512 is 448
// - append length as 64 bit integer
// number of bits
size_t paddedLength = m_bufferSize * 8;
// plus one bit set to 1 (always appended)
paddedLength++;
// number of bits must be (numBits % 512) = 448
size_t lower11Bits = paddedLength & 511;
if (lower11Bits <= 448)
paddedLength += 448 - lower11Bits;
else
paddedLength += 512 + 448 - lower11Bits;
// convert from bits to bytes
paddedLength /= 8;
// only needed if additional data flows over into a second block
unsigned char extra[BlockSize];
// append a "1" bit, 128 => binary 10000000
if (m_bufferSize < BlockSize)
m_buffer[m_bufferSize] = 128;
else
extra[0] = 128;
size_t i;
for (i = m_bufferSize + 1; i < BlockSize; i++)
m_buffer[i] = 0;
for (; i < paddedLength; i++)
extra[i - BlockSize] = 0;
// add message length in bits as 64 bit number
uint64_t msgBits = 8 * (m_numBytes + m_bufferSize);
// find right position
unsigned char* addLength;
if (paddedLength < BlockSize)
addLength = m_buffer + paddedLength;
else
addLength = extra + paddedLength - BlockSize;
// must be big endian
*addLength++ = (unsigned char)((msgBits >> 56) & 0xFF);
*addLength++ = (unsigned char)((msgBits >> 48) & 0xFF);
*addLength++ = (unsigned char)((msgBits >> 40) & 0xFF);
*addLength++ = (unsigned char)((msgBits >> 32) & 0xFF);
*addLength++ = (unsigned char)((msgBits >> 24) & 0xFF);
*addLength++ = (unsigned char)((msgBits >> 16) & 0xFF);
*addLength++ = (unsigned char)((msgBits >> 8) & 0xFF);
*addLength = (unsigned char)( msgBits & 0xFF);
// process blocks
processBlock(m_buffer);
// flowed over into a second block ?
if (paddedLength > BlockSize)
processBlock(extra);
}
/// return latest hash as 40 hex characters
std::string SHA1::getHash()
{
// compute hash (as raw bytes)
unsigned char rawHash[HashBytes];
getHash(rawHash);
// convert to hex string
std::string result;
result.reserve(2 * HashBytes);
for (int i = 0; i < HashBytes; i++)
{
static const char dec2hex[16+1] = "0123456789abcdef";
result += dec2hex[(rawHash[i] >> 4) & 15];
result += dec2hex[ rawHash[i] & 15];
}
return result;
}
/// return latest hash as bytes
void SHA1::getHash(unsigned char buffer[SHA1::HashBytes])
{
// save old hash if buffer is partially filled
uint32_t oldHash[HashValues];
for (int i = 0; i < HashValues; i++)
oldHash[i] = m_hash[i];
// process remaining bytes
processBuffer();
unsigned char* current = buffer;
for (int i = 0; i < HashValues; i++)
{
*current++ = (m_hash[i] >> 24) & 0xFF;
*current++ = (m_hash[i] >> 16) & 0xFF;
*current++ = (m_hash[i] >> 8) & 0xFF;
*current++ = m_hash[i] & 0xFF;
// restore old hash
m_hash[i] = oldHash[i];
}
}
/// compute SHA1 of a memory block
std::string SHA1::operator()(const void* data, size_t numBytes)
{
reset();
add(data, numBytes);
return getHash();
}
/// compute SHA1 of a string, excluding final zero
std::string SHA1::operator()(const std::string& text)
{
reset();
add(text.c_str(), text.size());
return getHash();
}

View File

@@ -0,0 +1,411 @@
// //////////////////////////////////////////////////////////
// sha256.cpp
// Copyright (c) 2014,2015 Stephan Brumme. All rights reserved.
// see http://create.stephan-brumme.com/disclaimer.html
//
#include "sha256.h"
// big endian architectures need #define __BYTE_ORDER __BIG_ENDIAN
#ifndef _MSC_VER
#include <endian.h>
#endif
/// same as reset()
SHA256::SHA256()
{
reset();
}
/// restart
void SHA256::reset()
{
m_numBytes = 0;
m_bufferSize = 0;
// according to RFC 1321
m_hash[0] = 0x6a09e667;
m_hash[1] = 0xbb67ae85;
m_hash[2] = 0x3c6ef372;
m_hash[3] = 0xa54ff53a;
m_hash[4] = 0x510e527f;
m_hash[5] = 0x9b05688c;
m_hash[6] = 0x1f83d9ab;
m_hash[7] = 0x5be0cd19;
}
namespace
{
inline uint32_t rotate(uint32_t a, uint32_t c)
{
return (a >> c) | (a << (32 - c));
}
inline uint32_t swap(uint32_t x)
{
#if defined(__GNUC__) || defined(__clang__)
return __builtin_bswap32(x);
#endif
#ifdef MSC_VER
return _byteswap_ulong(x);
#endif
return (x >> 24) |
((x >> 8) & 0x0000FF00) |
((x << 8) & 0x00FF0000) |
(x << 24);
}
// mix functions for processBlock()
inline uint32_t f1(uint32_t e, uint32_t f, uint32_t g)
{
uint32_t term1 = rotate(e, 6) ^ rotate(e, 11) ^ rotate(e, 25);
uint32_t term2 = (e & f) ^ (~e & g); //(g ^ (e & (f ^ g)))
return term1 + term2;
}
inline uint32_t f2(uint32_t a, uint32_t b, uint32_t c)
{
uint32_t term1 = rotate(a, 2) ^ rotate(a, 13) ^ rotate(a, 22);
uint32_t term2 = ((a | b) & c) | (a & b); //(a & (b ^ c)) ^ (b & c);
return term1 + term2;
}
}
/// process 64 bytes
void SHA256::processBlock(const void* data)
{
// get last hash
uint32_t a = m_hash[0];
uint32_t b = m_hash[1];
uint32_t c = m_hash[2];
uint32_t d = m_hash[3];
uint32_t e = m_hash[4];
uint32_t f = m_hash[5];
uint32_t g = m_hash[6];
uint32_t h = m_hash[7];
// data represented as 16x 32-bit words
const uint32_t* input = (uint32_t*) data;
// convert to big endian
uint32_t words[64];
int i;
for (i = 0; i < 16; i++)
#if defined(__BYTE_ORDER) && (__BYTE_ORDER != 0) && (__BYTE_ORDER == __BIG_ENDIAN)
words[i] = input[i];
#else
words[i] = swap(input[i]);
#endif
uint32_t x,y; // temporaries
// first round
x = h + f1(e,f,g) + 0x428a2f98 + words[ 0]; y = f2(a,b,c); d += x; h = x + y;
x = g + f1(d,e,f) + 0x71374491 + words[ 1]; y = f2(h,a,b); c += x; g = x + y;
x = f + f1(c,d,e) + 0xb5c0fbcf + words[ 2]; y = f2(g,h,a); b += x; f = x + y;
x = e + f1(b,c,d) + 0xe9b5dba5 + words[ 3]; y = f2(f,g,h); a += x; e = x + y;
x = d + f1(a,b,c) + 0x3956c25b + words[ 4]; y = f2(e,f,g); h += x; d = x + y;
x = c + f1(h,a,b) + 0x59f111f1 + words[ 5]; y = f2(d,e,f); g += x; c = x + y;
x = b + f1(g,h,a) + 0x923f82a4 + words[ 6]; y = f2(c,d,e); f += x; b = x + y;
x = a + f1(f,g,h) + 0xab1c5ed5 + words[ 7]; y = f2(b,c,d); e += x; a = x + y;
// secound round
x = h + f1(e,f,g) + 0xd807aa98 + words[ 8]; y = f2(a,b,c); d += x; h = x + y;
x = g + f1(d,e,f) + 0x12835b01 + words[ 9]; y = f2(h,a,b); c += x; g = x + y;
x = f + f1(c,d,e) + 0x243185be + words[10]; y = f2(g,h,a); b += x; f = x + y;
x = e + f1(b,c,d) + 0x550c7dc3 + words[11]; y = f2(f,g,h); a += x; e = x + y;
x = d + f1(a,b,c) + 0x72be5d74 + words[12]; y = f2(e,f,g); h += x; d = x + y;
x = c + f1(h,a,b) + 0x80deb1fe + words[13]; y = f2(d,e,f); g += x; c = x + y;
x = b + f1(g,h,a) + 0x9bdc06a7 + words[14]; y = f2(c,d,e); f += x; b = x + y;
x = a + f1(f,g,h) + 0xc19bf174 + words[15]; y = f2(b,c,d); e += x; a = x + y;
// extend to 24 words
for (; i < 24; i++)
words[i] = words[i-16] +
(rotate(words[i-15], 7) ^ rotate(words[i-15], 18) ^ (words[i-15] >> 3)) +
words[i-7] +
(rotate(words[i- 2], 17) ^ rotate(words[i- 2], 19) ^ (words[i- 2] >> 10));
// third round
x = h + f1(e,f,g) + 0xe49b69c1 + words[16]; y = f2(a,b,c); d += x; h = x + y;
x = g + f1(d,e,f) + 0xefbe4786 + words[17]; y = f2(h,a,b); c += x; g = x + y;
x = f + f1(c,d,e) + 0x0fc19dc6 + words[18]; y = f2(g,h,a); b += x; f = x + y;
x = e + f1(b,c,d) + 0x240ca1cc + words[19]; y = f2(f,g,h); a += x; e = x + y;
x = d + f1(a,b,c) + 0x2de92c6f + words[20]; y = f2(e,f,g); h += x; d = x + y;
x = c + f1(h,a,b) + 0x4a7484aa + words[21]; y = f2(d,e,f); g += x; c = x + y;
x = b + f1(g,h,a) + 0x5cb0a9dc + words[22]; y = f2(c,d,e); f += x; b = x + y;
x = a + f1(f,g,h) + 0x76f988da + words[23]; y = f2(b,c,d); e += x; a = x + y;
// extend to 32 words
for (; i < 32; i++)
words[i] = words[i-16] +
(rotate(words[i-15], 7) ^ rotate(words[i-15], 18) ^ (words[i-15] >> 3)) +
words[i-7] +
(rotate(words[i- 2], 17) ^ rotate(words[i- 2], 19) ^ (words[i- 2] >> 10));
// fourth round
x = h + f1(e,f,g) + 0x983e5152 + words[24]; y = f2(a,b,c); d += x; h = x + y;
x = g + f1(d,e,f) + 0xa831c66d + words[25]; y = f2(h,a,b); c += x; g = x + y;
x = f + f1(c,d,e) + 0xb00327c8 + words[26]; y = f2(g,h,a); b += x; f = x + y;
x = e + f1(b,c,d) + 0xbf597fc7 + words[27]; y = f2(f,g,h); a += x; e = x + y;
x = d + f1(a,b,c) + 0xc6e00bf3 + words[28]; y = f2(e,f,g); h += x; d = x + y;
x = c + f1(h,a,b) + 0xd5a79147 + words[29]; y = f2(d,e,f); g += x; c = x + y;
x = b + f1(g,h,a) + 0x06ca6351 + words[30]; y = f2(c,d,e); f += x; b = x + y;
x = a + f1(f,g,h) + 0x14292967 + words[31]; y = f2(b,c,d); e += x; a = x + y;
// extend to 40 words
for (; i < 40; i++)
words[i] = words[i-16] +
(rotate(words[i-15], 7) ^ rotate(words[i-15], 18) ^ (words[i-15] >> 3)) +
words[i-7] +
(rotate(words[i- 2], 17) ^ rotate(words[i- 2], 19) ^ (words[i- 2] >> 10));
// fifth round
x = h + f1(e,f,g) + 0x27b70a85 + words[32]; y = f2(a,b,c); d += x; h = x + y;
x = g + f1(d,e,f) + 0x2e1b2138 + words[33]; y = f2(h,a,b); c += x; g = x + y;
x = f + f1(c,d,e) + 0x4d2c6dfc + words[34]; y = f2(g,h,a); b += x; f = x + y;
x = e + f1(b,c,d) + 0x53380d13 + words[35]; y = f2(f,g,h); a += x; e = x + y;
x = d + f1(a,b,c) + 0x650a7354 + words[36]; y = f2(e,f,g); h += x; d = x + y;
x = c + f1(h,a,b) + 0x766a0abb + words[37]; y = f2(d,e,f); g += x; c = x + y;
x = b + f1(g,h,a) + 0x81c2c92e + words[38]; y = f2(c,d,e); f += x; b = x + y;
x = a + f1(f,g,h) + 0x92722c85 + words[39]; y = f2(b,c,d); e += x; a = x + y;
// extend to 48 words
for (; i < 48; i++)
words[i] = words[i-16] +
(rotate(words[i-15], 7) ^ rotate(words[i-15], 18) ^ (words[i-15] >> 3)) +
words[i-7] +
(rotate(words[i- 2], 17) ^ rotate(words[i- 2], 19) ^ (words[i- 2] >> 10));
// sixth round
x = h + f1(e,f,g) + 0xa2bfe8a1 + words[40]; y = f2(a,b,c); d += x; h = x + y;
x = g + f1(d,e,f) + 0xa81a664b + words[41]; y = f2(h,a,b); c += x; g = x + y;
x = f + f1(c,d,e) + 0xc24b8b70 + words[42]; y = f2(g,h,a); b += x; f = x + y;
x = e + f1(b,c,d) + 0xc76c51a3 + words[43]; y = f2(f,g,h); a += x; e = x + y;
x = d + f1(a,b,c) + 0xd192e819 + words[44]; y = f2(e,f,g); h += x; d = x + y;
x = c + f1(h,a,b) + 0xd6990624 + words[45]; y = f2(d,e,f); g += x; c = x + y;
x = b + f1(g,h,a) + 0xf40e3585 + words[46]; y = f2(c,d,e); f += x; b = x + y;
x = a + f1(f,g,h) + 0x106aa070 + words[47]; y = f2(b,c,d); e += x; a = x + y;
// extend to 56 words
for (; i < 56; i++)
words[i] = words[i-16] +
(rotate(words[i-15], 7) ^ rotate(words[i-15], 18) ^ (words[i-15] >> 3)) +
words[i-7] +
(rotate(words[i- 2], 17) ^ rotate(words[i- 2], 19) ^ (words[i- 2] >> 10));
// seventh round
x = h + f1(e,f,g) + 0x19a4c116 + words[48]; y = f2(a,b,c); d += x; h = x + y;
x = g + f1(d,e,f) + 0x1e376c08 + words[49]; y = f2(h,a,b); c += x; g = x + y;
x = f + f1(c,d,e) + 0x2748774c + words[50]; y = f2(g,h,a); b += x; f = x + y;
x = e + f1(b,c,d) + 0x34b0bcb5 + words[51]; y = f2(f,g,h); a += x; e = x + y;
x = d + f1(a,b,c) + 0x391c0cb3 + words[52]; y = f2(e,f,g); h += x; d = x + y;
x = c + f1(h,a,b) + 0x4ed8aa4a + words[53]; y = f2(d,e,f); g += x; c = x + y;
x = b + f1(g,h,a) + 0x5b9cca4f + words[54]; y = f2(c,d,e); f += x; b = x + y;
x = a + f1(f,g,h) + 0x682e6ff3 + words[55]; y = f2(b,c,d); e += x; a = x + y;
// extend to 64 words
for (; i < 64; i++)
words[i] = words[i-16] +
(rotate(words[i-15], 7) ^ rotate(words[i-15], 18) ^ (words[i-15] >> 3)) +
words[i-7] +
(rotate(words[i- 2], 17) ^ rotate(words[i- 2], 19) ^ (words[i- 2] >> 10));
// eigth round
x = h + f1(e,f,g) + 0x748f82ee + words[56]; y = f2(a,b,c); d += x; h = x + y;
x = g + f1(d,e,f) + 0x78a5636f + words[57]; y = f2(h,a,b); c += x; g = x + y;
x = f + f1(c,d,e) + 0x84c87814 + words[58]; y = f2(g,h,a); b += x; f = x + y;
x = e + f1(b,c,d) + 0x8cc70208 + words[59]; y = f2(f,g,h); a += x; e = x + y;
x = d + f1(a,b,c) + 0x90befffa + words[60]; y = f2(e,f,g); h += x; d = x + y;
x = c + f1(h,a,b) + 0xa4506ceb + words[61]; y = f2(d,e,f); g += x; c = x + y;
x = b + f1(g,h,a) + 0xbef9a3f7 + words[62]; y = f2(c,d,e); f += x; b = x + y;
x = a + f1(f,g,h) + 0xc67178f2 + words[63]; y = f2(b,c,d); e += x; a = x + y;
// update hash
m_hash[0] += a;
m_hash[1] += b;
m_hash[2] += c;
m_hash[3] += d;
m_hash[4] += e;
m_hash[5] += f;
m_hash[6] += g;
m_hash[7] += h;
}
/// add arbitrary number of bytes
void SHA256::add(const void* data, size_t numBytes)
{
const uint8_t* current = (const uint8_t*) data;
if (m_bufferSize > 0)
{
while (numBytes > 0 && m_bufferSize < BlockSize)
{
m_buffer[m_bufferSize++] = *current++;
numBytes--;
}
}
// full buffer
if (m_bufferSize == BlockSize)
{
processBlock(m_buffer);
m_numBytes += BlockSize;
m_bufferSize = 0;
}
// no more data ?
if (numBytes == 0)
return;
// process full blocks
while (numBytes >= BlockSize)
{
processBlock(current);
current += BlockSize;
m_numBytes += BlockSize;
numBytes -= BlockSize;
}
// keep remaining bytes in buffer
while (numBytes > 0)
{
m_buffer[m_bufferSize++] = *current++;
numBytes--;
}
}
/// process final block, less than 64 bytes
void SHA256::processBuffer()
{
// the input bytes are considered as bits strings, where the first bit is the most significant bit of the byte
// - append "1" bit to message
// - append "0" bits until message length in bit mod 512 is 448
// - append length as 64 bit integer
// number of bits
size_t paddedLength = m_bufferSize * 8;
// plus one bit set to 1 (always appended)
paddedLength++;
// number of bits must be (numBits % 512) = 448
size_t lower11Bits = paddedLength & 511;
if (lower11Bits <= 448)
paddedLength += 448 - lower11Bits;
else
paddedLength += 512 + 448 - lower11Bits;
// convert from bits to bytes
paddedLength /= 8;
// only needed if additional data flows over into a second block
unsigned char extra[BlockSize];
// append a "1" bit, 128 => binary 10000000
if (m_bufferSize < BlockSize)
m_buffer[m_bufferSize] = 128;
else
extra[0] = 128;
size_t i;
for (i = m_bufferSize + 1; i < BlockSize; i++)
m_buffer[i] = 0;
for (; i < paddedLength; i++)
extra[i - BlockSize] = 0;
// add message length in bits as 64 bit number
uint64_t msgBits = 8 * (m_numBytes + m_bufferSize);
// find right position
unsigned char* addLength;
if (paddedLength < BlockSize)
addLength = m_buffer + paddedLength;
else
addLength = extra + paddedLength - BlockSize;
// must be big endian
*addLength++ = (unsigned char)((msgBits >> 56) & 0xFF);
*addLength++ = (unsigned char)((msgBits >> 48) & 0xFF);
*addLength++ = (unsigned char)((msgBits >> 40) & 0xFF);
*addLength++ = (unsigned char)((msgBits >> 32) & 0xFF);
*addLength++ = (unsigned char)((msgBits >> 24) & 0xFF);
*addLength++ = (unsigned char)((msgBits >> 16) & 0xFF);
*addLength++ = (unsigned char)((msgBits >> 8) & 0xFF);
*addLength = (unsigned char)( msgBits & 0xFF);
// process blocks
processBlock(m_buffer);
// flowed over into a second block ?
if (paddedLength > BlockSize)
processBlock(extra);
}
/// return latest hash as 64 hex characters
std::string SHA256::getHash()
{
// compute hash (as raw bytes)
unsigned char rawHash[HashBytes];
getHash(rawHash);
// convert to hex string
std::string result;
result.reserve(2 * HashBytes);
for (int i = 0; i < HashBytes; i++)
{
static const char dec2hex[16+1] = "0123456789abcdef";
result += dec2hex[(rawHash[i] >> 4) & 15];
result += dec2hex[ rawHash[i] & 15];
}
return result;
}
/// return latest hash as bytes
void SHA256::getHash(unsigned char buffer[SHA256::HashBytes])
{
// save old hash if buffer is partially filled
uint32_t oldHash[HashValues];
for (int i = 0; i < HashValues; i++)
oldHash[i] = m_hash[i];
// process remaining bytes
processBuffer();
unsigned char* current = buffer;
for (int i = 0; i < HashValues; i++)
{
*current++ = (m_hash[i] >> 24) & 0xFF;
*current++ = (m_hash[i] >> 16) & 0xFF;
*current++ = (m_hash[i] >> 8) & 0xFF;
*current++ = m_hash[i] & 0xFF;
// restore old hash
m_hash[i] = oldHash[i];
}
}
/// compute SHA256 of a memory block
std::string SHA256::operator()(const void* data, size_t numBytes)
{
reset();
add(data, numBytes);
return getHash();
}
/// compute SHA256 of a string, excluding final zero
std::string SHA256::operator()(const std::string& text)
{
reset();
add(text.c_str(), text.size());
return getHash();
}

View File

@@ -0,0 +1,289 @@
// //////////////////////////////////////////////////////////
// sha3.cpp
// Copyright (c) 2014,2015 Stephan Brumme. All rights reserved.
// see http://create.stephan-brumme.com/disclaimer.html
//
#include "sha3.h"
// big endian architectures need #define __BYTE_ORDER __BIG_ENDIAN
#ifndef _MSC_VER
#include <endian.h>
#endif
/// same as reset()
SHA3::SHA3(Bits bits)
: m_blockSize(200 - 2 * (bits / 8)),
m_bits(bits)
{
reset();
}
/// restart
void SHA3::reset()
{
for (size_t i = 0; i < StateSize; i++)
m_hash[i] = 0;
m_numBytes = 0;
m_bufferSize = 0;
}
/// constants and local helper functions
namespace
{
const unsigned int Rounds = 24;
const uint64_t XorMasks[Rounds] =
{
0x0000000000000001ULL, 0x0000000000008082ULL, 0x800000000000808aULL,
0x8000000080008000ULL, 0x000000000000808bULL, 0x0000000080000001ULL,
0x8000000080008081ULL, 0x8000000000008009ULL, 0x000000000000008aULL,
0x0000000000000088ULL, 0x0000000080008009ULL, 0x000000008000000aULL,
0x000000008000808bULL, 0x800000000000008bULL, 0x8000000000008089ULL,
0x8000000000008003ULL, 0x8000000000008002ULL, 0x8000000000000080ULL,
0x000000000000800aULL, 0x800000008000000aULL, 0x8000000080008081ULL,
0x8000000000008080ULL, 0x0000000080000001ULL, 0x8000000080008008ULL
};
/// rotate left and wrap around to the right
inline uint64_t rotateLeft(uint64_t x, uint8_t numBits)
{
return (x << numBits) | (x >> (64 - numBits));
}
/// convert litte vs big endian
inline uint64_t swap(uint64_t x)
{
#if defined(__GNUC__) || defined(__clang__)
return __builtin_bswap64(x);
#endif
#ifdef _MSC_VER
return _byteswap_uint64(x);
#endif
return (x >> 56) |
((x >> 40) & 0x000000000000FF00ULL) |
((x >> 24) & 0x0000000000FF0000ULL) |
((x >> 8) & 0x00000000FF000000ULL) |
((x << 8) & 0x000000FF00000000ULL) |
((x << 24) & 0x0000FF0000000000ULL) |
((x << 40) & 0x00FF000000000000ULL) |
(x << 56);
}
/// return x % 5 for 0 <= x <= 9
unsigned int mod5(unsigned int x)
{
if (x < 5)
return x;
return x - 5;
}
}
/// process a full block
void SHA3::processBlock(const void* data)
{
#if defined(__BYTE_ORDER) && (__BYTE_ORDER != 0) && (__BYTE_ORDER == __BIG_ENDIAN)
#define LITTLEENDIAN(x) swap(x)
#else
#define LITTLEENDIAN(x) (x)
#endif
const uint64_t* data64 = (const uint64_t*) data;
// mix data into state
for (unsigned int i = 0; i < m_blockSize / 8; i++)
m_hash[i] ^= LITTLEENDIAN(data64[i]);
// re-compute state
for (unsigned int round = 0; round < Rounds; round++)
{
// Theta
uint64_t coefficients[5];
for (unsigned int i = 0; i < 5; i++)
coefficients[i] = m_hash[i] ^ m_hash[i + 5] ^ m_hash[i + 10] ^ m_hash[i + 15] ^ m_hash[i + 20];
for (unsigned int i = 0; i < 5; i++)
{
uint64_t one = coefficients[mod5(i + 4)] ^ rotateLeft(coefficients[mod5(i + 1)], 1);
m_hash[i ] ^= one;
m_hash[i + 5] ^= one;
m_hash[i + 10] ^= one;
m_hash[i + 15] ^= one;
m_hash[i + 20] ^= one;
}
// temporary
uint64_t one;
// Rho Pi
uint64_t last = m_hash[1];
one = m_hash[10]; m_hash[10] = rotateLeft(last, 1); last = one;
one = m_hash[ 7]; m_hash[ 7] = rotateLeft(last, 3); last = one;
one = m_hash[11]; m_hash[11] = rotateLeft(last, 6); last = one;
one = m_hash[17]; m_hash[17] = rotateLeft(last, 10); last = one;
one = m_hash[18]; m_hash[18] = rotateLeft(last, 15); last = one;
one = m_hash[ 3]; m_hash[ 3] = rotateLeft(last, 21); last = one;
one = m_hash[ 5]; m_hash[ 5] = rotateLeft(last, 28); last = one;
one = m_hash[16]; m_hash[16] = rotateLeft(last, 36); last = one;
one = m_hash[ 8]; m_hash[ 8] = rotateLeft(last, 45); last = one;
one = m_hash[21]; m_hash[21] = rotateLeft(last, 55); last = one;
one = m_hash[24]; m_hash[24] = rotateLeft(last, 2); last = one;
one = m_hash[ 4]; m_hash[ 4] = rotateLeft(last, 14); last = one;
one = m_hash[15]; m_hash[15] = rotateLeft(last, 27); last = one;
one = m_hash[23]; m_hash[23] = rotateLeft(last, 41); last = one;
one = m_hash[19]; m_hash[19] = rotateLeft(last, 56); last = one;
one = m_hash[13]; m_hash[13] = rotateLeft(last, 8); last = one;
one = m_hash[12]; m_hash[12] = rotateLeft(last, 25); last = one;
one = m_hash[ 2]; m_hash[ 2] = rotateLeft(last, 43); last = one;
one = m_hash[20]; m_hash[20] = rotateLeft(last, 62); last = one;
one = m_hash[14]; m_hash[14] = rotateLeft(last, 18); last = one;
one = m_hash[22]; m_hash[22] = rotateLeft(last, 39); last = one;
one = m_hash[ 9]; m_hash[ 9] = rotateLeft(last, 61); last = one;
one = m_hash[ 6]; m_hash[ 6] = rotateLeft(last, 20); last = one;
m_hash[ 1] = rotateLeft(last, 44);
// Chi
for (unsigned int j = 0; j < 25; j += 5)
{
// temporaries
uint64_t one = m_hash[j];
uint64_t two = m_hash[j + 1];
m_hash[j] ^= m_hash[j + 2] & ~two;
m_hash[j + 1] ^= m_hash[j + 3] & ~m_hash[j + 2];
m_hash[j + 2] ^= m_hash[j + 4] & ~m_hash[j + 3];
m_hash[j + 3] ^= one & ~m_hash[j + 4];
m_hash[j + 4] ^= two & ~one;
}
// Iota
m_hash[0] ^= XorMasks[round];
}
}
/// add arbitrary number of bytes
void SHA3::add(const void* data, size_t numBytes)
{
const uint8_t* current = (const uint8_t*) data;
// copy data to buffer
if (m_bufferSize > 0)
{
while (numBytes > 0 && m_bufferSize < m_blockSize)
{
m_buffer[m_bufferSize++] = *current++;
numBytes--;
}
}
// full buffer
if (m_bufferSize == m_blockSize)
{
processBlock((void*)m_buffer);
m_numBytes += m_blockSize;
m_bufferSize = 0;
}
// no more data ?
if (numBytes == 0)
return;
// process full blocks
while (numBytes >= m_blockSize)
{
processBlock(current);
current += m_blockSize;
m_numBytes += m_blockSize;
numBytes -= m_blockSize;
}
// keep remaining bytes in buffer
while (numBytes > 0)
{
m_buffer[m_bufferSize++] = *current++;
numBytes--;
}
}
/// process everything left in the internal buffer
void SHA3::processBuffer()
{
// add padding
size_t offset = m_bufferSize;
// add a "1" byte
m_buffer[offset++] = 0x06;
// fill with zeros
while (offset < m_blockSize)
m_buffer[offset++] = 0;
// and add a single set bit
m_buffer[offset - 1] |= 0x80;
processBlock(m_buffer);
}
/// return latest hash as 16 hex characters
std::string SHA3::getHash()
{
// process remaining bytes
processBuffer();
// convert hash to string
static const char dec2hex[16 + 1] = "0123456789abcdef";
// number of significant elements in hash (uint64_t)
unsigned int hashLength = m_bits / 64;
std::string result;
result.reserve(m_bits / 4);
for (unsigned int i = 0; i < hashLength; i++)
for (unsigned int j = 0; j < 8; j++) // 64 bits => 8 bytes
{
// convert a byte to hex
unsigned char oneByte = (unsigned char) (m_hash[i] >> (8 * j));
result += dec2hex[oneByte >> 4];
result += dec2hex[oneByte & 15];
}
// SHA3-224's last entry in m_hash provides only 32 bits instead of 64 bits
unsigned int remainder = m_bits - hashLength * 64;
unsigned int processed = 0;
while (processed < remainder)
{
// convert a byte to hex
unsigned char oneByte = (unsigned char) (m_hash[hashLength] >> processed);
result += dec2hex[oneByte >> 4];
result += dec2hex[oneByte & 15];
processed += 8;
}
return result;
}
/// compute SHA3 of a memory block
std::string SHA3::operator()(const void* data, size_t numBytes)
{
reset();
add(data, numBytes);
return getHash();
}
/// compute SHA3 of a string, excluding final zero
std::string SHA3::operator()(const std::string& text)
{
reset();
add(text.c_str(), text.size());
return getHash();
}

View File

@@ -0,0 +1,13 @@
# Create the WhirlpoolLib library
add_library(WhirlpoolLib STATIC
include/ustd.h
include/whirlpool.h
byte_order.h byte_order.c
whirlpool.c.c
whirlpool_sbox.c
)
# Configure include folders
target_include_directories(WhirlpoolLib PRIVATE ${CMAKE_CURRENT_LIST_DIR})
target_include_directories(WhirlpoolLib PUBLIC ${CMAKE_CURRENT_LIST_DIR}/include)
# Configure build options
target_compile_definitions(WhirlpoolLib PRIVATE )

View File

@@ -0,0 +1,150 @@
/* byte_order.c - byte order related platform dependent routines,
*
* Copyright: 2008-2012 Aleksey Kravchenko <rhash.admin@gmail.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. Use this program at your own risk!
*/
#include "byte_order.h"
#if !(__GNUC__ >= 4 || (__GNUC__ ==3 && __GNUC_MINOR__ >= 4)) /* if !GCC or GCC < 4.3 */
# if _MSC_VER >= 1300 && (_M_IX86 || _M_AMD64 || _M_IA64) /* if MSVC++ >= 2002 on x86/x64 */
# include <intrin.h>
# pragma intrinsic(_BitScanForward)
/**
* Returns index of the trailing bit of x.
*
* @param x the number to process
* @return zero-based index of the trailing bit
*/
unsigned rhash_ctz(unsigned x)
{
unsigned long index;
unsigned char isNonzero = _BitScanForward(&index, x); /* MSVC intrinsic */
return (isNonzero ? (unsigned)index : 0);
}
# else /* _MSC_VER >= 1300... */
/**
* Returns index of the trailing bit of a 32-bit number.
* This is a plain C equivalent for GCC __builtin_ctz() bit scan.
*
* @param x the number to process
* @return zero-based index of the trailing bit
*/
unsigned rhash_ctz(unsigned x)
{
/* array for conversion to bit position */
static unsigned char bit_pos[32] = {
0, 1, 28, 2, 29, 14, 24, 3, 30, 22, 20, 15, 25, 17, 4, 8,
31, 27, 13, 23, 21, 19, 16, 7, 26, 12, 18, 6, 11, 5, 10, 9
};
/* The De Bruijn bit-scan was devised in 1997, according to Donald Knuth
* by Martin Lauter. The constant 0x077CB531UL is a De Bruijn sequence,
* which produces a unique pattern of bits into the high 5 bits for each
* possible bit position that it is multiplied against.
* See http://graphics.stanford.edu/~seander/bithacks.html
* and http://chessprogramming.wikispaces.com/BitScan */
return (unsigned)bit_pos[((uint32_t)((x & -x) * 0x077CB531U)) >> 27];
}
# endif /* _MSC_VER >= 1300... */
#endif /* !(GCC >= 4.3) */
/**
* Copy a memory block with simultaneous exchanging byte order.
* The byte order is changed from little-endian 32-bit integers
* to big-endian (or vice-versa).
*
* @param to the pointer where to copy memory block
* @param index the index to start writing from
* @param from the source block to copy
* @param length length of the memory block
*/
void rhash_swap_copy_str_to_u32(void* to, int index, const void* from, size_t length)
{
/* if all pointers and length are 32-bits aligned */
if ( 0 == (( (int)((char*)to - (char*)0) | ((char*)from - (char*)0) | index | length ) & 3) ) {
/* copy memory as 32-bit words */
const uint32_t* src = (const uint32_t*)from;
const uint32_t* end = (const uint32_t*)((const char*)src + length);
uint32_t* dst = (uint32_t*)((char*)to + index);
while (src < end) *(dst++) = bswap_32( *(src++) );
} else {
const char* src = (const char*)from;
for (length += index; (size_t)index < length; index++) ((char*)to)[index ^ 3] = *(src++);
}
}
/**
* Copy a memory block with changed byte order.
* The byte order is changed from little-endian 64-bit integers
* to big-endian (or vice-versa).
*
* @param to the pointer where to copy memory block
* @param index the index to start writing from
* @param from the source block to copy
* @param length length of the memory block
*/
void rhash_swap_copy_str_to_u64(void* to, int index, const void* from, size_t length)
{
/* if all pointers and length are 64-bits aligned */
if ( 0 == (( (int)((char*)to - (char*)0) | ((char*)from - (char*)0) | index | length ) & 7) ) {
/* copy aligned memory block as 64-bit integers */
const uint64_t* src = (const uint64_t*)from;
const uint64_t* end = (const uint64_t*)((const char*)src + length);
uint64_t* dst = (uint64_t*)((char*)to + index);
while (src < end) *(dst++) = bswap_64( *(src++) );
} else {
const char* src = (const char*)from;
for (length += index; (size_t)index < length; index++) ((char*)to)[index ^ 7] = *(src++);
}
}
/**
* Copy data from a sequence of 64-bit words to a binary string of given length,
* while changing byte order.
*
* @param to the binary string to receive data
* @param from the source sequence of 64-bit words
* @param length the size in bytes of the data being copied
*/
void rhash_swap_copy_u64_to_str(void* to, const void* from, size_t length)
{
/* if all pointers and length are 64-bits aligned */
if ( 0 == (( (int)((char*)to - (char*)0) | ((char*)from - (char*)0) | length ) & 7) ) {
/* copy aligned memory block as 64-bit integers */
const uint64_t* src = (const uint64_t*)from;
const uint64_t* end = (const uint64_t*)((const char*)src + length);
uint64_t* dst = (uint64_t*)to;
while (src < end) *(dst++) = bswap_64( *(src++) );
} else {
size_t index;
char* dst = (char*)to;
for (index = 0; index < length; index++) *(dst++) = ((char*)from)[index ^ 7];
}
}
/**
* Exchange byte order in the given array of 32-bit integers.
*
* @param arr the array to process
* @param length array length
*/
void rhash_u32_mem_swap(unsigned *arr, int length)
{
unsigned* end = arr + length;
for (; arr < end; arr++) {
*arr = bswap_32(*arr);
}
}

View File

@@ -0,0 +1,171 @@
/* byte_order.h */
#ifndef BYTE_ORDER_H
#define BYTE_ORDER_H
#include "ustd.h"
#include <stdlib.h>
#ifdef IN_RHASH
#include "config.h"
#endif
#ifdef __GLIBC__
# include <endian.h>
#endif
#ifdef __cplusplus
extern "C" {
#endif
/* if x86 compatible cpu */
#if defined(i386) || defined(__i386__) || defined(__i486__) || \
defined(__i586__) || defined(__i686__) || defined(__pentium__) || \
defined(__pentiumpro__) || defined(__pentium4__) || \
defined(__nocona__) || defined(prescott) || defined(__core2__) || \
defined(__k6__) || defined(__k8__) || defined(__athlon__) || \
defined(__amd64) || defined(__amd64__) || \
defined(__x86_64) || defined(__x86_64__) || defined(_M_IX86) || \
defined(_M_AMD64) || defined(_M_IA64) || defined(_M_X64)
/* detect if x86-64 instruction set is supported */
# if defined(_LP64) || defined(__LP64__) || defined(__x86_64) || \
defined(__x86_64__) || defined(_M_AMD64) || defined(_M_X64)
# define CPU_X64
# else
# define CPU_IA32
# endif
#endif
/* detect CPU endianness */
#if (defined(__BYTE_ORDER) && defined(__LITTLE_ENDIAN) && \
__BYTE_ORDER == __LITTLE_ENDIAN) || \
defined(CPU_IA32) || defined(CPU_X64) || \
defined(__ia64) || defined(__ia64__) || defined(__alpha__) || defined(_M_ALPHA) || \
defined(vax) || defined(MIPSEL) || defined(_ARM_) || defined(__arm__)
# define CPU_LITTLE_ENDIAN
# define IS_BIG_ENDIAN 0
# define IS_LITTLE_ENDIAN 1
#elif (defined(__BYTE_ORDER) && defined(__BIG_ENDIAN) && \
__BYTE_ORDER == __BIG_ENDIAN) || \
defined(__sparc) || defined(__sparc__) || defined(sparc) || \
defined(_ARCH_PPC) || defined(_ARCH_PPC64) || defined(_POWER) || \
defined(__POWERPC__) || defined(POWERPC) || defined(__powerpc) || \
defined(__powerpc__) || defined(__powerpc64__) || defined(__ppc__) || \
defined(__hpux) || defined(_MIPSEB) || defined(mc68000) || \
defined(__s390__) || defined(__s390x__) || defined(sel)
# define CPU_BIG_ENDIAN
# define IS_BIG_ENDIAN 1
# define IS_LITTLE_ENDIAN 0
#else
# error "Can't detect CPU architechture"
#endif
#define IS_ALIGNED_32(p) (0 == (3 & ((const char*)(p) - (const char*)0)))
#define IS_ALIGNED_64(p) (0 == (7 & ((const char*)(p) - (const char*)0)))
#if defined(_MSC_VER)
#define ALIGN_ATTR(n) __declspec(align(n))
#elif defined(__GNUC__)
#define ALIGN_ATTR(n) __attribute__((aligned (n)))
#else
#define ALIGN_ATTR(n) /* nothing */
#endif
#if defined(_MSC_VER) || defined(__BORLANDC__)
#define I64(x) x##ui64
#else
#define I64(x) x##LL
#endif
/* convert a hash flag to index */
#if __GNUC__ >= 4 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) /* GCC < 3.4 */
# define rhash_ctz(x) __builtin_ctz(x)
#else
unsigned rhash_ctz(unsigned); /* define as function */
#endif
void rhash_swap_copy_str_to_u32(void* to, int index, const void* from, size_t length);
void rhash_swap_copy_str_to_u64(void* to, int index, const void* from, size_t length);
void rhash_swap_copy_u64_to_str(void* to, const void* from, size_t length);
void rhash_u32_mem_swap(unsigned *p, int length_in_u32);
/* define bswap_32 */
#if defined(__GNUC__) && defined(CPU_IA32) && !defined(__i386__)
/* for intel x86 CPU */
static inline uint32_t bswap_32(uint32_t x) {
__asm("bswap\t%0" : "=r" (x) : "0" (x));
return x;
}
#elif defined(__GNUC__) && (__GNUC__ >= 4) && (__GNUC__ > 4 || __GNUC_MINOR__ >= 3)
/* for GCC >= 4.3 */
# define bswap_32(x) __builtin_bswap32(x)
#elif (_MSC_VER > 1300) && (defined(CPU_IA32) || defined(CPU_X64)) /* MS VC */
# define bswap_32(x) _byteswap_ulong((unsigned long)x)
#elif !defined(__STRICT_ANSI__)
/* general bswap_32 definition */
static inline uint32_t bswap_32(uint32_t x) {
x = ((x << 8) & 0xFF00FF00) | ((x >> 8) & 0x00FF00FF);
return (x >> 16) | (x << 16);
}
#else
#define bswap_32(x) ((((x) & 0xff000000) >> 24) | (((x) & 0x00ff0000) >> 8) | \
(((x) & 0x0000ff00) << 8) | (((x) & 0x000000ff) << 24))
#endif /* bswap_32 */
#if defined(__GNUC__) && (__GNUC__ >= 4) && (__GNUC__ > 4 || __GNUC_MINOR__ >= 3)
# define bswap_64(x) __builtin_bswap64(x)
#elif (_MSC_VER > 1300) && (defined(CPU_IA32) || defined(CPU_X64)) /* MS VC */
# define bswap_64(x) _byteswap_uint64((__int64)x)
#elif !defined(__STRICT_ANSI__)
static inline uint64_t bswap_64(uint64_t x) {
union {
uint64_t ll;
uint32_t l[2];
} w, r;
w.ll = x;
r.l[0] = bswap_32(w.l[1]);
r.l[1] = bswap_32(w.l[0]);
return r.ll;
}
#else
#error "bswap_64 unsupported"
#endif
#ifdef CPU_BIG_ENDIAN
# define be2me_32(x) (x)
# define be2me_64(x) (x)
# define le2me_32(x) bswap_32(x)
# define le2me_64(x) bswap_64(x)
# define be32_copy(to, index, from, length) memcpy((to) + (index), (from), (length))
# define le32_copy(to, index, from, length) rhash_swap_copy_str_to_u32((to), (index), (from), (length))
# define be64_copy(to, index, from, length) memcpy((to) + (index), (from), (length))
# define le64_copy(to, index, from, length) rhash_swap_copy_str_to_u64((to), (index), (from), (length))
# define me64_to_be_str(to, from, length) memcpy((to), (from), (length))
# define me64_to_le_str(to, from, length) rhash_swap_copy_u64_to_str((to), (from), (length))
#else /* CPU_BIG_ENDIAN */
# define be2me_32(x) bswap_32(x)
# define be2me_64(x) bswap_64(x)
# define le2me_32(x) (x)
# define le2me_64(x) (x)
# define be32_copy(to, index, from, length) rhash_swap_copy_str_to_u32((to), (index), (from), (length))
# define le32_copy(to, index, from, length) memcpy((to) + (index), (from), (length))
# define be64_copy(to, index, from, length) rhash_swap_copy_str_to_u64((to), (index), (from), (length))
# define le64_copy(to, index, from, length) memcpy((to) + (index), (from), (length))
# define me64_to_be_str(to, from, length) rhash_swap_copy_u64_to_str((to), (from), (length))
# define me64_to_le_str(to, from, length) memcpy((to), (from), (length))
#endif /* CPU_BIG_ENDIAN */
/* ROTL/ROTR macros rotate a 32/64-bit word left/right by n bits */
#define ROTL32(dword, n) ((dword) << (n) ^ ((dword) >> (32 - (n))))
#define ROTR32(dword, n) ((dword) >> (n) ^ ((dword) << (32 - (n))))
#define ROTL64(qword, n) ((qword) << (n) ^ ((qword) >> (64 - (n))))
#define ROTR64(qword, n) ((qword) >> (n) ^ ((qword) << (64 - (n))))
#ifdef __cplusplus
} /* extern "C" */
#endif /* __cplusplus */
#endif /* BYTE_ORDER_H */

View File

@@ -0,0 +1,30 @@
/* ustd.h common macros and includes */
#ifndef LIBRHASH_USTD_H
#define LIBRHASH_USTD_H
#if _MSC_VER >= 1300
# define int64_t __int64
# define int32_t __int32
# define int16_t __int16
# define int8_t __int8
# define uint64_t unsigned __int64
# define uint32_t unsigned __int32
# define uint16_t unsigned __int16
# define uint8_t unsigned __int8
/* disable warnings: The POSIX name for this item is deprecated. Use the ISO C++ conformant name. */
#pragma warning(disable : 4996)
#else /* _MSC_VER >= 1300 */
# include <stdint.h>
# include <unistd.h>
#endif /* _MSC_VER >= 1300 */
#if _MSC_VER <= 1300
# include <stdlib.h> /* size_t for vc6.0 */
#endif /* _MSC_VER <= 1300 */
#endif /* LIBRHASH_USTD_H */

View File

@@ -0,0 +1,34 @@
/* whirlpool.h */
#ifndef WHIRLPOOL_H
#define WHIRLPOOL_H
#include "ustd.h"
#ifdef __cplusplus
extern "C" {
#endif
#define whirlpool_block_size 64
/* algorithm context */
typedef struct whirlpool_ctx
{
uint64_t hash[8]; /* 512-bit algorithm internal hashing state */
unsigned char message[whirlpool_block_size]; /* 512-bit buffer to hash */
/* Note: original algorith uses 256-bit counter, allowing to hash up to
2^256 bits sized message. For optimization we use here 64-bit counter,
thus reducing maximal message size to 2^64 bits = 2 Exbibytes = 2^21 TiB) */
uint64_t length; /* number of processed bytes */
} whirlpool_ctx;
/* hash functions */
void rhash_whirlpool_init(whirlpool_ctx* ctx);
void rhash_whirlpool_update(whirlpool_ctx* ctx, const unsigned char* msg, size_t size);
void rhash_whirlpool_final(whirlpool_ctx* ctx, unsigned char* result);
#ifdef __cplusplus
} /* extern "C" */
#endif /* __cplusplus */
#endif /* WHIRLPOOL_H */

View File

@@ -0,0 +1,207 @@
/* whirlpool.c - an implementation of the Whirlpool Hash Function.
*
* Copyright: 2009-2012 Aleksey Kravchenko <rhash.admin@gmail.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. Use this program at your own risk!
*
* Documentation:
* P. S. L. M. Barreto, V. Rijmen, ``The Whirlpool hashing function,''
* NESSIE submission, 2000 (tweaked version, 2001)
*
* The algorithm is named after the Whirlpool Galaxy in Canes Venatici.
*/
#include <assert.h>
#include <string.h>
#include "byte_order.h"
#include "whirlpool.h"
/**
* Initialize context before calculating hash.
*
* @param ctx context to initialize
*/
void rhash_whirlpool_init(struct whirlpool_ctx* ctx)
{
ctx->length = 0;
memset(ctx->hash, 0, sizeof(ctx->hash));
}
/* Algorithm S-Box */
extern uint64_t rhash_whirlpool_sbox[8][256];
#define WHIRLPOOL_OP(src, shift) ( \
rhash_whirlpool_sbox[0][(int)(src[ shift & 7] >> 56) ] ^ \
rhash_whirlpool_sbox[1][(int)(src[(shift + 7) & 7] >> 48) & 0xff] ^ \
rhash_whirlpool_sbox[2][(int)(src[(shift + 6) & 7] >> 40) & 0xff] ^ \
rhash_whirlpool_sbox[3][(int)(src[(shift + 5) & 7] >> 32) & 0xff] ^ \
rhash_whirlpool_sbox[4][(int)(src[(shift + 4) & 7] >> 24) & 0xff] ^ \
rhash_whirlpool_sbox[5][(int)(src[(shift + 3) & 7] >> 16) & 0xff] ^ \
rhash_whirlpool_sbox[6][(int)(src[(shift + 2) & 7] >> 8) & 0xff] ^ \
rhash_whirlpool_sbox[7][(int)(src[(shift + 1) & 7] ) & 0xff])
/**
* The core transformation. Process a 512-bit block.
*
* @param hash algorithm state
* @param block the message block to process
*/
static void rhash_whirlpool_process_block(uint64_t *hash, uint64_t* p_block)
{
int i; /* loop counter */
uint64_t K[2][8]; /* key */
uint64_t state[2][8]; /* state */
/* alternating binary flags */
unsigned int m = 0;
/* the number of rounds of the internal dedicated block cipher */
const int number_of_rounds = 10;
/* array used in the rounds */
static const uint64_t rc[10] = {
I64(0x1823c6e887b8014f),
I64(0x36a6d2f5796f9152),
I64(0x60bc9b8ea30c7b35),
I64(0x1de0d7c22e4bfe57),
I64(0x157737e59ff04ada),
I64(0x58c9290ab1a06b85),
I64(0xbd5d10f4cb3e0567),
I64(0xe427418ba77d95d8),
I64(0xfbee7c66dd17479e),
I64(0xca2dbf07ad5a8333)
};
/* map the message buffer to a block */
for (i = 0; i < 8; i++) {
/* store K^0 and xor it with the intermediate hash state */
K[0][i] = hash[i];
state[0][i] = be2me_64(p_block[i]) ^ hash[i];
hash[i] = state[0][i];
}
/* iterate over algorithm rounds */
for (i = 0; i < number_of_rounds; i++)
{
/* compute K^i from K^{i-1} */
K[m ^ 1][0] = WHIRLPOOL_OP(K[m], 0) ^ rc[i];
K[m ^ 1][1] = WHIRLPOOL_OP(K[m], 1);
K[m ^ 1][2] = WHIRLPOOL_OP(K[m], 2);
K[m ^ 1][3] = WHIRLPOOL_OP(K[m], 3);
K[m ^ 1][4] = WHIRLPOOL_OP(K[m], 4);
K[m ^ 1][5] = WHIRLPOOL_OP(K[m], 5);
K[m ^ 1][6] = WHIRLPOOL_OP(K[m], 6);
K[m ^ 1][7] = WHIRLPOOL_OP(K[m], 7);
/* apply the i-th round transformation */
state[m ^ 1][0] = WHIRLPOOL_OP(state[m], 0) ^ K[m ^ 1][0];
state[m ^ 1][1] = WHIRLPOOL_OP(state[m], 1) ^ K[m ^ 1][1];
state[m ^ 1][2] = WHIRLPOOL_OP(state[m], 2) ^ K[m ^ 1][2];
state[m ^ 1][3] = WHIRLPOOL_OP(state[m], 3) ^ K[m ^ 1][3];
state[m ^ 1][4] = WHIRLPOOL_OP(state[m], 4) ^ K[m ^ 1][4];
state[m ^ 1][5] = WHIRLPOOL_OP(state[m], 5) ^ K[m ^ 1][5];
state[m ^ 1][6] = WHIRLPOOL_OP(state[m], 6) ^ K[m ^ 1][6];
state[m ^ 1][7] = WHIRLPOOL_OP(state[m], 7) ^ K[m ^ 1][7];
m = m ^ 1;
}
/* apply the Miyaguchi-Preneel compression function */
hash[0] ^= state[0][0];
hash[1] ^= state[0][1];
hash[2] ^= state[0][2];
hash[3] ^= state[0][3];
hash[4] ^= state[0][4];
hash[5] ^= state[0][5];
hash[6] ^= state[0][6];
hash[7] ^= state[0][7];
}
/**
* Calculate message hash.
* Can be called repeatedly with chunks of the message to be hashed.
*
* @param ctx the algorithm context containing current hashing state
* @param msg message chunk
* @param size length of the message chunk
*/
void rhash_whirlpool_update(whirlpool_ctx *ctx, const unsigned char* msg, size_t size)
{
unsigned index = (unsigned)ctx->length & 63;
unsigned left;
ctx->length += size;
/* fill partial block */
if (index) {
left = whirlpool_block_size - index;
memcpy(ctx->message + index, msg, (size < left ? size : left));
if (size < left) return;
/* process partial block */
rhash_whirlpool_process_block(ctx->hash, (uint64_t*)ctx->message);
msg += left;
size -= left;
}
while (size >= whirlpool_block_size) {
uint64_t* aligned_message_block;
if (IS_ALIGNED_64(msg)) {
/* the most common case is processing of an already aligned message
without copying it */
aligned_message_block = (uint64_t*)msg;
} else {
memcpy(ctx->message, msg, whirlpool_block_size);
aligned_message_block = (uint64_t*)ctx->message;
}
rhash_whirlpool_process_block(ctx->hash, aligned_message_block);
msg += whirlpool_block_size;
size -= whirlpool_block_size;
}
if (size) {
/* save leftovers */
memcpy(ctx->message, msg, size);
}
}
/**
* Store calculated hash into the given array.
*
* @param ctx the algorithm context containing current hashing state
* @param result calculated hash in binary form
*/
void rhash_whirlpool_final(whirlpool_ctx *ctx, unsigned char* result)
{
unsigned index = (unsigned)ctx->length & 63;
uint64_t* msg64 = (uint64_t*)ctx->message;
/* pad message and run for last block */
ctx->message[index++] = 0x80;
/* if no room left in the message to store 256-bit message length */
if (index > 32) {
/* then pad the rest with zeros and process it */
while (index < 64) {
ctx->message[index++] = 0;
}
rhash_whirlpool_process_block(ctx->hash, msg64);
index = 0;
}
/* due to optimization actually only 64-bit of message length are stored */
while (index < 56) {
ctx->message[index++] = 0;
}
msg64[7] = be2me_64(ctx->length << 3);
rhash_whirlpool_process_block(ctx->hash, msg64);
/* save result hash */
be64_copy(result, 0, ctx->hash, 64);
}

View File

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