
#ifndef PORTABLE_C__
#define PORTABLE_C__

#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

/* Definition of minimum-width integer types
 * 
 * u8   -> unsigned integer type, at least 8 bits, equivalent to unsigned char
 * u16  -> unsigned integer type, at least 16 bits
 * u32  -> unsigned integer type, at least 32 bits
 *
 * s8, s16, s32  -> signed counterparts of u8, u16, u32
 *
 * Always use macro's T8(), T16() or T32() to obtain exact-width results,
 * i.e., to specify the size of the result of each expression.
 */

typedef signed char s8;
typedef unsigned char u8;

#if UINT_MAX >= 4294967295UL

typedef signed short s16;
typedef signed int s32;
typedef unsigned short u16;
typedef unsigned int u32;

#define ONE32   0xffffffffU

#else

typedef signed int s16;
typedef signed long s32;
typedef unsigned int u16;
typedef unsigned long u32;

#define ONE32   0xffffffffUL

#endif

#define ONE8    0xffU
#define ONE16   0xffffU

#define T8(x)   ((x) & ONE8)
#define T16(x)  ((x) & ONE16)
#define T32(x)  ((x) & ONE32)

/*
 * If you want 64-bit values, uncomment the following lines; this
 * reduces portability.
 */
#if ((1UL << 31) * 2UL) != 0UL
#ifdef _MSC_VER
typedef unsigned __int64 u64;
typedef signed __int64 s64;
#else  /* !_MSC_VER */
typedef unsigned long u64;
typedef signed long s64;
#define ONE64   0xffffffffffffffffUL
#endif /* ?_MSC_VER */
#else
#ifdef _MSC_VER
typedef unsigned __int64 u64;
typedef signed __int64 s64;
#else  /* !_MSC_VER */
typedef unsigned long long u64;
typedef signed long long s64;
#define ONE64   0xffffffffffffffffULL
#endif /* ?_MSC_VER */
#endif
#define T64(x)  ((x) & ONE64)
/*
 * Note: the test is used to detect native 64-bit architectures;
 * if the unsigned long is strictly greater than 32-bit, it is
 * assumed to be at least 64-bit. This will not work correctly
 * on (old) 36-bit architectures (PDP-11 for instance).
 *
 * On non-64-bit architectures, "long long" is used.
 */

/*
 * U8TO32_BIG(c) returns the 32-bit value stored in big-endian convention
 * in the unsigned char array pointed to by c.
 */
#define U8TO32_BIG(c)  (((u32)T8(*(c)) << 24) | ((u32)T8(*((c) + 1)) << 16) \
                       ((u32)T8(*((c) + 2)) << 8) | ((u32)T8(*((c) + 3))))

/*
 * U8TO32_LITTLE(c) returns the 32-bit value stored in little-endian convention
 * in the unsigned char array pointed to by c.
 */
#define U8TO32_LITTLE(c)  (((u32)T8(*(c))) | ((u32)T8(*((c) + 1)) << 8) \
                      (u32)T8(*((c) + 2)) << 16) | ((u32)T8(*((c) + 3)) << 24))

/*
 * U8TO32_BIG(c, v) stores the 32-bit-value v in big-endian convention
 * into the unsigned char array pointed to by c.
 */
#define U32TO8_BIG(c, v)    do { \
		u32 x = (v); \
		u8 *d = (c); \
		d[0] = T8(x >> 24); \
		d[1] = T8(x >> 16); \
		d[2] = T8(x >> 8); \
		d[3] = T8(x); \
	} while (0)

/*
 * U8TO32_LITTLE(c, v) stores the 32-bit-value v in little-endian convention
 * into the unsigned char array pointed to by c.
 */
#define U32TO8_LITTLE(c, v)    do { \
		u32 x = (v); \
		u8 *d = (c); \
		d[0] = T8(x); \
		d[1] = T8(x >> 8); \
		d[2] = T8(x >> 16); \
		d[3] = T8(x >> 24); \
	} while (0)

/*
 * ROTL32(v, n) returns the value of the 32-bit unsigned value v after
 * a rotation of n bits to the left. It might be replaced by the appropriate
 * architecture-specific macro.
 *
 * It evaluates v and n twice.
 *
 * The compiler might emit a warning if n is the constant 0. The result
 * is undefined if n is greater than 31.
 */
#define ROTL32(v, n)   (T32((v) << (n)) | ((v) >> (32 - (n))))

/*
 *  Khazad-specific definitions
 */
#define R			8
#define KEYSIZE		128
#define KEYSIZEB	(KEYSIZE/8)
#define BLOCKSIZE	64
#define BLOCKSIZEB	(BLOCKSIZE/8)

typedef struct NESSIEstruct {
	u32 roundKeyEnc[R + 1][2];
	u32 roundKeyDec[R + 1][2];
} NESSIEstruct;

/**
 * Create the Khazad key schedule for a given cipher key.
 * Both encryption and decryption key schedules are generated.
 * 
 * @param key			The 128-bit cipher key.
 * @param structpointer	Pointer to the structure that will hold the expanded key.
 */
void NESSIEkeysetup(const unsigned char * const key,
				struct NESSIEstruct * const structpointer);

/**
 * Encrypt a data block.
 * 
 * @param	structpointer	the expanded key.
 * @param	plaintext		the data block to be encrypted.
 * @param	ciphertext		the encrypted data block.
 */
void NESSIEencrypt(const struct NESSIEstruct * const structpointer,
				   const unsigned char * const plaintext,
				         unsigned char * const ciphertext);

/**
 * Decrypt a data block.
 * 
 * @param	structpointer	the expanded key.
 * @param	ciphertext		the data block to be decrypted.
 * @param	plaintext		the decrypted data block.
 */
void NESSIEdecrypt(const struct NESSIEstruct * const structpointer,
				   const unsigned char * const ciphertext,
				         unsigned char * const plaintext);


#endif   /* PORTABLE_C__ */

/**
 * The Khazad legacy-level block cipher (32-bit implementation).
 *
 * <P>
 * <b>References</b>
 *
 * <P>
 * The Khazad algorithm was developed by
 * <a href="mailto:pbarreto@scopus.com.br">Paulo S. L. M. Barreto</a> and
 * <a href="mailto:vincent.rijmen@cryptomathic.com">Vincent Rijmen</a>.
 *
 * See
 *		P.S.L.M. Barreto, V. Rijmen,
 *		``The Khazad legacy-level block cipher,''
 *		NESSIE submission, 2000.
 * 
 * @author	Paulo S.L.M. Barreto
 * @author	Vincent Rijmen.
 *
 * @version 2.0 (2001.09.24)
 * 
 * =============================================================================
 *
 * Differences from version 1.0:
 *
 * - Original S-box replaced by the tweaked, hardware-efficient version.
 *
 * =============================================================================
 *
 * 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.
 *
 */

/*
 * Though Khazad is endianness-neutral, the encryption tables are listed
 * in BIG-ENDIAN format, which is adopted throughout this implementation
 * (but little-endian notation would be equally suitable if consistently
 * employed).
 */

static const u32 U0[256] = {
    0xbad3d268UL, 0x54fc4d19UL, 0x2f71bc93UL, 0x749ccdb9UL,
    0x53f55102UL, 0xd3686bb8UL, 0xd26b6fbdUL, 0x4dd72964UL,
    0x50f05d0dUL, 0xace98a26UL, 0x8d8a0e83UL, 0xbfdcc679UL,
    0x7090ddadUL, 0x52f65507UL, 0x9ab352c8UL, 0x4cd42d61UL,
    0xea238f65UL, 0xd56273a6UL, 0x97a466f1UL, 0xd16e63b2UL,
    0x3355ccffUL, 0x51f35908UL, 0x5bed712aUL, 0xa6f7a204UL,
    0xde7f5f81UL, 0x48d83d75UL, 0xa8e59a32UL, 0x99b65ec7UL,
    0xdb704b90UL, 0x3256c8faUL, 0xb7c4e651UL, 0xfc19d72bUL,
    0xe338ab48UL, 0x9ebf42dcUL, 0x91ae7eefUL, 0x9bb056cdUL,
    0xe23baf4dUL, 0xbbd0d66dUL, 0x41c31958UL, 0x6eb2a5cbUL,
    0xa5f2ae0bUL, 0xcb400bc0UL, 0x6bbdb1daUL, 0x95a26efbUL,
    0xa1febe1fUL, 0xf308eb18UL, 0xb1cefe4fUL, 0x0206080aUL,
    0xcc4917dbUL, 0xc45137f3UL, 0x1d277469UL, 0x143c5044UL,
    0xc3582be8UL, 0x63a591f2UL, 0xda734f95UL, 0x5de76934UL,
    0x5fe1613eUL, 0xdc79578bUL, 0x7d87e994UL, 0xcd4a13deUL,
    0x7f81e19eUL, 0x5aee752fUL, 0x6cb4adc1UL, 0x5ce46d31UL,
    0xf704fb0cUL, 0x266a98beUL, 0xff1cdb24UL, 0xed2a937eUL,
    0xe825876fUL, 0x9dba4ed3UL, 0x6fb1a1ceUL, 0x8e8f028cUL,
    0x192b647dUL, 0xa0fdba1aUL, 0xf00de717UL, 0x89861e97UL,
    0x0f113c33UL, 0x07091c1bUL, 0xafec8629UL, 0xfb10cb30UL,
    0x08182028UL, 0x153f5441UL, 0x0d173439UL, 0x040c1014UL,
    0x01030405UL, 0x64ac8de9UL, 0xdf7c5b84UL, 0x769ac5b3UL,
    0x798bf980UL, 0xdd7a538eUL, 0x3d47f4c9UL, 0x163a584eUL,
    0x3f41fcc3UL, 0x3759dcebUL, 0x6db7a9c4UL, 0x3848e0d8UL,
    0xb9d6de67UL, 0x7395d1a2UL, 0xe926836aUL, 0x355fd4e1UL,
    0x55ff491cUL, 0x7193d9a8UL, 0x7b8df18aUL, 0x8c890a86UL,
    0x7296d5a7UL, 0x88851a92UL, 0xf607ff09UL, 0x2a7ea882UL,
    0x3e42f8c6UL, 0x5ee2653bUL, 0x27699cbbUL, 0x46ca0543UL,
    0x0c14303cUL, 0x65af89ecUL, 0x68b8bdd5UL, 0x61a399f8UL,
    0x03050c0fUL, 0xc15e23e2UL, 0x57f94116UL, 0xd6677fa9UL,
    0xd976439aUL, 0x58e87d25UL, 0xd875479fUL, 0x66aa85e3UL,
    0xd7647bacUL, 0x3a4ee8d2UL, 0xc84507cfUL, 0x3c44f0ccUL,
    0xfa13cf35UL, 0x96a762f4UL, 0xa7f4a601UL, 0x98b55ac2UL,
    0xec29977bUL, 0xb8d5da62UL, 0xc7543bfcUL, 0xaeef822cUL,
    0x69bbb9d0UL, 0x4bdd317aUL, 0xabe0963dUL, 0xa9e69e37UL,
    0x67a981e6UL, 0x0a1e2822UL, 0x47c90146UL, 0xf20bef1dUL,
    0xb5c2ee5bUL, 0x226688aaUL, 0xe532b356UL, 0xee2f9f71UL,
    0xbedfc27cUL, 0x2b7dac87UL, 0x819e3ebfUL, 0x1236485aUL,
    0x839836b5UL, 0x1b2d6c77UL, 0x0e123836UL, 0x23658cafUL,
    0xf502f306UL, 0x45cf094cUL, 0x216384a5UL, 0xce4f1fd1UL,
    0x49db3970UL, 0x2c74b09cUL, 0xf916c33aUL, 0xe637bf59UL,
    0xb6c7e254UL, 0x2878a088UL, 0x17395c4bUL, 0x829b32b0UL,
    0x1a2e6872UL, 0x8b80169dUL, 0xfe1fdf21UL, 0x8a831298UL,
    0x091b242dUL, 0xc94603caUL, 0x879426a1UL, 0x4ed2256bUL,
    0xe13ea342UL, 0x2e72b896UL, 0xe431b753UL, 0xe03da747UL,
    0xeb208b60UL, 0x90ad7aeaUL, 0xa4f1aa0eUL, 0x1e227866UL,
    0x85922eabUL, 0x60a09dfdUL, 0x00000000UL, 0x256f94b1UL,
    0xf401f703UL, 0xf10ee312UL, 0x94a16afeUL, 0x0b1d2c27UL,
    0xe734bb5cUL, 0x759fc9bcUL, 0xef2c9b74UL, 0x345cd0e4UL,
    0x3153c4f5UL, 0xd46177a3UL, 0xd06d67b7UL, 0x869722a4UL,
    0x7e82e59bUL, 0xadea8e23UL, 0xfd1ad32eUL, 0x297ba48dUL,
    0x3050c0f0UL, 0x3b4decd7UL, 0x9fbc46d9UL, 0xf815c73fUL,
    0xc6573ff9UL, 0x13354c5fUL, 0x060a181eUL, 0x050f1411UL,
    0xc55233f6UL, 0x11334455UL, 0x7799c1b6UL, 0x7c84ed91UL,
    0x7a8ef58fUL, 0x7888fd85UL, 0x365ad8eeUL, 0x1c24706cUL,
    0x394be4ddUL, 0x59eb7920UL, 0x18286078UL, 0x56fa4513UL,
    0xb3c8f645UL, 0xb0cdfa4aUL, 0x246c90b4UL, 0x206080a0UL,
    0xb2cbf240UL, 0x92ab72e0UL, 0xa3f8b615UL, 0xc05d27e7UL,
    0x44cc0d49UL, 0x62a695f7UL, 0x10304050UL, 0xb4c1ea5eUL,
    0x84912aaeUL, 0x43c51152UL, 0x93a876e5UL, 0xc25b2fedUL,
    0x4ade357fUL, 0xbddace73UL, 0x8f8c0689UL, 0x2d77b499UL,
    0xbcd9ca76UL, 0x9cb94ad6UL, 0x6abeb5dfUL, 0x40c01d5dUL,
    0xcf4c1bd4UL, 0xa2fbb210UL, 0x809d3abaUL, 0x4fd1216eUL,
    0x1f217c63UL, 0xca430fc5UL, 0xaae39238UL, 0x42c61557UL,
};

static const u32 V0[256] = {
    0xbbb96a01UL, 0xe59a66b1UL, 0xe26514cdUL, 0x25871b51UL,
    0xf7a257a4UL, 0xd0d6be03UL, 0xd6deb504UL, 0xb35285feUL,
    0xfdba4aadUL, 0xcf09e063UL, 0x091c9684UL, 0xa5914d1aUL,
    0x3da7374dUL, 0xf1aa5ca3UL, 0x7ba417e1UL, 0xb55a8ef9UL,
    0x460320acUL, 0xc4e68411UL, 0x55cc68c2UL, 0xdcc6a80dUL,
    0xaa85d099UL, 0xfbb241aaUL, 0xc7e20f9cUL, 0xf359ae55UL,
    0xfebec120UL, 0xad7aa2e5UL, 0xd729cc7fUL, 0x71bc0ae8UL,
    0xe096e63bUL, 0xac8ddb9eUL, 0x95d11522UL, 0x32b3aaceUL,
    0x704b7393UL, 0x63843bfdUL, 0x41fc52d0UL, 0x7dac1ce6UL,
    0x76437894UL, 0xbdb16106UL, 0x9b32f1daUL, 0x7957e517UL,
    0xf941b35cUL, 0x8016564bUL, 0x677fc20cUL, 0x59dc7eccUL,
    0xe1619f40UL, 0x10cbc3e3UL, 0x81e12f30UL, 0x0c10160eUL,
    0x922e675eUL, 0xa26e3f66UL, 0x4ee8cf53UL, 0x78a09c6cUL,
    0xb0560e73UL, 0x573f9a34UL, 0xe69eed3cUL, 0xd3d2358eUL,
    0xdfc22380UL, 0xf2aed72eUL, 0x13cf486eUL, 0x94266c59UL,
    0x1fdf5e60UL, 0xc1ea049bUL, 0x7547f319UL, 0xd5da3e89UL,
    0x08ebefffUL, 0xd42d47f2UL, 0x38abb7c7UL, 0x543b11b9UL,
    0x4a1336a2UL, 0x699c26f4UL, 0x7f5fee10UL, 0x03048b8dUL,
    0x56c8e34fUL, 0xe7699447UL, 0x1ad3deeaUL, 0x113cba98UL,
    0x2278692dUL, 0x12383115UL, 0xc511fd6aUL, 0x208b9bdbUL,
    0x30405838UL, 0x7ea8976bUL, 0x2e687f23UL, 0x18202c1cUL,
    0x06080b07UL, 0x4507ab21UL, 0xf8b6ca27UL, 0x29970d5fUL,
    0x0bef6472UL, 0xf4a6dc29UL, 0x8ef5b2b3UL, 0x74b08a62UL,
    0x82e5a4bdUL, 0xb2a5fc85UL, 0x734ff81eUL, 0x90dd95a8UL,
    0xb1a17708UL, 0x37bf2a44UL, 0x4c1b3da5UL, 0xbeb5ea8bUL,
    0xe3926db6UL, 0x3baf3c4aUL, 0x07ff727cUL, 0x0f149d83UL,
    0x31b72143UL, 0x1734b19fUL, 0x0ee3e4f8UL, 0xfc4d33d6UL,
    0x84edafbaUL, 0xd9ca2887UL, 0xd2254cf5UL, 0x890ac0cfUL,
    0x28607424UL, 0x430fa026UL, 0x6d67df05UL, 0x5b2f8c3aUL,
    0x0a181d09UL, 0xbc46187dUL, 0xef827bb8UL, 0xcefe9918UL,
    0xec86f035UL, 0xcdfa1295UL, 0xea8efb32UL, 0x4917bd2fUL,
    0xc8f6921fUL, 0x9ccd83a6UL, 0x8a0e4b42UL, 0x88fdb9b4UL,
    0x268390dcUL, 0x53c463c5UL, 0xf551a552UL, 0x77b401efUL,
    0x52331abeUL, 0xb7a97c0fUL, 0xa876226fUL, 0xc319f66dUL,
    0x6b6fd402UL, 0xa762bfecUL, 0xdd31d176UL, 0xd121c778UL,
    0x4f1fb628UL, 0x3c504e36UL, 0x8f02cbc8UL, 0x16c3c8e4UL,
    0x99c1032cUL, 0xcc0d6beeUL, 0x647b4981UL, 0x5e230cb0UL,
    0xa399461dUL, 0xfa4538d1UL, 0x217ce2a0UL, 0x6c90a67eUL,
    0x2d6cf4aeUL, 0x5ad8f541UL, 0x2470622aUL, 0xca0560e9UL,
    0x04fbf9f1UL, 0x8312ddc6UL, 0xc61576e7UL, 0x9e3e7150UL,
    0xab72a9e2UL, 0xe87d09c4UL, 0x2c9b8dd5UL, 0x6e635488UL,
    0x93d91e25UL, 0xf05d25d8UL, 0x72b88165UL, 0x2b64ffa9UL,
    0x5cd0fe46UL, 0x1d2cac96UL, 0x3ea3bcc0UL, 0x1b24a791UL,
    0x3648533fUL, 0x8c064045UL, 0x354cd8b2UL, 0xb94a98f7UL,
    0x7c5b659dUL, 0xe46d1fcaUL, 0x62734286UL, 0x7a536e9aUL,
    0x400b2babUL, 0x47f459d7UL, 0xff49b85bUL, 0x44f0d25aUL,
    0x395ccebcUL, 0x5d27873dUL, 0x00000000UL, 0xde355afbUL,
    0x02f3f2f6UL, 0x1cdbd5edUL, 0x5fd475cbUL, 0x3a584531UL,
    0x686b5f8fUL, 0x238f1056UL, 0x582b07b7UL, 0xb8bde18cUL,
    0xa695c697UL, 0xc2ee8f16UL, 0xdacea30aUL, 0x3344d3b5UL,
    0x19d75567UL, 0xc901eb64UL, 0x34bba1c9UL, 0xf6552edfUL,
    0xa09dcd90UL, 0x9ac588a1UL, 0x658c30faUL, 0x2a9386d2UL,
    0xae7e2968UL, 0x6a98ad79UL, 0x14303a12UL, 0x1e28271bUL,
    0xa4663461UL, 0x6688bb77UL, 0x2f9f0658UL, 0x15c74369UL,
    0x01f7797bUL, 0x0de76f75UL, 0xb4adf782UL, 0x48e0c454UL,
    0x96d59eafUL, 0xcbf21992UL, 0x50c0e848UL, 0xe98a70bfUL,
    0x8df1393eUL, 0x87e92437UL, 0xd83d51fcUL, 0xc01d7de0UL,
    0x8bf93239UL, 0x4be44fd9UL, 0xed71894eUL, 0xba4e137aUL,
    0x851ad6c1UL, 0x51379133UL, 0x6080b070UL, 0x9fc9082bUL,
    0x3f54c5bbUL, 0x9722e7d4UL, 0x4dec44deUL, 0xb65e0574UL,
    0xa16ab4ebUL, 0xa9815b14UL, 0x050c808aUL, 0xee7502c3UL,
    0xaf895013UL, 0x6f942df3UL, 0x6177c90bUL, 0x9d3afaddUL,
    0x98367a57UL, 0xeb798249UL, 0x2774e9a7UL, 0xbf4293f0UL,
    0x42f8d95dUL, 0x861e5d4cUL, 0xdb39da71UL, 0x912aecd3UL,
};

static const u32 U1[256] = {
    0xd3ba68d2UL, 0xfc54194dUL, 0x712f93bcUL, 0x9c74b9cdUL,
    0xf5530251UL, 0x68d3b86bUL, 0x6bd2bd6fUL, 0xd74d6429UL,
    0xf0500d5dUL, 0xe9ac268aUL, 0x8a8d830eUL, 0xdcbf79c6UL,
    0x9070adddUL, 0xf6520755UL, 0xb39ac852UL, 0xd44c612dUL,
    0x23ea658fUL, 0x62d5a673UL, 0xa497f166UL, 0x6ed1b263UL,
    0x5533ffccUL, 0xf3510859UL, 0xed5b2a71UL, 0xf7a604a2UL,
    0x7fde815fUL, 0xd848753dUL, 0xe5a8329aUL, 0xb699c75eUL,
    0x70db904bUL, 0x5632fac8UL, 0xc4b751e6UL, 0x19fc2bd7UL,
    0x38e348abUL, 0xbf9edc42UL, 0xae91ef7eUL, 0xb09bcd56UL,
    0x3be24dafUL, 0xd0bb6dd6UL, 0xc3415819UL, 0xb26ecba5UL,
    0xf2a50baeUL, 0x40cbc00bUL, 0xbd6bdab1UL, 0xa295fb6eUL,
    0xfea11fbeUL, 0x08f318ebUL, 0xceb14ffeUL, 0x06020a08UL,
    0x49ccdb17UL, 0x51c4f337UL, 0x271d6974UL, 0x3c144450UL,
    0x58c3e82bUL, 0xa563f291UL, 0x73da954fUL, 0xe75d3469UL,
    0xe15f3e61UL, 0x79dc8b57UL, 0x877d94e9UL, 0x4acdde13UL,
    0x817f9ee1UL, 0xee5a2f75UL, 0xb46cc1adUL, 0xe45c316dUL,
    0x04f70cfbUL, 0x6a26be98UL, 0x1cff24dbUL, 0x2aed7e93UL,
    0x25e86f87UL, 0xba9dd34eUL, 0xb16fcea1UL, 0x8f8e8c02UL,
    0x2b197d64UL, 0xfda01abaUL, 0x0df017e7UL, 0x8689971eUL,
    0x110f333cUL, 0x09071b1cUL, 0xecaf2986UL, 0x10fb30cbUL,
    0x18082820UL, 0x3f154154UL, 0x170d3934UL, 0x0c041410UL,
    0x03010504UL, 0xac64e98dUL, 0x7cdf845bUL, 0x9a76b3c5UL,
    0x8b7980f9UL, 0x7add8e53UL, 0x473dc9f4UL, 0x3a164e58UL,
    0x413fc3fcUL, 0x5937ebdcUL, 0xb76dc4a9UL, 0x4838d8e0UL,
    0xd6b967deUL, 0x9573a2d1UL, 0x26e96a83UL, 0x5f35e1d4UL,
    0xff551c49UL, 0x9371a8d9UL, 0x8d7b8af1UL, 0x898c860aUL,
    0x9672a7d5UL, 0x8588921aUL, 0x07f609ffUL, 0x7e2a82a8UL,
    0x423ec6f8UL, 0xe25e3b65UL, 0x6927bb9cUL, 0xca464305UL,
    0x140c3c30UL, 0xaf65ec89UL, 0xb868d5bdUL, 0xa361f899UL,
    0x05030f0cUL, 0x5ec1e223UL, 0xf9571641UL, 0x67d6a97fUL,
    0x76d99a43UL, 0xe858257dUL, 0x75d89f47UL, 0xaa66e385UL,
    0x64d7ac7bUL, 0x4e3ad2e8UL, 0x45c8cf07UL, 0x443cccf0UL,
    0x13fa35cfUL, 0xa796f462UL, 0xf4a701a6UL, 0xb598c25aUL,
    0x29ec7b97UL, 0xd5b862daUL, 0x54c7fc3bUL, 0xefae2c82UL,
    0xbb69d0b9UL, 0xdd4b7a31UL, 0xe0ab3d96UL, 0xe6a9379eUL,
    0xa967e681UL, 0x1e0a2228UL, 0xc9474601UL, 0x0bf21defUL,
    0xc2b55beeUL, 0x6622aa88UL, 0x32e556b3UL, 0x2fee719fUL,
    0xdfbe7cc2UL, 0x7d2b87acUL, 0x9e81bf3eUL, 0x36125a48UL,
    0x9883b536UL, 0x2d1b776cUL, 0x120e3638UL, 0x6523af8cUL,
    0x02f506f3UL, 0xcf454c09UL, 0x6321a584UL, 0x4fced11fUL,
    0xdb497039UL, 0x742c9cb0UL, 0x16f93ac3UL, 0x37e659bfUL,
    0xc7b654e2UL, 0x782888a0UL, 0x39174b5cUL, 0x9b82b032UL,
    0x2e1a7268UL, 0x808b9d16UL, 0x1ffe21dfUL, 0x838a9812UL,
    0x1b092d24UL, 0x46c9ca03UL, 0x9487a126UL, 0xd24e6b25UL,
    0x3ee142a3UL, 0x722e96b8UL, 0x31e453b7UL, 0x3de047a7UL,
    0x20eb608bUL, 0xad90ea7aUL, 0xf1a40eaaUL, 0x221e6678UL,
    0x9285ab2eUL, 0xa060fd9dUL, 0x00000000UL, 0x6f25b194UL,
    0x01f403f7UL, 0x0ef112e3UL, 0xa194fe6aUL, 0x1d0b272cUL,
    0x34e75cbbUL, 0x9f75bcc9UL, 0x2cef749bUL, 0x5c34e4d0UL,
    0x5331f5c4UL, 0x61d4a377UL, 0x6dd0b767UL, 0x9786a422UL,
    0x827e9be5UL, 0xeaad238eUL, 0x1afd2ed3UL, 0x7b298da4UL,
    0x5030f0c0UL, 0x4d3bd7ecUL, 0xbc9fd946UL, 0x15f83fc7UL,
    0x57c6f93fUL, 0x35135f4cUL, 0x0a061e18UL, 0x0f051114UL,
    0x52c5f633UL, 0x33115544UL, 0x9977b6c1UL, 0x847c91edUL,
    0x8e7a8ff5UL, 0x887885fdUL, 0x5a36eed8UL, 0x241c6c70UL,
    0x4b39dde4UL, 0xeb592079UL, 0x28187860UL, 0xfa561345UL,
    0xc8b345f6UL, 0xcdb04afaUL, 0x6c24b490UL, 0x6020a080UL,
    0xcbb240f2UL, 0xab92e072UL, 0xf8a315b6UL, 0x5dc0e727UL,
    0xcc44490dUL, 0xa662f795UL, 0x30105040UL, 0xc1b45eeaUL,
    0x9184ae2aUL, 0xc5435211UL, 0xa893e576UL, 0x5bc2ed2fUL,
    0xde4a7f35UL, 0xdabd73ceUL, 0x8c8f8906UL, 0x772d99b4UL,
    0xd9bc76caUL, 0xb99cd64aUL, 0xbe6adfb5UL, 0xc0405d1dUL,
    0x4ccfd41bUL, 0xfba210b2UL, 0x9d80ba3aUL, 0xd14f6e21UL,
    0x211f637cUL, 0x43cac50fUL, 0xe3aa3892UL, 0xc6425715UL,
};

static const u32 V1[256] = {
    0xb9bb016aUL, 0x9ae5b166UL, 0x65e2cd14UL, 0x8725511bUL,
    0xa2f7a457UL, 0xd6d003beUL, 0xded604b5UL, 0x52b3fe85UL,
    0xbafdad4aUL, 0x09cf63e0UL, 0x1c098496UL, 0x91a51a4dUL,
    0xa73d4d37UL, 0xaaf1a35cUL, 0xa47be117UL, 0x5ab5f98eUL,
    0x0346ac20UL, 0xe6c41184UL, 0xcc55c268UL, 0xc6dc0da8UL,
    0x85aa99d0UL, 0xb2fbaa41UL, 0xe2c79c0fUL, 0x59f355aeUL,
    0xbefe20c1UL, 0x7aade5a2UL, 0x29d77fccUL, 0xbc71e80aUL,
    0x96e03be6UL, 0x8dac9edbUL, 0xd1952215UL, 0xb332ceaaUL,
    0x4b709373UL, 0x8463fd3bUL, 0xfc41d052UL, 0xac7de61cUL,
    0x43769478UL, 0xb1bd0661UL, 0x329bdaf1UL, 0x577917e5UL,
    0x41f95cb3UL, 0x16804b56UL, 0x7f670cc2UL, 0xdc59cc7eUL,
    0x61e1409fUL, 0xcb10e3c3UL, 0xe181302fUL, 0x100c0e16UL,
    0x2e925e67UL, 0x6ea2663fUL, 0xe84e53cfUL, 0xa0786c9cUL,
    0x56b0730eUL, 0x3f57349aUL, 0x9ee63cedUL, 0xd2d38e35UL,
    0xc2df8023UL, 0xaef22ed7UL, 0xcf136e48UL, 0x2694596cUL,
    0xdf1f605eUL, 0xeac19b04UL, 0x477519f3UL, 0xdad5893eUL,
    0xeb08ffefUL, 0x2dd4f247UL, 0xab38c7b7UL, 0x3b54b911UL,
    0x134aa236UL, 0x9c69f426UL, 0x5f7f10eeUL, 0x04038d8bUL,
    0xc8564fe3UL, 0x69e74794UL, 0xd31aeadeUL, 0x3c1198baUL,
    0x78222d69UL, 0x38121531UL, 0x11c56afdUL, 0x8b20db9bUL,
    0x40303858UL, 0xa87e6b97UL, 0x682e237fUL, 0x20181c2cUL,
    0x0806070bUL, 0x074521abUL, 0xb6f827caUL, 0x97295f0dUL,
    0xef0b7264UL, 0xa6f429dcUL, 0xf58eb3b2UL, 0xb074628aUL,
    0xe582bda4UL, 0xa5b285fcUL, 0x4f731ef8UL, 0xdd90a895UL,
    0xa1b10877UL, 0xbf37442aUL, 0x1b4ca53dUL, 0xb5be8beaUL,
    0x92e3b66dUL, 0xaf3b4a3cUL, 0xff077c72UL, 0x140f839dUL,
    0xb7314321UL, 0x34179fb1UL, 0xe30ef8e4UL, 0x4dfcd633UL,
    0xed84baafUL, 0xcad98728UL, 0x25d2f54cUL, 0x0a89cfc0UL,
    0x60282474UL, 0x0f4326a0UL, 0x676d05dfUL, 0x2f5b3a8cUL,
    0x180a091dUL, 0x46bc7d18UL, 0x82efb87bUL, 0xfece1899UL,
    0x86ec35f0UL, 0xfacd9512UL, 0x8eea32fbUL, 0x17492fbdUL,
    0xf6c81f92UL, 0xcd9ca683UL, 0x0e8a424bUL, 0xfd88b4b9UL,
    0x8326dc90UL, 0xc453c563UL, 0x51f552a5UL, 0xb477ef01UL,
    0x3352be1aUL, 0xa9b70f7cUL, 0x76a86f22UL, 0x19c36df6UL,
    0x6f6b02d4UL, 0x62a7ecbfUL, 0x31dd76d1UL, 0x21d178c7UL,
    0x1f4f28b6UL, 0x503c364eUL, 0x028fc8cbUL, 0xc316e4c8UL,
    0xc1992c03UL, 0x0dccee6bUL, 0x7b648149UL, 0x235eb00cUL,
    0x99a31d46UL, 0x45fad138UL, 0x7c21a0e2UL, 0x906c7ea6UL,
    0x6c2daef4UL, 0xd85a41f5UL, 0x70242a62UL, 0x05cae960UL,
    0xfb04f1f9UL, 0x1283c6ddUL, 0x15c6e776UL, 0x3e9e5071UL,
    0x72abe2a9UL, 0x7de8c409UL, 0x9b2cd58dUL, 0x636e8854UL,
    0xd993251eUL, 0x5df0d825UL, 0xb8726581UL, 0x642ba9ffUL,
    0xd05c46feUL, 0x2c1d96acUL, 0xa33ec0bcUL, 0x241b91a7UL,
    0x48363f53UL, 0x068c4540UL, 0x4c35b2d8UL, 0x4ab9f798UL,
    0x5b7c9d65UL, 0x6de4ca1fUL, 0x73628642UL, 0x537a9a6eUL,
    0x0b40ab2bUL, 0xf447d759UL, 0x49ff5bb8UL, 0xf0445ad2UL,
    0x5c39bcceUL, 0x275d3d87UL, 0x00000000UL, 0x35defb5aUL,
    0xf302f6f2UL, 0xdb1cedd5UL, 0xd45fcb75UL, 0x583a3145UL,
    0x6b688f5fUL, 0x8f235610UL, 0x2b58b707UL, 0xbdb88ce1UL,
    0x95a697c6UL, 0xeec2168fUL, 0xceda0aa3UL, 0x4433b5d3UL,
    0xd7196755UL, 0x01c964ebUL, 0xbb34c9a1UL, 0x55f6df2eUL,
    0x9da090cdUL, 0xc59aa188UL, 0x8c65fa30UL, 0x932ad286UL,
    0x7eae6829UL, 0x986a79adUL, 0x3014123aUL, 0x281e1b27UL,
    0x66a46134UL, 0x886677bbUL, 0x9f2f5806UL, 0xc7156943UL,
    0xf7017b79UL, 0xe70d756fUL, 0xadb482f7UL, 0xe04854c4UL,
    0xd596af9eUL, 0xf2cb9219UL, 0xc05048e8UL, 0x8ae9bf70UL,
    0xf18d3e39UL, 0xe9873724UL, 0x3dd8fc51UL, 0x1dc0e07dUL,
    0xf98b3932UL, 0xe44bd94fUL, 0x71ed4e89UL, 0x4eba7a13UL,
    0x1a85c1d6UL, 0x37513391UL, 0x806070b0UL, 0xc99f2b08UL,
    0x543fbbc5UL, 0x2297d4e7UL, 0xec4dde44UL, 0x5eb67405UL,
    0x6aa1ebb4UL, 0x81a9145bUL, 0x0c058a80UL, 0x75eec302UL,
    0x89af1350UL, 0x946ff32dUL, 0x77610bc9UL, 0x3a9dddfaUL,
    0x3698577aUL, 0x79eb4982UL, 0x7427a7e9UL, 0x42bff093UL,
    0xf8425dd9UL, 0x1e864c5dUL, 0x39db71daUL, 0x2a91d3ecUL,
};

static const u32 U2[256] = {
    0xd268bad3UL, 0x4d1954fcUL, 0xbc932f71UL, 0xcdb9749cUL,
    0x510253f5UL, 0x6bb8d368UL, 0x6fbdd26bUL, 0x29644dd7UL,
    0x5d0d50f0UL, 0x8a26ace9UL, 0x0e838d8aUL, 0xc679bfdcUL,
    0xddad7090UL, 0x550752f6UL, 0x52c89ab3UL, 0x2d614cd4UL,
    0x8f65ea23UL, 0x73a6d562UL, 0x66f197a4UL, 0x63b2d16eUL,
    0xccff3355UL, 0x590851f3UL, 0x712a5bedUL, 0xa204a6f7UL,
    0x5f81de7fUL, 0x3d7548d8UL, 0x9a32a8e5UL, 0x5ec799b6UL,
    0x4b90db70UL, 0xc8fa3256UL, 0xe651b7c4UL, 0xd72bfc19UL,
    0xab48e338UL, 0x42dc9ebfUL, 0x7eef91aeUL, 0x56cd9bb0UL,
    0xaf4de23bUL, 0xd66dbbd0UL, 0x195841c3UL, 0xa5cb6eb2UL,
    0xae0ba5f2UL, 0x0bc0cb40UL, 0xb1da6bbdUL, 0x6efb95a2UL,
    0xbe1fa1feUL, 0xeb18f308UL, 0xfe4fb1ceUL, 0x080a0206UL,
    0x17dbcc49UL, 0x37f3c451UL, 0x74691d27UL, 0x5044143cUL,
    0x2be8c358UL, 0x91f263a5UL, 0x4f95da73UL, 0x69345de7UL,
    0x613e5fe1UL, 0x578bdc79UL, 0xe9947d87UL, 0x13decd4aUL,
    0xe19e7f81UL, 0x752f5aeeUL, 0xadc16cb4UL, 0x6d315ce4UL,
    0xfb0cf704UL, 0x98be266aUL, 0xdb24ff1cUL, 0x937eed2aUL,
    0x876fe825UL, 0x4ed39dbaUL, 0xa1ce6fb1UL, 0x028c8e8fUL,
    0x647d192bUL, 0xba1aa0fdUL, 0xe717f00dUL, 0x1e978986UL,
    0x3c330f11UL, 0x1c1b0709UL, 0x8629afecUL, 0xcb30fb10UL,
    0x20280818UL, 0x5441153fUL, 0x34390d17UL, 0x1014040cUL,
    0x04050103UL, 0x8de964acUL, 0x5b84df7cUL, 0xc5b3769aUL,
    0xf980798bUL, 0x538edd7aUL, 0xf4c93d47UL, 0x584e163aUL,
    0xfcc33f41UL, 0xdceb3759UL, 0xa9c46db7UL, 0xe0d83848UL,
    0xde67b9d6UL, 0xd1a27395UL, 0x836ae926UL, 0xd4e1355fUL,
    0x491c55ffUL, 0xd9a87193UL, 0xf18a7b8dUL, 0x0a868c89UL,
    0xd5a77296UL, 0x1a928885UL, 0xff09f607UL, 0xa8822a7eUL,
    0xf8c63e42UL, 0x653b5ee2UL, 0x9cbb2769UL, 0x054346caUL,
    0x303c0c14UL, 0x89ec65afUL, 0xbdd568b8UL, 0x99f861a3UL,
    0x0c0f0305UL, 0x23e2c15eUL, 0x411657f9UL, 0x7fa9d667UL,
    0x439ad976UL, 0x7d2558e8UL, 0x479fd875UL, 0x85e366aaUL,
    0x7bacd764UL, 0xe8d23a4eUL, 0x07cfc845UL, 0xf0cc3c44UL,
    0xcf35fa13UL, 0x62f496a7UL, 0xa601a7f4UL, 0x5ac298b5UL,
    0x977bec29UL, 0xda62b8d5UL, 0x3bfcc754UL, 0x822caeefUL,
    0xb9d069bbUL, 0x317a4bddUL, 0x963dabe0UL, 0x9e37a9e6UL,
    0x81e667a9UL, 0x28220a1eUL, 0x014647c9UL, 0xef1df20bUL,
    0xee5bb5c2UL, 0x88aa2266UL, 0xb356e532UL, 0x9f71ee2fUL,
    0xc27cbedfUL, 0xac872b7dUL, 0x3ebf819eUL, 0x485a1236UL,
    0x36b58398UL, 0x6c771b2dUL, 0x38360e12UL, 0x8caf2365UL,
    0xf306f502UL, 0x094c45cfUL, 0x84a52163UL, 0x1fd1ce4fUL,
    0x397049dbUL, 0xb09c2c74UL, 0xc33af916UL, 0xbf59e637UL,
    0xe254b6c7UL, 0xa0882878UL, 0x5c4b1739UL, 0x32b0829bUL,
    0x68721a2eUL, 0x169d8b80UL, 0xdf21fe1fUL, 0x12988a83UL,
    0x242d091bUL, 0x03cac946UL, 0x26a18794UL, 0x256b4ed2UL,
    0xa342e13eUL, 0xb8962e72UL, 0xb753e431UL, 0xa747e03dUL,
    0x8b60eb20UL, 0x7aea90adUL, 0xaa0ea4f1UL, 0x78661e22UL,
    0x2eab8592UL, 0x9dfd60a0UL, 0x00000000UL, 0x94b1256fUL,
    0xf703f401UL, 0xe312f10eUL, 0x6afe94a1UL, 0x2c270b1dUL,
    0xbb5ce734UL, 0xc9bc759fUL, 0x9b74ef2cUL, 0xd0e4345cUL,
    0xc4f53153UL, 0x77a3d461UL, 0x67b7d06dUL, 0x22a48697UL,
    0xe59b7e82UL, 0x8e23adeaUL, 0xd32efd1aUL, 0xa48d297bUL,
    0xc0f03050UL, 0xecd73b4dUL, 0x46d99fbcUL, 0xc73ff815UL,
    0x3ff9c657UL, 0x4c5f1335UL, 0x181e060aUL, 0x1411050fUL,
    0x33f6c552UL, 0x44551133UL, 0xc1b67799UL, 0xed917c84UL,
    0xf58f7a8eUL, 0xfd857888UL, 0xd8ee365aUL, 0x706c1c24UL,
    0xe4dd394bUL, 0x792059ebUL, 0x60781828UL, 0x451356faUL,
    0xf645b3c8UL, 0xfa4ab0cdUL, 0x90b4246cUL, 0x80a02060UL,
    0xf240b2cbUL, 0x72e092abUL, 0xb615a3f8UL, 0x27e7c05dUL,
    0x0d4944ccUL, 0x95f762a6UL, 0x40501030UL, 0xea5eb4c1UL,
    0x2aae8491UL, 0x115243c5UL, 0x76e593a8UL, 0x2fedc25bUL,
    0x357f4adeUL, 0xce73bddaUL, 0x06898f8cUL, 0xb4992d77UL,
    0xca76bcd9UL, 0x4ad69cb9UL, 0xb5df6abeUL, 0x1d5d40c0UL,
    0x1bd4cf4cUL, 0xb210a2fbUL, 0x3aba809dUL, 0x216e4fd1UL,
    0x7c631f21UL, 0x0fc5ca43UL, 0x9238aae3UL, 0x155742c6UL,
};

static const u32 V2[256] = {
    0x6a01bbb9UL, 0x66b1e59aUL, 0x14cde265UL, 0x1b512587UL,
    0x57a4f7a2UL, 0xbe03d0d6UL, 0xb504d6deUL, 0x85feb352UL,
    0x4aadfdbaUL, 0xe063cf09UL, 0x9684091cUL, 0x4d1aa591UL,
    0x374d3da7UL, 0x5ca3f1aaUL, 0x17e17ba4UL, 0x8ef9b55aUL,
    0x20ac4603UL, 0x8411c4e6UL, 0x68c255ccUL, 0xa80ddcc6UL,
    0xd099aa85UL, 0x41aafbb2UL, 0x0f9cc7e2UL, 0xae55f359UL,
    0xc120febeUL, 0xa2e5ad7aUL, 0xcc7fd729UL, 0x0ae871bcUL,
    0xe63be096UL, 0xdb9eac8dUL, 0x152295d1UL, 0xaace32b3UL,
    0x7393704bUL, 0x3bfd6384UL, 0x52d041fcUL, 0x1ce67dacUL,
    0x78947643UL, 0x6106bdb1UL, 0xf1da9b32UL, 0xe5177957UL,
    0xb35cf941UL, 0x564b8016UL, 0xc20c677fUL, 0x7ecc59dcUL,
    0x9f40e161UL, 0xc3e310cbUL, 0x2f3081e1UL, 0x160e0c10UL,
    0x675e922eUL, 0x3f66a26eUL, 0xcf534ee8UL, 0x9c6c78a0UL,
    0x0e73b056UL, 0x9a34573fUL, 0xed3ce69eUL, 0x358ed3d2UL,
    0x2380dfc2UL, 0xd72ef2aeUL, 0x486e13cfUL, 0x6c599426UL,
    0x5e601fdfUL, 0x049bc1eaUL, 0xf3197547UL, 0x3e89d5daUL,
    0xefff08ebUL, 0x47f2d42dUL, 0xb7c738abUL, 0x11b9543bUL,
    0x36a24a13UL, 0x26f4699cUL, 0xee107f5fUL, 0x8b8d0304UL,
    0xe34f56c8UL, 0x9447e769UL, 0xdeea1ad3UL, 0xba98113cUL,
    0x692d2278UL, 0x31151238UL, 0xfd6ac511UL, 0x9bdb208bUL,
    0x58383040UL, 0x976b7ea8UL, 0x7f232e68UL, 0x2c1c1820UL,
    0x0b070608UL, 0xab214507UL, 0xca27f8b6UL, 0x0d5f2997UL,
    0x64720befUL, 0xdc29f4a6UL, 0xb2b38ef5UL, 0x8a6274b0UL,
    0xa4bd82e5UL, 0xfc85b2a5UL, 0xf81e734fUL, 0x95a890ddUL,
    0x7708b1a1UL, 0x2a4437bfUL, 0x3da54c1bUL, 0xea8bbeb5UL,
    0x6db6e392UL, 0x3c4a3bafUL, 0x727c07ffUL, 0x9d830f14UL,
    0x214331b7UL, 0xb19f1734UL, 0xe4f80ee3UL, 0x33d6fc4dUL,
    0xafba84edUL, 0x2887d9caUL, 0x4cf5d225UL, 0xc0cf890aUL,
    0x74242860UL, 0xa026430fUL, 0xdf056d67UL, 0x8c3a5b2fUL,
    0x1d090a18UL, 0x187dbc46UL, 0x7bb8ef82UL, 0x9918cefeUL,
    0xf035ec86UL, 0x1295cdfaUL, 0xfb32ea8eUL, 0xbd2f4917UL,
    0x921fc8f6UL, 0x83a69ccdUL, 0x4b428a0eUL, 0xb9b488fdUL,
    0x90dc2683UL, 0x63c553c4UL, 0xa552f551UL, 0x01ef77b4UL,
    0x1abe5233UL, 0x7c0fb7a9UL, 0x226fa876UL, 0xf66dc319UL,
    0xd4026b6fUL, 0xbfeca762UL, 0xd176dd31UL, 0xc778d121UL,
    0xb6284f1fUL, 0x4e363c50UL, 0xcbc88f02UL, 0xc8e416c3UL,
    0x032c99c1UL, 0x6beecc0dUL, 0x4981647bUL, 0x0cb05e23UL,
    0x461da399UL, 0x38d1fa45UL, 0xe2a0217cUL, 0xa67e6c90UL,
    0xf4ae2d6cUL, 0xf5415ad8UL, 0x622a2470UL, 0x60e9ca05UL,
    0xf9f104fbUL, 0xddc68312UL, 0x76e7c615UL, 0x71509e3eUL,
    0xa9e2ab72UL, 0x09c4e87dUL, 0x8dd52c9bUL, 0x54886e63UL,
    0x1e2593d9UL, 0x25d8f05dUL, 0x816572b8UL, 0xffa92b64UL,
    0xfe465cd0UL, 0xac961d2cUL, 0xbcc03ea3UL, 0xa7911b24UL,
    0x533f3648UL, 0x40458c06UL, 0xd8b2354cUL, 0x98f7b94aUL,
    0x659d7c5bUL, 0x1fcae46dUL, 0x42866273UL, 0x6e9a7a53UL,
    0x2bab400bUL, 0x59d747f4UL, 0xb85bff49UL, 0xd25a44f0UL,
    0xcebc395cUL, 0x873d5d27UL, 0x00000000UL, 0x5afbde35UL,
    0xf2f602f3UL, 0xd5ed1cdbUL, 0x75cb5fd4UL, 0x45313a58UL,
    0x5f8f686bUL, 0x1056238fUL, 0x07b7582bUL, 0xe18cb8bdUL,
    0xc697a695UL, 0x8f16c2eeUL, 0xa30adaceUL, 0xd3b53344UL,
    0x556719d7UL, 0xeb64c901UL, 0xa1c934bbUL, 0x2edff655UL,
    0xcd90a09dUL, 0x88a19ac5UL, 0x30fa658cUL, 0x86d22a93UL,
    0x2968ae7eUL, 0xad796a98UL, 0x3a121430UL, 0x271b1e28UL,
    0x3461a466UL, 0xbb776688UL, 0x06582f9fUL, 0x436915c7UL,
    0x797b01f7UL, 0x6f750de7UL, 0xf782b4adUL, 0xc45448e0UL,
    0x9eaf96d5UL, 0x1992cbf2UL, 0xe84850c0UL, 0x70bfe98aUL,
    0x393e8df1UL, 0x243787e9UL, 0x51fcd83dUL, 0x7de0c01dUL,
    0x32398bf9UL, 0x4fd94be4UL, 0x894eed71UL, 0x137aba4eUL,
    0xd6c1851aUL, 0x91335137UL, 0xb0706080UL, 0x082b9fc9UL,
    0xc5bb3f54UL, 0xe7d49722UL, 0x44de4decUL, 0x0574b65eUL,
    0xb4eba16aUL, 0x5b14a981UL, 0x808a050cUL, 0x02c3ee75UL,
    0x5013af89UL, 0x2df36f94UL, 0xc90b6177UL, 0xfadd9d3aUL,
    0x7a579836UL, 0x8249eb79UL, 0xe9a72774UL, 0x93f0bf42UL,
    0xd95d42f8UL, 0x5d4c861eUL, 0xda71db39UL, 0xecd3912aUL,
};

static const u32 U3[256] = {
    0x68d2d3baUL, 0x194dfc54UL, 0x93bc712fUL, 0xb9cd9c74UL,
    0x0251f553UL, 0xb86b68d3UL, 0xbd6f6bd2UL, 0x6429d74dUL,
    0x0d5df050UL, 0x268ae9acUL, 0x830e8a8dUL, 0x79c6dcbfUL,
    0xaddd9070UL, 0x0755f652UL, 0xc852b39aUL, 0x612dd44cUL,
    0x658f23eaUL, 0xa67362d5UL, 0xf166a497UL, 0xb2636ed1UL,
    0xffcc5533UL, 0x0859f351UL, 0x2a71ed5bUL, 0x04a2f7a6UL,
    0x815f7fdeUL, 0x753dd848UL, 0x329ae5a8UL, 0xc75eb699UL,
    0x904b70dbUL, 0xfac85632UL, 0x51e6c4b7UL, 0x2bd719fcUL,
    0x48ab38e3UL, 0xdc42bf9eUL, 0xef7eae91UL, 0xcd56b09bUL,
    0x4daf3be2UL, 0x6dd6d0bbUL, 0x5819c341UL, 0xcba5b26eUL,
    0x0baef2a5UL, 0xc00b40cbUL, 0xdab1bd6bUL, 0xfb6ea295UL,
    0x1fbefea1UL, 0x18eb08f3UL, 0x4ffeceb1UL, 0x0a080602UL,
    0xdb1749ccUL, 0xf33751c4UL, 0x6974271dUL, 0x44503c14UL,
    0xe82b58c3UL, 0xf291a563UL, 0x954f73daUL, 0x3469e75dUL,
    0x3e61e15fUL, 0x8b5779dcUL, 0x94e9877dUL, 0xde134acdUL,
    0x9ee1817fUL, 0x2f75ee5aUL, 0xc1adb46cUL, 0x316de45cUL,
    0x0cfb04f7UL, 0xbe986a26UL, 0x24db1cffUL, 0x7e932aedUL,
    0x6f8725e8UL, 0xd34eba9dUL, 0xcea1b16fUL, 0x8c028f8eUL,
    0x7d642b19UL, 0x1abafda0UL, 0x17e70df0UL, 0x971e8689UL,
    0x333c110fUL, 0x1b1c0907UL, 0x2986ecafUL, 0x30cb10fbUL,
    0x28201808UL, 0x41543f15UL, 0x3934170dUL, 0x14100c04UL,
    0x05040301UL, 0xe98dac64UL, 0x845b7cdfUL, 0xb3c59a76UL,
    0x80f98b79UL, 0x8e537addUL, 0xc9f4473dUL, 0x4e583a16UL,
    0xc3fc413fUL, 0xebdc5937UL, 0xc4a9b76dUL, 0xd8e04838UL,
    0x67ded6b9UL, 0xa2d19573UL, 0x6a8326e9UL, 0xe1d45f35UL,
    0x1c49ff55UL, 0xa8d99371UL, 0x8af18d7bUL, 0x860a898cUL,
    0xa7d59672UL, 0x921a8588UL, 0x09ff07f6UL, 0x82a87e2aUL,
    0xc6f8423eUL, 0x3b65e25eUL, 0xbb9c6927UL, 0x4305ca46UL,
    0x3c30140cUL, 0xec89af65UL, 0xd5bdb868UL, 0xf899a361UL,
    0x0f0c0503UL, 0xe2235ec1UL, 0x1641f957UL, 0xa97f67d6UL,
    0x9a4376d9UL, 0x257de858UL, 0x9f4775d8UL, 0xe385aa66UL,
    0xac7b64d7UL, 0xd2e84e3aUL, 0xcf0745c8UL, 0xccf0443cUL,
    0x35cf13faUL, 0xf462a796UL, 0x01a6f4a7UL, 0xc25ab598UL,
    0x7b9729ecUL, 0x62dad5b8UL, 0xfc3b54c7UL, 0x2c82efaeUL,
    0xd0b9bb69UL, 0x7a31dd4bUL, 0x3d96e0abUL, 0x379ee6a9UL,
    0xe681a967UL, 0x22281e0aUL, 0x4601c947UL, 0x1def0bf2UL,
    0x5beec2b5UL, 0xaa886622UL, 0x56b332e5UL, 0x719f2feeUL,
    0x7cc2dfbeUL, 0x87ac7d2bUL, 0xbf3e9e81UL, 0x5a483612UL,
    0xb5369883UL, 0x776c2d1bUL, 0x3638120eUL, 0xaf8c6523UL,
    0x06f302f5UL, 0x4c09cf45UL, 0xa5846321UL, 0xd11f4fceUL,
    0x7039db49UL, 0x9cb0742cUL, 0x3ac316f9UL, 0x59bf37e6UL,
    0x54e2c7b6UL, 0x88a07828UL, 0x4b5c3917UL, 0xb0329b82UL,
    0x72682e1aUL, 0x9d16808bUL, 0x21df1ffeUL, 0x9812838aUL,
    0x2d241b09UL, 0xca0346c9UL, 0xa1269487UL, 0x6b25d24eUL,
    0x42a33ee1UL, 0x96b8722eUL, 0x53b731e4UL, 0x47a73de0UL,
    0x608b20ebUL, 0xea7aad90UL, 0x0eaaf1a4UL, 0x6678221eUL,
    0xab2e9285UL, 0xfd9da060UL, 0x00000000UL, 0xb1946f25UL,
    0x03f701f4UL, 0x12e30ef1UL, 0xfe6aa194UL, 0x272c1d0bUL,
    0x5cbb34e7UL, 0xbcc99f75UL, 0x749b2cefUL, 0xe4d05c34UL,
    0xf5c45331UL, 0xa37761d4UL, 0xb7676dd0UL, 0xa4229786UL,
    0x9be5827eUL, 0x238eeaadUL, 0x2ed31afdUL, 0x8da47b29UL,
    0xf0c05030UL, 0xd7ec4d3bUL, 0xd946bc9fUL, 0x3fc715f8UL,
    0xf93f57c6UL, 0x5f4c3513UL, 0x1e180a06UL, 0x11140f05UL,
    0xf63352c5UL, 0x55443311UL, 0xb6c19977UL, 0x91ed847cUL,
    0x8ff58e7aUL, 0x85fd8878UL, 0xeed85a36UL, 0x6c70241cUL,
    0xdde44b39UL, 0x2079eb59UL, 0x78602818UL, 0x1345fa56UL,
    0x45f6c8b3UL, 0x4afacdb0UL, 0xb4906c24UL, 0xa0806020UL,
    0x40f2cbb2UL, 0xe072ab92UL, 0x15b6f8a3UL, 0xe7275dc0UL,
    0x490dcc44UL, 0xf795a662UL, 0x50403010UL, 0x5eeac1b4UL,
    0xae2a9184UL, 0x5211c543UL, 0xe576a893UL, 0xed2f5bc2UL,
    0x7f35de4aUL, 0x73cedabdUL, 0x89068c8fUL, 0x99b4772dUL,
    0x76cad9bcUL, 0xd64ab99cUL, 0xdfb5be6aUL, 0x5d1dc040UL,
    0xd41b4ccfUL, 0x10b2fba2UL, 0xba3a9d80UL, 0x6e21d14fUL,
    0x637c211fUL, 0xc50f43caUL, 0x3892e3aaUL, 0x5715c642UL,
};

static const u32 V3[256] = {
    0x016ab9bbUL, 0xb1669ae5UL, 0xcd1465e2UL, 0x511b8725UL,
    0xa457a2f7UL, 0x03bed6d0UL, 0x04b5ded6UL, 0xfe8552b3UL,
    0xad4abafdUL, 0x63e009cfUL, 0x84961c09UL, 0x1a4d91a5UL,
    0x4d37a73dUL, 0xa35caaf1UL, 0xe117a47bUL, 0xf98e5ab5UL,
    0xac200346UL, 0x1184e6c4UL, 0xc268cc55UL, 0x0da8c6dcUL,
    0x99d085aaUL, 0xaa41b2fbUL, 0x9c0fe2c7UL, 0x55ae59f3UL,
    0x20c1befeUL, 0xe5a27aadUL, 0x7fcc29d7UL, 0xe80abc71UL,
    0x3be696e0UL, 0x9edb8dacUL, 0x2215d195UL, 0xceaab332UL,
    0x93734b70UL, 0xfd3b8463UL, 0xd052fc41UL, 0xe61cac7dUL,
    0x94784376UL, 0x0661b1bdUL, 0xdaf1329bUL, 0x17e55779UL,
    0x5cb341f9UL, 0x4b561680UL, 0x0cc27f67UL, 0xcc7edc59UL,
    0x409f61e1UL, 0xe3c3cb10UL, 0x302fe181UL, 0x0e16100cUL,
    0x5e672e92UL, 0x663f6ea2UL, 0x53cfe84eUL, 0x6c9ca078UL,
    0x730e56b0UL, 0x349a3f57UL, 0x3ced9ee6UL, 0x8e35d2d3UL,
    0x8023c2dfUL, 0x2ed7aef2UL, 0x6e48cf13UL, 0x596c2694UL,
    0x605edf1fUL, 0x9b04eac1UL, 0x19f34775UL, 0x893edad5UL,
    0xffefeb08UL, 0xf2472dd4UL, 0xc7b7ab38UL, 0xb9113b54UL,
    0xa236134aUL, 0xf4269c69UL, 0x10ee5f7fUL, 0x8d8b0403UL,
    0x4fe3c856UL, 0x479469e7UL, 0xeaded31aUL, 0x98ba3c11UL,
    0x2d697822UL, 0x15313812UL, 0x6afd11c5UL, 0xdb9b8b20UL,
    0x38584030UL, 0x6b97a87eUL, 0x237f682eUL, 0x1c2c2018UL,
    0x070b0806UL, 0x21ab0745UL, 0x27cab6f8UL, 0x5f0d9729UL,
    0x7264ef0bUL, 0x29dca6f4UL, 0xb3b2f58eUL, 0x628ab074UL,
    0xbda4e582UL, 0x85fca5b2UL, 0x1ef84f73UL, 0xa895dd90UL,
    0x0877a1b1UL, 0x442abf37UL, 0xa53d1b4cUL, 0x8beab5beUL,
    0xb66d92e3UL, 0x4a3caf3bUL, 0x7c72ff07UL, 0x839d140fUL,
    0x4321b731UL, 0x9fb13417UL, 0xf8e4e30eUL, 0xd6334dfcUL,
    0xbaafed84UL, 0x8728cad9UL, 0xf54c25d2UL, 0xcfc00a89UL,
    0x24746028UL, 0x26a00f43UL, 0x05df676dUL, 0x3a8c2f5bUL,
    0x091d180aUL, 0x7d1846bcUL, 0xb87b82efUL, 0x1899feceUL,
    0x35f086ecUL, 0x9512facdUL, 0x32fb8eeaUL, 0x2fbd1749UL,
    0x1f92f6c8UL, 0xa683cd9cUL, 0x424b0e8aUL, 0xb4b9fd88UL,
    0xdc908326UL, 0xc563c453UL, 0x52a551f5UL, 0xef01b477UL,
    0xbe1a3352UL, 0x0f7ca9b7UL, 0x6f2276a8UL, 0x6df619c3UL,
    0x02d46f6bUL, 0xecbf62a7UL, 0x76d131ddUL, 0x78c721d1UL,
    0x28b61f4fUL, 0x364e503cUL, 0xc8cb028fUL, 0xe4c8c316UL,
    0x2c03c199UL, 0xee6b0dccUL, 0x81497b64UL, 0xb00c235eUL,
    0x1d4699a3UL, 0xd13845faUL, 0xa0e27c21UL, 0x7ea6906cUL,
    0xaef46c2dUL, 0x41f5d85aUL, 0x2a627024UL, 0xe96005caUL,
    0xf1f9fb04UL, 0xc6dd1283UL, 0xe77615c6UL, 0x50713e9eUL,
    0xe2a972abUL, 0xc4097de8UL, 0xd58d9b2cUL, 0x8854636eUL,
    0x251ed993UL, 0xd8255df0UL, 0x6581b872UL, 0xa9ff642bUL,
    0x46fed05cUL, 0x96ac2c1dUL, 0xc0bca33eUL, 0x91a7241bUL,
    0x3f534836UL, 0x4540068cUL, 0xb2d84c35UL, 0xf7984ab9UL,
    0x9d655b7cUL, 0xca1f6de4UL, 0x86427362UL, 0x9a6e537aUL,
    0xab2b0b40UL, 0xd759f447UL, 0x5bb849ffUL, 0x5ad2f044UL,
    0xbcce5c39UL, 0x3d87275dUL, 0x00000000UL, 0xfb5a35deUL,
    0xf6f2f302UL, 0xedd5db1cUL, 0xcb75d45fUL, 0x3145583aUL,
    0x8f5f6b68UL, 0x56108f23UL, 0xb7072b58UL, 0x8ce1bdb8UL,
    0x97c695a6UL, 0x168feec2UL, 0x0aa3cedaUL, 0xb5d34433UL,
    0x6755d719UL, 0x64eb01c9UL, 0xc9a1bb34UL, 0xdf2e55f6UL,
    0x90cd9da0UL, 0xa188c59aUL, 0xfa308c65UL, 0xd286932aUL,
    0x68297eaeUL, 0x79ad986aUL, 0x123a3014UL, 0x1b27281eUL,
    0x613466a4UL, 0x77bb8866UL, 0x58069f2fUL, 0x6943c715UL,
    0x7b79f701UL, 0x756fe70dUL, 0x82f7adb4UL, 0x54c4e048UL,
    0xaf9ed596UL, 0x9219f2cbUL, 0x48e8c050UL, 0xbf708ae9UL,
    0x3e39f18dUL, 0x3724e987UL, 0xfc513dd8UL, 0xe07d1dc0UL,
    0x3932f98bUL, 0xd94fe44bUL, 0x4e8971edUL, 0x7a134ebaUL,
    0xc1d61a85UL, 0x33913751UL, 0x70b08060UL, 0x2b08c99fUL,
    0xbbc5543fUL, 0xd4e72297UL, 0xde44ec4dUL, 0x74055eb6UL,
    0xebb46aa1UL, 0x145b81a9UL, 0x8a800c05UL, 0xc30275eeUL,
    0x135089afUL, 0xf32d946fUL, 0x0bc97761UL, 0xddfa3a9dUL,
    0x577a3698UL, 0x498279ebUL, 0xa7e97427UL, 0xf09342bfUL,
    0x5dd9f842UL, 0x4c5d1e86UL, 0x71da39dbUL, 0xd3ec2a91UL,
};

static const u32 U4[256] = {
    0xbbb96a01UL, 0xe59a66b1UL, 0xe26514cdUL, 0x25871b51UL,
    0xf7a257a4UL, 0xd0d6be03UL, 0xd6deb504UL, 0xb35285feUL,
    0xfdba4aadUL, 0xcf09e063UL, 0x091c9684UL, 0xa5914d1aUL,
    0x3da7374dUL, 0xf1aa5ca3UL, 0x7ba417e1UL, 0xb55a8ef9UL,
    0x460320acUL, 0xc4e68411UL, 0x55cc68c2UL, 0xdcc6a80dUL,
    0xaa85d099UL, 0xfbb241aaUL, 0xc7e20f9cUL, 0xf359ae55UL,
    0xfebec120UL, 0xad7aa2e5UL, 0xd729cc7fUL, 0x71bc0ae8UL,
    0xe096e63bUL, 0xac8ddb9eUL, 0x95d11522UL, 0x32b3aaceUL,
    0x704b7393UL, 0x63843bfdUL, 0x41fc52d0UL, 0x7dac1ce6UL,
    0x76437894UL, 0xbdb16106UL, 0x9b32f1daUL, 0x7957e517UL,
    0xf941b35cUL, 0x8016564bUL, 0x677fc20cUL, 0x59dc7eccUL,
    0xe1619f40UL, 0x10cbc3e3UL, 0x81e12f30UL, 0x0c10160eUL,
    0x922e675eUL, 0xa26e3f66UL, 0x4ee8cf53UL, 0x78a09c6cUL,
    0xb0560e73UL, 0x573f9a34UL, 0xe69eed3cUL, 0xd3d2358eUL,
    0xdfc22380UL, 0xf2aed72eUL, 0x13cf486eUL, 0x94266c59UL,
    0x1fdf5e60UL, 0xc1ea049bUL, 0x7547f319UL, 0xd5da3e89UL,
    0x08ebefffUL, 0xd42d47f2UL, 0x38abb7c7UL, 0x543b11b9UL,
    0x4a1336a2UL, 0x699c26f4UL, 0x7f5fee10UL, 0x03048b8dUL,
    0x56c8e34fUL, 0xe7699447UL, 0x1ad3deeaUL, 0x113cba98UL,
    0x2278692dUL, 0x12383115UL, 0xc511fd6aUL, 0x208b9bdbUL,
    0x30405838UL, 0x7ea8976bUL, 0x2e687f23UL, 0x18202c1cUL,
    0x06080b07UL, 0x4507ab21UL, 0xf8b6ca27UL, 0x29970d5fUL,
    0x0bef6472UL, 0xf4a6dc29UL, 0x8ef5b2b3UL, 0x74b08a62UL,
    0x82e5a4bdUL, 0xb2a5fc85UL, 0x734ff81eUL, 0x90dd95a8UL,
    0xb1a17708UL, 0x37bf2a44UL, 0x4c1b3da5UL, 0xbeb5ea8bUL,
    0xe3926db6UL, 0x3baf3c4aUL, 0x07ff727cUL, 0x0f149d83UL,
    0x31b72143UL, 0x1734b19fUL, 0x0ee3e4f8UL, 0xfc4d33d6UL,
    0x84edafbaUL, 0xd9ca2887UL, 0xd2254cf5UL, 0x890ac0cfUL,
    0x28607424UL, 0x430fa026UL, 0x6d67df05UL, 0x5b2f8c3aUL,
    0x0a181d09UL, 0xbc46187dUL, 0xef827bb8UL, 0xcefe9918UL,
    0xec86f035UL, 0xcdfa1295UL, 0xea8efb32UL, 0x4917bd2fUL,
    0xc8f6921fUL, 0x9ccd83a6UL, 0x8a0e4b42UL, 0x88fdb9b4UL,
    0x268390dcUL, 0x53c463c5UL, 0xf551a552UL, 0x77b401efUL,
    0x52331abeUL, 0xb7a97c0fUL, 0xa876226fUL, 0xc319f66dUL,
    0x6b6fd402UL, 0xa762bfecUL, 0xdd31d176UL, 0xd121c778UL,
    0x4f1fb628UL, 0x3c504e36UL, 0x8f02cbc8UL, 0x16c3c8e4UL,
    0x99c1032cUL, 0xcc0d6beeUL, 0x647b4981UL, 0x5e230cb0UL,
    0xa399461dUL, 0xfa4538d1UL, 0x217ce2a0UL, 0x6c90a67eUL,
    0x2d6cf4aeUL, 0x5ad8f541UL, 0x2470622aUL, 0xca0560e9UL,
    0x04fbf9f1UL, 0x8312ddc6UL, 0xc61576e7UL, 0x9e3e7150UL,
    0xab72a9e2UL, 0xe87d09c4UL, 0x2c9b8dd5UL, 0x6e635488UL,
    0x93d91e25UL, 0xf05d25d8UL, 0x72b88165UL, 0x2b64ffa9UL,
    0x5cd0fe46UL, 0x1d2cac96UL, 0x3ea3bcc0UL, 0x1b24a791UL,
    0x3648533fUL, 0x8c064045UL, 0x354cd8b2UL, 0xb94a98f7UL,
    0x7c5b659dUL, 0xe46d1fcaUL, 0x62734286UL, 0x7a536e9aUL,
    0x400b2babUL, 0x47f459d7UL, 0xff49b85bUL, 0x44f0d25aUL,
    0x395ccebcUL, 0x5d27873dUL, 0x00000000UL, 0xde355afbUL,
    0x02f3f2f6UL, 0x1cdbd5edUL, 0x5fd475cbUL, 0x3a584531UL,
    0x686b5f8fUL, 0x238f1056UL, 0x582b07b7UL, 0xb8bde18cUL,
    0xa695c697UL, 0xc2ee8f16UL, 0xdacea30aUL, 0x3344d3b5UL,
    0x19d75567UL, 0xc901eb64UL, 0x34bba1c9UL, 0xf6552edfUL,
    0xa09dcd90UL, 0x9ac588a1UL, 0x658c30faUL, 0x2a9386d2UL,
    0xae7e2968UL, 0x6a98ad79UL, 0x14303a12UL, 0x1e28271bUL,
    0xa4663461UL, 0x6688bb77UL, 0x2f9f0658UL, 0x15c74369UL,
    0x01f7797bUL, 0x0de76f75UL, 0xb4adf782UL, 0x48e0c454UL,
    0x96d59eafUL, 0xcbf21992UL, 0x50c0e848UL, 0xe98a70bfUL,
    0x8df1393eUL, 0x87e92437UL, 0xd83d51fcUL, 0xc01d7de0UL,
    0x8bf93239UL, 0x4be44fd9UL, 0xed71894eUL, 0xba4e137aUL,
    0x851ad6c1UL, 0x51379133UL, 0x6080b070UL, 0x9fc9082bUL,
    0x3f54c5bbUL, 0x9722e7d4UL, 0x4dec44deUL, 0xb65e0574UL,
    0xa16ab4ebUL, 0xa9815b14UL, 0x050c808aUL, 0xee7502c3UL,
    0xaf895013UL, 0x6f942df3UL, 0x6177c90bUL, 0x9d3afaddUL,
    0x98367a57UL, 0xeb798249UL, 0x2774e9a7UL, 0xbf4293f0UL,
    0x42f8d95dUL, 0x861e5d4cUL, 0xdb39da71UL, 0x912aecd3UL,
};

static const u32 V4[256] = {
    0xbad3d268UL, 0x54fc4d19UL, 0x2f71bc93UL, 0x749ccdb9UL,
    0x53f55102UL, 0xd3686bb8UL, 0xd26b6fbdUL, 0x4dd72964UL,
    0x50f05d0dUL, 0xace98a26UL, 0x8d8a0e83UL, 0xbfdcc679UL,
    0x7090ddadUL, 0x52f65507UL, 0x9ab352c8UL, 0x4cd42d61UL,
    0xea238f65UL, 0xd56273a6UL, 0x97a466f1UL, 0xd16e63b2UL,
    0x3355ccffUL, 0x51f35908UL, 0x5bed712aUL, 0xa6f7a204UL,
    0xde7f5f81UL, 0x48d83d75UL, 0xa8e59a32UL, 0x99b65ec7UL,
    0xdb704b90UL, 0x3256c8faUL, 0xb7c4e651UL, 0xfc19d72bUL,
    0xe338ab48UL, 0x9ebf42dcUL, 0x91ae7eefUL, 0x9bb056cdUL,
    0xe23baf4dUL, 0xbbd0d66dUL, 0x41c31958UL, 0x6eb2a5cbUL,
    0xa5f2ae0bUL, 0xcb400bc0UL, 0x6bbdb1daUL, 0x95a26efbUL,
    0xa1febe1fUL, 0xf308eb18UL, 0xb1cefe4fUL, 0x0206080aUL,
    0xcc4917dbUL, 0xc45137f3UL, 0x1d277469UL, 0x143c5044UL,
    0xc3582be8UL, 0x63a591f2UL, 0xda734f95UL, 0x5de76934UL,
    0x5fe1613eUL, 0xdc79578bUL, 0x7d87e994UL, 0xcd4a13deUL,
    0x7f81e19eUL, 0x5aee752fUL, 0x6cb4adc1UL, 0x5ce46d31UL,
    0xf704fb0cUL, 0x266a98beUL, 0xff1cdb24UL, 0xed2a937eUL,
    0xe825876fUL, 0x9dba4ed3UL, 0x6fb1a1ceUL, 0x8e8f028cUL,
    0x192b647dUL, 0xa0fdba1aUL, 0xf00de717UL, 0x89861e97UL,
    0x0f113c33UL, 0x07091c1bUL, 0xafec8629UL, 0xfb10cb30UL,
    0x08182028UL, 0x153f5441UL, 0x0d173439UL, 0x040c1014UL,
    0x01030405UL, 0x64ac8de9UL, 0xdf7c5b84UL, 0x769ac5b3UL,
    0x798bf980UL, 0xdd7a538eUL, 0x3d47f4c9UL, 0x163a584eUL,
    0x3f41fcc3UL, 0x3759dcebUL, 0x6db7a9c4UL, 0x3848e0d8UL,
    0xb9d6de67UL, 0x7395d1a2UL, 0xe926836aUL, 0x355fd4e1UL,
    0x55ff491cUL, 0x7193d9a8UL, 0x7b8df18aUL, 0x8c890a86UL,
    0x7296d5a7UL, 0x88851a92UL, 0xf607ff09UL, 0x2a7ea882UL,
    0x3e42f8c6UL, 0x5ee2653bUL, 0x27699cbbUL, 0x46ca0543UL,
    0x0c14303cUL, 0x65af89ecUL, 0x68b8bdd5UL, 0x61a399f8UL,
    0x03050c0fUL, 0xc15e23e2UL, 0x57f94116UL, 0xd6677fa9UL,
    0xd976439aUL, 0x58e87d25UL, 0xd875479fUL, 0x66aa85e3UL,
    0xd7647bacUL, 0x3a4ee8d2UL, 0xc84507cfUL, 0x3c44f0ccUL,
    0xfa13cf35UL, 0x96a762f4UL, 0xa7f4a601UL, 0x98b55ac2UL,
    0xec29977bUL, 0xb8d5da62UL, 0xc7543bfcUL, 0xaeef822cUL,
    0x69bbb9d0UL, 0x4bdd317aUL, 0xabe0963dUL, 0xa9e69e37UL,
    0x67a981e6UL, 0x0a1e2822UL, 0x47c90146UL, 0xf20bef1dUL,
    0xb5c2ee5bUL, 0x226688aaUL, 0xe532b356UL, 0xee2f9f71UL,
    0xbedfc27cUL, 0x2b7dac87UL, 0x819e3ebfUL, 0x1236485aUL,
    0x839836b5UL, 0x1b2d6c77UL, 0x0e123836UL, 0x23658cafUL,
    0xf502f306UL, 0x45cf094cUL, 0x216384a5UL, 0xce4f1fd1UL,
    0x49db3970UL, 0x2c74b09cUL, 0xf916c33aUL, 0xe637bf59UL,
    0xb6c7e254UL, 0x2878a088UL, 0x17395c4bUL, 0x829b32b0UL,
    0x1a2e6872UL, 0x8b80169dUL, 0xfe1fdf21UL, 0x8a831298UL,
    0x091b242dUL, 0xc94603caUL, 0x879426a1UL, 0x4ed2256bUL,
    0xe13ea342UL, 0x2e72b896UL, 0xe431b753UL, 0xe03da747UL,
    0xeb208b60UL, 0x90ad7aeaUL, 0xa4f1aa0eUL, 0x1e227866UL,
    0x85922eabUL, 0x60a09dfdUL, 0x00000000UL, 0x256f94b1UL,
    0xf401f703UL, 0xf10ee312UL, 0x94a16afeUL, 0x0b1d2c27UL,
    0xe734bb5cUL, 0x759fc9bcUL, 0xef2c9b74UL, 0x345cd0e4UL,
    0x3153c4f5UL, 0xd46177a3UL, 0xd06d67b7UL, 0x869722a4UL,
    0x7e82e59bUL, 0xadea8e23UL, 0xfd1ad32eUL, 0x297ba48dUL,
    0x3050c0f0UL, 0x3b4decd7UL, 0x9fbc46d9UL, 0xf815c73fUL,
    0xc6573ff9UL, 0x13354c5fUL, 0x060a181eUL, 0x050f1411UL,
    0xc55233f6UL, 0x11334455UL, 0x7799c1b6UL, 0x7c84ed91UL,
    0x7a8ef58fUL, 0x7888fd85UL, 0x365ad8eeUL, 0x1c24706cUL,
    0x394be4ddUL, 0x59eb7920UL, 0x18286078UL, 0x56fa4513UL,
    0xb3c8f645UL, 0xb0cdfa4aUL, 0x246c90b4UL, 0x206080a0UL,
    0xb2cbf240UL, 0x92ab72e0UL, 0xa3f8b615UL, 0xc05d27e7UL,
    0x44cc0d49UL, 0x62a695f7UL, 0x10304050UL, 0xb4c1ea5eUL,
    0x84912aaeUL, 0x43c51152UL, 0x93a876e5UL, 0xc25b2fedUL,
    0x4ade357fUL, 0xbddace73UL, 0x8f8c0689UL, 0x2d77b499UL,
    0xbcd9ca76UL, 0x9cb94ad6UL, 0x6abeb5dfUL, 0x40c01d5dUL,
    0xcf4c1bd4UL, 0xa2fbb210UL, 0x809d3abaUL, 0x4fd1216eUL,
    0x1f217c63UL, 0xca430fc5UL, 0xaae39238UL, 0x42c61557UL,
};

static const u32 U5[256] = {
    0xb9bb016aUL, 0x9ae5b166UL, 0x65e2cd14UL, 0x8725511bUL,
    0xa2f7a457UL, 0xd6d003beUL, 0xded604b5UL, 0x52b3fe85UL,
    0xbafdad4aUL, 0x09cf63e0UL, 0x1c098496UL, 0x91a51a4dUL,
    0xa73d4d37UL, 0xaaf1a35cUL, 0xa47be117UL, 0x5ab5f98eUL,
    0x0346ac20UL, 0xe6c41184UL, 0xcc55c268UL, 0xc6dc0da8UL,
    0x85aa99d0UL, 0xb2fbaa41UL, 0xe2c79c0fUL, 0x59f355aeUL,
    0xbefe20c1UL, 0x7aade5a2UL, 0x29d77fccUL, 0xbc71e80aUL,
    0x96e03be6UL, 0x8dac9edbUL, 0xd1952215UL, 0xb332ceaaUL,
    0x4b709373UL, 0x8463fd3bUL, 0xfc41d052UL, 0xac7de61cUL,
    0x43769478UL, 0xb1bd0661UL, 0x329bdaf1UL, 0x577917e5UL,
    0x41f95cb3UL, 0x16804b56UL, 0x7f670cc2UL, 0xdc59cc7eUL,
    0x61e1409fUL, 0xcb10e3c3UL, 0xe181302fUL, 0x100c0e16UL,
    0x2e925e67UL, 0x6ea2663fUL, 0xe84e53cfUL, 0xa0786c9cUL,
    0x56b0730eUL, 0x3f57349aUL, 0x9ee63cedUL, 0xd2d38e35UL,
    0xc2df8023UL, 0xaef22ed7UL, 0xcf136e48UL, 0x2694596cUL,
    0xdf1f605eUL, 0xeac19b04UL, 0x477519f3UL, 0xdad5893eUL,
    0xeb08ffefUL, 0x2dd4f247UL, 0xab38c7b7UL, 0x3b54b911UL,
    0x134aa236UL, 0x9c69f426UL, 0x5f7f10eeUL, 0x04038d8bUL,
    0xc8564fe3UL, 0x69e74794UL, 0xd31aeadeUL, 0x3c1198baUL,
    0x78222d69UL, 0x38121531UL, 0x11c56afdUL, 0x8b20db9bUL,
    0x40303858UL, 0xa87e6b97UL, 0x682e237fUL, 0x20181c2cUL,
    0x0806070bUL, 0x074521abUL, 0xb6f827caUL, 0x97295f0dUL,
    0xef0b7264UL, 0xa6f429dcUL, 0xf58eb3b2UL, 0xb074628aUL,
    0xe582bda4UL, 0xa5b285fcUL, 0x4f731ef8UL, 0xdd90a895UL,
    0xa1b10877UL, 0xbf37442aUL, 0x1b4ca53dUL, 0xb5be8beaUL,
    0x92e3b66dUL, 0xaf3b4a3cUL, 0xff077c72UL, 0x140f839dUL,
    0xb7314321UL, 0x34179fb1UL, 0xe30ef8e4UL, 0x4dfcd633UL,
    0xed84baafUL, 0xcad98728UL, 0x25d2f54cUL, 0x0a89cfc0UL,
    0x60282474UL, 0x0f4326a0UL, 0x676d05dfUL, 0x2f5b3a8cUL,
    0x180a091dUL, 0x46bc7d18UL, 0x82efb87bUL, 0xfece1899UL,
    0x86ec35f0UL, 0xfacd9512UL, 0x8eea32fbUL, 0x17492fbdUL,
    0xf6c81f92UL, 0xcd9ca683UL, 0x0e8a424bUL, 0xfd88b4b9UL,
    0x8326dc90UL, 0xc453c563UL, 0x51f552a5UL, 0xb477ef01UL,
    0x3352be1aUL, 0xa9b70f7cUL, 0x76a86f22UL, 0x19c36df6UL,
    0x6f6b02d4UL, 0x62a7ecbfUL, 0x31dd76d1UL, 0x21d178c7UL,
    0x1f4f28b6UL, 0x503c364eUL, 0x028fc8cbUL, 0xc316e4c8UL,
    0xc1992c03UL, 0x0dccee6bUL, 0x7b648149UL, 0x235eb00cUL,
    0x99a31d46UL, 0x45fad138UL, 0x7c21a0e2UL, 0x906c7ea6UL,
    0x6c2daef4UL, 0xd85a41f5UL, 0x70242a62UL, 0x05cae960UL,
    0xfb04f1f9UL, 0x1283c6ddUL, 0x15c6e776UL, 0x3e9e5071UL,
    0x72abe2a9UL, 0x7de8c409UL, 0x9b2cd58dUL, 0x636e8854UL,
    0xd993251eUL, 0x5df0d825UL, 0xb8726581UL, 0x642ba9ffUL,
    0xd05c46feUL, 0x2c1d96acUL, 0xa33ec0bcUL, 0x241b91a7UL,
    0x48363f53UL, 0x068c4540UL, 0x4c35b2d8UL, 0x4ab9f798UL,
    0x5b7c9d65UL, 0x6de4ca1fUL, 0x73628642UL, 0x537a9a6eUL,
    0x0b40ab2bUL, 0xf447d759UL, 0x49ff5bb8UL, 0xf0445ad2UL,
    0x5c39bcceUL, 0x275d3d87UL, 0x00000000UL, 0x35defb5aUL,
    0xf302f6f2UL, 0xdb1cedd5UL, 0xd45fcb75UL, 0x583a3145UL,
    0x6b688f5fUL, 0x8f235610UL, 0x2b58b707UL, 0xbdb88ce1UL,
    0x95a697c6UL, 0xeec2168fUL, 0xceda0aa3UL, 0x4433b5d3UL,
    0xd7196755UL, 0x01c964ebUL, 0xbb34c9a1UL, 0x55f6df2eUL,
    0x9da090cdUL, 0xc59aa188UL, 0x8c65fa30UL, 0x932ad286UL,
    0x7eae6829UL, 0x986a79adUL, 0x3014123aUL, 0x281e1b27UL,
    0x66a46134UL, 0x886677bbUL, 0x9f2f5806UL, 0xc7156943UL,
    0xf7017b79UL, 0xe70d756fUL, 0xadb482f7UL, 0xe04854c4UL,
    0xd596af9eUL, 0xf2cb9219UL, 0xc05048e8UL, 0x8ae9bf70UL,
    0xf18d3e39UL, 0xe9873724UL, 0x3dd8fc51UL, 0x1dc0e07dUL,
    0xf98b3932UL, 0xe44bd94fUL, 0x71ed4e89UL, 0x4eba7a13UL,
    0x1a85c1d6UL, 0x37513391UL, 0x806070b0UL, 0xc99f2b08UL,
    0x543fbbc5UL, 0x2297d4e7UL, 0xec4dde44UL, 0x5eb67405UL,
    0x6aa1ebb4UL, 0x81a9145bUL, 0x0c058a80UL, 0x75eec302UL,
    0x89af1350UL, 0x946ff32dUL, 0x77610bc9UL, 0x3a9dddfaUL,
    0x3698577aUL, 0x79eb4982UL, 0x7427a7e9UL, 0x42bff093UL,
    0xf8425dd9UL, 0x1e864c5dUL, 0x39db71daUL, 0x2a91d3ecUL,
};

static const u32 V5[256] = {
    0xd3ba68d2UL, 0xfc54194dUL, 0x712f93bcUL, 0x9c74b9cdUL,
    0xf5530251UL, 0x68d3b86bUL, 0x6bd2bd6fUL, 0xd74d6429UL,
    0xf0500d5dUL, 0xe9ac268aUL, 0x8a8d830eUL, 0xdcbf79c6UL,
    0x9070adddUL, 0xf6520755UL, 0xb39ac852UL, 0xd44c612dUL,
    0x23ea658fUL, 0x62d5a673UL, 0xa497f166UL, 0x6ed1b263UL,
    0x5533ffccUL, 0xf3510859UL, 0xed5b2a71UL, 0xf7a604a2UL,
    0x7fde815fUL, 0xd848753dUL, 0xe5a8329aUL, 0xb699c75eUL,
    0x70db904bUL, 0x5632fac8UL, 0xc4b751e6UL, 0x19fc2bd7UL,
    0x38e348abUL, 0xbf9edc42UL, 0xae91ef7eUL, 0xb09bcd56UL,
    0x3be24dafUL, 0xd0bb6dd6UL, 0xc3415819UL, 0xb26ecba5UL,
    0xf2a50baeUL, 0x40cbc00bUL, 0xbd6bdab1UL, 0xa295fb6eUL,
    0xfea11fbeUL, 0x08f318ebUL, 0xceb14ffeUL, 0x06020a08UL,
    0x49ccdb17UL, 0x51c4f337UL, 0x271d6974UL, 0x3c144450UL,
    0x58c3e82bUL, 0xa563f291UL, 0x73da954fUL, 0xe75d3469UL,
    0xe15f3e61UL, 0x79dc8b57UL, 0x877d94e9UL, 0x4acdde13UL,
    0x817f9ee1UL, 0xee5a2f75UL, 0xb46cc1adUL, 0xe45c316dUL,
    0x04f70cfbUL, 0x6a26be98UL, 0x1cff24dbUL, 0x2aed7e93UL,
    0x25e86f87UL, 0xba9dd34eUL, 0xb16fcea1UL, 0x8f8e8c02UL,
    0x2b197d64UL, 0xfda01abaUL, 0x0df017e7UL, 0x8689971eUL,
    0x110f333cUL, 0x09071b1cUL, 0xecaf2986UL, 0x10fb30cbUL,
    0x18082820UL, 0x3f154154UL, 0x170d3934UL, 0x0c041410UL,
    0x03010504UL, 0xac64e98dUL, 0x7cdf845bUL, 0x9a76b3c5UL,
    0x8b7980f9UL, 0x7add8e53UL, 0x473dc9f4UL, 0x3a164e58UL,
    0x413fc3fcUL, 0x5937ebdcUL, 0xb76dc4a9UL, 0x4838d8e0UL,
    0xd6b967deUL, 0x9573a2d1UL, 0x26e96a83UL, 0x5f35e1d4UL,
    0xff551c49UL, 0x9371a8d9UL, 0x8d7b8af1UL, 0x898c860aUL,
    0x9672a7d5UL, 0x8588921aUL, 0x07f609ffUL, 0x7e2a82a8UL,
    0x423ec6f8UL, 0xe25e3b65UL, 0x6927bb9cUL, 0xca464305UL,
    0x140c3c30UL, 0xaf65ec89UL, 0xb868d5bdUL, 0xa361f899UL,
    0x05030f0cUL, 0x5ec1e223UL, 0xf9571641UL, 0x67d6a97fUL,
    0x76d99a43UL, 0xe858257dUL, 0x75d89f47UL, 0xaa66e385UL,
    0x64d7ac7bUL, 0x4e3ad2e8UL, 0x45c8cf07UL, 0x443cccf0UL,
    0x13fa35cfUL, 0xa796f462UL, 0xf4a701a6UL, 0xb598c25aUL,
    0x29ec7b97UL, 0xd5b862daUL, 0x54c7fc3bUL, 0xefae2c82UL,
    0xbb69d0b9UL, 0xdd4b7a31UL, 0xe0ab3d96UL, 0xe6a9379eUL,
    0xa967e681UL, 0x1e0a2228UL, 0xc9474601UL, 0x0bf21defUL,
    0xc2b55beeUL, 0x6622aa88UL, 0x32e556b3UL, 0x2fee719fUL,
    0xdfbe7cc2UL, 0x7d2b87acUL, 0x9e81bf3eUL, 0x36125a48UL,
    0x9883b536UL, 0x2d1b776cUL, 0x120e3638UL, 0x6523af8cUL,
    0x02f506f3UL, 0xcf454c09UL, 0x6321a584UL, 0x4fced11fUL,
    0xdb497039UL, 0x742c9cb0UL, 0x16f93ac3UL, 0x37e659bfUL,
    0xc7b654e2UL, 0x782888a0UL, 0x39174b5cUL, 0x9b82b032UL,
    0x2e1a7268UL, 0x808b9d16UL, 0x1ffe21dfUL, 0x838a9812UL,
    0x1b092d24UL, 0x46c9ca03UL, 0x9487a126UL, 0xd24e6b25UL,
    0x3ee142a3UL, 0x722e96b8UL, 0x31e453b7UL, 0x3de047a7UL,
    0x20eb608bUL, 0xad90ea7aUL, 0xf1a40eaaUL, 0x221e6678UL,
    0x9285ab2eUL, 0xa060fd9dUL, 0x00000000UL, 0x6f25b194UL,
    0x01f403f7UL, 0x0ef112e3UL, 0xa194fe6aUL, 0x1d0b272cUL,
    0x34e75cbbUL, 0x9f75bcc9UL, 0x2cef749bUL, 0x5c34e4d0UL,
    0x5331f5c4UL, 0x61d4a377UL, 0x6dd0b767UL, 0x9786a422UL,
    0x827e9be5UL, 0xeaad238eUL, 0x1afd2ed3UL, 0x7b298da4UL,
    0x5030f0c0UL, 0x4d3bd7ecUL, 0xbc9fd946UL, 0x15f83fc7UL,
    0x57c6f93fUL, 0x35135f4cUL, 0x0a061e18UL, 0x0f051114UL,
    0x52c5f633UL, 0x33115544UL, 0x9977b6c1UL, 0x847c91edUL,
    0x8e7a8ff5UL, 0x887885fdUL, 0x5a36eed8UL, 0x241c6c70UL,
    0x4b39dde4UL, 0xeb592079UL, 0x28187860UL, 0xfa561345UL,
    0xc8b345f6UL, 0xcdb04afaUL, 0x6c24b490UL, 0x6020a080UL,
    0xcbb240f2UL, 0xab92e072UL, 0xf8a315b6UL, 0x5dc0e727UL,
    0xcc44490dUL, 0xa662f795UL, 0x30105040UL, 0xc1b45eeaUL,
    0x9184ae2aUL, 0xc5435211UL, 0xa893e576UL, 0x5bc2ed2fUL,
    0xde4a7f35UL, 0xdabd73ceUL, 0x8c8f8906UL, 0x772d99b4UL,
    0xd9bc76caUL, 0xb99cd64aUL, 0xbe6adfb5UL, 0xc0405d1dUL,
    0x4ccfd41bUL, 0xfba210b2UL, 0x9d80ba3aUL, 0xd14f6e21UL,
    0x211f637cUL, 0x43cac50fUL, 0xe3aa3892UL, 0xc6425715UL,
};

static const u32 U6[256] = {
    0x6a01bbb9UL, 0x66b1e59aUL, 0x14cde265UL, 0x1b512587UL,
    0x57a4f7a2UL, 0xbe03d0d6UL, 0xb504d6deUL, 0x85feb352UL,
    0x4aadfdbaUL, 0xe063cf09UL, 0x9684091cUL, 0x4d1aa591UL,
    0x374d3da7UL, 0x5ca3f1aaUL, 0x17e17ba4UL, 0x8ef9b55aUL,
    0x20ac4603UL, 0x8411c4e6UL, 0x68c255ccUL, 0xa80ddcc6UL,
    0xd099aa85UL, 0x41aafbb2UL, 0x0f9cc7e2UL, 0xae55f359UL,
    0xc120febeUL, 0xa2e5ad7aUL, 0xcc7fd729UL, 0x0ae871bcUL,
    0xe63be096UL, 0xdb9eac8dUL, 0x152295d1UL, 0xaace32b3UL,
    0x7393704bUL, 0x3bfd6384UL, 0x52d041fcUL, 0x1ce67dacUL,
    0x78947643UL, 0x6106bdb1UL, 0xf1da9b32UL, 0xe5177957UL,
    0xb35cf941UL, 0x564b8016UL, 0xc20c677fUL, 0x7ecc59dcUL,
    0x9f40e161UL, 0xc3e310cbUL, 0x2f3081e1UL, 0x160e0c10UL,
    0x675e922eUL, 0x3f66a26eUL, 0xcf534ee8UL, 0x9c6c78a0UL,
    0x0e73b056UL, 0x9a34573fUL, 0xed3ce69eUL, 0x358ed3d2UL,
    0x2380dfc2UL, 0xd72ef2aeUL, 0x486e13cfUL, 0x6c599426UL,
    0x5e601fdfUL, 0x049bc1eaUL, 0xf3197547UL, 0x3e89d5daUL,
    0xefff08ebUL, 0x47f2d42dUL, 0xb7c738abUL, 0x11b9543bUL,
    0x36a24a13UL, 0x26f4699cUL, 0xee107f5fUL, 0x8b8d0304UL,
    0xe34f56c8UL, 0x9447e769UL, 0xdeea1ad3UL, 0xba98113cUL,
    0x692d2278UL, 0x31151238UL, 0xfd6ac511UL, 0x9bdb208bUL,
    0x58383040UL, 0x976b7ea8UL, 0x7f232e68UL, 0x2c1c1820UL,
    0x0b070608UL, 0xab214507UL, 0xca27f8b6UL, 0x0d5f2997UL,
    0x64720befUL, 0xdc29f4a6UL, 0xb2b38ef5UL, 0x8a6274b0UL,
    0xa4bd82e5UL, 0xfc85b2a5UL, 0xf81e734fUL, 0x95a890ddUL,
    0x7708b1a1UL, 0x2a4437bfUL, 0x3da54c1bUL, 0xea8bbeb5UL,
    0x6db6e392UL, 0x3c4a3bafUL, 0x727c07ffUL, 0x9d830f14UL,
    0x214331b7UL, 0xb19f1734UL, 0xe4f80ee3UL, 0x33d6fc4dUL,
    0xafba84edUL, 0x2887d9caUL, 0x4cf5d225UL, 0xc0cf890aUL,
    0x74242860UL, 0xa026430fUL, 0xdf056d67UL, 0x8c3a5b2fUL,
    0x1d090a18UL, 0x187dbc46UL, 0x7bb8ef82UL, 0x9918cefeUL,
    0xf035ec86UL, 0x1295cdfaUL, 0xfb32ea8eUL, 0xbd2f4917UL,
    0x921fc8f6UL, 0x83a69ccdUL, 0x4b428a0eUL, 0xb9b488fdUL,
    0x90dc2683UL, 0x63c553c4UL, 0xa552f551UL, 0x01ef77b4UL,
    0x1abe5233UL, 0x7c0fb7a9UL, 0x226fa876UL, 0xf66dc319UL,
    0xd4026b6fUL, 0xbfeca762UL, 0xd176dd31UL, 0xc778d121UL,
    0xb6284f1fUL, 0x4e363c50UL, 0xcbc88f02UL, 0xc8e416c3UL,
    0x032c99c1UL, 0x6beecc0dUL, 0x4981647bUL, 0x0cb05e23UL,
    0x461da399UL, 0x38d1fa45UL, 0xe2a0217cUL, 0xa67e6c90UL,
    0xf4ae2d6cUL, 0xf5415ad8UL, 0x622a2470UL, 0x60e9ca05UL,
    0xf9f104fbUL, 0xddc68312UL, 0x76e7c615UL, 0x71509e3eUL,
    0xa9e2ab72UL, 0x09c4e87dUL, 0x8dd52c9bUL, 0x54886e63UL,
    0x1e2593d9UL, 0x25d8f05dUL, 0x816572b8UL, 0xffa92b64UL,
    0xfe465cd0UL, 0xac961d2cUL, 0xbcc03ea3UL, 0xa7911b24UL,
    0x533f3648UL, 0x40458c06UL, 0xd8b2354cUL, 0x98f7b94aUL,
    0x659d7c5bUL, 0x1fcae46dUL, 0x42866273UL, 0x6e9a7a53UL,
    0x2bab400bUL, 0x59d747f4UL, 0xb85bff49UL, 0xd25a44f0UL,
    0xcebc395cUL, 0x873d5d27UL, 0x00000000UL, 0x5afbde35UL,
    0xf2f602f3UL, 0xd5ed1cdbUL, 0x75cb5fd4UL, 0x45313a58UL,
    0x5f8f686bUL, 0x1056238fUL, 0x07b7582bUL, 0xe18cb8bdUL,
    0xc697a695UL, 0x8f16c2eeUL, 0xa30adaceUL, 0xd3b53344UL,
    0x556719d7UL, 0xeb64c901UL, 0xa1c934bbUL, 0x2edff655UL,
    0xcd90a09dUL, 0x88a19ac5UL, 0x30fa658cUL, 0x86d22a93UL,
    0x2968ae7eUL, 0xad796a98UL, 0x3a121430UL, 0x271b1e28UL,
    0x3461a466UL, 0xbb776688UL, 0x06582f9fUL, 0x436915c7UL,
    0x797b01f7UL, 0x6f750de7UL, 0xf782b4adUL, 0xc45448e0UL,
    0x9eaf96d5UL, 0x1992cbf2UL, 0xe84850c0UL, 0x70bfe98aUL,
    0x393e8df1UL, 0x243787e9UL, 0x51fcd83dUL, 0x7de0c01dUL,
    0x32398bf9UL, 0x4fd94be4UL, 0x894eed71UL, 0x137aba4eUL,
    0xd6c1851aUL, 0x91335137UL, 0xb0706080UL, 0x082b9fc9UL,
    0xc5bb3f54UL, 0xe7d49722UL, 0x44de4decUL, 0x0574b65eUL,
    0xb4eba16aUL, 0x5b14a981UL, 0x808a050cUL, 0x02c3ee75UL,
    0x5013af89UL, 0x2df36f94UL, 0xc90b6177UL, 0xfadd9d3aUL,
    0x7a579836UL, 0x8249eb79UL, 0xe9a72774UL, 0x93f0bf42UL,
    0xd95d42f8UL, 0x5d4c861eUL, 0xda71db39UL, 0xecd3912aUL,
};

static const u32 V6[256] = {
    0xd268bad3UL, 0x4d1954fcUL, 0xbc932f71UL, 0xcdb9749cUL,
    0x510253f5UL, 0x6bb8d368UL, 0x6fbdd26bUL, 0x29644dd7UL,
    0x5d0d50f0UL, 0x8a26ace9UL, 0x0e838d8aUL, 0xc679bfdcUL,
    0xddad7090UL, 0x550752f6UL, 0x52c89ab3UL, 0x2d614cd4UL,
    0x8f65ea23UL, 0x73a6d562UL, 0x66f197a4UL, 0x63b2d16eUL,
    0xccff3355UL, 0x590851f3UL, 0x712a5bedUL, 0xa204a6f7UL,
    0x5f81de7fUL, 0x3d7548d8UL, 0x9a32a8e5UL, 0x5ec799b6UL,
    0x4b90db70UL, 0xc8fa3256UL, 0xe651b7c4UL, 0xd72bfc19UL,
    0xab48e338UL, 0x42dc9ebfUL, 0x7eef91aeUL, 0x56cd9bb0UL,
    0xaf4de23bUL, 0xd66dbbd0UL, 0x195841c3UL, 0xa5cb6eb2UL,
    0xae0ba5f2UL, 0x0bc0cb40UL, 0xb1da6bbdUL, 0x6efb95a2UL,
    0xbe1fa1feUL, 0xeb18f308UL, 0xfe4fb1ceUL, 0x080a0206UL,
    0x17dbcc49UL, 0x37f3c451UL, 0x74691d27UL, 0x5044143cUL,
    0x2be8c358UL, 0x91f263a5UL, 0x4f95da73UL, 0x69345de7UL,
    0x613e5fe1UL, 0x578bdc79UL, 0xe9947d87UL, 0x13decd4aUL,
    0xe19e7f81UL, 0x752f5aeeUL, 0xadc16cb4UL, 0x6d315ce4UL,
    0xfb0cf704UL, 0x98be266aUL, 0xdb24ff1cUL, 0x937eed2aUL,
    0x876fe825UL, 0x4ed39dbaUL, 0xa1ce6fb1UL, 0x028c8e8fUL,
    0x647d192bUL, 0xba1aa0fdUL, 0xe717f00dUL, 0x1e978986UL,
    0x3c330f11UL, 0x1c1b0709UL, 0x8629afecUL, 0xcb30fb10UL,
    0x20280818UL, 0x5441153fUL, 0x34390d17UL, 0x1014040cUL,
    0x04050103UL, 0x8de964acUL, 0x5b84df7cUL, 0xc5b3769aUL,
    0xf980798bUL, 0x538edd7aUL, 0xf4c93d47UL, 0x584e163aUL,
    0xfcc33f41UL, 0xdceb3759UL, 0xa9c46db7UL, 0xe0d83848UL,
    0xde67b9d6UL, 0xd1a27395UL, 0x836ae926UL, 0xd4e1355fUL,
    0x491c55ffUL, 0xd9a87193UL, 0xf18a7b8dUL, 0x0a868c89UL,
    0xd5a77296UL, 0x1a928885UL, 0xff09f607UL, 0xa8822a7eUL,
    0xf8c63e42UL, 0x653b5ee2UL, 0x9cbb2769UL, 0x054346caUL,
    0x303c0c14UL, 0x89ec65afUL, 0xbdd568b8UL, 0x99f861a3UL,
    0x0c0f0305UL, 0x23e2c15eUL, 0x411657f9UL, 0x7fa9d667UL,
    0x439ad976UL, 0x7d2558e8UL, 0x479fd875UL, 0x85e366aaUL,
    0x7bacd764UL, 0xe8d23a4eUL, 0x07cfc845UL, 0xf0cc3c44UL,
    0xcf35fa13UL, 0x62f496a7UL, 0xa601a7f4UL, 0x5ac298b5UL,
    0x977bec29UL, 0xda62b8d5UL, 0x3bfcc754UL, 0x822caeefUL,
    0xb9d069bbUL, 0x317a4bddUL, 0x963dabe0UL, 0x9e37a9e6UL,
    0x81e667a9UL, 0x28220a1eUL, 0x014647c9UL, 0xef1df20bUL,
    0xee5bb5c2UL, 0x88aa2266UL, 0xb356e532UL, 0x9f71ee2fUL,
    0xc27cbedfUL, 0xac872b7dUL, 0x3ebf819eUL, 0x485a1236UL,
    0x36b58398UL, 0x6c771b2dUL, 0x38360e12UL, 0x8caf2365UL,
    0xf306f502UL, 0x094c45cfUL, 0x84a52163UL, 0x1fd1ce4fUL,
    0x397049dbUL, 0xb09c2c74UL, 0xc33af916UL, 0xbf59e637UL,
    0xe254b6c7UL, 0xa0882878UL, 0x5c4b1739UL, 0x32b0829bUL,
    0x68721a2eUL, 0x169d8b80UL, 0xdf21fe1fUL, 0x12988a83UL,
    0x242d091bUL, 0x03cac946UL, 0x26a18794UL, 0x256b4ed2UL,
    0xa342e13eUL, 0xb8962e72UL, 0xb753e431UL, 0xa747e03dUL,
    0x8b60eb20UL, 0x7aea90adUL, 0xaa0ea4f1UL, 0x78661e22UL,
    0x2eab8592UL, 0x9dfd60a0UL, 0x00000000UL, 0x94b1256fUL,
    0xf703f401UL, 0xe312f10eUL, 0x6afe94a1UL, 0x2c270b1dUL,
    0xbb5ce734UL, 0xc9bc759fUL, 0x9b74ef2cUL, 0xd0e4345cUL,
    0xc4f53153UL, 0x77a3d461UL, 0x67b7d06dUL, 0x22a48697UL,
    0xe59b7e82UL, 0x8e23adeaUL, 0xd32efd1aUL, 0xa48d297bUL,
    0xc0f03050UL, 0xecd73b4dUL, 0x46d99fbcUL, 0xc73ff815UL,
    0x3ff9c657UL, 0x4c5f1335UL, 0x181e060aUL, 0x1411050fUL,
    0x33f6c552UL, 0x44551133UL, 0xc1b67799UL, 0xed917c84UL,
    0xf58f7a8eUL, 0xfd857888UL, 0xd8ee365aUL, 0x706c1c24UL,
    0xe4dd394bUL, 0x792059ebUL, 0x60781828UL, 0x451356faUL,
    0xf645b3c8UL, 0xfa4ab0cdUL, 0x90b4246cUL, 0x80a02060UL,
    0xf240b2cbUL, 0x72e092abUL, 0xb615a3f8UL, 0x27e7c05dUL,
    0x0d4944ccUL, 0x95f762a6UL, 0x40501030UL, 0xea5eb4c1UL,
    0x2aae8491UL, 0x115243c5UL, 0x76e593a8UL, 0x2fedc25bUL,
    0x357f4adeUL, 0xce73bddaUL, 0x06898f8cUL, 0xb4992d77UL,
    0xca76bcd9UL, 0x4ad69cb9UL, 0xb5df6abeUL, 0x1d5d40c0UL,
    0x1bd4cf4cUL, 0xb210a2fbUL, 0x3aba809dUL, 0x216e4fd1UL,
    0x7c631f21UL, 0x0fc5ca43UL, 0x9238aae3UL, 0x155742c6UL,
};

static const u32 U7[256] = {
    0x016ab9bbUL, 0xb1669ae5UL, 0xcd1465e2UL, 0x511b8725UL,
    0xa457a2f7UL, 0x03bed6d0UL, 0x04b5ded6UL, 0xfe8552b3UL,
    0xad4abafdUL, 0x63e009cfUL, 0x84961c09UL, 0x1a4d91a5UL,
    0x4d37a73dUL, 0xa35caaf1UL, 0xe117a47bUL, 0xf98e5ab5UL,
    0xac200346UL, 0x1184e6c4UL, 0xc268cc55UL, 0x0da8c6dcUL,
    0x99d085aaUL, 0xaa41b2fbUL, 0x9c0fe2c7UL, 0x55ae59f3UL,
    0x20c1befeUL, 0xe5a27aadUL, 0x7fcc29d7UL, 0xe80abc71UL,
    0x3be696e0UL, 0x9edb8dacUL, 0x2215d195UL, 0xceaab332UL,
    0x93734b70UL, 0xfd3b8463UL, 0xd052fc41UL, 0xe61cac7dUL,
    0x94784376UL, 0x0661b1bdUL, 0xdaf1329bUL, 0x17e55779UL,
    0x5cb341f9UL, 0x4b561680UL, 0x0cc27f67UL, 0xcc7edc59UL,
    0x409f61e1UL, 0xe3c3cb10UL, 0x302fe181UL, 0x0e16100cUL,
    0x5e672e92UL, 0x663f6ea2UL, 0x53cfe84eUL, 0x6c9ca078UL,
    0x730e56b0UL, 0x349a3f57UL, 0x3ced9ee6UL, 0x8e35d2d3UL,
    0x8023c2dfUL, 0x2ed7aef2UL, 0x6e48cf13UL, 0x596c2694UL,
    0x605edf1fUL, 0x9b04eac1UL, 0x19f34775UL, 0x893edad5UL,
    0xffefeb08UL, 0xf2472dd4UL, 0xc7b7ab38UL, 0xb9113b54UL,
    0xa236134aUL, 0xf4269c69UL, 0x10ee5f7fUL, 0x8d8b0403UL,
    0x4fe3c856UL, 0x479469e7UL, 0xeaded31aUL, 0x98ba3c11UL,
    0x2d697822UL, 0x15313812UL, 0x6afd11c5UL, 0xdb9b8b20UL,
    0x38584030UL, 0x6b97a87eUL, 0x237f682eUL, 0x1c2c2018UL,
    0x070b0806UL, 0x21ab0745UL, 0x27cab6f8UL, 0x5f0d9729UL,
    0x7264ef0bUL, 0x29dca6f4UL, 0xb3b2f58eUL, 0x628ab074UL,
    0xbda4e582UL, 0x85fca5b2UL, 0x1ef84f73UL, 0xa895dd90UL,
    0x0877a1b1UL, 0x442abf37UL, 0xa53d1b4cUL, 0x8beab5beUL,
    0xb66d92e3UL, 0x4a3caf3bUL, 0x7c72ff07UL, 0x839d140fUL,
    0x4321b731UL, 0x9fb13417UL, 0xf8e4e30eUL, 0xd6334dfcUL,
    0xbaafed84UL, 0x8728cad9UL, 0xf54c25d2UL, 0xcfc00a89UL,
    0x24746028UL, 0x26a00f43UL, 0x05df676dUL, 0x3a8c2f5bUL,
    0x091d180aUL, 0x7d1846bcUL, 0xb87b82efUL, 0x1899feceUL,
    0x35f086ecUL, 0x9512facdUL, 0x32fb8eeaUL, 0x2fbd1749UL,
    0x1f92f6c8UL, 0xa683cd9cUL, 0x424b0e8aUL, 0xb4b9fd88UL,
    0xdc908326UL, 0xc563c453UL, 0x52a551f5UL, 0xef01b477UL,
    0xbe1a3352UL, 0x0f7ca9b7UL, 0x6f2276a8UL, 0x6df619c3UL,
    0x02d46f6bUL, 0xecbf62a7UL, 0x76d131ddUL, 0x78c721d1UL,
    0x28b61f4fUL, 0x364e503cUL, 0xc8cb028fUL, 0xe4c8c316UL,
    0x2c03c199UL, 0xee6b0dccUL, 0x81497b64UL, 0xb00c235eUL,
    0x1d4699a3UL, 0xd13845faUL, 0xa0e27c21UL, 0x7ea6906cUL,
    0xaef46c2dUL, 0x41f5d85aUL, 0x2a627024UL, 0xe96005caUL,
    0xf1f9fb04UL, 0xc6dd1283UL, 0xe77615c6UL, 0x50713e9eUL,
    0xe2a972abUL, 0xc4097de8UL, 0xd58d9b2cUL, 0x8854636eUL,
    0x251ed993UL, 0xd8255df0UL, 0x6581b872UL, 0xa9ff642bUL,
    0x46fed05cUL, 0x96ac2c1dUL, 0xc0bca33eUL, 0x91a7241bUL,
    0x3f534836UL, 0x4540068cUL, 0xb2d84c35UL, 0xf7984ab9UL,
    0x9d655b7cUL, 0xca1f6de4UL, 0x86427362UL, 0x9a6e537aUL,
    0xab2b0b40UL, 0xd759f447UL, 0x5bb849ffUL, 0x5ad2f044UL,
    0xbcce5c39UL, 0x3d87275dUL, 0x00000000UL, 0xfb5a35deUL,
    0xf6f2f302UL, 0xedd5db1cUL, 0xcb75d45fUL, 0x3145583aUL,
    0x8f5f6b68UL, 0x56108f23UL, 0xb7072b58UL, 0x8ce1bdb8UL,
    0x97c695a6UL, 0x168feec2UL, 0x0aa3cedaUL, 0xb5d34433UL,
    0x6755d719UL, 0x64eb01c9UL, 0xc9a1bb34UL, 0xdf2e55f6UL,
    0x90cd9da0UL, 0xa188c59aUL, 0xfa308c65UL, 0xd286932aUL,
    0x68297eaeUL, 0x79ad986aUL, 0x123a3014UL, 0x1b27281eUL,
    0x613466a4UL, 0x77bb8866UL, 0x58069f2fUL, 0x6943c715UL,
    0x7b79f701UL, 0x756fe70dUL, 0x82f7adb4UL, 0x54c4e048UL,
    0xaf9ed596UL, 0x9219f2cbUL, 0x48e8c050UL, 0xbf708ae9UL,
    0x3e39f18dUL, 0x3724e987UL, 0xfc513dd8UL, 0xe07d1dc0UL,
    0x3932f98bUL, 0xd94fe44bUL, 0x4e8971edUL, 0x7a134ebaUL,
    0xc1d61a85UL, 0x33913751UL, 0x70b08060UL, 0x2b08c99fUL,
    0xbbc5543fUL, 0xd4e72297UL, 0xde44ec4dUL, 0x74055eb6UL,
    0xebb46aa1UL, 0x145b81a9UL, 0x8a800c05UL, 0xc30275eeUL,
    0x135089afUL, 0xf32d946fUL, 0x0bc97761UL, 0xddfa3a9dUL,
    0x577a3698UL, 0x498279ebUL, 0xa7e97427UL, 0xf09342bfUL,
    0x5dd9f842UL, 0x4c5d1e86UL, 0x71da39dbUL, 0xd3ec2a91UL,
};

static const u32 V7[256] = {
    0x68d2d3baUL, 0x194dfc54UL, 0x93bc712fUL, 0xb9cd9c74UL,
    0x0251f553UL, 0xb86b68d3UL, 0xbd6f6bd2UL, 0x6429d74dUL,
    0x0d5df050UL, 0x268ae9acUL, 0x830e8a8dUL, 0x79c6dcbfUL,
    0xaddd9070UL, 0x0755f652UL, 0xc852b39aUL, 0x612dd44cUL,
    0x658f23eaUL, 0xa67362d5UL, 0xf166a497UL, 0xb2636ed1UL,
    0xffcc5533UL, 0x0859f351UL, 0x2a71ed5bUL, 0x04a2f7a6UL,
    0x815f7fdeUL, 0x753dd848UL, 0x329ae5a8UL, 0xc75eb699UL,
    0x904b70dbUL, 0xfac85632UL, 0x51e6c4b7UL, 0x2bd719fcUL,
    0x48ab38e3UL, 0xdc42bf9eUL, 0xef7eae91UL, 0xcd56b09bUL,
    0x4daf3be2UL, 0x6dd6d0bbUL, 0x5819c341UL, 0xcba5b26eUL,
    0x0baef2a5UL, 0xc00b40cbUL, 0xdab1bd6bUL, 0xfb6ea295UL,
    0x1fbefea1UL, 0x18eb08f3UL, 0x4ffeceb1UL, 0x0a080602UL,
    0xdb1749ccUL, 0xf33751c4UL, 0x6974271dUL, 0x44503c14UL,
    0xe82b58c3UL, 0xf291a563UL, 0x954f73daUL, 0x3469e75dUL,
    0x3e61e15fUL, 0x8b5779dcUL, 0x94e9877dUL, 0xde134acdUL,
    0x9ee1817fUL, 0x2f75ee5aUL, 0xc1adb46cUL, 0x316de45cUL,
    0x0cfb04f7UL, 0xbe986a26UL, 0x24db1cffUL, 0x7e932aedUL,
    0x6f8725e8UL, 0xd34eba9dUL, 0xcea1b16fUL, 0x8c028f8eUL,
    0x7d642b19UL, 0x1abafda0UL, 0x17e70df0UL, 0x971e8689UL,
    0x333c110fUL, 0x1b1c0907UL, 0x2986ecafUL, 0x30cb10fbUL,
    0x28201808UL, 0x41543f15UL, 0x3934170dUL, 0x14100c04UL,
    0x05040301UL, 0xe98dac64UL, 0x845b7cdfUL, 0xb3c59a76UL,
    0x80f98b79UL, 0x8e537addUL, 0xc9f4473dUL, 0x4e583a16UL,
    0xc3fc413fUL, 0xebdc5937UL, 0xc4a9b76dUL, 0xd8e04838UL,
    0x67ded6b9UL, 0xa2d19573UL, 0x6a8326e9UL, 0xe1d45f35UL,
    0x1c49ff55UL, 0xa8d99371UL, 0x8af18d7bUL, 0x860a898cUL,
    0xa7d59672UL, 0x921a8588UL, 0x09ff07f6UL, 0x82a87e2aUL,
    0xc6f8423eUL, 0x3b65e25eUL, 0xbb9c6927UL, 0x4305ca46UL,
    0x3c30140cUL, 0xec89af65UL, 0xd5bdb868UL, 0xf899a361UL,
    0x0f0c0503UL, 0xe2235ec1UL, 0x1641f957UL, 0xa97f67d6UL,
    0x9a4376d9UL, 0x257de858UL, 0x9f4775d8UL, 0xe385aa66UL,
    0xac7b64d7UL, 0xd2e84e3aUL, 0xcf0745c8UL, 0xccf0443cUL,
    0x35cf13faUL, 0xf462a796UL, 0x01a6f4a7UL, 0xc25ab598UL,
    0x7b9729ecUL, 0x62dad5b8UL, 0xfc3b54c7UL, 0x2c82efaeUL,
    0xd0b9bb69UL, 0x7a31dd4bUL, 0x3d96e0abUL, 0x379ee6a9UL,
    0xe681a967UL, 0x22281e0aUL, 0x4601c947UL, 0x1def0bf2UL,
    0x5beec2b5UL, 0xaa886622UL, 0x56b332e5UL, 0x719f2feeUL,
    0x7cc2dfbeUL, 0x87ac7d2bUL, 0xbf3e9e81UL, 0x5a483612UL,
    0xb5369883UL, 0x776c2d1bUL, 0x3638120eUL, 0xaf8c6523UL,
    0x06f302f5UL, 0x4c09cf45UL, 0xa5846321UL, 0xd11f4fceUL,
    0x7039db49UL, 0x9cb0742cUL, 0x3ac316f9UL, 0x59bf37e6UL,
    0x54e2c7b6UL, 0x88a07828UL, 0x4b5c3917UL, 0xb0329b82UL,
    0x72682e1aUL, 0x9d16808bUL, 0x21df1ffeUL, 0x9812838aUL,
    0x2d241b09UL, 0xca0346c9UL, 0xa1269487UL, 0x6b25d24eUL,
    0x42a33ee1UL, 0x96b8722eUL, 0x53b731e4UL, 0x47a73de0UL,
    0x608b20ebUL, 0xea7aad90UL, 0x0eaaf1a4UL, 0x6678221eUL,
    0xab2e9285UL, 0xfd9da060UL, 0x00000000UL, 0xb1946f25UL,
    0x03f701f4UL, 0x12e30ef1UL, 0xfe6aa194UL, 0x272c1d0bUL,
    0x5cbb34e7UL, 0xbcc99f75UL, 0x749b2cefUL, 0xe4d05c34UL,
    0xf5c45331UL, 0xa37761d4UL, 0xb7676dd0UL, 0xa4229786UL,
    0x9be5827eUL, 0x238eeaadUL, 0x2ed31afdUL, 0x8da47b29UL,
    0xf0c05030UL, 0xd7ec4d3bUL, 0xd946bc9fUL, 0x3fc715f8UL,
    0xf93f57c6UL, 0x5f4c3513UL, 0x1e180a06UL, 0x11140f05UL,
    0xf63352c5UL, 0x55443311UL, 0xb6c19977UL, 0x91ed847cUL,
    0x8ff58e7aUL, 0x85fd8878UL, 0xeed85a36UL, 0x6c70241cUL,
    0xdde44b39UL, 0x2079eb59UL, 0x78602818UL, 0x1345fa56UL,
    0x45f6c8b3UL, 0x4afacdb0UL, 0xb4906c24UL, 0xa0806020UL,
    0x40f2cbb2UL, 0xe072ab92UL, 0x15b6f8a3UL, 0xe7275dc0UL,
    0x490dcc44UL, 0xf795a662UL, 0x50403010UL, 0x5eeac1b4UL,
    0xae2a9184UL, 0x5211c543UL, 0xe576a893UL, 0xed2f5bc2UL,
    0x7f35de4aUL, 0x73cedabdUL, 0x89068c8fUL, 0x99b4772dUL,
    0x76cad9bcUL, 0xd64ab99cUL, 0xdfb5be6aUL, 0x5d1dc040UL,
    0xd41b4ccfUL, 0x10b2fba2UL, 0xba3a9d80UL, 0x6e21d14fUL,
    0x637c211fUL, 0xc50f43caUL, 0x3892e3aaUL, 0x5715c642UL,
};

static const u32 c[R + 1][2] = {
    {0xba542f74UL, 0x53d3d24dUL},
    {0x50ac8dbfUL, 0x70529a4cUL},
    {0xead597d1UL, 0x33515ba6UL},
    {0xde48a899UL, 0xdb32b7fcUL},
    {0xe39e919bUL, 0xe2bb416eUL},
    {0xa5cb6b95UL, 0xa1f3b102UL},
    {0xccc41d14UL, 0xc363da5dUL},
    {0x5fdc7dcdUL, 0x7f5a6c5cUL},
    {0xf726ffedUL, 0xe89d6f8eUL},
};

/*
Definition of the 32-bit $U$ and $V$ matrices:

\begin{eqnarray*}
H & = & \left[\begin{array}{cc}
U & V \\
V & U
\end{array}\right], \\
U & = & \left[\begin{array}{cccc}
\gf{01} & \gf{03} & \gf{04} & \gf{05} \\
\gf{03} & \gf{01} & \gf{05} & \gf{04} \\
\gf{04} & \gf{05} & \gf{01} & \gf{03} \\
\gf{05} & \gf{04} & \gf{03} & \gf{01}
\end{array}\right], \\
V & = & \left[\begin{array}{cccc}
\gf{06} & \gf{08} & \gf{0b} & \gf{07} \\
\gf{08} & \gf{06} & \gf{07} & \gf{0b} \\
\gf{0b} & \gf{07} & \gf{06} & \gf{08} \\
\gf{07} & \gf{0b} & \gf{08} & \gf{06}
\end{array}\right].
\end{eqnarray*}

Definition of the corresponding $U$ and $V$ tables:

\begin{eqnarray*}
U_0[x] & = & S[x] \cdot \left[\begin{array}{cccc} \gf{01} & \gf{03} & \gf{04} & \gf{05} \end{array}\right],\\%
U_1[x] & = & S[x] \cdot \left[\begin{array}{cccc} \gf{03} & \gf{01} & \gf{05} & \gf{04} \end{array}\right],\\%
U_2[x] & = & S[x] \cdot \left[\begin{array}{cccc} \gf{04} & \gf{05} & \gf{01} & \gf{03} \end{array}\right],\\%
U_3[x] & = & S[x] \cdot \left[\begin{array}{cccc} \gf{05} & \gf{04} & \gf{03} & \gf{01} \end{array}\right];\\%
V_0[x] & = & S[x] \cdot \left[\begin{array}{cccc} \gf{06} & \gf{08} & \gf{0b} & \gf{07} \end{array}\right],\\%
V_1[x] & = & S[x] \cdot \left[\begin{array}{cccc} \gf{08} & \gf{06} & \gf{07} & \gf{0b} \end{array}\right],\\%
V_2[x] & = & S[x] \cdot \left[\begin{array}{cccc} \gf{0b} & \gf{07} & \gf{06} & \gf{08} \end{array}\right],\\%
V_3[x] & = & S[x] \cdot \left[\begin{array}{cccc} \gf{07} & \gf{0b} & \gf{08} & \gf{06} \end{array}\right];  %
\end{eqnarray*}

In terms of $T_i$:
\begin{eqnarray*}
U_i[x] & = & T_i[x] \rrr 32,\\%
V_i[x] & = & T_i[x] \& \mathtt{0xffffffff};  %
\end{eqnarray*}

*/

/**
 * Create the Khazad key schedule for a given cipher key.
 * Both encryption and decryption key schedules are generated.
 * 
 * @param key			The 128-bit cipher key.
 * @param structpointer	Pointer to the structure that will hold the expanded key.
 */
void NESSIEkeysetup(const unsigned char * const key,
				struct NESSIEstruct * const structpointer)
{
	int r;
	const u32 *S = U3;

    /*
	 * map u8 array cipher key to initial key state (mu):
	 */
	u32 K20 =
		((u32)key[ 0] << 24) ^
		((u32)key[ 1] << 16) ^
		((u32)key[ 2] <<  8) ^
		((u32)key[ 3]      );
	u32 K21 =
		((u32)key[ 4] << 24) ^
		((u32)key[ 5] << 16) ^
		((u32)key[ 6] <<  8) ^
		((u32)key[ 7]      );
	u32 K10 =
		((u32)key[ 8] << 24) ^
		((u32)key[ 9] << 16) ^
		((u32)key[10] <<  8) ^
		((u32)key[11]      );
	u32 K11 =
		((u32)key[12] << 24) ^
		((u32)key[13] << 16) ^
		((u32)key[14] <<  8) ^
		((u32)key[15]      );

	/*
	 * compute the round keys:
	 */
	for (r = 0; r <= R; r++) {
		/*
		 * K[r] = rho(c[r], K1) ^ K2;
		 */
		structpointer->roundKeyEnc[r][0] =
			U0[(K10 >> 24)       ] ^
			U1[(K10 >> 16) & 0xff] ^
			U2[(K10 >>  8) & 0xff] ^
			U3[(K10      ) & 0xff] ^
			V0[(K11 >> 24) & 0xff] ^
			V1[(K11 >> 16) & 0xff] ^
			V2[(K11 >>  8) & 0xff] ^
			V3[(K11      ) & 0xff] ^
			c[r][0] ^ K20;
		structpointer->roundKeyEnc[r][1] =
			U0[(K11 >> 24)       ] ^
			U1[(K11 >> 16) & 0xff] ^
			U2[(K11 >>  8) & 0xff] ^
			U3[(K11      ) & 0xff] ^
			V0[(K10 >> 24) & 0xff] ^
			V1[(K10 >> 16) & 0xff] ^
			V2[(K10 >>  8) & 0xff] ^
			V3[(K10      ) & 0xff] ^
			c[r][1] ^ K21;
		K20 = K10;
		K21 = K11;
		K10 = structpointer->roundKeyEnc[r][0];
		K11 = structpointer->roundKeyEnc[r][1];
	}
	/*
	 * compute the inverse key schedule:
	 * K'^0 = K^R, K'^R = K^0, K'^r = theta(K^{R-r})
	 */
	structpointer->roundKeyDec[0][0] = structpointer->roundKeyEnc[R][0];
	structpointer->roundKeyDec[0][1] = structpointer->roundKeyEnc[R][1];
	for (r = 1; r < R; r++) {
		K10 = structpointer->roundKeyEnc[R - r][0];
		K11 = structpointer->roundKeyEnc[R - r][1];
		structpointer->roundKeyDec[r][0] =
			U0[S[(K10 >> 24)       ] & 0xff] ^
			U1[S[(K10 >> 16) & 0xff] & 0xff] ^
			U2[S[(K10 >>  8) & 0xff] & 0xff] ^
			U3[S[(K10      ) & 0xff] & 0xff] ^
			V0[S[(K11 >> 24) & 0xff] & 0xff] ^
			V1[S[(K11 >> 16) & 0xff] & 0xff] ^
			V2[S[(K11 >>  8) & 0xff] & 0xff] ^
			V3[S[(K11      ) & 0xff] & 0xff];
		structpointer->roundKeyDec[r][1] =
			U0[S[(K11 >> 24)       ] & 0xff] ^
			U1[S[(K11 >> 16) & 0xff] & 0xff] ^
			U2[S[(K11 >>  8) & 0xff] & 0xff] ^
			U3[S[(K11      ) & 0xff] & 0xff] ^
			V0[S[(K10 >> 24) & 0xff] & 0xff] ^
			V1[S[(K10 >> 16) & 0xff] & 0xff] ^
			V2[S[(K10 >>  8) & 0xff] & 0xff] ^
			V3[S[(K10      ) & 0xff] & 0xff];
	}
	structpointer->roundKeyDec[R][0] = structpointer->roundKeyEnc[0][0];
	structpointer->roundKeyDec[R][1] = structpointer->roundKeyEnc[0][1];
}

/**
 * Either encrypt or decrypt a data block, according to the key schedule.
 * 
 * @param	block		the data block to be encrypted/decrypted.
 * @param	roundKey	the key schedule to be used.
 */
static void kcrypt(const u8 plaintext[/*8*/], u8 ciphertext[/*8*/],
				  const u32 roundKey[R + 1][2]) {
	int r;
	u32 s0, s1, t0, t1;

    /*
	 * map plaintext block to cipher state (mu)
	 * and add initial round key (sigma[K^0]):
	 */
	s0 =
		((u32)plaintext[0] << 24) ^
		((u32)plaintext[1] << 16) ^
		((u32)plaintext[2] <<  8) ^
		((u32)plaintext[3]      ) ^
		roundKey[0][0];
	s1 =
		((u32)plaintext[4] << 24) ^
		((u32)plaintext[5] << 16) ^
		((u32)plaintext[6] <<  8) ^
		((u32)plaintext[7]      ) ^
		roundKey[0][1];

    /*
	 * R - 1 full rounds:
	 */
    for (r = 1; r < R; r++) {
		t0 =
			U0[(s0 >> 24)       ] ^
			U1[(s0 >> 16) & 0xff] ^
			U2[(s0 >>  8) & 0xff] ^
			U3[(s0      ) & 0xff] ^
			V0[(s1 >> 24) & 0xff] ^
			V1[(s1 >> 16) & 0xff] ^
			V2[(s1 >>  8) & 0xff] ^
			V3[(s1      ) & 0xff] ^
			roundKey[r][0];
		t1 =
			U0[(s1 >> 24)       ] ^
			U1[(s1 >> 16) & 0xff] ^
			U2[(s1 >>  8) & 0xff] ^
			U3[(s1      ) & 0xff] ^
			V0[(s0 >> 24) & 0xff] ^
			V1[(s0 >> 16) & 0xff] ^
			V2[(s0 >>  8) & 0xff] ^
			V3[(s0      ) & 0xff] ^
			roundKey[r][1];
		s0 = t0;
		s1 = t1;
    }

    /*
	 * last round:
	 */
	s0 =
		(U0[(s0 >> 24)       ] & 0xff000000UL) ^
		(U1[(s0 >> 16) & 0xff] & 0x00ff0000UL) ^
		(U2[(s0 >>  8) & 0xff] & 0x0000ff00UL) ^
		(U3[(s0      ) & 0xff] & 0x000000ffUL) ^
		roundKey[R][0];
	s1 =
		(U0[(s1 >> 24)       ] & 0xff000000UL) ^
		(U1[(s1 >> 16) & 0xff] & 0x00ff0000UL) ^
		(U2[(s1 >>  8) & 0xff] & 0x0000ff00UL) ^
		(U3[(s1      ) & 0xff] & 0x000000ffUL) ^
		roundKey[R][1];

	/*
	 * map cipher state to ciphertext block (mu^{-1}):
	 */
	ciphertext[0] = (u8)(s0 >> 24);
	ciphertext[1] = (u8)(s0 >> 16);
	ciphertext[2] = (u8)(s0 >>  8);
	ciphertext[3] = (u8)(s0      );
	ciphertext[4] = (u8)(s1 >> 24);
	ciphertext[5] = (u8)(s1 >> 16);
	ciphertext[6] = (u8)(s1 >>  8);
	ciphertext[7] = (u8)(s1      );
}

/**
 * Encrypt a data block.
 * 
 * @param	structpointer	the expanded key.
 * @param	plaintext		the data block to be encrypted.
 * @param	ciphertext		the encrypted data block.
 */
void NESSIEencrypt(const struct NESSIEstruct * const structpointer,
				   const unsigned char * const plaintext,
				         unsigned char * const ciphertext)
{
	kcrypt(plaintext, ciphertext, structpointer->roundKeyEnc);
}

/**
 * Decrypt a data block.
 * 
 * @param	structpointer	the expanded key.
 * @param	ciphertext		the data block to be decrypted.
 * @param	plaintext		the decrypted data block.
 */
void NESSIEdecrypt(const struct NESSIEstruct * const structpointer,
				   const unsigned char * const ciphertext,
				         unsigned char * const plaintext)
{
	kcrypt(ciphertext, plaintext, structpointer->roundKeyDec);
}

void print_data(char *str, u8 *val, int len)
{
  int i;

  static char *hex="0123456789abcdef";

  printf("%s=", str);
  for(i=0; i<len; i++)
    {
      putchar(hex[(val[i]>>4)&0xf]);
      putchar(hex[(val[i]   )&0xf]);
    }
  putchar('\n');
}

int compare_blocks(u8 *m1, u8 *m2, int len_bits)
{
  int i;
  int lenb=(len_bits+7)>>3;
  int mask0 = (1<<(((len_bits-1)&7)+1))-1;

  if((m1[0]&mask0) != (m2[0]&mask0))
    return 1;

  for(i=1; i<lenb; i++)
    if(m1[i] != m2[i])
        return 1;

  return 0;
}

int main(void)
{
  struct NESSIEstruct subkeys;
  u8 key[KEYSIZEB];
  u8 plain[BLOCKSIZEB];
  u8 cipher[BLOCKSIZEB];
  u8 decrypted[BLOCKSIZEB];

  int v;

  printf("Test vectors -- set 1\n");
  printf("=====================\n\n");

  /* If key size is not a multiple of 8, this tests too much (intentionally) */
  for(v=0; v<(KEYSIZEB*8); v++)
    {
      memset(plain, 0, BLOCKSIZEB);
      memset(key, 0, KEYSIZEB);
      key[v>>3] = 1<<(7-(v&7));

      NESSIEkeysetup(key, &subkeys);
      NESSIEencrypt(&subkeys, plain, cipher);
      NESSIEdecrypt(&subkeys, cipher, decrypted);

      printf("Set 1, vector#%3d:\n", v);
      print_data("key", key, KEYSIZEB);
      print_data("plain", plain, BLOCKSIZEB);
      print_data("cipher", cipher, BLOCKSIZEB);
      print_data("decrypted", decrypted, BLOCKSIZEB);

      if(compare_blocks(plain, decrypted, BLOCKSIZE) != 0)
        printf("** Decryption error: **\n"
               "   Decrypted ciphertext is different than the plaintext!\n");

      printf("\n");
    }

  printf("Test vectors -- set 2\n");
  printf("=====================\n\n");

  /* If block size is not a multiple of 8, this tests too much (intentionally) */
  for(v=0; v<(BLOCKSIZEB*8); v++)
    {
      memset(plain, 0, BLOCKSIZEB);
      memset(key, 0, KEYSIZEB);
      plain[v>>3] = 1<<(7-(v&7));

      NESSIEkeysetup(key, &subkeys);
      NESSIEencrypt(&subkeys, plain, cipher);
      NESSIEdecrypt(&subkeys, cipher, decrypted);

      printf("Set 2, vector#%3d:\n", v);
      print_data("key", key, KEYSIZEB);
      print_data("plain", plain, BLOCKSIZEB);
      print_data("cipher", cipher, BLOCKSIZEB);
      print_data("decrypted", decrypted, BLOCKSIZEB);

      if(compare_blocks(plain, decrypted, BLOCKSIZE) != 0)
        printf("** Decryption error: **\n"
               "   Decrypted ciphertext is different than the plaintext!\n");

      printf("\n");
    }

  printf("Test vectors -- set 3\n");
  printf("=====================\n\n");

  for(v=0; v<256; v++)
    {
      memset(plain, v, BLOCKSIZEB);
      memset(key, v, KEYSIZEB);

      NESSIEkeysetup(key, &subkeys);
      NESSIEencrypt(&subkeys, plain, cipher);
      NESSIEdecrypt(&subkeys, cipher, decrypted);

      printf("Set 3, vector#%3d:\n", v);
      print_data("key", key, KEYSIZEB);
      print_data("plain", plain, BLOCKSIZEB);
      print_data("cipher", cipher, BLOCKSIZEB);
      print_data("decrypted", decrypted, BLOCKSIZEB);

      if(compare_blocks(plain, decrypted, BLOCKSIZE) != 0)
        printf("** Decryption error: **\n"
               "   Decrypted ciphertext is different than the plaintext!\n");

      printf("\n");
    }

  return 0;
}

