#include <stdio.h>
#include <string.h>
/* #include <assert.h> */

#undef BIG_ENDIAN   /* jcd */

#ifndef __SQUARE_H
#define __SQUARE_H

#define R 8	/* number of rounds */
#define SQUARE_BLOCKSIZE (4*sizeof(word32))

#ifndef USUAL_TYPES
#define USUAL_TYPES
	typedef unsigned char	byte;	/*  8 bit */
	typedef unsigned short	word16;	/* 16 bit */
#ifdef __alpha
	typedef unsigned int	word32;	/* 32 bit */
#else  /* !__alpha */
	typedef unsigned long	word32;	/* 32 bit */
#endif /* ?__alpha */
#endif /* ?USUAL_TYPES */

extern const char *squareBanner;

typedef byte squareBlock[SQUARE_BLOCKSIZE];
typedef word32 squareKeySchedule[R+1][4];

void squareGenerateRoundKeys (const squareBlock key,
	squareKeySchedule roundKeys_e, squareKeySchedule roundKeys_d);
void squareExpandKey (const squareBlock key, squareKeySchedule roundKeys_e);
void squareEncrypt (word32 text[4], word32 ctext[4], squareKeySchedule roundKeys);
void squareDecrypt (word32 text[4], word32 ptext[4], squareKeySchedule roundKeys);

#endif /* __SQUARE_H */

static const byte Se[256] = {
0xb1U, 0xceU, 0xc3U, 0x95U, 0x5aU, 0xadU, 0xe7U, 0x02U,
0x4dU, 0x44U, 0xfbU, 0x91U, 0x0cU, 0x87U, 0xa1U, 0x50U,
0xcbU, 0x67U, 0x54U, 0xddU, 0x46U, 0x8fU, 0xe1U, 0x4eU,
0xf0U, 0xfdU, 0xfcU, 0xebU, 0xf9U, 0xc4U, 0x1aU, 0x6eU,
0x5eU, 0xf5U, 0xccU, 0x8dU, 0x1cU, 0x56U, 0x43U, 0xfeU,
0x07U, 0x61U, 0xf8U, 0x75U, 0x59U, 0xffU, 0x03U, 0x22U,
0x8aU, 0xd1U, 0x13U, 0xeeU, 0x88U, 0x00U, 0x0eU, 0x34U,
0x15U, 0x80U, 0x94U, 0xe3U, 0xedU, 0xb5U, 0x53U, 0x23U,
0x4bU, 0x47U, 0x17U, 0xa7U, 0x90U, 0x35U, 0xabU, 0xd8U,
0xb8U, 0xdfU, 0x4fU, 0x57U, 0x9aU, 0x92U, 0xdbU, 0x1bU,
0x3cU, 0xc8U, 0x99U, 0x04U, 0x8eU, 0xe0U, 0xd7U, 0x7dU,
0x85U, 0xbbU, 0x40U, 0x2cU, 0x3aU, 0x45U, 0xf1U, 0x42U,
0x65U, 0x20U, 0x41U, 0x18U, 0x72U, 0x25U, 0x93U, 0x70U,
0x36U, 0x05U, 0xf2U, 0x0bU, 0xa3U, 0x79U, 0xecU, 0x08U,
0x27U, 0x31U, 0x32U, 0xb6U, 0x7cU, 0xb0U, 0x0aU, 0x73U,
0x5bU, 0x7bU, 0xb7U, 0x81U, 0xd2U, 0x0dU, 0x6aU, 0x26U,
0x9eU, 0x58U, 0x9cU, 0x83U, 0x74U, 0xb3U, 0xacU, 0x30U,
0x7aU, 0x69U, 0x77U, 0x0fU, 0xaeU, 0x21U, 0xdeU, 0xd0U,
0x2eU, 0x97U, 0x10U, 0xa4U, 0x98U, 0xa8U, 0xd4U, 0x68U,
0x2dU, 0x62U, 0x29U, 0x6dU, 0x16U, 0x49U, 0x76U, 0xc7U,
0xe8U, 0xc1U, 0x96U, 0x37U, 0xe5U, 0xcaU, 0xf4U, 0xe9U,
0x63U, 0x12U, 0xc2U, 0xa6U, 0x14U, 0xbcU, 0xd3U, 0x28U,
0xafU, 0x2fU, 0xe6U, 0x24U, 0x52U, 0xc6U, 0xa0U, 0x09U,
0xbdU, 0x8cU, 0xcfU, 0x5dU, 0x11U, 0x5fU, 0x01U, 0xc5U,
0x9fU, 0x3dU, 0xa2U, 0x9bU, 0xc9U, 0x3bU, 0xbeU, 0x51U,
0x19U, 0x1fU, 0x3fU, 0x5cU, 0xb2U, 0xefU, 0x4aU, 0xcdU,
0xbfU, 0xbaU, 0x6fU, 0x64U, 0xd9U, 0xf3U, 0x3eU, 0xb4U,
0xaaU, 0xdcU, 0xd5U, 0x06U, 0xc0U, 0x7eU, 0xf6U, 0x66U,
0x6cU, 0x84U, 0x71U, 0x38U, 0xb9U, 0x1dU, 0x7fU, 0x9dU,
0x48U, 0x8bU, 0x2aU, 0xdaU, 0xa5U, 0x33U, 0x82U, 0x39U,
0xd6U, 0x78U, 0x86U, 0xfaU, 0xe4U, 0x2bU, 0xa9U, 0x1eU,
0x89U, 0x60U, 0x6bU, 0xeaU, 0x55U, 0x4cU, 0xf7U, 0xe2U,
};

static const byte Sd[256] = {
0x35U, 0xbeU, 0x07U, 0x2eU, 0x53U, 0x69U, 0xdbU, 0x28U,
0x6fU, 0xb7U, 0x76U, 0x6bU, 0x0cU, 0x7dU, 0x36U, 0x8bU,
0x92U, 0xbcU, 0xa9U, 0x32U, 0xacU, 0x38U, 0x9cU, 0x42U,
0x63U, 0xc8U, 0x1eU, 0x4fU, 0x24U, 0xe5U, 0xf7U, 0xc9U,
0x61U, 0x8dU, 0x2fU, 0x3fU, 0xb3U, 0x65U, 0x7fU, 0x70U,
0xafU, 0x9aU, 0xeaU, 0xf5U, 0x5bU, 0x98U, 0x90U, 0xb1U,
0x87U, 0x71U, 0x72U, 0xedU, 0x37U, 0x45U, 0x68U, 0xa3U,
0xe3U, 0xefU, 0x5cU, 0xc5U, 0x50U, 0xc1U, 0xd6U, 0xcaU,
0x5aU, 0x62U, 0x5fU, 0x26U, 0x09U, 0x5dU, 0x14U, 0x41U,
0xe8U, 0x9dU, 0xceU, 0x40U, 0xfdU, 0x08U, 0x17U, 0x4aU,
0x0fU, 0xc7U, 0xb4U, 0x3eU, 0x12U, 0xfcU, 0x25U, 0x4bU,
0x81U, 0x2cU, 0x04U, 0x78U, 0xcbU, 0xbbU, 0x20U, 0xbdU,
0xf9U, 0x29U, 0x99U, 0xa8U, 0xd3U, 0x60U, 0xdfU, 0x11U,
0x97U, 0x89U, 0x7eU, 0xfaU, 0xe0U, 0x9bU, 0x1fU, 0xd2U,
0x67U, 0xe2U, 0x64U, 0x77U, 0x84U, 0x2bU, 0x9eU, 0x8aU,
0xf1U, 0x6dU, 0x88U, 0x79U, 0x74U, 0x57U, 0xddU, 0xe6U,
0x39U, 0x7bU, 0xeeU, 0x83U, 0xe1U, 0x58U, 0xf2U, 0x0dU,
0x34U, 0xf8U, 0x30U, 0xe9U, 0xb9U, 0x23U, 0x54U, 0x15U,
0x44U, 0x0bU, 0x4dU, 0x66U, 0x3aU, 0x03U, 0xa2U, 0x91U,
0x94U, 0x52U, 0x4cU, 0xc3U, 0x82U, 0xe7U, 0x80U, 0xc0U,
0xb6U, 0x0eU, 0xc2U, 0x6cU, 0x93U, 0xecU, 0xabU, 0x43U,
0x95U, 0xf6U, 0xd8U, 0x46U, 0x86U, 0x05U, 0x8cU, 0xb0U,
0x75U, 0x00U, 0xccU, 0x85U, 0xd7U, 0x3dU, 0x73U, 0x7aU,
0x48U, 0xe4U, 0xd1U, 0x59U, 0xadU, 0xb8U, 0xc6U, 0xd0U,
0xdcU, 0xa1U, 0xaaU, 0x02U, 0x1dU, 0xbfU, 0xb5U, 0x9fU,
0x51U, 0xc4U, 0xa5U, 0x10U, 0x22U, 0xcfU, 0x01U, 0xbaU,
0x8fU, 0x31U, 0x7cU, 0xaeU, 0x96U, 0xdaU, 0xf0U, 0x56U,
0x47U, 0xd4U, 0xebU, 0x4eU, 0xd9U, 0x13U, 0x8eU, 0x49U,
0x55U, 0x16U, 0xffU, 0x3bU, 0xf4U, 0xa4U, 0xb2U, 0x06U,
0xa0U, 0xa7U, 0xfbU, 0x1bU, 0x6eU, 0x3cU, 0x33U, 0xcdU,
0x18U, 0x5eU, 0x6aU, 0xd5U, 0xa6U, 0x21U, 0xdeU, 0xfeU,
0x2aU, 0x1cU, 0xf3U, 0x0aU, 0x1aU, 0x19U, 0x27U, 0x2dU,
};

#ifdef LITTLE_ENDIAN

static const word32 phi[256] = {
0x00000000UL, 0x03010102UL, 0x06020204UL, 0x05030306UL,
0x0c040408UL, 0x0f05050aUL, 0x0a06060cUL, 0x0907070eUL,
0x18080810UL, 0x1b090912UL, 0x1e0a0a14UL, 0x1d0b0b16UL,
0x140c0c18UL, 0x170d0d1aUL, 0x120e0e1cUL, 0x110f0f1eUL,
0x30101020UL, 0x33111122UL, 0x36121224UL, 0x35131326UL,
0x3c141428UL, 0x3f15152aUL, 0x3a16162cUL, 0x3917172eUL,
0x28181830UL, 0x2b191932UL, 0x2e1a1a34UL, 0x2d1b1b36UL,
0x241c1c38UL, 0x271d1d3aUL, 0x221e1e3cUL, 0x211f1f3eUL,
0x60202040UL, 0x63212142UL, 0x66222244UL, 0x65232346UL,
0x6c242448UL, 0x6f25254aUL, 0x6a26264cUL, 0x6927274eUL,
0x78282850UL, 0x7b292952UL, 0x7e2a2a54UL, 0x7d2b2b56UL,
0x742c2c58UL, 0x772d2d5aUL, 0x722e2e5cUL, 0x712f2f5eUL,
0x50303060UL, 0x53313162UL, 0x56323264UL, 0x55333366UL,
0x5c343468UL, 0x5f35356aUL, 0x5a36366cUL, 0x5937376eUL,
0x48383870UL, 0x4b393972UL, 0x4e3a3a74UL, 0x4d3b3b76UL,
0x443c3c78UL, 0x473d3d7aUL, 0x423e3e7cUL, 0x413f3f7eUL,
0xc0404080UL, 0xc3414182UL, 0xc6424284UL, 0xc5434386UL,
0xcc444488UL, 0xcf45458aUL, 0xca46468cUL, 0xc947478eUL,
0xd8484890UL, 0xdb494992UL, 0xde4a4a94UL, 0xdd4b4b96UL,
0xd44c4c98UL, 0xd74d4d9aUL, 0xd24e4e9cUL, 0xd14f4f9eUL,
0xf05050a0UL, 0xf35151a2UL, 0xf65252a4UL, 0xf55353a6UL,
0xfc5454a8UL, 0xff5555aaUL, 0xfa5656acUL, 0xf95757aeUL,
0xe85858b0UL, 0xeb5959b2UL, 0xee5a5ab4UL, 0xed5b5bb6UL,
0xe45c5cb8UL, 0xe75d5dbaUL, 0xe25e5ebcUL, 0xe15f5fbeUL,
0xa06060c0UL, 0xa36161c2UL, 0xa66262c4UL, 0xa56363c6UL,
0xac6464c8UL, 0xaf6565caUL, 0xaa6666ccUL, 0xa96767ceUL,
0xb86868d0UL, 0xbb6969d2UL, 0xbe6a6ad4UL, 0xbd6b6bd6UL,
0xb46c6cd8UL, 0xb76d6ddaUL, 0xb26e6edcUL, 0xb16f6fdeUL,
0x907070e0UL, 0x937171e2UL, 0x967272e4UL, 0x957373e6UL,
0x9c7474e8UL, 0x9f7575eaUL, 0x9a7676ecUL, 0x997777eeUL,
0x887878f0UL, 0x8b7979f2UL, 0x8e7a7af4UL, 0x8d7b7bf6UL,
0x847c7cf8UL, 0x877d7dfaUL, 0x827e7efcUL, 0x817f7ffeUL,
0x758080f5UL, 0x768181f7UL, 0x738282f1UL, 0x708383f3UL,
0x798484fdUL, 0x7a8585ffUL, 0x7f8686f9UL, 0x7c8787fbUL,
0x6d8888e5UL, 0x6e8989e7UL, 0x6b8a8ae1UL, 0x688b8be3UL,
0x618c8cedUL, 0x628d8defUL, 0x678e8ee9UL, 0x648f8febUL,
0x459090d5UL, 0x469191d7UL, 0x439292d1UL, 0x409393d3UL,
0x499494ddUL, 0x4a9595dfUL, 0x4f9696d9UL, 0x4c9797dbUL,
0x5d9898c5UL, 0x5e9999c7UL, 0x5b9a9ac1UL, 0x589b9bc3UL,
0x519c9ccdUL, 0x529d9dcfUL, 0x579e9ec9UL, 0x549f9fcbUL,
0x15a0a0b5UL, 0x16a1a1b7UL, 0x13a2a2b1UL, 0x10a3a3b3UL,
0x19a4a4bdUL, 0x1aa5a5bfUL, 0x1fa6a6b9UL, 0x1ca7a7bbUL,
0x0da8a8a5UL, 0x0ea9a9a7UL, 0x0baaaaa1UL, 0x08ababa3UL,
0x01acacadUL, 0x02adadafUL, 0x07aeaea9UL, 0x04afafabUL,
0x25b0b095UL, 0x26b1b197UL, 0x23b2b291UL, 0x20b3b393UL,
0x29b4b49dUL, 0x2ab5b59fUL, 0x2fb6b699UL, 0x2cb7b79bUL,
0x3db8b885UL, 0x3eb9b987UL, 0x3bbaba81UL, 0x38bbbb83UL,
0x31bcbc8dUL, 0x32bdbd8fUL, 0x37bebe89UL, 0x34bfbf8bUL,
0xb5c0c075UL, 0xb6c1c177UL, 0xb3c2c271UL, 0xb0c3c373UL,
0xb9c4c47dUL, 0xbac5c57fUL, 0xbfc6c679UL, 0xbcc7c77bUL,
0xadc8c865UL, 0xaec9c967UL, 0xabcaca61UL, 0xa8cbcb63UL,
0xa1cccc6dUL, 0xa2cdcd6fUL, 0xa7cece69UL, 0xa4cfcf6bUL,
0x85d0d055UL, 0x86d1d157UL, 0x83d2d251UL, 0x80d3d353UL,
0x89d4d45dUL, 0x8ad5d55fUL, 0x8fd6d659UL, 0x8cd7d75bUL,
0x9dd8d845UL, 0x9ed9d947UL, 0x9bdada41UL, 0x98dbdb43UL,
0x91dcdc4dUL, 0x92dddd4fUL, 0x97dede49UL, 0x94dfdf4bUL,
0xd5e0e035UL, 0xd6e1e137UL, 0xd3e2e231UL, 0xd0e3e333UL,
0xd9e4e43dUL, 0xdae5e53fUL, 0xdfe6e639UL, 0xdce7e73bUL,
0xcde8e825UL, 0xcee9e927UL, 0xcbeaea21UL, 0xc8ebeb23UL,
0xc1ecec2dUL, 0xc2eded2fUL, 0xc7eeee29UL, 0xc4efef2bUL,
0xe5f0f015UL, 0xe6f1f117UL, 0xe3f2f211UL, 0xe0f3f313UL,
0xe9f4f41dUL, 0xeaf5f51fUL, 0xeff6f619UL, 0xecf7f71bUL,
0xfdf8f805UL, 0xfef9f907UL, 0xfbfafa01UL, 0xf8fbfb03UL,
0xf1fcfc0dUL, 0xf2fdfd0fUL, 0xf7fefe09UL, 0xf4ffff0bUL,
};

static const word32 offset[R] = {
0x00000001UL, 0x00000002UL, 0x00000004UL, 0x00000008UL,
0x00000010UL, 0x00000020UL, 0x00000040UL, 0x00000080UL,
};

static const word32 Te0[256] = {
0x26b1b197UL, 0xa7cece69UL, 0xb0c3c373UL, 0x4a9595dfUL, 
0xee5a5ab4UL, 0x02adadafUL, 0xdce7e73bUL, 0x06020204UL, 
0xd74d4d9aUL, 0xcc444488UL, 0xf8fbfb03UL, 0x469191d7UL, 
0x140c0c18UL, 0x7c8787fbUL, 0x16a1a1b7UL, 0xf05050a0UL, 
0xa8cbcb63UL, 0xa96767ceUL, 0xfc5454a8UL, 0x92dddd4fUL, 
0xca46468cUL, 0x648f8febUL, 0xd6e1e137UL, 0xd24e4e9cUL, 
0xe5f0f015UL, 0xf2fdfd0fUL, 0xf1fcfc0dUL, 0xc8ebeb23UL, 
0xfef9f907UL, 0xb9c4c47dUL, 0x2e1a1a34UL, 0xb26e6edcUL, 
0xe25e5ebcUL, 0xeaf5f51fUL, 0xa1cccc6dUL, 0x628d8defUL, 
0x241c1c38UL, 0xfa5656acUL, 0xc5434386UL, 0xf7fefe09UL, 
0x0907070eUL, 0xa36161c2UL, 0xfdf8f805UL, 0x9f7575eaUL, 
0xeb5959b2UL, 0xf4ffff0bUL, 0x05030306UL, 0x66222244UL, 
0x6b8a8ae1UL, 0x86d1d157UL, 0x35131326UL, 0xc7eeee29UL, 
0x6d8888e5UL, 0x00000000UL, 0x120e0e1cUL, 0x5c343468UL, 
0x3f15152aUL, 0x758080f5UL, 0x499494ddUL, 0xd0e3e333UL, 
0xc2eded2fUL, 0x2ab5b59fUL, 0xf55353a6UL, 0x65232346UL, 
0xdd4b4b96UL, 0xc947478eUL, 0x3917172eUL, 0x1ca7a7bbUL, 
0x459090d5UL, 0x5f35356aUL, 0x08ababa3UL, 0x9dd8d845UL, 
0x3db8b885UL, 0x94dfdf4bUL, 0xd14f4f9eUL, 0xf95757aeUL, 
0x5b9a9ac1UL, 0x439292d1UL, 0x98dbdb43UL, 0x2d1b1b36UL, 
0x443c3c78UL, 0xadc8c865UL, 0x5e9999c7UL, 0x0c040408UL, 
0x678e8ee9UL, 0xd5e0e035UL, 0x8cd7d75bUL, 0x877d7dfaUL, 
0x7a8585ffUL, 0x38bbbb83UL, 0xc0404080UL, 0x742c2c58UL, 
0x4e3a3a74UL, 0xcf45458aUL, 0xe6f1f117UL, 0xc6424284UL, 
0xaf6565caUL, 0x60202040UL, 0xc3414182UL, 0x28181830UL, 
0x967272e4UL, 0x6f25254aUL, 0x409393d3UL, 0x907070e0UL, 
0x5a36366cUL, 0x0f05050aUL, 0xe3f2f211UL, 0x1d0b0b16UL, 
0x10a3a3b3UL, 0x8b7979f2UL, 0xc1ecec2dUL, 0x18080810UL, 
0x6927274eUL, 0x53313162UL, 0x56323264UL, 0x2fb6b699UL, 
0x847c7cf8UL, 0x25b0b095UL, 0x1e0a0a14UL, 0x957373e6UL, 
0xed5b5bb6UL, 0x8d7b7bf6UL, 0x2cb7b79bUL, 0x768181f7UL, 
0x83d2d251UL, 0x170d0d1aUL, 0xbe6a6ad4UL, 0x6a26264cUL, 
0x579e9ec9UL, 0xe85858b0UL, 0x519c9ccdUL, 0x708383f3UL, 
0x9c7474e8UL, 0x20b3b393UL, 0x01acacadUL, 0x50303060UL, 
0x8e7a7af4UL, 0xbb6969d2UL, 0x997777eeUL, 0x110f0f1eUL, 
0x07aeaea9UL, 0x63212142UL, 0x97dede49UL, 0x85d0d055UL, 
0x722e2e5cUL, 0x4c9797dbUL, 0x30101020UL, 0x19a4a4bdUL, 
0x5d9898c5UL, 0x0da8a8a5UL, 0x89d4d45dUL, 0xb86868d0UL, 
0x772d2d5aUL, 0xa66262c4UL, 0x7b292952UL, 0xb76d6ddaUL, 
0x3a16162cUL, 0xdb494992UL, 0x9a7676ecUL, 0xbcc7c77bUL, 
0xcde8e825UL, 0xb6c1c177UL, 0x4f9696d9UL, 0x5937376eUL, 
0xdae5e53fUL, 0xabcaca61UL, 0xe9f4f41dUL, 0xcee9e927UL, 
0xa56363c6UL, 0x36121224UL, 0xb3c2c271UL, 0x1fa6a6b9UL, 
0x3c141428UL, 0x31bcbc8dUL, 0x80d3d353UL, 0x78282850UL, 
0x04afafabUL, 0x712f2f5eUL, 0xdfe6e639UL, 0x6c242448UL, 
0xf65252a4UL, 0xbfc6c679UL, 0x15a0a0b5UL, 0x1b090912UL, 
0x32bdbd8fUL, 0x618c8cedUL, 0xa4cfcf6bUL, 0xe75d5dbaUL, 
0x33111122UL, 0xe15f5fbeUL, 0x03010102UL, 0xbac5c57fUL, 
0x549f9fcbUL, 0x473d3d7aUL, 0x13a2a2b1UL, 0x589b9bc3UL, 
0xaec9c967UL, 0x4d3b3b76UL, 0x37bebe89UL, 0xf35151a2UL, 
0x2b191932UL, 0x211f1f3eUL, 0x413f3f7eUL, 0xe45c5cb8UL, 
0x23b2b291UL, 0xc4efef2bUL, 0xde4a4a94UL, 0xa2cdcd6fUL, 
0x34bfbf8bUL, 0x3bbaba81UL, 0xb16f6fdeUL, 0xac6464c8UL, 
0x9ed9d947UL, 0xe0f3f313UL, 0x423e3e7cUL, 0x29b4b49dUL, 
0x0baaaaa1UL, 0x91dcdc4dUL, 0x8ad5d55fUL, 0x0a06060cUL, 
0xb5c0c075UL, 0x827e7efcUL, 0xeff6f619UL, 0xaa6666ccUL, 
0xb46c6cd8UL, 0x798484fdUL, 0x937171e2UL, 0x48383870UL, 
0x3eb9b987UL, 0x271d1d3aUL, 0x817f7ffeUL, 0x529d9dcfUL, 
0xd8484890UL, 0x688b8be3UL, 0x7e2a2a54UL, 0x9bdada41UL, 
0x1aa5a5bfUL, 0x55333366UL, 0x738282f1UL, 0x4b393972UL, 
0x8fd6d659UL, 0x887878f0UL, 0x7f8686f9UL, 0xfbfafa01UL, 
0xd9e4e43dUL, 0x7d2b2b56UL, 0x0ea9a9a7UL, 0x221e1e3cUL, 
0x6e8989e7UL, 0xa06060c0UL, 0xbd6b6bd6UL, 0xcbeaea21UL, 
0xff5555aaUL, 0xd44c4c98UL, 0xecf7f71bUL, 0xd3e2e231UL, 
};

static const word32 Te1[256] = {
0xb1b19726UL, 0xcece69a7UL, 0xc3c373b0UL, 0x9595df4aUL, 
0x5a5ab4eeUL, 0xadadaf02UL, 0xe7e73bdcUL, 0x02020406UL, 
0x4d4d9ad7UL, 0x444488ccUL, 0xfbfb03f8UL, 0x9191d746UL, 
0x0c0c1814UL, 0x8787fb7cUL, 0xa1a1b716UL, 0x5050a0f0UL, 
0xcbcb63a8UL, 0x6767cea9UL, 0x5454a8fcUL, 0xdddd4f92UL, 
0x46468ccaUL, 0x8f8feb64UL, 0xe1e137d6UL, 0x4e4e9cd2UL, 
0xf0f015e5UL, 0xfdfd0ff2UL, 0xfcfc0df1UL, 0xebeb23c8UL, 
0xf9f907feUL, 0xc4c47db9UL, 0x1a1a342eUL, 0x6e6edcb2UL, 
0x5e5ebce2UL, 0xf5f51feaUL, 0xcccc6da1UL, 0x8d8def62UL, 
0x1c1c3824UL, 0x5656acfaUL, 0x434386c5UL, 0xfefe09f7UL, 
0x07070e09UL, 0x6161c2a3UL, 0xf8f805fdUL, 0x7575ea9fUL, 
0x5959b2ebUL, 0xffff0bf4UL, 0x03030605UL, 0x22224466UL, 
0x8a8ae16bUL, 0xd1d15786UL, 0x13132635UL, 0xeeee29c7UL, 
0x8888e56dUL, 0x00000000UL, 0x0e0e1c12UL, 0x3434685cUL, 
0x15152a3fUL, 0x8080f575UL, 0x9494dd49UL, 0xe3e333d0UL, 
0xeded2fc2UL, 0xb5b59f2aUL, 0x5353a6f5UL, 0x23234665UL, 
0x4b4b96ddUL, 0x47478ec9UL, 0x17172e39UL, 0xa7a7bb1cUL, 
0x9090d545UL, 0x35356a5fUL, 0xababa308UL, 0xd8d8459dUL, 
0xb8b8853dUL, 0xdfdf4b94UL, 0x4f4f9ed1UL, 0x5757aef9UL, 
0x9a9ac15bUL, 0x9292d143UL, 0xdbdb4398UL, 0x1b1b362dUL, 
0x3c3c7844UL, 0xc8c865adUL, 0x9999c75eUL, 0x0404080cUL, 
0x8e8ee967UL, 0xe0e035d5UL, 0xd7d75b8cUL, 0x7d7dfa87UL, 
0x8585ff7aUL, 0xbbbb8338UL, 0x404080c0UL, 0x2c2c5874UL, 
0x3a3a744eUL, 0x45458acfUL, 0xf1f117e6UL, 0x424284c6UL, 
0x6565caafUL, 0x20204060UL, 0x414182c3UL, 0x18183028UL, 
0x7272e496UL, 0x25254a6fUL, 0x9393d340UL, 0x7070e090UL, 
0x36366c5aUL, 0x05050a0fUL, 0xf2f211e3UL, 0x0b0b161dUL, 
0xa3a3b310UL, 0x7979f28bUL, 0xecec2dc1UL, 0x08081018UL, 
0x27274e69UL, 0x31316253UL, 0x32326456UL, 0xb6b6992fUL, 
0x7c7cf884UL, 0xb0b09525UL, 0x0a0a141eUL, 0x7373e695UL, 
0x5b5bb6edUL, 0x7b7bf68dUL, 0xb7b79b2cUL, 0x8181f776UL, 
0xd2d25183UL, 0x0d0d1a17UL, 0x6a6ad4beUL, 0x26264c6aUL, 
0x9e9ec957UL, 0x5858b0e8UL, 0x9c9ccd51UL, 0x8383f370UL, 
0x7474e89cUL, 0xb3b39320UL, 0xacacad01UL, 0x30306050UL, 
0x7a7af48eUL, 0x6969d2bbUL, 0x7777ee99UL, 0x0f0f1e11UL, 
0xaeaea907UL, 0x21214263UL, 0xdede4997UL, 0xd0d05585UL, 
0x2e2e5c72UL, 0x9797db4cUL, 0x10102030UL, 0xa4a4bd19UL, 
0x9898c55dUL, 0xa8a8a50dUL, 0xd4d45d89UL, 0x6868d0b8UL, 
0x2d2d5a77UL, 0x6262c4a6UL, 0x2929527bUL, 0x6d6ddab7UL, 
0x16162c3aUL, 0x494992dbUL, 0x7676ec9aUL, 0xc7c77bbcUL, 
0xe8e825cdUL, 0xc1c177b6UL, 0x9696d94fUL, 0x37376e59UL, 
0xe5e53fdaUL, 0xcaca61abUL, 0xf4f41de9UL, 0xe9e927ceUL, 
0x6363c6a5UL, 0x12122436UL, 0xc2c271b3UL, 0xa6a6b91fUL, 
0x1414283cUL, 0xbcbc8d31UL, 0xd3d35380UL, 0x28285078UL, 
0xafafab04UL, 0x2f2f5e71UL, 0xe6e639dfUL, 0x2424486cUL, 
0x5252a4f6UL, 0xc6c679bfUL, 0xa0a0b515UL, 0x0909121bUL, 
0xbdbd8f32UL, 0x8c8ced61UL, 0xcfcf6ba4UL, 0x5d5dbae7UL, 
0x11112233UL, 0x5f5fbee1UL, 0x01010203UL, 0xc5c57fbaUL, 
0x9f9fcb54UL, 0x3d3d7a47UL, 0xa2a2b113UL, 0x9b9bc358UL, 
0xc9c967aeUL, 0x3b3b764dUL, 0xbebe8937UL, 0x5151a2f3UL, 
0x1919322bUL, 0x1f1f3e21UL, 0x3f3f7e41UL, 0x5c5cb8e4UL, 
0xb2b29123UL, 0xefef2bc4UL, 0x4a4a94deUL, 0xcdcd6fa2UL, 
0xbfbf8b34UL, 0xbaba813bUL, 0x6f6fdeb1UL, 0x6464c8acUL, 
0xd9d9479eUL, 0xf3f313e0UL, 0x3e3e7c42UL, 0xb4b49d29UL, 
0xaaaaa10bUL, 0xdcdc4d91UL, 0xd5d55f8aUL, 0x06060c0aUL, 
0xc0c075b5UL, 0x7e7efc82UL, 0xf6f619efUL, 0x6666ccaaUL, 
0x6c6cd8b4UL, 0x8484fd79UL, 0x7171e293UL, 0x38387048UL, 
0xb9b9873eUL, 0x1d1d3a27UL, 0x7f7ffe81UL, 0x9d9dcf52UL, 
0x484890d8UL, 0x8b8be368UL, 0x2a2a547eUL, 0xdada419bUL, 
0xa5a5bf1aUL, 0x33336655UL, 0x8282f173UL, 0x3939724bUL, 
0xd6d6598fUL, 0x7878f088UL, 0x8686f97fUL, 0xfafa01fbUL, 
0xe4e43dd9UL, 0x2b2b567dUL, 0xa9a9a70eUL, 0x1e1e3c22UL, 
0x8989e76eUL, 0x6060c0a0UL, 0x6b6bd6bdUL, 0xeaea21cbUL, 
0x5555aaffUL, 0x4c4c98d4UL, 0xf7f71becUL, 0xe2e231d3UL, 
};

static const word32 Te2[256] = {
0xb19726b1UL, 0xce69a7ceUL, 0xc373b0c3UL, 0x95df4a95UL, 
0x5ab4ee5aUL, 0xadaf02adUL, 0xe73bdce7UL, 0x02040602UL, 
0x4d9ad74dUL, 0x4488cc44UL, 0xfb03f8fbUL, 0x91d74691UL, 
0x0c18140cUL, 0x87fb7c87UL, 0xa1b716a1UL, 0x50a0f050UL, 
0xcb63a8cbUL, 0x67cea967UL, 0x54a8fc54UL, 0xdd4f92ddUL, 
0x468cca46UL, 0x8feb648fUL, 0xe137d6e1UL, 0x4e9cd24eUL, 
0xf015e5f0UL, 0xfd0ff2fdUL, 0xfc0df1fcUL, 0xeb23c8ebUL, 
0xf907fef9UL, 0xc47db9c4UL, 0x1a342e1aUL, 0x6edcb26eUL, 
0x5ebce25eUL, 0xf51feaf5UL, 0xcc6da1ccUL, 0x8def628dUL, 
0x1c38241cUL, 0x56acfa56UL, 0x4386c543UL, 0xfe09f7feUL, 
0x070e0907UL, 0x61c2a361UL, 0xf805fdf8UL, 0x75ea9f75UL, 
0x59b2eb59UL, 0xff0bf4ffUL, 0x03060503UL, 0x22446622UL, 
0x8ae16b8aUL, 0xd15786d1UL, 0x13263513UL, 0xee29c7eeUL, 
0x88e56d88UL, 0x00000000UL, 0x0e1c120eUL, 0x34685c34UL, 
0x152a3f15UL, 0x80f57580UL, 0x94dd4994UL, 0xe333d0e3UL, 
0xed2fc2edUL, 0xb59f2ab5UL, 0x53a6f553UL, 0x23466523UL, 
0x4b96dd4bUL, 0x478ec947UL, 0x172e3917UL, 0xa7bb1ca7UL, 
0x90d54590UL, 0x356a5f35UL, 0xaba308abUL, 0xd8459dd8UL, 
0xb8853db8UL, 0xdf4b94dfUL, 0x4f9ed14fUL, 0x57aef957UL, 
0x9ac15b9aUL, 0x92d14392UL, 0xdb4398dbUL, 0x1b362d1bUL, 
0x3c78443cUL, 0xc865adc8UL, 0x99c75e99UL, 0x04080c04UL, 
0x8ee9678eUL, 0xe035d5e0UL, 0xd75b8cd7UL, 0x7dfa877dUL, 
0x85ff7a85UL, 0xbb8338bbUL, 0x4080c040UL, 0x2c58742cUL, 
0x3a744e3aUL, 0x458acf45UL, 0xf117e6f1UL, 0x4284c642UL, 
0x65caaf65UL, 0x20406020UL, 0x4182c341UL, 0x18302818UL, 
0x72e49672UL, 0x254a6f25UL, 0x93d34093UL, 0x70e09070UL, 
0x366c5a36UL, 0x050a0f05UL, 0xf211e3f2UL, 0x0b161d0bUL, 
0xa3b310a3UL, 0x79f28b79UL, 0xec2dc1ecUL, 0x08101808UL, 
0x274e6927UL, 0x31625331UL, 0x32645632UL, 0xb6992fb6UL, 
0x7cf8847cUL, 0xb09525b0UL, 0x0a141e0aUL, 0x73e69573UL, 
0x5bb6ed5bUL, 0x7bf68d7bUL, 0xb79b2cb7UL, 0x81f77681UL, 
0xd25183d2UL, 0x0d1a170dUL, 0x6ad4be6aUL, 0x264c6a26UL, 
0x9ec9579eUL, 0x58b0e858UL, 0x9ccd519cUL, 0x83f37083UL, 
0x74e89c74UL, 0xb39320b3UL, 0xacad01acUL, 0x30605030UL, 
0x7af48e7aUL, 0x69d2bb69UL, 0x77ee9977UL, 0x0f1e110fUL, 
0xaea907aeUL, 0x21426321UL, 0xde4997deUL, 0xd05585d0UL, 
0x2e5c722eUL, 0x97db4c97UL, 0x10203010UL, 0xa4bd19a4UL, 
0x98c55d98UL, 0xa8a50da8UL, 0xd45d89d4UL, 0x68d0b868UL, 
0x2d5a772dUL, 0x62c4a662UL, 0x29527b29UL, 0x6ddab76dUL, 
0x162c3a16UL, 0x4992db49UL, 0x76ec9a76UL, 0xc77bbcc7UL, 
0xe825cde8UL, 0xc177b6c1UL, 0x96d94f96UL, 0x376e5937UL, 
0xe53fdae5UL, 0xca61abcaUL, 0xf41de9f4UL, 0xe927cee9UL, 
0x63c6a563UL, 0x12243612UL, 0xc271b3c2UL, 0xa6b91fa6UL, 
0x14283c14UL, 0xbc8d31bcUL, 0xd35380d3UL, 0x28507828UL, 
0xafab04afUL, 0x2f5e712fUL, 0xe639dfe6UL, 0x24486c24UL, 
0x52a4f652UL, 0xc679bfc6UL, 0xa0b515a0UL, 0x09121b09UL, 
0xbd8f32bdUL, 0x8ced618cUL, 0xcf6ba4cfUL, 0x5dbae75dUL, 
0x11223311UL, 0x5fbee15fUL, 0x01020301UL, 0xc57fbac5UL, 
0x9fcb549fUL, 0x3d7a473dUL, 0xa2b113a2UL, 0x9bc3589bUL, 
0xc967aec9UL, 0x3b764d3bUL, 0xbe8937beUL, 0x51a2f351UL, 
0x19322b19UL, 0x1f3e211fUL, 0x3f7e413fUL, 0x5cb8e45cUL, 
0xb29123b2UL, 0xef2bc4efUL, 0x4a94de4aUL, 0xcd6fa2cdUL, 
0xbf8b34bfUL, 0xba813bbaUL, 0x6fdeb16fUL, 0x64c8ac64UL, 
0xd9479ed9UL, 0xf313e0f3UL, 0x3e7c423eUL, 0xb49d29b4UL, 
0xaaa10baaUL, 0xdc4d91dcUL, 0xd55f8ad5UL, 0x060c0a06UL, 
0xc075b5c0UL, 0x7efc827eUL, 0xf619eff6UL, 0x66ccaa66UL, 
0x6cd8b46cUL, 0x84fd7984UL, 0x71e29371UL, 0x38704838UL, 
0xb9873eb9UL, 0x1d3a271dUL, 0x7ffe817fUL, 0x9dcf529dUL, 
0x4890d848UL, 0x8be3688bUL, 0x2a547e2aUL, 0xda419bdaUL, 
0xa5bf1aa5UL, 0x33665533UL, 0x82f17382UL, 0x39724b39UL, 
0xd6598fd6UL, 0x78f08878UL, 0x86f97f86UL, 0xfa01fbfaUL, 
0xe43dd9e4UL, 0x2b567d2bUL, 0xa9a70ea9UL, 0x1e3c221eUL, 
0x89e76e89UL, 0x60c0a060UL, 0x6bd6bd6bUL, 0xea21cbeaUL, 
0x55aaff55UL, 0x4c98d44cUL, 0xf71becf7UL, 0xe231d3e2UL, 
};

static const word32 Te3[256] = {
0x9726b1b1UL, 0x69a7ceceUL, 0x73b0c3c3UL, 0xdf4a9595UL, 
0xb4ee5a5aUL, 0xaf02adadUL, 0x3bdce7e7UL, 0x04060202UL, 
0x9ad74d4dUL, 0x88cc4444UL, 0x03f8fbfbUL, 0xd7469191UL, 
0x18140c0cUL, 0xfb7c8787UL, 0xb716a1a1UL, 0xa0f05050UL, 
0x63a8cbcbUL, 0xcea96767UL, 0xa8fc5454UL, 0x4f92ddddUL, 
0x8cca4646UL, 0xeb648f8fUL, 0x37d6e1e1UL, 0x9cd24e4eUL, 
0x15e5f0f0UL, 0x0ff2fdfdUL, 0x0df1fcfcUL, 0x23c8ebebUL, 
0x07fef9f9UL, 0x7db9c4c4UL, 0x342e1a1aUL, 0xdcb26e6eUL, 
0xbce25e5eUL, 0x1feaf5f5UL, 0x6da1ccccUL, 0xef628d8dUL, 
0x38241c1cUL, 0xacfa5656UL, 0x86c54343UL, 0x09f7fefeUL, 
0x0e090707UL, 0xc2a36161UL, 0x05fdf8f8UL, 0xea9f7575UL, 
0xb2eb5959UL, 0x0bf4ffffUL, 0x06050303UL, 0x44662222UL, 
0xe16b8a8aUL, 0x5786d1d1UL, 0x26351313UL, 0x29c7eeeeUL, 
0xe56d8888UL, 0x00000000UL, 0x1c120e0eUL, 0x685c3434UL, 
0x2a3f1515UL, 0xf5758080UL, 0xdd499494UL, 0x33d0e3e3UL, 
0x2fc2ededUL, 0x9f2ab5b5UL, 0xa6f55353UL, 0x46652323UL, 
0x96dd4b4bUL, 0x8ec94747UL, 0x2e391717UL, 0xbb1ca7a7UL, 
0xd5459090UL, 0x6a5f3535UL, 0xa308ababUL, 0x459dd8d8UL, 
0x853db8b8UL, 0x4b94dfdfUL, 0x9ed14f4fUL, 0xaef95757UL, 
0xc15b9a9aUL, 0xd1439292UL, 0x4398dbdbUL, 0x362d1b1bUL, 
0x78443c3cUL, 0x65adc8c8UL, 0xc75e9999UL, 0x080c0404UL, 
0xe9678e8eUL, 0x35d5e0e0UL, 0x5b8cd7d7UL, 0xfa877d7dUL, 
0xff7a8585UL, 0x8338bbbbUL, 0x80c04040UL, 0x58742c2cUL, 
0x744e3a3aUL, 0x8acf4545UL, 0x17e6f1f1UL, 0x84c64242UL, 
0xcaaf6565UL, 0x40602020UL, 0x82c34141UL, 0x30281818UL, 
0xe4967272UL, 0x4a6f2525UL, 0xd3409393UL, 0xe0907070UL, 
0x6c5a3636UL, 0x0a0f0505UL, 0x11e3f2f2UL, 0x161d0b0bUL, 
0xb310a3a3UL, 0xf28b7979UL, 0x2dc1ececUL, 0x10180808UL, 
0x4e692727UL, 0x62533131UL, 0x64563232UL, 0x992fb6b6UL, 
0xf8847c7cUL, 0x9525b0b0UL, 0x141e0a0aUL, 0xe6957373UL, 
0xb6ed5b5bUL, 0xf68d7b7bUL, 0x9b2cb7b7UL, 0xf7768181UL, 
0x5183d2d2UL, 0x1a170d0dUL, 0xd4be6a6aUL, 0x4c6a2626UL, 
0xc9579e9eUL, 0xb0e85858UL, 0xcd519c9cUL, 0xf3708383UL, 
0xe89c7474UL, 0x9320b3b3UL, 0xad01acacUL, 0x60503030UL, 
0xf48e7a7aUL, 0xd2bb6969UL, 0xee997777UL, 0x1e110f0fUL, 
0xa907aeaeUL, 0x42632121UL, 0x4997dedeUL, 0x5585d0d0UL, 
0x5c722e2eUL, 0xdb4c9797UL, 0x20301010UL, 0xbd19a4a4UL, 
0xc55d9898UL, 0xa50da8a8UL, 0x5d89d4d4UL, 0xd0b86868UL, 
0x5a772d2dUL, 0xc4a66262UL, 0x527b2929UL, 0xdab76d6dUL, 
0x2c3a1616UL, 0x92db4949UL, 0xec9a7676UL, 0x7bbcc7c7UL, 
0x25cde8e8UL, 0x77b6c1c1UL, 0xd94f9696UL, 0x6e593737UL, 
0x3fdae5e5UL, 0x61abcacaUL, 0x1de9f4f4UL, 0x27cee9e9UL, 
0xc6a56363UL, 0x24361212UL, 0x71b3c2c2UL, 0xb91fa6a6UL, 
0x283c1414UL, 0x8d31bcbcUL, 0x5380d3d3UL, 0x50782828UL, 
0xab04afafUL, 0x5e712f2fUL, 0x39dfe6e6UL, 0x486c2424UL, 
0xa4f65252UL, 0x79bfc6c6UL, 0xb515a0a0UL, 0x121b0909UL, 
0x8f32bdbdUL, 0xed618c8cUL, 0x6ba4cfcfUL, 0xbae75d5dUL, 
0x22331111UL, 0xbee15f5fUL, 0x02030101UL, 0x7fbac5c5UL, 
0xcb549f9fUL, 0x7a473d3dUL, 0xb113a2a2UL, 0xc3589b9bUL, 
0x67aec9c9UL, 0x764d3b3bUL, 0x8937bebeUL, 0xa2f35151UL, 
0x322b1919UL, 0x3e211f1fUL, 0x7e413f3fUL, 0xb8e45c5cUL, 
0x9123b2b2UL, 0x2bc4efefUL, 0x94de4a4aUL, 0x6fa2cdcdUL, 
0x8b34bfbfUL, 0x813bbabaUL, 0xdeb16f6fUL, 0xc8ac6464UL, 
0x479ed9d9UL, 0x13e0f3f3UL, 0x7c423e3eUL, 0x9d29b4b4UL, 
0xa10baaaaUL, 0x4d91dcdcUL, 0x5f8ad5d5UL, 0x0c0a0606UL, 
0x75b5c0c0UL, 0xfc827e7eUL, 0x19eff6f6UL, 0xccaa6666UL, 
0xd8b46c6cUL, 0xfd798484UL, 0xe2937171UL, 0x70483838UL, 
0x873eb9b9UL, 0x3a271d1dUL, 0xfe817f7fUL, 0xcf529d9dUL, 
0x90d84848UL, 0xe3688b8bUL, 0x547e2a2aUL, 0x419bdadaUL, 
0xbf1aa5a5UL, 0x66553333UL, 0xf1738282UL, 0x724b3939UL, 
0x598fd6d6UL, 0xf0887878UL, 0xf97f8686UL, 0x01fbfafaUL, 
0x3dd9e4e4UL, 0x567d2b2bUL, 0xa70ea9a9UL, 0x3c221e1eUL, 
0xe76e8989UL, 0xc0a06060UL, 0xd6bd6b6bUL, 0x21cbeaeaUL, 
0xaaff5555UL, 0x98d44c4cUL, 0x1becf7f7UL, 0x31d3e2e2UL, 
};

static const word32 Td0[256] = {
0x02bc68e3UL, 0x0c628555UL, 0x31233f2aUL, 0xf713ab61UL, 
0x726dd498UL, 0x199acb21UL, 0x61a4223cUL, 0xcd3d9d45UL, 
0x23b4fd05UL, 0x5f07c42bUL, 0xc0012c9bUL, 0x0f80d93dUL, 
0x745c6c48UL, 0x857e7ff9UL, 0x1fab73f1UL, 0x0edeedb6UL, 
0xed6b3c28UL, 0x1a789749UL, 0x8d912a9fUL, 0x339f57c9UL, 
0xaaa807a9UL, 0x7ded0da5UL, 0x8f2d427cUL, 0xc9b04d76UL, 
0x57e8914dUL, 0xcc63a9ceUL, 0xd296eeb4UL, 0xb6e12830UL, 
0xb961f10dUL, 0x266719bdUL, 0x80ad9b41UL, 0xc76ea0c0UL, 
0x41f28351UL, 0x34f0db92UL, 0xfc1ea26fUL, 0x4cce328fUL, 
0x7333e013UL, 0x6dc6a769UL, 0x93646de5UL, 0xfa2f1abfUL, 
0xb7bf1cbbUL, 0xb5037458UL, 0x4f2c6ee7UL, 0x96b7895dUL, 
0x2a059ce8UL, 0xa3196644UL, 0xfb712e34UL, 0x6529f20fUL, 
0x7a8281feUL, 0xf12213b1UL, 0xec3508a3UL, 0x7e0f51cdUL, 
0x14a67affUL, 0xf893725cUL, 0x1297c22fUL, 0xc3e370f3UL, 
0x1c492f99UL, 0x681543d1UL, 0x1b26a3c2UL, 0xb332cc88UL, 
0x6f7acf8aUL, 0x9f06e8b0UL, 0x1ef5477aUL, 0xda79bbd2UL, 
0x210895e6UL, 0x5ce59843UL, 0x0631b8d0UL, 0xaf7be311UL, 
0x5365417eUL, 0x102baaccUL, 0x9ce4b4d8UL, 0xd4a75664UL, 
0x59367cfbUL, 0x84204b72UL, 0xf64d9feaUL, 0xdfaa5f6aUL, 
0xcedfc12dUL, 0x58684870UL, 0x81f3afcaUL, 0x91d80506UL, 
0x694b775aUL, 0xa528de94UL, 0x4210df39UL, 0x47c33b81UL, 
0xa6ca82fcUL, 0xc5d2c823UL, 0xb26cf803UL, 0x9ad50c08UL, 
0x40acb7daUL, 0xe109b97dUL, 0x2c342438UL, 0xa24752cfUL, 
0xd174b2dcUL, 0x2b5ba863UL, 0x9555d535UL, 0x11759e47UL, 
0xe2ebe515UL, 0xc630944bUL, 0xa8146f4aUL, 0x869c2391UL, 
0x39cc6a4cUL, 0x4aff8a5fUL, 0x4d900604UL, 0xbbdd99eeUL, 
0xca52111eUL, 0x18c4ffaaUL, 0x986964ebUL, 0xfffcfe07UL, 
0x015e348bUL, 0xbe0e7d56UL, 0xd99be7baUL, 0x32c16342UL, 
0x7bdcb575UL, 0x17442697UL, 0x66cbae67UL, 0xcb0c2595UL, 
0x67959aecUL, 0xd02a8657UL, 0x99375060UL, 0x05d3e4b8UL, 
0xba83ad65UL, 0x35aeef19UL, 0x13c9f6a4UL, 0xa94a5bc1UL, 
0xd61b3e87UL, 0x5e59f0a0UL, 0x5b8a1418UL, 0x3b7002afUL, 
0x76e004abUL, 0xbf5049ddUL, 0x63184adfUL, 0x56b6a5c6UL, 
0x0a533d85UL, 0x371287faUL, 0xa794b677UL, 0x7f516546UL, 
0x09b161edUL, 0xe9e6ec1bUL, 0x258545d5UL, 0x523b75f5UL, 
0x3d41ba7fUL, 0x8842ce27UL, 0x434eebb2UL, 0x97e9bdd6UL, 
0xf39e7b52UL, 0x457f5362UL, 0xa0fb3a2cUL, 0x70d1bc7bUL, 
0x6bf71fb9UL, 0x1d171b12UL, 0xc8ee79fdUL, 0xf07c273aUL, 
0xd7450a0cUL, 0x7960dd96UL, 0xabf63322UL, 0x891cfaacUL, 
0x5dbbacc8UL, 0x307d0ba1UL, 0x4ba1bed4UL, 0x940be1beUL, 
0x540acd25UL, 0x62467e54UL, 0x8211f3a2UL, 0x3ea3e617UL, 
0xe6663526UL, 0x750258c3UL, 0x9b8b3883UL, 0xc2bd4478UL, 
0xdc480302UL, 0x8ba0924fUL, 0x7cb3392eUL, 0xe584694eUL, 
0x718f88f0UL, 0x27392d36UL, 0x3ffdd29cUL, 0x6e24fb01UL, 
0xdd163789UL, 0x00000000UL, 0xe0578df6UL, 0x6c9893e2UL, 
0x15f84e74UL, 0x5ad42093UL, 0xe73801adUL, 0xb45d40d3UL, 
0x87c2171aUL, 0x2d6a10b3UL, 0x2fd67850UL, 0x3c1f8ef4UL, 
0xa1a50ea7UL, 0x364cb371UL, 0xae25d79aUL, 0x24db715eUL, 
0x50871d16UL, 0xd5f962efUL, 0x9086318dUL, 0x161a121cUL, 
0xcf81f5a6UL, 0x076f8c5bUL, 0x491dd637UL, 0x923a596eUL, 
0x6477c684UL, 0xb83fc586UL, 0xf9cd46d7UL, 0xb0d090e0UL, 
0x834fc729UL, 0xfd4096e4UL, 0x0b0d090eUL, 0x2056a16dUL, 
0x22eac98eUL, 0x2e884cdbUL, 0x8e7376f7UL, 0xbcb215b5UL, 
0xc15f1810UL, 0x6aa92b32UL, 0xb18ea46bUL, 0x5554f9aeUL, 
0xee896040UL, 0x08ef5566UL, 0x442167e9UL, 0xbdec213eUL, 
0x77be3020UL, 0xadc78bf2UL, 0x29e7c080UL, 0x8ccf1e14UL, 
0x4843e2bcUL, 0x8afea6c4UL, 0xd8c5d331UL, 0x60fa16b7UL, 
0x9dba8053UL, 0xf2c04fd9UL, 0x783ee91dUL, 0x3a2e3624UL, 
0xdef46be1UL, 0xefd754cbUL, 0xf4f1f709UL, 0xf5afc382UL, 
0x28b9f40bUL, 0x51d9299dUL, 0x38925ec7UL, 0xeb5a84f8UL, 
0xe8b8d890UL, 0x0d3cb1deUL, 0x048dd033UL, 0x03e25c68UL, 
0xe4da5dc5UL, 0x9e58dc3bUL, 0x469d0f0aUL, 0xd3c8da3fUL, 
0xdb278f59UL, 0xc48cfca8UL, 0xac99bf79UL, 0x4e725a6cUL, 
0xfea2ca8cUL, 0xe3b5d19eUL, 0xa476ea1fUL, 0xea04b073UL, 
};

static const word32 Td1[256] = {
0xbc68e302UL, 0x6285550cUL, 0x233f2a31UL, 0x13ab61f7UL, 
0x6dd49872UL, 0x9acb2119UL, 0xa4223c61UL, 0x3d9d45cdUL, 
0xb4fd0523UL, 0x07c42b5fUL, 0x012c9bc0UL, 0x80d93d0fUL, 
0x5c6c4874UL, 0x7e7ff985UL, 0xab73f11fUL, 0xdeedb60eUL, 
0x6b3c28edUL, 0x7897491aUL, 0x912a9f8dUL, 0x9f57c933UL, 
0xa807a9aaUL, 0xed0da57dUL, 0x2d427c8fUL, 0xb04d76c9UL, 
0xe8914d57UL, 0x63a9ceccUL, 0x96eeb4d2UL, 0xe12830b6UL, 
0x61f10db9UL, 0x6719bd26UL, 0xad9b4180UL, 0x6ea0c0c7UL, 
0xf2835141UL, 0xf0db9234UL, 0x1ea26ffcUL, 0xce328f4cUL, 
0x33e01373UL, 0xc6a7696dUL, 0x646de593UL, 0x2f1abffaUL, 
0xbf1cbbb7UL, 0x037458b5UL, 0x2c6ee74fUL, 0xb7895d96UL, 
0x059ce82aUL, 0x196644a3UL, 0x712e34fbUL, 0x29f20f65UL, 
0x8281fe7aUL, 0x2213b1f1UL, 0x3508a3ecUL, 0x0f51cd7eUL, 
0xa67aff14UL, 0x93725cf8UL, 0x97c22f12UL, 0xe370f3c3UL, 
0x492f991cUL, 0x1543d168UL, 0x26a3c21bUL, 0x32cc88b3UL, 
0x7acf8a6fUL, 0x06e8b09fUL, 0xf5477a1eUL, 0x79bbd2daUL, 
0x0895e621UL, 0xe598435cUL, 0x31b8d006UL, 0x7be311afUL, 
0x65417e53UL, 0x2baacc10UL, 0xe4b4d89cUL, 0xa75664d4UL, 
0x367cfb59UL, 0x204b7284UL, 0x4d9feaf6UL, 0xaa5f6adfUL, 
0xdfc12dceUL, 0x68487058UL, 0xf3afca81UL, 0xd8050691UL, 
0x4b775a69UL, 0x28de94a5UL, 0x10df3942UL, 0xc33b8147UL, 
0xca82fca6UL, 0xd2c823c5UL, 0x6cf803b2UL, 0xd50c089aUL, 
0xacb7da40UL, 0x09b97de1UL, 0x3424382cUL, 0x4752cfa2UL, 
0x74b2dcd1UL, 0x5ba8632bUL, 0x55d53595UL, 0x759e4711UL, 
0xebe515e2UL, 0x30944bc6UL, 0x146f4aa8UL, 0x9c239186UL, 
0xcc6a4c39UL, 0xff8a5f4aUL, 0x9006044dUL, 0xdd99eebbUL, 
0x52111ecaUL, 0xc4ffaa18UL, 0x6964eb98UL, 0xfcfe07ffUL, 
0x5e348b01UL, 0x0e7d56beUL, 0x9be7bad9UL, 0xc1634232UL, 
0xdcb5757bUL, 0x44269717UL, 0xcbae6766UL, 0x0c2595cbUL, 
0x959aec67UL, 0x2a8657d0UL, 0x37506099UL, 0xd3e4b805UL, 
0x83ad65baUL, 0xaeef1935UL, 0xc9f6a413UL, 0x4a5bc1a9UL, 
0x1b3e87d6UL, 0x59f0a05eUL, 0x8a14185bUL, 0x7002af3bUL, 
0xe004ab76UL, 0x5049ddbfUL, 0x184adf63UL, 0xb6a5c656UL, 
0x533d850aUL, 0x1287fa37UL, 0x94b677a7UL, 0x5165467fUL, 
0xb161ed09UL, 0xe6ec1be9UL, 0x8545d525UL, 0x3b75f552UL, 
0x41ba7f3dUL, 0x42ce2788UL, 0x4eebb243UL, 0xe9bdd697UL, 
0x9e7b52f3UL, 0x7f536245UL, 0xfb3a2ca0UL, 0xd1bc7b70UL, 
0xf71fb96bUL, 0x171b121dUL, 0xee79fdc8UL, 0x7c273af0UL, 
0x450a0cd7UL, 0x60dd9679UL, 0xf63322abUL, 0x1cfaac89UL, 
0xbbacc85dUL, 0x7d0ba130UL, 0xa1bed44bUL, 0x0be1be94UL, 
0x0acd2554UL, 0x467e5462UL, 0x11f3a282UL, 0xa3e6173eUL, 
0x663526e6UL, 0x0258c375UL, 0x8b38839bUL, 0xbd4478c2UL, 
0x480302dcUL, 0xa0924f8bUL, 0xb3392e7cUL, 0x84694ee5UL, 
0x8f88f071UL, 0x392d3627UL, 0xfdd29c3fUL, 0x24fb016eUL, 
0x163789ddUL, 0x00000000UL, 0x578df6e0UL, 0x9893e26cUL, 
0xf84e7415UL, 0xd420935aUL, 0x3801ade7UL, 0x5d40d3b4UL, 
0xc2171a87UL, 0x6a10b32dUL, 0xd678502fUL, 0x1f8ef43cUL, 
0xa50ea7a1UL, 0x4cb37136UL, 0x25d79aaeUL, 0xdb715e24UL, 
0x871d1650UL, 0xf962efd5UL, 0x86318d90UL, 0x1a121c16UL, 
0x81f5a6cfUL, 0x6f8c5b07UL, 0x1dd63749UL, 0x3a596e92UL, 
0x77c68464UL, 0x3fc586b8UL, 0xcd46d7f9UL, 0xd090e0b0UL, 
0x4fc72983UL, 0x4096e4fdUL, 0x0d090e0bUL, 0x56a16d20UL, 
0xeac98e22UL, 0x884cdb2eUL, 0x7376f78eUL, 0xb215b5bcUL, 
0x5f1810c1UL, 0xa92b326aUL, 0x8ea46bb1UL, 0x54f9ae55UL, 
0x896040eeUL, 0xef556608UL, 0x2167e944UL, 0xec213ebdUL, 
0xbe302077UL, 0xc78bf2adUL, 0xe7c08029UL, 0xcf1e148cUL, 
0x43e2bc48UL, 0xfea6c48aUL, 0xc5d331d8UL, 0xfa16b760UL, 
0xba80539dUL, 0xc04fd9f2UL, 0x3ee91d78UL, 0x2e36243aUL, 
0xf46be1deUL, 0xd754cbefUL, 0xf1f709f4UL, 0xafc382f5UL, 
0xb9f40b28UL, 0xd9299d51UL, 0x925ec738UL, 0x5a84f8ebUL, 
0xb8d890e8UL, 0x3cb1de0dUL, 0x8dd03304UL, 0xe25c6803UL, 
0xda5dc5e4UL, 0x58dc3b9eUL, 0x9d0f0a46UL, 0xc8da3fd3UL, 
0x278f59dbUL, 0x8cfca8c4UL, 0x99bf79acUL, 0x725a6c4eUL, 
0xa2ca8cfeUL, 0xb5d19ee3UL, 0x76ea1fa4UL, 0x04b073eaUL, 
};

static const word32 Td2[256] = {
0x68e302bcUL, 0x85550c62UL, 0x3f2a3123UL, 0xab61f713UL, 
0xd498726dUL, 0xcb21199aUL, 0x223c61a4UL, 0x9d45cd3dUL, 
0xfd0523b4UL, 0xc42b5f07UL, 0x2c9bc001UL, 0xd93d0f80UL, 
0x6c48745cUL, 0x7ff9857eUL, 0x73f11fabUL, 0xedb60edeUL, 
0x3c28ed6bUL, 0x97491a78UL, 0x2a9f8d91UL, 0x57c9339fUL, 
0x07a9aaa8UL, 0x0da57dedUL, 0x427c8f2dUL, 0x4d76c9b0UL, 
0x914d57e8UL, 0xa9cecc63UL, 0xeeb4d296UL, 0x2830b6e1UL, 
0xf10db961UL, 0x19bd2667UL, 0x9b4180adUL, 0xa0c0c76eUL, 
0x835141f2UL, 0xdb9234f0UL, 0xa26ffc1eUL, 0x328f4cceUL, 
0xe0137333UL, 0xa7696dc6UL, 0x6de59364UL, 0x1abffa2fUL, 
0x1cbbb7bfUL, 0x7458b503UL, 0x6ee74f2cUL, 0x895d96b7UL, 
0x9ce82a05UL, 0x6644a319UL, 0x2e34fb71UL, 0xf20f6529UL, 
0x81fe7a82UL, 0x13b1f122UL, 0x08a3ec35UL, 0x51cd7e0fUL, 
0x7aff14a6UL, 0x725cf893UL, 0xc22f1297UL, 0x70f3c3e3UL, 
0x2f991c49UL, 0x43d16815UL, 0xa3c21b26UL, 0xcc88b332UL, 
0xcf8a6f7aUL, 0xe8b09f06UL, 0x477a1ef5UL, 0xbbd2da79UL, 
0x95e62108UL, 0x98435ce5UL, 0xb8d00631UL, 0xe311af7bUL, 
0x417e5365UL, 0xaacc102bUL, 0xb4d89ce4UL, 0x5664d4a7UL, 
0x7cfb5936UL, 0x4b728420UL, 0x9feaf64dUL, 0x5f6adfaaUL, 
0xc12dcedfUL, 0x48705868UL, 0xafca81f3UL, 0x050691d8UL, 
0x775a694bUL, 0xde94a528UL, 0xdf394210UL, 0x3b8147c3UL, 
0x82fca6caUL, 0xc823c5d2UL, 0xf803b26cUL, 0x0c089ad5UL, 
0xb7da40acUL, 0xb97de109UL, 0x24382c34UL, 0x52cfa247UL, 
0xb2dcd174UL, 0xa8632b5bUL, 0xd5359555UL, 0x9e471175UL, 
0xe515e2ebUL, 0x944bc630UL, 0x6f4aa814UL, 0x2391869cUL, 
0x6a4c39ccUL, 0x8a5f4affUL, 0x06044d90UL, 0x99eebbddUL, 
0x111eca52UL, 0xffaa18c4UL, 0x64eb9869UL, 0xfe07fffcUL, 
0x348b015eUL, 0x7d56be0eUL, 0xe7bad99bUL, 0x634232c1UL, 
0xb5757bdcUL, 0x26971744UL, 0xae6766cbUL, 0x2595cb0cUL, 
0x9aec6795UL, 0x8657d02aUL, 0x50609937UL, 0xe4b805d3UL, 
0xad65ba83UL, 0xef1935aeUL, 0xf6a413c9UL, 0x5bc1a94aUL, 
0x3e87d61bUL, 0xf0a05e59UL, 0x14185b8aUL, 0x02af3b70UL, 
0x04ab76e0UL, 0x49ddbf50UL, 0x4adf6318UL, 0xa5c656b6UL, 
0x3d850a53UL, 0x87fa3712UL, 0xb677a794UL, 0x65467f51UL, 
0x61ed09b1UL, 0xec1be9e6UL, 0x45d52585UL, 0x75f5523bUL, 
0xba7f3d41UL, 0xce278842UL, 0xebb2434eUL, 0xbdd697e9UL, 
0x7b52f39eUL, 0x5362457fUL, 0x3a2ca0fbUL, 0xbc7b70d1UL, 
0x1fb96bf7UL, 0x1b121d17UL, 0x79fdc8eeUL, 0x273af07cUL, 
0x0a0cd745UL, 0xdd967960UL, 0x3322abf6UL, 0xfaac891cUL, 
0xacc85dbbUL, 0x0ba1307dUL, 0xbed44ba1UL, 0xe1be940bUL, 
0xcd25540aUL, 0x7e546246UL, 0xf3a28211UL, 0xe6173ea3UL, 
0x3526e666UL, 0x58c37502UL, 0x38839b8bUL, 0x4478c2bdUL, 
0x0302dc48UL, 0x924f8ba0UL, 0x392e7cb3UL, 0x694ee584UL, 
0x88f0718fUL, 0x2d362739UL, 0xd29c3ffdUL, 0xfb016e24UL, 
0x3789dd16UL, 0x00000000UL, 0x8df6e057UL, 0x93e26c98UL, 
0x4e7415f8UL, 0x20935ad4UL, 0x01ade738UL, 0x40d3b45dUL, 
0x171a87c2UL, 0x10b32d6aUL, 0x78502fd6UL, 0x8ef43c1fUL, 
0x0ea7a1a5UL, 0xb371364cUL, 0xd79aae25UL, 0x715e24dbUL, 
0x1d165087UL, 0x62efd5f9UL, 0x318d9086UL, 0x121c161aUL, 
0xf5a6cf81UL, 0x8c5b076fUL, 0xd637491dUL, 0x596e923aUL, 
0xc6846477UL, 0xc586b83fUL, 0x46d7f9cdUL, 0x90e0b0d0UL, 
0xc729834fUL, 0x96e4fd40UL, 0x090e0b0dUL, 0xa16d2056UL, 
0xc98e22eaUL, 0x4cdb2e88UL, 0x76f78e73UL, 0x15b5bcb2UL, 
0x1810c15fUL, 0x2b326aa9UL, 0xa46bb18eUL, 0xf9ae5554UL, 
0x6040ee89UL, 0x556608efUL, 0x67e94421UL, 0x213ebdecUL, 
0x302077beUL, 0x8bf2adc7UL, 0xc08029e7UL, 0x1e148ccfUL, 
0xe2bc4843UL, 0xa6c48afeUL, 0xd331d8c5UL, 0x16b760faUL, 
0x80539dbaUL, 0x4fd9f2c0UL, 0xe91d783eUL, 0x36243a2eUL, 
0x6be1def4UL, 0x54cbefd7UL, 0xf709f4f1UL, 0xc382f5afUL, 
0xf40b28b9UL, 0x299d51d9UL, 0x5ec73892UL, 0x84f8eb5aUL, 
0xd890e8b8UL, 0xb1de0d3cUL, 0xd033048dUL, 0x5c6803e2UL, 
0x5dc5e4daUL, 0xdc3b9e58UL, 0x0f0a469dUL, 0xda3fd3c8UL, 
0x8f59db27UL, 0xfca8c48cUL, 0xbf79ac99UL, 0x5a6c4e72UL, 
0xca8cfea2UL, 0xd19ee3b5UL, 0xea1fa476UL, 0xb073ea04UL, 
};

static const word32 Td3[256] = {
0xe302bc68UL, 0x550c6285UL, 0x2a31233fUL, 0x61f713abUL, 
0x98726dd4UL, 0x21199acbUL, 0x3c61a422UL, 0x45cd3d9dUL, 
0x0523b4fdUL, 0x2b5f07c4UL, 0x9bc0012cUL, 0x3d0f80d9UL, 
0x48745c6cUL, 0xf9857e7fUL, 0xf11fab73UL, 0xb60edeedUL, 
0x28ed6b3cUL, 0x491a7897UL, 0x9f8d912aUL, 0xc9339f57UL, 
0xa9aaa807UL, 0xa57ded0dUL, 0x7c8f2d42UL, 0x76c9b04dUL, 
0x4d57e891UL, 0xcecc63a9UL, 0xb4d296eeUL, 0x30b6e128UL, 
0x0db961f1UL, 0xbd266719UL, 0x4180ad9bUL, 0xc0c76ea0UL, 
0x5141f283UL, 0x9234f0dbUL, 0x6ffc1ea2UL, 0x8f4cce32UL, 
0x137333e0UL, 0x696dc6a7UL, 0xe593646dUL, 0xbffa2f1aUL, 
0xbbb7bf1cUL, 0x58b50374UL, 0xe74f2c6eUL, 0x5d96b789UL, 
0xe82a059cUL, 0x44a31966UL, 0x34fb712eUL, 0x0f6529f2UL, 
0xfe7a8281UL, 0xb1f12213UL, 0xa3ec3508UL, 0xcd7e0f51UL, 
0xff14a67aUL, 0x5cf89372UL, 0x2f1297c2UL, 0xf3c3e370UL, 
0x991c492fUL, 0xd1681543UL, 0xc21b26a3UL, 0x88b332ccUL, 
0x8a6f7acfUL, 0xb09f06e8UL, 0x7a1ef547UL, 0xd2da79bbUL, 
0xe6210895UL, 0x435ce598UL, 0xd00631b8UL, 0x11af7be3UL, 
0x7e536541UL, 0xcc102baaUL, 0xd89ce4b4UL, 0x64d4a756UL, 
0xfb59367cUL, 0x7284204bUL, 0xeaf64d9fUL, 0x6adfaa5fUL, 
0x2dcedfc1UL, 0x70586848UL, 0xca81f3afUL, 0x0691d805UL, 
0x5a694b77UL, 0x94a528deUL, 0x394210dfUL, 0x8147c33bUL, 
0xfca6ca82UL, 0x23c5d2c8UL, 0x03b26cf8UL, 0x089ad50cUL, 
0xda40acb7UL, 0x7de109b9UL, 0x382c3424UL, 0xcfa24752UL, 
0xdcd174b2UL, 0x632b5ba8UL, 0x359555d5UL, 0x4711759eUL, 
0x15e2ebe5UL, 0x4bc63094UL, 0x4aa8146fUL, 0x91869c23UL, 
0x4c39cc6aUL, 0x5f4aff8aUL, 0x044d9006UL, 0xeebbdd99UL, 
0x1eca5211UL, 0xaa18c4ffUL, 0xeb986964UL, 0x07fffcfeUL, 
0x8b015e34UL, 0x56be0e7dUL, 0xbad99be7UL, 0x4232c163UL, 
0x757bdcb5UL, 0x97174426UL, 0x6766cbaeUL, 0x95cb0c25UL, 
0xec67959aUL, 0x57d02a86UL, 0x60993750UL, 0xb805d3e4UL, 
0x65ba83adUL, 0x1935aeefUL, 0xa413c9f6UL, 0xc1a94a5bUL, 
0x87d61b3eUL, 0xa05e59f0UL, 0x185b8a14UL, 0xaf3b7002UL, 
0xab76e004UL, 0xddbf5049UL, 0xdf63184aUL, 0xc656b6a5UL, 
0x850a533dUL, 0xfa371287UL, 0x77a794b6UL, 0x467f5165UL, 
0xed09b161UL, 0x1be9e6ecUL, 0xd5258545UL, 0xf5523b75UL, 
0x7f3d41baUL, 0x278842ceUL, 0xb2434eebUL, 0xd697e9bdUL, 
0x52f39e7bUL, 0x62457f53UL, 0x2ca0fb3aUL, 0x7b70d1bcUL, 
0xb96bf71fUL, 0x121d171bUL, 0xfdc8ee79UL, 0x3af07c27UL, 
0x0cd7450aUL, 0x967960ddUL, 0x22abf633UL, 0xac891cfaUL, 
0xc85dbbacUL, 0xa1307d0bUL, 0xd44ba1beUL, 0xbe940be1UL, 
0x25540acdUL, 0x5462467eUL, 0xa28211f3UL, 0x173ea3e6UL, 
0x26e66635UL, 0xc3750258UL, 0x839b8b38UL, 0x78c2bd44UL, 
0x02dc4803UL, 0x4f8ba092UL, 0x2e7cb339UL, 0x4ee58469UL, 
0xf0718f88UL, 0x3627392dUL, 0x9c3ffdd2UL, 0x016e24fbUL, 
0x89dd1637UL, 0x00000000UL, 0xf6e0578dUL, 0xe26c9893UL, 
0x7415f84eUL, 0x935ad420UL, 0xade73801UL, 0xd3b45d40UL, 
0x1a87c217UL, 0xb32d6a10UL, 0x502fd678UL, 0xf43c1f8eUL, 
0xa7a1a50eUL, 0x71364cb3UL, 0x9aae25d7UL, 0x5e24db71UL, 
0x1650871dUL, 0xefd5f962UL, 0x8d908631UL, 0x1c161a12UL, 
0xa6cf81f5UL, 0x5b076f8cUL, 0x37491dd6UL, 0x6e923a59UL, 
0x846477c6UL, 0x86b83fc5UL, 0xd7f9cd46UL, 0xe0b0d090UL, 
0x29834fc7UL, 0xe4fd4096UL, 0x0e0b0d09UL, 0x6d2056a1UL, 
0x8e22eac9UL, 0xdb2e884cUL, 0xf78e7376UL, 0xb5bcb215UL, 
0x10c15f18UL, 0x326aa92bUL, 0x6bb18ea4UL, 0xae5554f9UL, 
0x40ee8960UL, 0x6608ef55UL, 0xe9442167UL, 0x3ebdec21UL, 
0x2077be30UL, 0xf2adc78bUL, 0x8029e7c0UL, 0x148ccf1eUL, 
0xbc4843e2UL, 0xc48afea6UL, 0x31d8c5d3UL, 0xb760fa16UL, 
0x539dba80UL, 0xd9f2c04fUL, 0x1d783ee9UL, 0x243a2e36UL, 
0xe1def46bUL, 0xcbefd754UL, 0x09f4f1f7UL, 0x82f5afc3UL, 
0x0b28b9f4UL, 0x9d51d929UL, 0xc738925eUL, 0xf8eb5a84UL, 
0x90e8b8d8UL, 0xde0d3cb1UL, 0x33048dd0UL, 0x6803e25cUL, 
0xc5e4da5dUL, 0x3b9e58dcUL, 0x0a469d0fUL, 0x3fd3c8daUL, 
0x59db278fUL, 0xa8c48cfcUL, 0x79ac99bfUL, 0x6c4e725aUL, 
0x8cfea2caUL, 0x9ee3b5d1UL, 0x1fa476eaUL, 0x73ea04b0UL, 
};

#else  /* BIG_ENDIAN */

static const word32 phi[256] = {
0x00000000UL, 0x02010103UL, 0x04020206UL, 0x06030305UL,
0x0804040cUL, 0x0a05050fUL, 0x0c06060aUL, 0x0e070709UL,
0x10080818UL, 0x1209091bUL, 0x140a0a1eUL, 0x160b0b1dUL,
0x180c0c14UL, 0x1a0d0d17UL, 0x1c0e0e12UL, 0x1e0f0f11UL,
0x20101030UL, 0x22111133UL, 0x24121236UL, 0x26131335UL,
0x2814143cUL, 0x2a15153fUL, 0x2c16163aUL, 0x2e171739UL,
0x30181828UL, 0x3219192bUL, 0x341a1a2eUL, 0x361b1b2dUL,
0x381c1c24UL, 0x3a1d1d27UL, 0x3c1e1e22UL, 0x3e1f1f21UL,
0x40202060UL, 0x42212163UL, 0x44222266UL, 0x46232365UL,
0x4824246cUL, 0x4a25256fUL, 0x4c26266aUL, 0x4e272769UL,
0x50282878UL, 0x5229297bUL, 0x542a2a7eUL, 0x562b2b7dUL,
0x582c2c74UL, 0x5a2d2d77UL, 0x5c2e2e72UL, 0x5e2f2f71UL,
0x60303050UL, 0x62313153UL, 0x64323256UL, 0x66333355UL,
0x6834345cUL, 0x6a35355fUL, 0x6c36365aUL, 0x6e373759UL,
0x70383848UL, 0x7239394bUL, 0x743a3a4eUL, 0x763b3b4dUL,
0x783c3c44UL, 0x7a3d3d47UL, 0x7c3e3e42UL, 0x7e3f3f41UL,
0x804040c0UL, 0x824141c3UL, 0x844242c6UL, 0x864343c5UL,
0x884444ccUL, 0x8a4545cfUL, 0x8c4646caUL, 0x8e4747c9UL,
0x904848d8UL, 0x924949dbUL, 0x944a4adeUL, 0x964b4bddUL,
0x984c4cd4UL, 0x9a4d4dd7UL, 0x9c4e4ed2UL, 0x9e4f4fd1UL,
0xa05050f0UL, 0xa25151f3UL, 0xa45252f6UL, 0xa65353f5UL,
0xa85454fcUL, 0xaa5555ffUL, 0xac5656faUL, 0xae5757f9UL,
0xb05858e8UL, 0xb25959ebUL, 0xb45a5aeeUL, 0xb65b5bedUL,
0xb85c5ce4UL, 0xba5d5de7UL, 0xbc5e5ee2UL, 0xbe5f5fe1UL,
0xc06060a0UL, 0xc26161a3UL, 0xc46262a6UL, 0xc66363a5UL,
0xc86464acUL, 0xca6565afUL, 0xcc6666aaUL, 0xce6767a9UL,
0xd06868b8UL, 0xd26969bbUL, 0xd46a6abeUL, 0xd66b6bbdUL,
0xd86c6cb4UL, 0xda6d6db7UL, 0xdc6e6eb2UL, 0xde6f6fb1UL,
0xe0707090UL, 0xe2717193UL, 0xe4727296UL, 0xe6737395UL,
0xe874749cUL, 0xea75759fUL, 0xec76769aUL, 0xee777799UL,
0xf0787888UL, 0xf279798bUL, 0xf47a7a8eUL, 0xf67b7b8dUL,
0xf87c7c84UL, 0xfa7d7d87UL, 0xfc7e7e82UL, 0xfe7f7f81UL,
0xf5808075UL, 0xf7818176UL, 0xf1828273UL, 0xf3838370UL,
0xfd848479UL, 0xff85857aUL, 0xf986867fUL, 0xfb87877cUL,
0xe588886dUL, 0xe789896eUL, 0xe18a8a6bUL, 0xe38b8b68UL,
0xed8c8c61UL, 0xef8d8d62UL, 0xe98e8e67UL, 0xeb8f8f64UL,
0xd5909045UL, 0xd7919146UL, 0xd1929243UL, 0xd3939340UL,
0xdd949449UL, 0xdf95954aUL, 0xd996964fUL, 0xdb97974cUL,
0xc598985dUL, 0xc799995eUL, 0xc19a9a5bUL, 0xc39b9b58UL,
0xcd9c9c51UL, 0xcf9d9d52UL, 0xc99e9e57UL, 0xcb9f9f54UL,
0xb5a0a015UL, 0xb7a1a116UL, 0xb1a2a213UL, 0xb3a3a310UL,
0xbda4a419UL, 0xbfa5a51aUL, 0xb9a6a61fUL, 0xbba7a71cUL,
0xa5a8a80dUL, 0xa7a9a90eUL, 0xa1aaaa0bUL, 0xa3abab08UL,
0xadacac01UL, 0xafadad02UL, 0xa9aeae07UL, 0xabafaf04UL,
0x95b0b025UL, 0x97b1b126UL, 0x91b2b223UL, 0x93b3b320UL,
0x9db4b429UL, 0x9fb5b52aUL, 0x99b6b62fUL, 0x9bb7b72cUL,
0x85b8b83dUL, 0x87b9b93eUL, 0x81baba3bUL, 0x83bbbb38UL,
0x8dbcbc31UL, 0x8fbdbd32UL, 0x89bebe37UL, 0x8bbfbf34UL,
0x75c0c0b5UL, 0x77c1c1b6UL, 0x71c2c2b3UL, 0x73c3c3b0UL,
0x7dc4c4b9UL, 0x7fc5c5baUL, 0x79c6c6bfUL, 0x7bc7c7bcUL,
0x65c8c8adUL, 0x67c9c9aeUL, 0x61cacaabUL, 0x63cbcba8UL,
0x6dcccca1UL, 0x6fcdcda2UL, 0x69cecea7UL, 0x6bcfcfa4UL,
0x55d0d085UL, 0x57d1d186UL, 0x51d2d283UL, 0x53d3d380UL,
0x5dd4d489UL, 0x5fd5d58aUL, 0x59d6d68fUL, 0x5bd7d78cUL,
0x45d8d89dUL, 0x47d9d99eUL, 0x41dada9bUL, 0x43dbdb98UL,
0x4ddcdc91UL, 0x4fdddd92UL, 0x49dede97UL, 0x4bdfdf94UL,
0x35e0e0d5UL, 0x37e1e1d6UL, 0x31e2e2d3UL, 0x33e3e3d0UL,
0x3de4e4d9UL, 0x3fe5e5daUL, 0x39e6e6dfUL, 0x3be7e7dcUL,
0x25e8e8cdUL, 0x27e9e9ceUL, 0x21eaeacbUL, 0x23ebebc8UL,
0x2dececc1UL, 0x2fededc2UL, 0x29eeeec7UL, 0x2befefc4UL,
0x15f0f0e5UL, 0x17f1f1e6UL, 0x11f2f2e3UL, 0x13f3f3e0UL,
0x1df4f4e9UL, 0x1ff5f5eaUL, 0x19f6f6efUL, 0x1bf7f7ecUL,
0x05f8f8fdUL, 0x07f9f9feUL, 0x01fafafbUL, 0x03fbfbf8UL,
0x0dfcfcf1UL, 0x0ffdfdf2UL, 0x09fefef7UL, 0x0bfffff4UL,
};

static const word32 offset[R] = {
0x01000000UL, 0x02000000UL, 0x04000000UL, 0x08000000UL,
0x10000000UL, 0x20000000UL, 0x40000000UL, 0x80000000UL,
};

static const word32 Te0[256] = {
0x97b1b126UL, 0x69cecea7UL, 0x73c3c3b0UL, 0xdf95954aUL, 
0xb45a5aeeUL, 0xafadad02UL, 0x3be7e7dcUL, 0x04020206UL, 
0x9a4d4dd7UL, 0x884444ccUL, 0x03fbfbf8UL, 0xd7919146UL, 
0x180c0c14UL, 0xfb87877cUL, 0xb7a1a116UL, 0xa05050f0UL, 
0x63cbcba8UL, 0xce6767a9UL, 0xa85454fcUL, 0x4fdddd92UL, 
0x8c4646caUL, 0xeb8f8f64UL, 0x37e1e1d6UL, 0x9c4e4ed2UL, 
0x15f0f0e5UL, 0x0ffdfdf2UL, 0x0dfcfcf1UL, 0x23ebebc8UL, 
0x07f9f9feUL, 0x7dc4c4b9UL, 0x341a1a2eUL, 0xdc6e6eb2UL, 
0xbc5e5ee2UL, 0x1ff5f5eaUL, 0x6dcccca1UL, 0xef8d8d62UL, 
0x381c1c24UL, 0xac5656faUL, 0x864343c5UL, 0x09fefef7UL, 
0x0e070709UL, 0xc26161a3UL, 0x05f8f8fdUL, 0xea75759fUL, 
0xb25959ebUL, 0x0bfffff4UL, 0x06030305UL, 0x44222266UL, 
0xe18a8a6bUL, 0x57d1d186UL, 0x26131335UL, 0x29eeeec7UL, 
0xe588886dUL, 0x00000000UL, 0x1c0e0e12UL, 0x6834345cUL, 
0x2a15153fUL, 0xf5808075UL, 0xdd949449UL, 0x33e3e3d0UL, 
0x2fededc2UL, 0x9fb5b52aUL, 0xa65353f5UL, 0x46232365UL, 
0x964b4bddUL, 0x8e4747c9UL, 0x2e171739UL, 0xbba7a71cUL, 
0xd5909045UL, 0x6a35355fUL, 0xa3abab08UL, 0x45d8d89dUL, 
0x85b8b83dUL, 0x4bdfdf94UL, 0x9e4f4fd1UL, 0xae5757f9UL, 
0xc19a9a5bUL, 0xd1929243UL, 0x43dbdb98UL, 0x361b1b2dUL, 
0x783c3c44UL, 0x65c8c8adUL, 0xc799995eUL, 0x0804040cUL, 
0xe98e8e67UL, 0x35e0e0d5UL, 0x5bd7d78cUL, 0xfa7d7d87UL, 
0xff85857aUL, 0x83bbbb38UL, 0x804040c0UL, 0x582c2c74UL, 
0x743a3a4eUL, 0x8a4545cfUL, 0x17f1f1e6UL, 0x844242c6UL, 
0xca6565afUL, 0x40202060UL, 0x824141c3UL, 0x30181828UL, 
0xe4727296UL, 0x4a25256fUL, 0xd3939340UL, 0xe0707090UL, 
0x6c36365aUL, 0x0a05050fUL, 0x11f2f2e3UL, 0x160b0b1dUL, 
0xb3a3a310UL, 0xf279798bUL, 0x2dececc1UL, 0x10080818UL, 
0x4e272769UL, 0x62313153UL, 0x64323256UL, 0x99b6b62fUL, 
0xf87c7c84UL, 0x95b0b025UL, 0x140a0a1eUL, 0xe6737395UL, 
0xb65b5bedUL, 0xf67b7b8dUL, 0x9bb7b72cUL, 0xf7818176UL, 
0x51d2d283UL, 0x1a0d0d17UL, 0xd46a6abeUL, 0x4c26266aUL, 
0xc99e9e57UL, 0xb05858e8UL, 0xcd9c9c51UL, 0xf3838370UL, 
0xe874749cUL, 0x93b3b320UL, 0xadacac01UL, 0x60303050UL, 
0xf47a7a8eUL, 0xd26969bbUL, 0xee777799UL, 0x1e0f0f11UL, 
0xa9aeae07UL, 0x42212163UL, 0x49dede97UL, 0x55d0d085UL, 
0x5c2e2e72UL, 0xdb97974cUL, 0x20101030UL, 0xbda4a419UL, 
0xc598985dUL, 0xa5a8a80dUL, 0x5dd4d489UL, 0xd06868b8UL, 
0x5a2d2d77UL, 0xc46262a6UL, 0x5229297bUL, 0xda6d6db7UL, 
0x2c16163aUL, 0x924949dbUL, 0xec76769aUL, 0x7bc7c7bcUL, 
0x25e8e8cdUL, 0x77c1c1b6UL, 0xd996964fUL, 0x6e373759UL, 
0x3fe5e5daUL, 0x61cacaabUL, 0x1df4f4e9UL, 0x27e9e9ceUL, 
0xc66363a5UL, 0x24121236UL, 0x71c2c2b3UL, 0xb9a6a61fUL, 
0x2814143cUL, 0x8dbcbc31UL, 0x53d3d380UL, 0x50282878UL, 
0xabafaf04UL, 0x5e2f2f71UL, 0x39e6e6dfUL, 0x4824246cUL, 
0xa45252f6UL, 0x79c6c6bfUL, 0xb5a0a015UL, 0x1209091bUL, 
0x8fbdbd32UL, 0xed8c8c61UL, 0x6bcfcfa4UL, 0xba5d5de7UL, 
0x22111133UL, 0xbe5f5fe1UL, 0x02010103UL, 0x7fc5c5baUL, 
0xcb9f9f54UL, 0x7a3d3d47UL, 0xb1a2a213UL, 0xc39b9b58UL, 
0x67c9c9aeUL, 0x763b3b4dUL, 0x89bebe37UL, 0xa25151f3UL, 
0x3219192bUL, 0x3e1f1f21UL, 0x7e3f3f41UL, 0xb85c5ce4UL, 
0x91b2b223UL, 0x2befefc4UL, 0x944a4adeUL, 0x6fcdcda2UL, 
0x8bbfbf34UL, 0x81baba3bUL, 0xde6f6fb1UL, 0xc86464acUL, 
0x47d9d99eUL, 0x13f3f3e0UL, 0x7c3e3e42UL, 0x9db4b429UL, 
0xa1aaaa0bUL, 0x4ddcdc91UL, 0x5fd5d58aUL, 0x0c06060aUL, 
0x75c0c0b5UL, 0xfc7e7e82UL, 0x19f6f6efUL, 0xcc6666aaUL, 
0xd86c6cb4UL, 0xfd848479UL, 0xe2717193UL, 0x70383848UL, 
0x87b9b93eUL, 0x3a1d1d27UL, 0xfe7f7f81UL, 0xcf9d9d52UL, 
0x904848d8UL, 0xe38b8b68UL, 0x542a2a7eUL, 0x41dada9bUL, 
0xbfa5a51aUL, 0x66333355UL, 0xf1828273UL, 0x7239394bUL, 
0x59d6d68fUL, 0xf0787888UL, 0xf986867fUL, 0x01fafafbUL, 
0x3de4e4d9UL, 0x562b2b7dUL, 0xa7a9a90eUL, 0x3c1e1e22UL, 
0xe789896eUL, 0xc06060a0UL, 0xd66b6bbdUL, 0x21eaeacbUL, 
0xaa5555ffUL, 0x984c4cd4UL, 0x1bf7f7ecUL, 0x31e2e2d3UL, 
};

static const word32 Te1[256] = {
0x2697b1b1UL, 0xa769ceceUL, 0xb073c3c3UL, 0x4adf9595UL, 
0xeeb45a5aUL, 0x02afadadUL, 0xdc3be7e7UL, 0x06040202UL, 
0xd79a4d4dUL, 0xcc884444UL, 0xf803fbfbUL, 0x46d79191UL, 
0x14180c0cUL, 0x7cfb8787UL, 0x16b7a1a1UL, 0xf0a05050UL, 
0xa863cbcbUL, 0xa9ce6767UL, 0xfca85454UL, 0x924fddddUL, 
0xca8c4646UL, 0x64eb8f8fUL, 0xd637e1e1UL, 0xd29c4e4eUL, 
0xe515f0f0UL, 0xf20ffdfdUL, 0xf10dfcfcUL, 0xc823ebebUL, 
0xfe07f9f9UL, 0xb97dc4c4UL, 0x2e341a1aUL, 0xb2dc6e6eUL, 
0xe2bc5e5eUL, 0xea1ff5f5UL, 0xa16dccccUL, 0x62ef8d8dUL, 
0x24381c1cUL, 0xfaac5656UL, 0xc5864343UL, 0xf709fefeUL, 
0x090e0707UL, 0xa3c26161UL, 0xfd05f8f8UL, 0x9fea7575UL, 
0xebb25959UL, 0xf40bffffUL, 0x05060303UL, 0x66442222UL, 
0x6be18a8aUL, 0x8657d1d1UL, 0x35261313UL, 0xc729eeeeUL, 
0x6de58888UL, 0x00000000UL, 0x121c0e0eUL, 0x5c683434UL, 
0x3f2a1515UL, 0x75f58080UL, 0x49dd9494UL, 0xd033e3e3UL, 
0xc22fededUL, 0x2a9fb5b5UL, 0xf5a65353UL, 0x65462323UL, 
0xdd964b4bUL, 0xc98e4747UL, 0x392e1717UL, 0x1cbba7a7UL, 
0x45d59090UL, 0x5f6a3535UL, 0x08a3ababUL, 0x9d45d8d8UL, 
0x3d85b8b8UL, 0x944bdfdfUL, 0xd19e4f4fUL, 0xf9ae5757UL, 
0x5bc19a9aUL, 0x43d19292UL, 0x9843dbdbUL, 0x2d361b1bUL, 
0x44783c3cUL, 0xad65c8c8UL, 0x5ec79999UL, 0x0c080404UL, 
0x67e98e8eUL, 0xd535e0e0UL, 0x8c5bd7d7UL, 0x87fa7d7dUL, 
0x7aff8585UL, 0x3883bbbbUL, 0xc0804040UL, 0x74582c2cUL, 
0x4e743a3aUL, 0xcf8a4545UL, 0xe617f1f1UL, 0xc6844242UL, 
0xafca6565UL, 0x60402020UL, 0xc3824141UL, 0x28301818UL, 
0x96e47272UL, 0x6f4a2525UL, 0x40d39393UL, 0x90e07070UL, 
0x5a6c3636UL, 0x0f0a0505UL, 0xe311f2f2UL, 0x1d160b0bUL, 
0x10b3a3a3UL, 0x8bf27979UL, 0xc12dececUL, 0x18100808UL, 
0x694e2727UL, 0x53623131UL, 0x56643232UL, 0x2f99b6b6UL, 
0x84f87c7cUL, 0x2595b0b0UL, 0x1e140a0aUL, 0x95e67373UL, 
0xedb65b5bUL, 0x8df67b7bUL, 0x2c9bb7b7UL, 0x76f78181UL, 
0x8351d2d2UL, 0x171a0d0dUL, 0xbed46a6aUL, 0x6a4c2626UL, 
0x57c99e9eUL, 0xe8b05858UL, 0x51cd9c9cUL, 0x70f38383UL, 
0x9ce87474UL, 0x2093b3b3UL, 0x01adacacUL, 0x50603030UL, 
0x8ef47a7aUL, 0xbbd26969UL, 0x99ee7777UL, 0x111e0f0fUL, 
0x07a9aeaeUL, 0x63422121UL, 0x9749dedeUL, 0x8555d0d0UL, 
0x725c2e2eUL, 0x4cdb9797UL, 0x30201010UL, 0x19bda4a4UL, 
0x5dc59898UL, 0x0da5a8a8UL, 0x895dd4d4UL, 0xb8d06868UL, 
0x775a2d2dUL, 0xa6c46262UL, 0x7b522929UL, 0xb7da6d6dUL, 
0x3a2c1616UL, 0xdb924949UL, 0x9aec7676UL, 0xbc7bc7c7UL, 
0xcd25e8e8UL, 0xb677c1c1UL, 0x4fd99696UL, 0x596e3737UL, 
0xda3fe5e5UL, 0xab61cacaUL, 0xe91df4f4UL, 0xce27e9e9UL, 
0xa5c66363UL, 0x36241212UL, 0xb371c2c2UL, 0x1fb9a6a6UL, 
0x3c281414UL, 0x318dbcbcUL, 0x8053d3d3UL, 0x78502828UL, 
0x04abafafUL, 0x715e2f2fUL, 0xdf39e6e6UL, 0x6c482424UL, 
0xf6a45252UL, 0xbf79c6c6UL, 0x15b5a0a0UL, 0x1b120909UL, 
0x328fbdbdUL, 0x61ed8c8cUL, 0xa46bcfcfUL, 0xe7ba5d5dUL, 
0x33221111UL, 0xe1be5f5fUL, 0x03020101UL, 0xba7fc5c5UL, 
0x54cb9f9fUL, 0x477a3d3dUL, 0x13b1a2a2UL, 0x58c39b9bUL, 
0xae67c9c9UL, 0x4d763b3bUL, 0x3789bebeUL, 0xf3a25151UL, 
0x2b321919UL, 0x213e1f1fUL, 0x417e3f3fUL, 0xe4b85c5cUL, 
0x2391b2b2UL, 0xc42befefUL, 0xde944a4aUL, 0xa26fcdcdUL, 
0x348bbfbfUL, 0x3b81babaUL, 0xb1de6f6fUL, 0xacc86464UL, 
0x9e47d9d9UL, 0xe013f3f3UL, 0x427c3e3eUL, 0x299db4b4UL, 
0x0ba1aaaaUL, 0x914ddcdcUL, 0x8a5fd5d5UL, 0x0a0c0606UL, 
0xb575c0c0UL, 0x82fc7e7eUL, 0xef19f6f6UL, 0xaacc6666UL, 
0xb4d86c6cUL, 0x79fd8484UL, 0x93e27171UL, 0x48703838UL, 
0x3e87b9b9UL, 0x273a1d1dUL, 0x81fe7f7fUL, 0x52cf9d9dUL, 
0xd8904848UL, 0x68e38b8bUL, 0x7e542a2aUL, 0x9b41dadaUL, 
0x1abfa5a5UL, 0x55663333UL, 0x73f18282UL, 0x4b723939UL, 
0x8f59d6d6UL, 0x88f07878UL, 0x7ff98686UL, 0xfb01fafaUL, 
0xd93de4e4UL, 0x7d562b2bUL, 0x0ea7a9a9UL, 0x223c1e1eUL, 
0x6ee78989UL, 0xa0c06060UL, 0xbdd66b6bUL, 0xcb21eaeaUL, 
0xffaa5555UL, 0xd4984c4cUL, 0xec1bf7f7UL, 0xd331e2e2UL, 
};

static const word32 Te2[256] = {
0xb12697b1UL, 0xcea769ceUL, 0xc3b073c3UL, 0x954adf95UL, 
0x5aeeb45aUL, 0xad02afadUL, 0xe7dc3be7UL, 0x02060402UL, 
0x4dd79a4dUL, 0x44cc8844UL, 0xfbf803fbUL, 0x9146d791UL, 
0x0c14180cUL, 0x877cfb87UL, 0xa116b7a1UL, 0x50f0a050UL, 
0xcba863cbUL, 0x67a9ce67UL, 0x54fca854UL, 0xdd924fddUL, 
0x46ca8c46UL, 0x8f64eb8fUL, 0xe1d637e1UL, 0x4ed29c4eUL, 
0xf0e515f0UL, 0xfdf20ffdUL, 0xfcf10dfcUL, 0xebc823ebUL, 
0xf9fe07f9UL, 0xc4b97dc4UL, 0x1a2e341aUL, 0x6eb2dc6eUL, 
0x5ee2bc5eUL, 0xf5ea1ff5UL, 0xcca16dccUL, 0x8d62ef8dUL, 
0x1c24381cUL, 0x56faac56UL, 0x43c58643UL, 0xfef709feUL, 
0x07090e07UL, 0x61a3c261UL, 0xf8fd05f8UL, 0x759fea75UL, 
0x59ebb259UL, 0xfff40bffUL, 0x03050603UL, 0x22664422UL, 
0x8a6be18aUL, 0xd18657d1UL, 0x13352613UL, 0xeec729eeUL, 
0x886de588UL, 0x00000000UL, 0x0e121c0eUL, 0x345c6834UL, 
0x153f2a15UL, 0x8075f580UL, 0x9449dd94UL, 0xe3d033e3UL, 
0xedc22fedUL, 0xb52a9fb5UL, 0x53f5a653UL, 0x23654623UL, 
0x4bdd964bUL, 0x47c98e47UL, 0x17392e17UL, 0xa71cbba7UL, 
0x9045d590UL, 0x355f6a35UL, 0xab08a3abUL, 0xd89d45d8UL, 
0xb83d85b8UL, 0xdf944bdfUL, 0x4fd19e4fUL, 0x57f9ae57UL, 
0x9a5bc19aUL, 0x9243d192UL, 0xdb9843dbUL, 0x1b2d361bUL, 
0x3c44783cUL, 0xc8ad65c8UL, 0x995ec799UL, 0x040c0804UL, 
0x8e67e98eUL, 0xe0d535e0UL, 0xd78c5bd7UL, 0x7d87fa7dUL, 
0x857aff85UL, 0xbb3883bbUL, 0x40c08040UL, 0x2c74582cUL, 
0x3a4e743aUL, 0x45cf8a45UL, 0xf1e617f1UL, 0x42c68442UL, 
0x65afca65UL, 0x20604020UL, 0x41c38241UL, 0x18283018UL, 
0x7296e472UL, 0x256f4a25UL, 0x9340d393UL, 0x7090e070UL, 
0x365a6c36UL, 0x050f0a05UL, 0xf2e311f2UL, 0x0b1d160bUL, 
0xa310b3a3UL, 0x798bf279UL, 0xecc12decUL, 0x08181008UL, 
0x27694e27UL, 0x31536231UL, 0x32566432UL, 0xb62f99b6UL, 
0x7c84f87cUL, 0xb02595b0UL, 0x0a1e140aUL, 0x7395e673UL, 
0x5bedb65bUL, 0x7b8df67bUL, 0xb72c9bb7UL, 0x8176f781UL, 
0xd28351d2UL, 0x0d171a0dUL, 0x6abed46aUL, 0x266a4c26UL, 
0x9e57c99eUL, 0x58e8b058UL, 0x9c51cd9cUL, 0x8370f383UL, 
0x749ce874UL, 0xb32093b3UL, 0xac01adacUL, 0x30506030UL, 
0x7a8ef47aUL, 0x69bbd269UL, 0x7799ee77UL, 0x0f111e0fUL, 
0xae07a9aeUL, 0x21634221UL, 0xde9749deUL, 0xd08555d0UL, 
0x2e725c2eUL, 0x974cdb97UL, 0x10302010UL, 0xa419bda4UL, 
0x985dc598UL, 0xa80da5a8UL, 0xd4895dd4UL, 0x68b8d068UL, 
0x2d775a2dUL, 0x62a6c462UL, 0x297b5229UL, 0x6db7da6dUL, 
0x163a2c16UL, 0x49db9249UL, 0x769aec76UL, 0xc7bc7bc7UL, 
0xe8cd25e8UL, 0xc1b677c1UL, 0x964fd996UL, 0x37596e37UL, 
0xe5da3fe5UL, 0xcaab61caUL, 0xf4e91df4UL, 0xe9ce27e9UL, 
0x63a5c663UL, 0x12362412UL, 0xc2b371c2UL, 0xa61fb9a6UL, 
0x143c2814UL, 0xbc318dbcUL, 0xd38053d3UL, 0x28785028UL, 
0xaf04abafUL, 0x2f715e2fUL, 0xe6df39e6UL, 0x246c4824UL, 
0x52f6a452UL, 0xc6bf79c6UL, 0xa015b5a0UL, 0x091b1209UL, 
0xbd328fbdUL, 0x8c61ed8cUL, 0xcfa46bcfUL, 0x5de7ba5dUL, 
0x11332211UL, 0x5fe1be5fUL, 0x01030201UL, 0xc5ba7fc5UL, 
0x9f54cb9fUL, 0x3d477a3dUL, 0xa213b1a2UL, 0x9b58c39bUL, 
0xc9ae67c9UL, 0x3b4d763bUL, 0xbe3789beUL, 0x51f3a251UL, 
0x192b3219UL, 0x1f213e1fUL, 0x3f417e3fUL, 0x5ce4b85cUL, 
0xb22391b2UL, 0xefc42befUL, 0x4ade944aUL, 0xcda26fcdUL, 
0xbf348bbfUL, 0xba3b81baUL, 0x6fb1de6fUL, 0x64acc864UL, 
0xd99e47d9UL, 0xf3e013f3UL, 0x3e427c3eUL, 0xb4299db4UL, 
0xaa0ba1aaUL, 0xdc914ddcUL, 0xd58a5fd5UL, 0x060a0c06UL, 
0xc0b575c0UL, 0x7e82fc7eUL, 0xf6ef19f6UL, 0x66aacc66UL, 
0x6cb4d86cUL, 0x8479fd84UL, 0x7193e271UL, 0x38487038UL, 
0xb93e87b9UL, 0x1d273a1dUL, 0x7f81fe7fUL, 0x9d52cf9dUL, 
0x48d89048UL, 0x8b68e38bUL, 0x2a7e542aUL, 0xda9b41daUL, 
0xa51abfa5UL, 0x33556633UL, 0x8273f182UL, 0x394b7239UL, 
0xd68f59d6UL, 0x7888f078UL, 0x867ff986UL, 0xfafb01faUL, 
0xe4d93de4UL, 0x2b7d562bUL, 0xa90ea7a9UL, 0x1e223c1eUL, 
0x896ee789UL, 0x60a0c060UL, 0x6bbdd66bUL, 0xeacb21eaUL, 
0x55ffaa55UL, 0x4cd4984cUL, 0xf7ec1bf7UL, 0xe2d331e2UL, 
};

static const word32 Te3[256] = {
0xb1b12697UL, 0xcecea769UL, 0xc3c3b073UL, 0x95954adfUL, 
0x5a5aeeb4UL, 0xadad02afUL, 0xe7e7dc3bUL, 0x02020604UL, 
0x4d4dd79aUL, 0x4444cc88UL, 0xfbfbf803UL, 0x919146d7UL, 
0x0c0c1418UL, 0x87877cfbUL, 0xa1a116b7UL, 0x5050f0a0UL, 
0xcbcba863UL, 0x6767a9ceUL, 0x5454fca8UL, 0xdddd924fUL, 
0x4646ca8cUL, 0x8f8f64ebUL, 0xe1e1d637UL, 0x4e4ed29cUL, 
0xf0f0e515UL, 0xfdfdf20fUL, 0xfcfcf10dUL, 0xebebc823UL, 
0xf9f9fe07UL, 0xc4c4b97dUL, 0x1a1a2e34UL, 0x6e6eb2dcUL, 
0x5e5ee2bcUL, 0xf5f5ea1fUL, 0xcccca16dUL, 0x8d8d62efUL, 
0x1c1c2438UL, 0x5656faacUL, 0x4343c586UL, 0xfefef709UL, 
0x0707090eUL, 0x6161a3c2UL, 0xf8f8fd05UL, 0x75759feaUL, 
0x5959ebb2UL, 0xfffff40bUL, 0x03030506UL, 0x22226644UL, 
0x8a8a6be1UL, 0xd1d18657UL, 0x13133526UL, 0xeeeec729UL, 
0x88886de5UL, 0x00000000UL, 0x0e0e121cUL, 0x34345c68UL, 
0x15153f2aUL, 0x808075f5UL, 0x949449ddUL, 0xe3e3d033UL, 
0xededc22fUL, 0xb5b52a9fUL, 0x5353f5a6UL, 0x23236546UL, 
0x4b4bdd96UL, 0x4747c98eUL, 0x1717392eUL, 0xa7a71cbbUL, 
0x909045d5UL, 0x35355f6aUL, 0xabab08a3UL, 0xd8d89d45UL, 
0xb8b83d85UL, 0xdfdf944bUL, 0x4f4fd19eUL, 0x5757f9aeUL, 
0x9a9a5bc1UL, 0x929243d1UL, 0xdbdb9843UL, 0x1b1b2d36UL, 
0x3c3c4478UL, 0xc8c8ad65UL, 0x99995ec7UL, 0x04040c08UL, 
0x8e8e67e9UL, 0xe0e0d535UL, 0xd7d78c5bUL, 0x7d7d87faUL, 
0x85857affUL, 0xbbbb3883UL, 0x4040c080UL, 0x2c2c7458UL, 
0x3a3a4e74UL, 0x4545cf8aUL, 0xf1f1e617UL, 0x4242c684UL, 
0x6565afcaUL, 0x20206040UL, 0x4141c382UL, 0x18182830UL, 
0x727296e4UL, 0x25256f4aUL, 0x939340d3UL, 0x707090e0UL, 
0x36365a6cUL, 0x05050f0aUL, 0xf2f2e311UL, 0x0b0b1d16UL, 
0xa3a310b3UL, 0x79798bf2UL, 0xececc12dUL, 0x08081810UL, 
0x2727694eUL, 0x31315362UL, 0x32325664UL, 0xb6b62f99UL, 
0x7c7c84f8UL, 0xb0b02595UL, 0x0a0a1e14UL, 0x737395e6UL, 
0x5b5bedb6UL, 0x7b7b8df6UL, 0xb7b72c9bUL, 0x818176f7UL, 
0xd2d28351UL, 0x0d0d171aUL, 0x6a6abed4UL, 0x26266a4cUL, 
0x9e9e57c9UL, 0x5858e8b0UL, 0x9c9c51cdUL, 0x838370f3UL, 
0x74749ce8UL, 0xb3b32093UL, 0xacac01adUL, 0x30305060UL, 
0x7a7a8ef4UL, 0x6969bbd2UL, 0x777799eeUL, 0x0f0f111eUL, 
0xaeae07a9UL, 0x21216342UL, 0xdede9749UL, 0xd0d08555UL, 
0x2e2e725cUL, 0x97974cdbUL, 0x10103020UL, 0xa4a419bdUL, 
0x98985dc5UL, 0xa8a80da5UL, 0xd4d4895dUL, 0x6868b8d0UL, 
0x2d2d775aUL, 0x6262a6c4UL, 0x29297b52UL, 0x6d6db7daUL, 
0x16163a2cUL, 0x4949db92UL, 0x76769aecUL, 0xc7c7bc7bUL, 
0xe8e8cd25UL, 0xc1c1b677UL, 0x96964fd9UL, 0x3737596eUL, 
0xe5e5da3fUL, 0xcacaab61UL, 0xf4f4e91dUL, 0xe9e9ce27UL, 
0x6363a5c6UL, 0x12123624UL, 0xc2c2b371UL, 0xa6a61fb9UL, 
0x14143c28UL, 0xbcbc318dUL, 0xd3d38053UL, 0x28287850UL, 
0xafaf04abUL, 0x2f2f715eUL, 0xe6e6df39UL, 0x24246c48UL, 
0x5252f6a4UL, 0xc6c6bf79UL, 0xa0a015b5UL, 0x09091b12UL, 
0xbdbd328fUL, 0x8c8c61edUL, 0xcfcfa46bUL, 0x5d5de7baUL, 
0x11113322UL, 0x5f5fe1beUL, 0x01010302UL, 0xc5c5ba7fUL, 
0x9f9f54cbUL, 0x3d3d477aUL, 0xa2a213b1UL, 0x9b9b58c3UL, 
0xc9c9ae67UL, 0x3b3b4d76UL, 0xbebe3789UL, 0x5151f3a2UL, 
0x19192b32UL, 0x1f1f213eUL, 0x3f3f417eUL, 0x5c5ce4b8UL, 
0xb2b22391UL, 0xefefc42bUL, 0x4a4ade94UL, 0xcdcda26fUL, 
0xbfbf348bUL, 0xbaba3b81UL, 0x6f6fb1deUL, 0x6464acc8UL, 
0xd9d99e47UL, 0xf3f3e013UL, 0x3e3e427cUL, 0xb4b4299dUL, 
0xaaaa0ba1UL, 0xdcdc914dUL, 0xd5d58a5fUL, 0x06060a0cUL, 
0xc0c0b575UL, 0x7e7e82fcUL, 0xf6f6ef19UL, 0x6666aaccUL, 
0x6c6cb4d8UL, 0x848479fdUL, 0x717193e2UL, 0x38384870UL, 
0xb9b93e87UL, 0x1d1d273aUL, 0x7f7f81feUL, 0x9d9d52cfUL, 
0x4848d890UL, 0x8b8b68e3UL, 0x2a2a7e54UL, 0xdada9b41UL, 
0xa5a51abfUL, 0x33335566UL, 0x828273f1UL, 0x39394b72UL, 
0xd6d68f59UL, 0x787888f0UL, 0x86867ff9UL, 0xfafafb01UL, 
0xe4e4d93dUL, 0x2b2b7d56UL, 0xa9a90ea7UL, 0x1e1e223cUL, 
0x89896ee7UL, 0x6060a0c0UL, 0x6b6bbdd6UL, 0xeaeacb21UL, 
0x5555ffaaUL, 0x4c4cd498UL, 0xf7f7ec1bUL, 0xe2e2d331UL, 
};

static const word32 Td0[256] = {
0xe368bc02UL, 0x5585620cUL, 0x2a3f2331UL, 0x61ab13f7UL, 
0x98d46d72UL, 0x21cb9a19UL, 0x3c22a461UL, 0x459d3dcdUL, 
0x05fdb423UL, 0x2bc4075fUL, 0x9b2c01c0UL, 0x3dd9800fUL, 
0x486c5c74UL, 0xf97f7e85UL, 0xf173ab1fUL, 0xb6edde0eUL, 
0x283c6bedUL, 0x4997781aUL, 0x9f2a918dUL, 0xc9579f33UL, 
0xa907a8aaUL, 0xa50ded7dUL, 0x7c422d8fUL, 0x764db0c9UL, 
0x4d91e857UL, 0xcea963ccUL, 0xb4ee96d2UL, 0x3028e1b6UL, 
0x0df161b9UL, 0xbd196726UL, 0x419bad80UL, 0xc0a06ec7UL, 
0x5183f241UL, 0x92dbf034UL, 0x6fa21efcUL, 0x8f32ce4cUL, 
0x13e03373UL, 0x69a7c66dUL, 0xe56d6493UL, 0xbf1a2ffaUL, 
0xbb1cbfb7UL, 0x587403b5UL, 0xe76e2c4fUL, 0x5d89b796UL, 
0xe89c052aUL, 0x446619a3UL, 0x342e71fbUL, 0x0ff22965UL, 
0xfe81827aUL, 0xb11322f1UL, 0xa30835ecUL, 0xcd510f7eUL, 
0xff7aa614UL, 0x5c7293f8UL, 0x2fc29712UL, 0xf370e3c3UL, 
0x992f491cUL, 0xd1431568UL, 0xc2a3261bUL, 0x88cc32b3UL, 
0x8acf7a6fUL, 0xb0e8069fUL, 0x7a47f51eUL, 0xd2bb79daUL, 
0xe6950821UL, 0x4398e55cUL, 0xd0b83106UL, 0x11e37bafUL, 
0x7e416553UL, 0xccaa2b10UL, 0xd8b4e49cUL, 0x6456a7d4UL, 
0xfb7c3659UL, 0x724b2084UL, 0xea9f4df6UL, 0x6a5faadfUL, 
0x2dc1dfceUL, 0x70486858UL, 0xcaaff381UL, 0x0605d891UL, 
0x5a774b69UL, 0x94de28a5UL, 0x39df1042UL, 0x813bc347UL, 
0xfc82caa6UL, 0x23c8d2c5UL, 0x03f86cb2UL, 0x080cd59aUL, 
0xdab7ac40UL, 0x7db909e1UL, 0x3824342cUL, 0xcf5247a2UL, 
0xdcb274d1UL, 0x63a85b2bUL, 0x35d55595UL, 0x479e7511UL, 
0x15e5ebe2UL, 0x4b9430c6UL, 0x4a6f14a8UL, 0x91239c86UL, 
0x4c6acc39UL, 0x5f8aff4aUL, 0x0406904dUL, 0xee99ddbbUL, 
0x1e1152caUL, 0xaaffc418UL, 0xeb646998UL, 0x07fefcffUL, 
0x8b345e01UL, 0x567d0ebeUL, 0xbae79bd9UL, 0x4263c132UL, 
0x75b5dc7bUL, 0x97264417UL, 0x67aecb66UL, 0x95250ccbUL, 
0xec9a9567UL, 0x57862ad0UL, 0x60503799UL, 0xb8e4d305UL, 
0x65ad83baUL, 0x19efae35UL, 0xa4f6c913UL, 0xc15b4aa9UL, 
0x873e1bd6UL, 0xa0f0595eUL, 0x18148a5bUL, 0xaf02703bUL, 
0xab04e076UL, 0xdd4950bfUL, 0xdf4a1863UL, 0xc6a5b656UL, 
0x853d530aUL, 0xfa871237UL, 0x77b694a7UL, 0x4665517fUL, 
0xed61b109UL, 0x1bece6e9UL, 0xd5458525UL, 0xf5753b52UL, 
0x7fba413dUL, 0x27ce4288UL, 0xb2eb4e43UL, 0xd6bde997UL, 
0x527b9ef3UL, 0x62537f45UL, 0x2c3afba0UL, 0x7bbcd170UL, 
0xb91ff76bUL, 0x121b171dUL, 0xfd79eec8UL, 0x3a277cf0UL, 
0x0c0a45d7UL, 0x96dd6079UL, 0x2233f6abUL, 0xacfa1c89UL, 
0xc8acbb5dUL, 0xa10b7d30UL, 0xd4bea14bUL, 0xbee10b94UL, 
0x25cd0a54UL, 0x547e4662UL, 0xa2f31182UL, 0x17e6a33eUL, 
0x263566e6UL, 0xc3580275UL, 0x83388b9bUL, 0x7844bdc2UL, 
0x020348dcUL, 0x4f92a08bUL, 0x2e39b37cUL, 0x4e6984e5UL, 
0xf0888f71UL, 0x362d3927UL, 0x9cd2fd3fUL, 0x01fb246eUL, 
0x893716ddUL, 0x00000000UL, 0xf68d57e0UL, 0xe293986cUL, 
0x744ef815UL, 0x9320d45aUL, 0xad0138e7UL, 0xd3405db4UL, 
0x1a17c287UL, 0xb3106a2dUL, 0x5078d62fUL, 0xf48e1f3cUL, 
0xa70ea5a1UL, 0x71b34c36UL, 0x9ad725aeUL, 0x5e71db24UL, 
0x161d8750UL, 0xef62f9d5UL, 0x8d318690UL, 0x1c121a16UL, 
0xa6f581cfUL, 0x5b8c6f07UL, 0x37d61d49UL, 0x6e593a92UL, 
0x84c67764UL, 0x86c53fb8UL, 0xd746cdf9UL, 0xe090d0b0UL, 
0x29c74f83UL, 0xe49640fdUL, 0x0e090d0bUL, 0x6da15620UL, 
0x8ec9ea22UL, 0xdb4c882eUL, 0xf776738eUL, 0xb515b2bcUL, 
0x10185fc1UL, 0x322ba96aUL, 0x6ba48eb1UL, 0xaef95455UL, 
0x406089eeUL, 0x6655ef08UL, 0xe9672144UL, 0x3e21ecbdUL, 
0x2030be77UL, 0xf28bc7adUL, 0x80c0e729UL, 0x141ecf8cUL, 
0xbce24348UL, 0xc4a6fe8aUL, 0x31d3c5d8UL, 0xb716fa60UL, 
0x5380ba9dUL, 0xd94fc0f2UL, 0x1de93e78UL, 0x24362e3aUL, 
0xe16bf4deUL, 0xcb54d7efUL, 0x09f7f1f4UL, 0x82c3aff5UL, 
0x0bf4b928UL, 0x9d29d951UL, 0xc75e9238UL, 0xf8845aebUL, 
0x90d8b8e8UL, 0xdeb13c0dUL, 0x33d08d04UL, 0x685ce203UL, 
0xc55ddae4UL, 0x3bdc589eUL, 0x0a0f9d46UL, 0x3fdac8d3UL, 
0x598f27dbUL, 0xa8fc8cc4UL, 0x79bf99acUL, 0x6c5a724eUL, 
0x8ccaa2feUL, 0x9ed1b5e3UL, 0x1fea76a4UL, 0x73b004eaUL, 
};

static const word32 Td1[256] = {
0x02e368bcUL, 0x0c558562UL, 0x312a3f23UL, 0xf761ab13UL, 
0x7298d46dUL, 0x1921cb9aUL, 0x613c22a4UL, 0xcd459d3dUL, 
0x2305fdb4UL, 0x5f2bc407UL, 0xc09b2c01UL, 0x0f3dd980UL, 
0x74486c5cUL, 0x85f97f7eUL, 0x1ff173abUL, 0x0eb6eddeUL, 
0xed283c6bUL, 0x1a499778UL, 0x8d9f2a91UL, 0x33c9579fUL, 
0xaaa907a8UL, 0x7da50dedUL, 0x8f7c422dUL, 0xc9764db0UL, 
0x574d91e8UL, 0xcccea963UL, 0xd2b4ee96UL, 0xb63028e1UL, 
0xb90df161UL, 0x26bd1967UL, 0x80419badUL, 0xc7c0a06eUL, 
0x415183f2UL, 0x3492dbf0UL, 0xfc6fa21eUL, 0x4c8f32ceUL, 
0x7313e033UL, 0x6d69a7c6UL, 0x93e56d64UL, 0xfabf1a2fUL, 
0xb7bb1cbfUL, 0xb5587403UL, 0x4fe76e2cUL, 0x965d89b7UL, 
0x2ae89c05UL, 0xa3446619UL, 0xfb342e71UL, 0x650ff229UL, 
0x7afe8182UL, 0xf1b11322UL, 0xeca30835UL, 0x7ecd510fUL, 
0x14ff7aa6UL, 0xf85c7293UL, 0x122fc297UL, 0xc3f370e3UL, 
0x1c992f49UL, 0x68d14315UL, 0x1bc2a326UL, 0xb388cc32UL, 
0x6f8acf7aUL, 0x9fb0e806UL, 0x1e7a47f5UL, 0xdad2bb79UL, 
0x21e69508UL, 0x5c4398e5UL, 0x06d0b831UL, 0xaf11e37bUL, 
0x537e4165UL, 0x10ccaa2bUL, 0x9cd8b4e4UL, 0xd46456a7UL, 
0x59fb7c36UL, 0x84724b20UL, 0xf6ea9f4dUL, 0xdf6a5faaUL, 
0xce2dc1dfUL, 0x58704868UL, 0x81caaff3UL, 0x910605d8UL, 
0x695a774bUL, 0xa594de28UL, 0x4239df10UL, 0x47813bc3UL, 
0xa6fc82caUL, 0xc523c8d2UL, 0xb203f86cUL, 0x9a080cd5UL, 
0x40dab7acUL, 0xe17db909UL, 0x2c382434UL, 0xa2cf5247UL, 
0xd1dcb274UL, 0x2b63a85bUL, 0x9535d555UL, 0x11479e75UL, 
0xe215e5ebUL, 0xc64b9430UL, 0xa84a6f14UL, 0x8691239cUL, 
0x394c6accUL, 0x4a5f8affUL, 0x4d040690UL, 0xbbee99ddUL, 
0xca1e1152UL, 0x18aaffc4UL, 0x98eb6469UL, 0xff07fefcUL, 
0x018b345eUL, 0xbe567d0eUL, 0xd9bae79bUL, 0x324263c1UL, 
0x7b75b5dcUL, 0x17972644UL, 0x6667aecbUL, 0xcb95250cUL, 
0x67ec9a95UL, 0xd057862aUL, 0x99605037UL, 0x05b8e4d3UL, 
0xba65ad83UL, 0x3519efaeUL, 0x13a4f6c9UL, 0xa9c15b4aUL, 
0xd6873e1bUL, 0x5ea0f059UL, 0x5b18148aUL, 0x3baf0270UL, 
0x76ab04e0UL, 0xbfdd4950UL, 0x63df4a18UL, 0x56c6a5b6UL, 
0x0a853d53UL, 0x37fa8712UL, 0xa777b694UL, 0x7f466551UL, 
0x09ed61b1UL, 0xe91bece6UL, 0x25d54585UL, 0x52f5753bUL, 
0x3d7fba41UL, 0x8827ce42UL, 0x43b2eb4eUL, 0x97d6bde9UL, 
0xf3527b9eUL, 0x4562537fUL, 0xa02c3afbUL, 0x707bbcd1UL, 
0x6bb91ff7UL, 0x1d121b17UL, 0xc8fd79eeUL, 0xf03a277cUL, 
0xd70c0a45UL, 0x7996dd60UL, 0xab2233f6UL, 0x89acfa1cUL, 
0x5dc8acbbUL, 0x30a10b7dUL, 0x4bd4bea1UL, 0x94bee10bUL, 
0x5425cd0aUL, 0x62547e46UL, 0x82a2f311UL, 0x3e17e6a3UL, 
0xe6263566UL, 0x75c35802UL, 0x9b83388bUL, 0xc27844bdUL, 
0xdc020348UL, 0x8b4f92a0UL, 0x7c2e39b3UL, 0xe54e6984UL, 
0x71f0888fUL, 0x27362d39UL, 0x3f9cd2fdUL, 0x6e01fb24UL, 
0xdd893716UL, 0x00000000UL, 0xe0f68d57UL, 0x6ce29398UL, 
0x15744ef8UL, 0x5a9320d4UL, 0xe7ad0138UL, 0xb4d3405dUL, 
0x871a17c2UL, 0x2db3106aUL, 0x2f5078d6UL, 0x3cf48e1fUL, 
0xa1a70ea5UL, 0x3671b34cUL, 0xae9ad725UL, 0x245e71dbUL, 
0x50161d87UL, 0xd5ef62f9UL, 0x908d3186UL, 0x161c121aUL, 
0xcfa6f581UL, 0x075b8c6fUL, 0x4937d61dUL, 0x926e593aUL, 
0x6484c677UL, 0xb886c53fUL, 0xf9d746cdUL, 0xb0e090d0UL, 
0x8329c74fUL, 0xfde49640UL, 0x0b0e090dUL, 0x206da156UL, 
0x228ec9eaUL, 0x2edb4c88UL, 0x8ef77673UL, 0xbcb515b2UL, 
0xc110185fUL, 0x6a322ba9UL, 0xb16ba48eUL, 0x55aef954UL, 
0xee406089UL, 0x086655efUL, 0x44e96721UL, 0xbd3e21ecUL, 
0x772030beUL, 0xadf28bc7UL, 0x2980c0e7UL, 0x8c141ecfUL, 
0x48bce243UL, 0x8ac4a6feUL, 0xd831d3c5UL, 0x60b716faUL, 
0x9d5380baUL, 0xf2d94fc0UL, 0x781de93eUL, 0x3a24362eUL, 
0xdee16bf4UL, 0xefcb54d7UL, 0xf409f7f1UL, 0xf582c3afUL, 
0x280bf4b9UL, 0x519d29d9UL, 0x38c75e92UL, 0xebf8845aUL, 
0xe890d8b8UL, 0x0ddeb13cUL, 0x0433d08dUL, 0x03685ce2UL, 
0xe4c55ddaUL, 0x9e3bdc58UL, 0x460a0f9dUL, 0xd33fdac8UL, 
0xdb598f27UL, 0xc4a8fc8cUL, 0xac79bf99UL, 0x4e6c5a72UL, 
0xfe8ccaa2UL, 0xe39ed1b5UL, 0xa41fea76UL, 0xea73b004UL, 
};

static const word32 Td2[256] = {
0xbc02e368UL, 0x620c5585UL, 0x23312a3fUL, 0x13f761abUL, 
0x6d7298d4UL, 0x9a1921cbUL, 0xa4613c22UL, 0x3dcd459dUL, 
0xb42305fdUL, 0x075f2bc4UL, 0x01c09b2cUL, 0x800f3dd9UL, 
0x5c74486cUL, 0x7e85f97fUL, 0xab1ff173UL, 0xde0eb6edUL, 
0x6bed283cUL, 0x781a4997UL, 0x918d9f2aUL, 0x9f33c957UL, 
0xa8aaa907UL, 0xed7da50dUL, 0x2d8f7c42UL, 0xb0c9764dUL, 
0xe8574d91UL, 0x63cccea9UL, 0x96d2b4eeUL, 0xe1b63028UL, 
0x61b90df1UL, 0x6726bd19UL, 0xad80419bUL, 0x6ec7c0a0UL, 
0xf2415183UL, 0xf03492dbUL, 0x1efc6fa2UL, 0xce4c8f32UL, 
0x337313e0UL, 0xc66d69a7UL, 0x6493e56dUL, 0x2ffabf1aUL, 
0xbfb7bb1cUL, 0x03b55874UL, 0x2c4fe76eUL, 0xb7965d89UL, 
0x052ae89cUL, 0x19a34466UL, 0x71fb342eUL, 0x29650ff2UL, 
0x827afe81UL, 0x22f1b113UL, 0x35eca308UL, 0x0f7ecd51UL, 
0xa614ff7aUL, 0x93f85c72UL, 0x97122fc2UL, 0xe3c3f370UL, 
0x491c992fUL, 0x1568d143UL, 0x261bc2a3UL, 0x32b388ccUL, 
0x7a6f8acfUL, 0x069fb0e8UL, 0xf51e7a47UL, 0x79dad2bbUL, 
0x0821e695UL, 0xe55c4398UL, 0x3106d0b8UL, 0x7baf11e3UL, 
0x65537e41UL, 0x2b10ccaaUL, 0xe49cd8b4UL, 0xa7d46456UL, 
0x3659fb7cUL, 0x2084724bUL, 0x4df6ea9fUL, 0xaadf6a5fUL, 
0xdfce2dc1UL, 0x68587048UL, 0xf381caafUL, 0xd8910605UL, 
0x4b695a77UL, 0x28a594deUL, 0x104239dfUL, 0xc347813bUL, 
0xcaa6fc82UL, 0xd2c523c8UL, 0x6cb203f8UL, 0xd59a080cUL, 
0xac40dab7UL, 0x09e17db9UL, 0x342c3824UL, 0x47a2cf52UL, 
0x74d1dcb2UL, 0x5b2b63a8UL, 0x559535d5UL, 0x7511479eUL, 
0xebe215e5UL, 0x30c64b94UL, 0x14a84a6fUL, 0x9c869123UL, 
0xcc394c6aUL, 0xff4a5f8aUL, 0x904d0406UL, 0xddbbee99UL, 
0x52ca1e11UL, 0xc418aaffUL, 0x6998eb64UL, 0xfcff07feUL, 
0x5e018b34UL, 0x0ebe567dUL, 0x9bd9bae7UL, 0xc1324263UL, 
0xdc7b75b5UL, 0x44179726UL, 0xcb6667aeUL, 0x0ccb9525UL, 
0x9567ec9aUL, 0x2ad05786UL, 0x37996050UL, 0xd305b8e4UL, 
0x83ba65adUL, 0xae3519efUL, 0xc913a4f6UL, 0x4aa9c15bUL, 
0x1bd6873eUL, 0x595ea0f0UL, 0x8a5b1814UL, 0x703baf02UL, 
0xe076ab04UL, 0x50bfdd49UL, 0x1863df4aUL, 0xb656c6a5UL, 
0x530a853dUL, 0x1237fa87UL, 0x94a777b6UL, 0x517f4665UL, 
0xb109ed61UL, 0xe6e91becUL, 0x8525d545UL, 0x3b52f575UL, 
0x413d7fbaUL, 0x428827ceUL, 0x4e43b2ebUL, 0xe997d6bdUL, 
0x9ef3527bUL, 0x7f456253UL, 0xfba02c3aUL, 0xd1707bbcUL, 
0xf76bb91fUL, 0x171d121bUL, 0xeec8fd79UL, 0x7cf03a27UL, 
0x45d70c0aUL, 0x607996ddUL, 0xf6ab2233UL, 0x1c89acfaUL, 
0xbb5dc8acUL, 0x7d30a10bUL, 0xa14bd4beUL, 0x0b94bee1UL, 
0x0a5425cdUL, 0x4662547eUL, 0x1182a2f3UL, 0xa33e17e6UL, 
0x66e62635UL, 0x0275c358UL, 0x8b9b8338UL, 0xbdc27844UL, 
0x48dc0203UL, 0xa08b4f92UL, 0xb37c2e39UL, 0x84e54e69UL, 
0x8f71f088UL, 0x3927362dUL, 0xfd3f9cd2UL, 0x246e01fbUL, 
0x16dd8937UL, 0x00000000UL, 0x57e0f68dUL, 0x986ce293UL, 
0xf815744eUL, 0xd45a9320UL, 0x38e7ad01UL, 0x5db4d340UL, 
0xc2871a17UL, 0x6a2db310UL, 0xd62f5078UL, 0x1f3cf48eUL, 
0xa5a1a70eUL, 0x4c3671b3UL, 0x25ae9ad7UL, 0xdb245e71UL, 
0x8750161dUL, 0xf9d5ef62UL, 0x86908d31UL, 0x1a161c12UL, 
0x81cfa6f5UL, 0x6f075b8cUL, 0x1d4937d6UL, 0x3a926e59UL, 
0x776484c6UL, 0x3fb886c5UL, 0xcdf9d746UL, 0xd0b0e090UL, 
0x4f8329c7UL, 0x40fde496UL, 0x0d0b0e09UL, 0x56206da1UL, 
0xea228ec9UL, 0x882edb4cUL, 0x738ef776UL, 0xb2bcb515UL, 
0x5fc11018UL, 0xa96a322bUL, 0x8eb16ba4UL, 0x5455aef9UL, 
0x89ee4060UL, 0xef086655UL, 0x2144e967UL, 0xecbd3e21UL, 
0xbe772030UL, 0xc7adf28bUL, 0xe72980c0UL, 0xcf8c141eUL, 
0x4348bce2UL, 0xfe8ac4a6UL, 0xc5d831d3UL, 0xfa60b716UL, 
0xba9d5380UL, 0xc0f2d94fUL, 0x3e781de9UL, 0x2e3a2436UL, 
0xf4dee16bUL, 0xd7efcb54UL, 0xf1f409f7UL, 0xaff582c3UL, 
0xb9280bf4UL, 0xd9519d29UL, 0x9238c75eUL, 0x5aebf884UL, 
0xb8e890d8UL, 0x3c0ddeb1UL, 0x8d0433d0UL, 0xe203685cUL, 
0xdae4c55dUL, 0x589e3bdcUL, 0x9d460a0fUL, 0xc8d33fdaUL, 
0x27db598fUL, 0x8cc4a8fcUL, 0x99ac79bfUL, 0x724e6c5aUL, 
0xa2fe8ccaUL, 0xb5e39ed1UL, 0x76a41feaUL, 0x04ea73b0UL, 
};

static const word32 Td3[256] = {
0x68bc02e3UL, 0x85620c55UL, 0x3f23312aUL, 0xab13f761UL, 
0xd46d7298UL, 0xcb9a1921UL, 0x22a4613cUL, 0x9d3dcd45UL, 
0xfdb42305UL, 0xc4075f2bUL, 0x2c01c09bUL, 0xd9800f3dUL, 
0x6c5c7448UL, 0x7f7e85f9UL, 0x73ab1ff1UL, 0xedde0eb6UL, 
0x3c6bed28UL, 0x97781a49UL, 0x2a918d9fUL, 0x579f33c9UL, 
0x07a8aaa9UL, 0x0ded7da5UL, 0x422d8f7cUL, 0x4db0c976UL, 
0x91e8574dUL, 0xa963ccceUL, 0xee96d2b4UL, 0x28e1b630UL, 
0xf161b90dUL, 0x196726bdUL, 0x9bad8041UL, 0xa06ec7c0UL, 
0x83f24151UL, 0xdbf03492UL, 0xa21efc6fUL, 0x32ce4c8fUL, 
0xe0337313UL, 0xa7c66d69UL, 0x6d6493e5UL, 0x1a2ffabfUL, 
0x1cbfb7bbUL, 0x7403b558UL, 0x6e2c4fe7UL, 0x89b7965dUL, 
0x9c052ae8UL, 0x6619a344UL, 0x2e71fb34UL, 0xf229650fUL, 
0x81827afeUL, 0x1322f1b1UL, 0x0835eca3UL, 0x510f7ecdUL, 
0x7aa614ffUL, 0x7293f85cUL, 0xc297122fUL, 0x70e3c3f3UL, 
0x2f491c99UL, 0x431568d1UL, 0xa3261bc2UL, 0xcc32b388UL, 
0xcf7a6f8aUL, 0xe8069fb0UL, 0x47f51e7aUL, 0xbb79dad2UL, 
0x950821e6UL, 0x98e55c43UL, 0xb83106d0UL, 0xe37baf11UL, 
0x4165537eUL, 0xaa2b10ccUL, 0xb4e49cd8UL, 0x56a7d464UL, 
0x7c3659fbUL, 0x4b208472UL, 0x9f4df6eaUL, 0x5faadf6aUL, 
0xc1dfce2dUL, 0x48685870UL, 0xaff381caUL, 0x05d89106UL, 
0x774b695aUL, 0xde28a594UL, 0xdf104239UL, 0x3bc34781UL, 
0x82caa6fcUL, 0xc8d2c523UL, 0xf86cb203UL, 0x0cd59a08UL, 
0xb7ac40daUL, 0xb909e17dUL, 0x24342c38UL, 0x5247a2cfUL, 
0xb274d1dcUL, 0xa85b2b63UL, 0xd5559535UL, 0x9e751147UL, 
0xe5ebe215UL, 0x9430c64bUL, 0x6f14a84aUL, 0x239c8691UL, 
0x6acc394cUL, 0x8aff4a5fUL, 0x06904d04UL, 0x99ddbbeeUL, 
0x1152ca1eUL, 0xffc418aaUL, 0x646998ebUL, 0xfefcff07UL, 
0x345e018bUL, 0x7d0ebe56UL, 0xe79bd9baUL, 0x63c13242UL, 
0xb5dc7b75UL, 0x26441797UL, 0xaecb6667UL, 0x250ccb95UL, 
0x9a9567ecUL, 0x862ad057UL, 0x50379960UL, 0xe4d305b8UL, 
0xad83ba65UL, 0xefae3519UL, 0xf6c913a4UL, 0x5b4aa9c1UL, 
0x3e1bd687UL, 0xf0595ea0UL, 0x148a5b18UL, 0x02703bafUL, 
0x04e076abUL, 0x4950bfddUL, 0x4a1863dfUL, 0xa5b656c6UL, 
0x3d530a85UL, 0x871237faUL, 0xb694a777UL, 0x65517f46UL, 
0x61b109edUL, 0xece6e91bUL, 0x458525d5UL, 0x753b52f5UL, 
0xba413d7fUL, 0xce428827UL, 0xeb4e43b2UL, 0xbde997d6UL, 
0x7b9ef352UL, 0x537f4562UL, 0x3afba02cUL, 0xbcd1707bUL, 
0x1ff76bb9UL, 0x1b171d12UL, 0x79eec8fdUL, 0x277cf03aUL, 
0x0a45d70cUL, 0xdd607996UL, 0x33f6ab22UL, 0xfa1c89acUL, 
0xacbb5dc8UL, 0x0b7d30a1UL, 0xbea14bd4UL, 0xe10b94beUL, 
0xcd0a5425UL, 0x7e466254UL, 0xf31182a2UL, 0xe6a33e17UL, 
0x3566e626UL, 0x580275c3UL, 0x388b9b83UL, 0x44bdc278UL, 
0x0348dc02UL, 0x92a08b4fUL, 0x39b37c2eUL, 0x6984e54eUL, 
0x888f71f0UL, 0x2d392736UL, 0xd2fd3f9cUL, 0xfb246e01UL, 
0x3716dd89UL, 0x00000000UL, 0x8d57e0f6UL, 0x93986ce2UL, 
0x4ef81574UL, 0x20d45a93UL, 0x0138e7adUL, 0x405db4d3UL, 
0x17c2871aUL, 0x106a2db3UL, 0x78d62f50UL, 0x8e1f3cf4UL, 
0x0ea5a1a7UL, 0xb34c3671UL, 0xd725ae9aUL, 0x71db245eUL, 
0x1d875016UL, 0x62f9d5efUL, 0x3186908dUL, 0x121a161cUL, 
0xf581cfa6UL, 0x8c6f075bUL, 0xd61d4937UL, 0x593a926eUL, 
0xc6776484UL, 0xc53fb886UL, 0x46cdf9d7UL, 0x90d0b0e0UL, 
0xc74f8329UL, 0x9640fde4UL, 0x090d0b0eUL, 0xa156206dUL, 
0xc9ea228eUL, 0x4c882edbUL, 0x76738ef7UL, 0x15b2bcb5UL, 
0x185fc110UL, 0x2ba96a32UL, 0xa48eb16bUL, 0xf95455aeUL, 
0x6089ee40UL, 0x55ef0866UL, 0x672144e9UL, 0x21ecbd3eUL, 
0x30be7720UL, 0x8bc7adf2UL, 0xc0e72980UL, 0x1ecf8c14UL, 
0xe24348bcUL, 0xa6fe8ac4UL, 0xd3c5d831UL, 0x16fa60b7UL, 
0x80ba9d53UL, 0x4fc0f2d9UL, 0xe93e781dUL, 0x362e3a24UL, 
0x6bf4dee1UL, 0x54d7efcbUL, 0xf7f1f409UL, 0xc3aff582UL, 
0xf4b9280bUL, 0x29d9519dUL, 0x5e9238c7UL, 0x845aebf8UL, 
0xd8b8e890UL, 0xb13c0ddeUL, 0xd08d0433UL, 0x5ce20368UL, 
0x5ddae4c5UL, 0xdc589e3bUL, 0x0f9d460aUL, 0xdac8d33fUL, 
0x8f27db59UL, 0xfc8cc4a8UL, 0xbf99ac79UL, 0x5a724e6cUL, 
0xcaa2fe8cUL, 0xd1b5e39eUL, 0xea76a41fUL, 0xb004ea73UL, 
};

#endif /* ?LITTLE_ENDIAN */
/**
 * The Square block cipher.
 *
 * Algorithm developed by Joan Daemen <daemen.j@protonworld.com> and
 * Vincent Rijmen <vincent.rijmen@esat.kuleuven.ac.be>.  Description available
 * from http://www.esat.kuleuven.ac.be/~cosicart/pdf/VR-9700.PDF
 *
 * This implementation is in the public domain.
 *
 * @author Paulo S.L.M. Barreto <pbarreto@nw.com.br>
 * @author George Barwood <george.barwood@dial.pipex.com>
 * @author Vincent Rijmen <vincent.rijmen@esat.kuleuven.ac.be>
 *
 * Caveat: this code assumes 32-bit words and probably will not work
 * otherwise.
 *
 * To correctly visualize this file, please set tabstop = 4.
 *
 * @version 2.7 (1999.06.29)
 *
 * =============================================================================
 *
 * Differences from version 2.6 (1997.05.24)
 *
 * - Fixed tables (files sqgen.c and consequently square.tab) and hashing
 *   computation (files sqhash.c and sqtest.c) for big-endian platforms.
 *   Thanks to Alan Hawrelak <alan@celcorp.com> for kindly pointing out
 *   the errors and helping in the debugging process.
 *
 * - Fixed the e-mails listed on this note.
 *
 * =============================================================================
 *
 * Differences from version 2.5 (1997.04.25)
 *
 * - Improved key scheduling setup to enhance hashing performance.  Modules
 *   sqgen.c and sqtest.c have been updated accordingly.  The new scheme
 *   (suggested by Vincent Rijmen) uses tables instead of explicit GF(2^8)
 *   multiplications.  Increase in size of the generated code is very small.
 *
 * - Hashing scheme (Matyas-Meyer-Oseas) added.
 *
 * =============================================================================
 *
 * Differences from version 2.4 (1997.04.09):
 *
 * - Changed all initialization functions so that the IV (when applicable)
 *   is separately loaded.
 *
 * - Ciphertext Stealing (CTS) mode added.
 *
 * - Output Feedback (OFB) mode added.
 *
 * - Cipher Block Chaining (CBC) mode added.
 *
 * - Split square.c int several files according to the specific functionality
 *   (basic functions, modes, testing).
 *
 * - Flipped tables according to the endianness of the subjacent platform
 *   for best performance.
 *
 * - Changed "maketabs.c" to "sqgen.c" for compatibility with the Pegwit system.
 *
 * =============================================================================
 *
 * Differences from version 2.3 (1997.04.09):
 *
 * - Defined function squareExpandKey() to enhance performance of both CFB
 *   initialization and hash computation (available in version 2.6).
 *
 * - Changed definition of function squareTransform() to accept a single in-out
 *   parameter, and optimized function squareGenerateRoundKeys accordingly.
 *
 * =============================================================================
 *
 * Differences from version 2.2 (1997.03.03):
 *
 * - Cipher feedback (CFB) mode added (heavily based on an old public domain CFB
 *   shell written by Colin Plumb for the IDEA cipher).
 *
 * - Fixed word size problem (64 bits rather than 32) arising on the Alpha.
 *
 * - Reformatted indented sections of compiler directives for use with old,
 *   non-ANSI compliant compilers.
 *
 * Differences from version 2.1 (1997.03.03):
 *
 * - Added optional Microsoft x86 assembler version, which increases performance
 *   by up to 20% depending on the target machine, and generates smaller code.
 *
 * Differences from version 2.0 (1997.02.11):
 *
 * - Added typecasts to the build-up of out[] in function squareTransform()
 *   to make it portable to 16-bit (MSDOS) systems.
 *
 * - Truncated alogtab[] back to 256 elements and changed the mul() macro
 *   accordingly.  Using an extended table to avoid a division seemed an
 *   unnecessary storage overhead (it could be useful to speed up hash
 *   functions derived from Square, but other optimizations are likely to be
 *   more effective).
 *
 * Differences from version 2.0 (1997.02.11):
 *
 * - Updated definition of Square algorithm (version 1.0 implemented an
 *   embryonic form of Square).
 *
 * ==============================================================================
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS
 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT(INCLUDING NEGLIGENCE
 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#ifndef R
	#define R 8
#endif /* R */

#if R != 8
	#error "This implementation is optimized for (and assumes) exactly 8 rounds"
#endif

#ifndef USUAL_TYPES
#	define USUAL_TYPES
	typedef unsigned char	byte;	/*  8 bit */
	typedef unsigned short	word16;	/* 16 bit */
#	ifdef __alpha
	typedef unsigned int	word32;	/* 32 bit */
#	else  /* !__alpha */
	typedef unsigned long	word32;	/* 32 bit */
#	endif /* ?__alpha */
#endif /* ?USUAL_TYPES */


/* platform endianness: */
#if !defined(LITTLE_ENDIAN) && !defined(BIG_ENDIAN)
#	if defined(_M_IX86) || defined(_M_I86) || defined(__alpha)
#		define LITTLE_ENDIAN
#	else
#		error "Either LITTLE_ENDIAN or BIG_ENDIAN must be defined"
#	endif
#elif defined(LITTLE_ENDIAN) && defined(BIG_ENDIAN)
#	error "LITTLE_ENDIAN and BIG_ENDIAN must not be simultaneously defined"
#endif /* !LITTLE_ENDIAN && !BIG_ENDIAN */


/* Microsoft C / Intel x86 optimizations: */
#if defined(_MSC_VER) && defined(_M_IX86) 
#	define HARDWARE_ROTATIONS
#	define ASSEMBLER_CORE
#endif /* ?(_MSC_VER && _M_IX86) */

const char *squareBanner =
	"Square cipher v.2.7 (compiled on " __DATE__ " " __TIME__ ").\n"
#ifdef LITTLE_ENDIAN
	"Compiled for little-endian platforms.\n"
#else  /* BIG_ENDIAN */
	"Compiled for big-endian platforms.\n"
#endif /* ?(LITTLE_ENDIAN, BIG_ENDIAN) */
#ifdef ASSEMBLER_CORE
	"Using assembler core functions.\n"
#endif /* ?ASSEMBLER_CORE */
#ifdef DESTROY_TEMPORARIES
	"Destroying temporaries after use.\n"
#endif /* ?DESTROY_TEMPORARIES */
	; /* squareBanner */

#ifdef HARDWARE_ROTATIONS
#	define ROTL(x, s) (_lrotl((x),(s)))
#	define ROTR(x, s) (_lrotr((x),(s)))
#else  /* !HARDWARE_ROTATIONS */
#	define ROTL(x, s) (((x) << (s)) |((x) >> (32 - (s))))
#	define ROTR(x, s) (((x) >> (s)) |((x) << (32 - (s))))
#endif /* ?HARDWARE_ROTATIONS */

#ifdef LITTLE_ENDIAN
#	ifdef MASKED_BYTE_EXTRACTION
#		define GETB0(x) (((x)      ) & 0xffU)
#		define GETB1(x) (((x) >>  8) & 0xffU)
#		define GETB2(x) (((x) >> 16) & 0xffU)
#		define GETB3(x) (((x) >> 24) & 0xffU)
#	else  /* !MASKED_BYTE_EXTRACTION */
#		define GETB0(x) ((byte)((x)      ))
#		define GETB1(x) ((byte)((x) >>  8))
#		define GETB2(x) ((byte)((x) >> 16))
#		define GETB3(x) ((byte)((x) >> 24))
#	endif /* ?MASKED_BYTE_EXTRACTION */
#	define PUTB0(x) ((word32)(x)      )
#	define PUTB1(x) ((word32)(x) <<  8)
#	define PUTB2(x) ((word32)(x) << 16)
#	define PUTB3(x) ((word32)(x) << 24)
#	define PSI_ROTL(x, s) ROTR(x, s)
#	define PSI_ROTR(x, s) ROTL(x, s)
#else  /* !LITTLE_ENDIAN */
#	ifdef MASKED_BYTE_EXTRACTION
#		define GETB0(x) (((x) >> 24) & 0xffU)
#		define GETB1(x) (((x) >> 16) & 0xffU)
#		define GETB2(x) (((x) >>  8) & 0xffU)
#		define GETB3(x) (((x)      ) & 0xffU)
#	else  /* !MASKED_BYTE_EXTRACTION */
#		define GETB0(x) ((byte)((x) >> 24))
#		define GETB1(x) ((byte)((x) >> 16))
#		define GETB2(x) ((byte)((x) >>  8))
#		define GETB3(x) ((byte)((x)      ))
#	endif /* ?MASKED_BYTE_EXTRACTION */
#	define PUTB0(x) ((word32)(x) << 24)
#	define PUTB1(x) ((word32)(x) << 16)
#	define PUTB2(x) ((word32)(x) <<  8)
#	define PUTB3(x) ((word32)(x)      )
#	define PSI_ROTL(x, s) ROTL(x, s)
#	define PSI_ROTR(x, s) ROTR(x, s)
#endif /* ?LITTLE_ENDIAN */

#define mul(a, b)((a && b) ? alogtab[(mtemp = logtab[a] + logtab[b]) >= 255 ? mtemp - 255 : mtemp] : 0)

#define D(p)((word32 *)(p))

#define COPY_BLOCK(target, source) \
{ \
	(target)[0] = (source)[0]; \
	(target)[1] = (source)[1]; \
	(target)[2] = (source)[2]; \
	(target)[3] = (source)[3]; \
} /* COPY_BLOCK */


static void squareTransform(word32 roundKey[4]) {
	roundKey[0] =phi[GETB0(roundKey[0])] ^
		PSI_ROTR(phi[GETB1(roundKey[0])],  8) ^
		PSI_ROTR(phi[GETB2(roundKey[0])], 16) ^
		PSI_ROTR(phi[GETB3(roundKey[0])], 24);
	roundKey[1] =phi[GETB0(roundKey[1])] ^
		PSI_ROTR(phi[GETB1(roundKey[1])],  8) ^
		PSI_ROTR(phi[GETB2(roundKey[1])], 16) ^
		PSI_ROTR(phi[GETB3(roundKey[1])], 24);
	roundKey[2] =phi[GETB0(roundKey[2])] ^
		PSI_ROTR(phi[GETB1(roundKey[2])],  8) ^
		PSI_ROTR(phi[GETB2(roundKey[2])], 16) ^
		PSI_ROTR(phi[GETB3(roundKey[2])], 24);
	roundKey[3] =phi[GETB0(roundKey[3])] ^
		PSI_ROTR(phi[GETB1(roundKey[3])],  8) ^
		PSI_ROTR(phi[GETB2(roundKey[3])], 16) ^
		PSI_ROTR(phi[GETB3(roundKey[3])], 24);
} /* squareTransform */


void squareGenerateRoundKeys(const squareBlock key,
		squareKeySchedule roundKeys_e, squareKeySchedule roundKeys_d) {
	int t;

	COPY_BLOCK(roundKeys_e[0], D(key));
	for (t = 1; t < R+1; t++) {
		/* apply the key evolution function: */
		roundKeys_d[R-t][0] = roundKeys_e[t][0] = roundKeys_e[t-1][0] ^ PSI_ROTL(roundKeys_e[t-1][3], 8) ^ offset[t-1];
		roundKeys_d[R-t][1] = roundKeys_e[t][1] = roundKeys_e[t-1][1] ^ roundKeys_e[t][0];
		roundKeys_d[R-t][2] = roundKeys_e[t][2] = roundKeys_e[t-1][2] ^ roundKeys_e[t][1];
		roundKeys_d[R-t][3] = roundKeys_e[t][3] = roundKeys_e[t-1][3] ^ roundKeys_e[t][2];
		/* apply the theta diffusion function: */
		squareTransform(roundKeys_e[t-1]);
	}  
	COPY_BLOCK(roundKeys_d[R], roundKeys_e[0]);
} /* squareGenerateRoundKeys */


void squareExpandKey(const squareBlock key, squareKeySchedule roundKeys_e) {
	int t;

	COPY_BLOCK(roundKeys_e[0], D(key));
	for (t = 1; t < R+1; t++) {
		/* apply the key evolution function: */
		roundKeys_e[t][0] = roundKeys_e[t-1][0] ^ PSI_ROTL(roundKeys_e[t-1][3], 8) ^ offset[t-1];
		roundKeys_e[t][1] = roundKeys_e[t-1][1] ^ roundKeys_e[t][0];
		roundKeys_e[t][2] = roundKeys_e[t-1][2] ^ roundKeys_e[t][1];
		roundKeys_e[t][3] = roundKeys_e[t-1][3] ^ roundKeys_e[t][2];
		/* apply the theta diffusion function: */
		squareTransform(roundKeys_e[t-1]);
	}  
} /* squareExpandKey */


#ifdef ASSEMBLER_CORE

/* Microsoft x86 version by George Barwood */
/* About 15-20% faster, using less code */
/* Notes:
   Calculate 4 outputs of each round in parallel using esi, edx, ecx, edi
   eax is used to hold the sub-round input
   ebx is used as a byte index register(and also to address text)
   ebp is used to address roundKeys and tables
   5 words of stack are used 
     1 - saved value of ebp
     2 - saved value of roundKeys address
     3,4,5 - round inputs(eax has first input)
   These are destroyed if DESTROY_TEMPORARIES is set
*/

#define INITIAL __asm      \
{                          \
	__asm push ebp  /*1*/    \
	__asm mov ebx, text      \
	__asm mov ebp, roundKeys \
	__asm push ebp  /*2*/    \
	__asm mov eax, [ebp][12] \
	__asm xor eax, [ebx][12] \
	__asm push eax  /*3*/    \
	__asm mov eax, [ebp][8]  \
	__asm xor eax, [ebx][8]  \
	__asm push eax  /*4*/    \
	__asm mov eax, [ebp][4]  \
	__asm xor eax, [ebx][4]  \
	__asm push eax  /*5*/    \
	__asm mov eax, [ebp][0]  \
	__asm xor eax, [ebx][0]  \
	__asm sub ebx, ebx       \
}

#define INIT_ROUND(RN)  __asm      \
{ /* load roundKeys */             \
	__asm mov edi, [ebp][RN*16+0*4]  \
	__asm mov ecx, [ebp][RN*16+1*4]  \
	__asm mov edx, [ebp][RN*16+2*4]  \
	__asm mov esi, [ebp][RN*16+3*4]  \
}

#define SUB_ROUND(TABLE) __asm \
{ /* the real work */          \
	__asm mov ebp,offset TABLE   \
	__asm mov bl,al              \
	__asm xor edi, [ebp][4*ebx]  \
	__asm mov bl,ah              \
	__asm shr eax,16             \
	__asm xor ecx, [ebp][4*ebx]  \
	__asm mov bl,al              \
	__asm shr eax,8              \
	__asm xor edx, [ebp][4*ebx]  \
	__asm xor esi, [ebp][4*eax]  \
}

#define END_ROUND __asm     \
{ /* save round output*/    \
	__asm mov ebp,[esp] /*2*/ \
	__asm push esi      /*3*/ \
	__asm push edx      /*4*/ \
	__asm push ecx      /*5*/ \
	__asm mov eax,edi         \
}

#define ENCRYPT_ROUND(RN) _asm  \
{ /* encryption round */ \
	INIT_ROUND(RN)         \
	SUB_ROUND(Te0)         \
	__asm pop eax  /*5*/   \
	SUB_ROUND(Te1)         \
	__asm pop eax  /*4*/   \
	SUB_ROUND(Te2)         \
	__asm pop eax  /*3*/   \
	SUB_ROUND(Te3)         \
	END_ROUND              \
}

#define DECRYPT_ROUND(RN) _asm  \
{ /* decryption round */ \
	INIT_ROUND(RN)         \
	SUB_ROUND(Td0)         \
	__asm pop eax  /*5*/   \
	SUB_ROUND(Td1)         \
	__asm pop eax  /*4*/   \
	SUB_ROUND(Td2)         \
	__asm pop eax  /*3*/   \
	SUB_ROUND(Td3)         \
	END_ROUND              \
}

#define HALF_FINAL __asm     \
{                            \
	__asm mov bl,al            \
	__asm mov bl, [ebp][ebx]   \
	__asm xor edi, ebx         \
	__asm mov bl,ah            \
	__asm shr eax,16           \
	__asm xor cl, [ebp][ebx]   \
	__asm mov bl,al            \
	__asm xor dl, [ebp][ebx]   \
	__asm mov bl, ah           \
	__asm mov bl, [ebp][ebx]   \
	__asm xor esi, ebx         \
	__asm pop eax              \
	__asm ror edi,8            \
	__asm mov bl,al            \
	__asm mov bl, [ebp][ebx]   \
	__asm xor edi,ebx          \
	__asm ror edi,8            \
	__asm sub bh,bh            \
	__asm mov bl,ah            \
	__asm shr eax,16           \
	__asm xor ch, [ebp][ebx]   \
	__asm ror ecx,16           \
	__asm mov bl,al            \
	__asm xor dh, [ebp][ebx]   \
	__asm ror edx,16           \
	__asm mov bl,ah            \
	__asm ror esi,8            \
	__asm mov bl, [ebp][ebx]   \
	__asm xor esi,ebx          \
	__asm ror esi,8            \
}

#define FINAL(TABLE) _asm  \
{                          \
	INIT_ROUND(8)            \
	__asm mov ebp,offset TABLE     \
	HALF_FINAL      /*5*/    \
	__asm pop eax   /*4*/    \
	HALF_FINAL      /*3*/    \
	__asm pop ebp   /*2*/    \
	__asm pop ebp   /*1*/    \
	__asm mov ebx, text      \
	__asm mov [ebx][4*3],esi \
	__asm mov [ebx][4*2],edx \
	__asm mov [ebx][4*1],ecx \
	__asm mov [ebx][4*0],edi \
}

#define BURN_STACK _asm  \
{                        \
	__asm mov eax, esp     \
	__asm push 0L          \
	__asm push 0L          \
	__asm push 0L          \
	__asm push 0L          \
	__asm push 0L          \
	__asm mov esp, eax     \
}

void squareEncrypt(word32 text[4], word32 ctext[4], squareKeySchedule roundKeys)
{ 
	INITIAL
	ENCRYPT_ROUND(1)
	ENCRYPT_ROUND(2)
	ENCRYPT_ROUND(3)
	ENCRYPT_ROUND(4)
	ENCRYPT_ROUND(5)
	ENCRYPT_ROUND(6)
	ENCRYPT_ROUND(7)
	FINAL(Se)
#ifdef DESTROY_TEMPORARIES
	BURN_STACK
#endif /* ?DESTROY_TEMPORARIES */
}

void squareDecrypt(word32 text[4], word32 ptext[4], squareKeySchedule roundKeys)
{ 
	INITIAL
	DECRYPT_ROUND(1)
	DECRYPT_ROUND(2)
	DECRYPT_ROUND(3)
	DECRYPT_ROUND(4)
	DECRYPT_ROUND(5)
	DECRYPT_ROUND(6)
	DECRYPT_ROUND(7)
	FINAL(Sd)
#ifdef DESTROY_TEMPORARIES
	BURN_STACK
#endif /* ?DESTROY_TEMPORARIES */
}

#else /* !ASSEMBLER_CORE */

#define squareRound(text, temp, T0, T1, T2, T3, roundKey) \
{ \
	temp[0] = T0[GETB0(text[0])] \
			^ T1[GETB0(text[1])] \
			^ T2[GETB0(text[2])] \
			^ T3[GETB0(text[3])] \
			^ roundKey[0]; \
	temp[1] = T0[GETB1(text[0])] \
			^ T1[GETB1(text[1])] \
			^ T2[GETB1(text[2])] \
			^ T3[GETB1(text[3])] \
			^ roundKey[1]; \
	temp[2] = T0[GETB2(text[0])] \
			^ T1[GETB2(text[1])] \
			^ T2[GETB2(text[2])] \
			^ T3[GETB2(text[3])] \
			^ roundKey[2]; \
	temp[3] = T0[GETB3(text[0])] \
			^ T1[GETB3(text[1])] \
			^ T2[GETB3(text[2])] \
			^ T3[GETB3(text[3])] \
			^ roundKey[3]; \
} /* squareRound */


#define squareFinal(text, temp, S, roundKey) \
{ \
	text[0] = PUTB0(S[GETB0(temp[0])]) \
			^ PUTB1(S[GETB0(temp[1])]) \
			^ PUTB2(S[GETB0(temp[2])]) \
			^ PUTB3(S[GETB0(temp[3])]) \
			^ roundKey[0]; \
	text[1] = PUTB0(S[GETB1(temp[0])]) \
			^ PUTB1(S[GETB1(temp[1])]) \
			^ PUTB2(S[GETB1(temp[2])]) \
			^ PUTB3(S[GETB1(temp[3])]) \
			^ roundKey[1]; \
	text[2] = PUTB0(S[GETB2(temp[0])]) \
			^ PUTB1(S[GETB2(temp[1])]) \
			^ PUTB2(S[GETB2(temp[2])]) \
			^ PUTB3(S[GETB2(temp[3])]) \
			^ roundKey[2]; \
	text[3] = PUTB0(S[GETB3(temp[0])]) \
			^ PUTB1(S[GETB3(temp[1])]) \
			^ PUTB2(S[GETB3(temp[2])]) \
			^ PUTB3(S[GETB3(temp[3])]) \
			^ roundKey[3]; \
} /* squareFinal */


void squareEncrypt(word32 ptext[4], word32 ctext[4],
    squareKeySchedule roundKeys) {
	word32 temp[4];

	/* initial key addition */
	ctext[0] = ptext[0] ^ roundKeys[0][0];
	ctext[1] = ptext[1] ^ roundKeys[0][1];
	ctext[2] = ptext[2] ^ roundKeys[0][2];
	ctext[3] = ptext[3] ^ roundKeys[0][3];

	/* R - 1 full rounds */
	squareRound(ctext, temp, Te0, Te1, Te2, Te3, roundKeys[1]);
	squareRound(temp, ctext, Te0, Te1, Te2, Te3, roundKeys[2]);
	squareRound(ctext, temp, Te0, Te1, Te2, Te3, roundKeys[3]);
	squareRound(temp, ctext, Te0, Te1, Te2, Te3, roundKeys[4]);
	squareRound(ctext, temp, Te0, Te1, Te2, Te3, roundKeys[5]);
	squareRound(temp, ctext, Te0, Te1, Te2, Te3, roundKeys[6]);
	squareRound(ctext, temp, Te0, Te1, Te2, Te3, roundKeys[7]);

	/* last round(diffusion becomes only transposition) */
	squareFinal(ctext, temp, Se, roundKeys[R]);

#ifdef DESTROY_TEMPORARIES
	/* destroy sensitive data: */
	temp[0] = temp[1] = temp[2] = temp[3] = 0L;
#endif /* ?DESTROY_TEMPORARIES */
} /* squareEncrypt */


void squareDecrypt(word32 ctext[4], word32 ptext[4],
    squareKeySchedule roundKeys) {
	word32 temp[4];

	/* initial key addition */
	ptext[0] = ctext[0] ^ roundKeys[0][0];
	ptext[1] = ctext[1] ^ roundKeys[0][1];
	ptext[2] = ctext[2] ^ roundKeys[0][2];
	ptext[3] = ctext[3] ^ roundKeys[0][3];

	/* R - 1 full rounds */
	squareRound(ptext, temp, Td0, Td1, Td2, Td3, roundKeys[1]);
	squareRound(temp, ptext, Td0, Td1, Td2, Td3, roundKeys[2]);
	squareRound(ptext, temp, Td0, Td1, Td2, Td3, roundKeys[3]);
	squareRound(temp, ptext, Td0, Td1, Td2, Td3, roundKeys[4]);
	squareRound(ptext, temp, Td0, Td1, Td2, Td3, roundKeys[5]);
	squareRound(temp, ptext, Td0, Td1, Td2, Td3, roundKeys[6]);
	squareRound(ptext, temp, Td0, Td1, Td2, Td3, roundKeys[7]);

	/* last round(diffusion becomes only transposition) */
	squareFinal(ptext, temp, Sd, roundKeys[R]);

#ifdef DESTROY_TEMPORARIES
	/* destroy sensitive data: */
	temp[0] = temp[1] = temp[2] = temp[3] = 0L;
#endif /* ?DESTROY_TEMPORARIES */
} /* squareDecrypt */

#endif /* ?ASSEMBLER_CORE */

static void squarePrint (const byte *block, const char *tag)
{
  printf ("%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x %s\n",
    block[ 0], block[ 1], block[ 2], block[ 3],
    block[ 4], block[ 5], block[ 6], block[ 7],
    block[ 8], block[ 9], block[10], block[11],
    block[12], block[13], block[14], block[15],
    tag);
} /* squarePrint */


int main (void)
{
  int i;
  squareBlock key, block, cblock;
  squareKeySchedule roundKeys_e, roundKeys_d;

  printf ("===========================================================================\n\n"
      "Validation data set for Square v1.0\n\n");

  printf ("===========================================================================\n\n"
      "Encryption of the null data block with every key where a single bit is set:\n\n");
  memset (block, 0, SQUARE_BLOCKSIZE);
  squarePrint (block, "plaintext\n");
  for (i = 0; i < 128; i++) {
    memset (key, 0, SQUARE_BLOCKSIZE);
    key[i/8] |= 1 << (7 - i%8); /* set only the i-th bit of the i-th test key */
    squarePrint (key, "key");
    memset (block, 0, SQUARE_BLOCKSIZE);
    /* squareExpandKey (key, roundKeys_e); */
    squareGenerateRoundKeys (key, roundKeys_e, roundKeys_d);
    squareEncrypt ((word32 *)block, (word32 *)cblock, roundKeys_e);
    squarePrint (cblock, "ciphertext\n\n");
  }

  printf ("===========================================================================\n\n"
      "Encryption of a sample data block with every key where a single bit is set:\n\n");
  memcpy (block, "\x0f\x1e\x2d\x3c\x4b\x5a\x69\x78\x87\x96\xa5\xb4\xc3\xd2\xe1\xf0", SQUARE_BLOCKSIZE);
  squarePrint (block, "plaintext\n");
  for (i = 0; i < 128; i++) {
    memset (key, 0, SQUARE_BLOCKSIZE);
    key[i/8] |= 1 << (7 - i%8); /* set only the i-th bit of the i-th test key */
    squarePrint (key, "key");
    memcpy (block, "\x0f\x1e\x2d\x3c\x4b\x5a\x69\x78\x87\x96\xa5\xb4\xc3\xd2\xe1\xf0", SQUARE_BLOCKSIZE);
    /* squareExpandKey (key, roundKeys_e); */
    squareGenerateRoundKeys (key, roundKeys_e, roundKeys_d);
    squareEncrypt ((word32 *)block, (word32 *)cblock, roundKeys_e);
    squarePrint (cblock, "ciphertext\n\n");
  }

  printf ("===========================================================================\n\n");

  return 0;
}

