#!/usr/bin/perl -w
# $Id: Rijndael_PP.pm,v 1.21 2010/09/22 13:31:36 lackas Exp $
package Crypt::Rijndael_PP;
require 5.004;
use strict;
use integer;
use Carp;
use vars qw'$VERSION @EXPORT @EXPORT_OK %EXPORT_TAGS @ISA';
require Exporter;
@ISA = 'Exporter';
$VERSION = 0.05;
@EXPORT_OK = qw(
blockDecrypt blockEncrypt blockEncryptRound blockDecryptRound
cipherUpdateRounds cipherInit makeKey
MODE_ECB MODE_CBC MODE_CFB1
DIR_ENCRYPT DIR_DECRYPT
);
@EXPORT = qw(rijndael_encrypt rijndael_decrypt);
%EXPORT_TAGS = (
all => [@EXPORT_OK,@EXPORT],
modes => [qw(MODE_ECB MODE_CBC MODE_CFB1)],
directions => [qw(DIR_ENCRYPT DIR_DECRYPT)],
CAPI => [qw(cipherInit makeKey blockDecrypt blockEncrypt)]
);
# boxes-ref.dat
use constant Logtable => [
0, 0, 25, 1, 50, 2, 26, 198, 75, 199, 27, 104, 51, 238, 223, 3,
100, 4, 224, 14, 52, 141, 129, 239, 76, 113, 8, 200, 248, 105, 28, 193,
125, 194, 29, 181, 249, 185, 39, 106, 77, 228, 166, 114, 154, 201, 9, 120,
101, 47, 138, 5, 33, 15, 225, 36, 18, 240, 130, 69, 53, 147, 218, 142,
150, 143, 219, 189, 54, 208, 206, 148, 19, 92, 210, 241, 64, 70, 131, 56,
102, 221, 253, 48, 191, 6, 139, 98, 179, 37, 226, 152, 34, 136, 145, 16,
126, 110, 72, 195, 163, 182, 30, 66, 58, 107, 40, 84, 250, 133, 61, 186,
43, 121, 10, 21, 155, 159, 94, 202, 78, 212, 172, 229, 243, 115, 167, 87,
175, 88, 168, 80, 244, 234, 214, 116, 79, 174, 233, 213, 231, 230, 173, 232,
44, 215, 117, 122, 235, 22, 11, 245, 89, 203, 95, 176, 156, 169, 81, 160,
127, 12, 246, 111, 23, 196, 73, 236, 216, 67, 31, 45, 164, 118, 123, 183,
204, 187, 62, 90, 251, 96, 177, 134, 59, 82, 161, 108, 170, 85, 41, 157,
151, 178, 135, 144, 97, 190, 220, 252, 188, 149, 207, 205, 55, 63, 91, 209,
83, 57, 132, 60, 65, 162, 109, 71, 20, 42, 158, 93, 86, 242, 211, 171,
68, 17, 146, 217, 35, 32, 46, 137, 180, 124, 184, 38, 119, 153, 227, 165,
103, 74, 237, 222, 197, 49, 254, 24, 13, 99, 140, 128, 192, 247, 112, 7
];
use constant Algotable => [
1, 3, 5, 15, 17, 51, 85, 255, 26, 46, 114, 150, 161, 248, 19, 53,
95, 225, 56, 72, 216, 115, 149, 164, 247, 2, 6, 10, 30, 34, 102, 170,
229, 52, 92, 228, 55, 89, 235, 38, 106, 190, 217, 112, 144, 171, 230, 49,
83, 245, 4, 12, 20, 60, 68, 204, 79, 209, 104, 184, 211, 110, 178, 205,
76, 212, 103, 169, 224, 59, 77, 215, 98, 166, 241, 8, 24, 40, 120, 136,
131, 158, 185, 208, 107, 189, 220, 127, 129, 152, 179, 206, 73, 219, 118, 154,
181, 196, 87, 249, 16, 48, 80, 240, 11, 29, 39, 105, 187, 214, 97, 163,
254, 25, 43, 125, 135, 146, 173, 236, 47, 113, 147, 174, 233, 32, 96, 160,
251, 22, 58, 78, 210, 109, 183, 194, 93, 231, 50, 86, 250, 21, 63, 65,
195, 94, 226, 61, 71, 201, 64, 192, 91, 237, 44, 116, 156, 191, 218, 117,
159, 186, 213, 100, 172, 239, 42, 126, 130, 157, 188, 223, 122, 142, 137, 128,
155, 182, 193, 88, 232, 35, 101, 175, 234, 37, 111, 177, 200, 67, 197, 84,
252, 31, 33, 99, 165, 244, 7, 9, 27, 45, 119, 153, 176, 203, 70, 202,
69, 207, 74, 222, 121, 139, 134, 145, 168, 227, 62, 66, 198, 81, 243, 14,
18, 54, 90, 238, 41, 123, 141, 140, 143, 138, 133, 148, 167, 242, 13, 23,
57, 75, 221, 124, 132, 151, 162, 253, 28, 36, 108, 180, 199, 82, 246, 1
];
my @S = (
99, 124, 119, 123, 242, 107, 111, 197, 48, 1, 103, 43, 254, 215, 171, 118,
202, 130, 201, 125, 250, 89, 71, 240, 173, 212, 162, 175, 156, 164, 114, 192,
183, 253, 147, 38, 54, 63, 247, 204, 52, 165, 229, 241, 113, 216, 49, 21,
4, 199, 35, 195, 24, 150, 5, 154, 7, 18, 128, 226, 235, 39, 178, 117,
9, 131, 44, 26, 27, 110, 90, 160, 82, 59, 214, 179, 41, 227, 47, 132,
83, 209, 0, 237, 32, 252, 177, 91, 106, 203, 190, 57, 74, 76, 88, 207,
208, 239, 170, 251, 67, 77, 51, 133, 69, 249, 2, 127, 80, 60, 159, 168,
81, 163, 64, 143, 146, 157, 56, 245, 188, 182, 218, 33, 16, 255, 243, 210,
205, 12, 19, 236, 95, 151, 68, 23, 196, 167, 126, 61, 100, 93, 25, 115,
96, 129, 79, 220, 34, 42, 144, 136, 70, 238, 184, 20, 222, 94, 11, 219,
224, 50, 58, 10, 73, 6, 36, 92, 194, 211, 172, 98, 145, 149, 228, 121,
231, 200, 55, 109, 141, 213, 78, 169, 108, 86, 244, 234, 101, 122, 174, 8,
186, 120, 37, 46, 28, 166, 180, 198, 232, 221, 116, 31, 75, 189, 139, 138,
112, 62, 181, 102, 72, 3, 246, 14, 97, 53, 87, 185, 134, 193, 29, 158,
225, 248, 152, 17, 105, 217, 142, 148, 155, 30, 135, 233, 206, 85, 40, 223,
140, 161, 137, 13, 191, 230, 66, 104, 65, 153, 45, 15, 176, 84, 187, 22
);
my @Si = (
82, 9, 106, 213, 48, 54, 165, 56, 191, 64, 163, 158, 129, 243, 215, 251,
124, 227, 57, 130, 155, 47, 255, 135, 52, 142, 67, 68, 196, 222, 233, 203,
84, 123, 148, 50, 166, 194, 35, 61, 238, 76, 149, 11, 66, 250, 195, 78,
8, 46, 161, 102, 40, 217, 36, 178, 118, 91, 162, 73, 109, 139, 209, 37,
114, 248, 246, 100, 134, 104, 152, 22, 212, 164, 92, 204, 93, 101, 182, 146,
108, 112, 72, 80, 253, 237, 185, 218, 94, 21, 70, 87, 167, 141, 157, 132,
144, 216, 171, 0, 140, 188, 211, 10, 247, 228, 88, 5, 184, 179, 69, 6,
208, 44, 30, 143, 202, 63, 15, 2, 193, 175, 189, 3, 1, 19, 138, 107,
58, 145, 17, 65, 79, 103, 220, 234, 151, 242, 207, 206, 240, 180, 230, 115,
150, 172, 116, 34, 231, 173, 53, 133, 226, 249, 55, 232, 28, 117, 223, 110,
71, 241, 26, 113, 29, 41, 197, 137, 111, 183, 98, 14, 170, 24, 190, 27,
252, 86, 62, 75, 198, 210, 121, 32, 154, 219, 192, 254, 120, 205, 90, 244,
31, 221, 168, 51, 136, 7, 199, 49, 177, 18, 16, 89, 39, 128, 236, 95,
96, 81, 127, 169, 25, 181, 74, 13, 45, 229, 122, 159, 147, 201, 156, 239,
160, 224, 59, 77, 174, 42, 245, 176, 200, 235, 187, 60, 131, 83, 153, 97,
23, 43, 4, 126, 186, 119, 214, 38, 225, 105, 20, 99, 85, 33, 12, 125
);
my @iG = (
[ 0x0e, 0x09, 0x0d, 0x0b ],
[ 0x0b, 0x0e, 0x09, 0x0d ],
[ 0x0d, 0x0b, 0x0e, 0x09 ],
[ 0x09, 0x0d, 0x0b, 0x0e ]
);
my @rcon = (
0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80,
0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f,
0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4,
0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91
);
my @T1 = (
[0xc6,0x63,0x63,0xa5], [0xf8,0x7c,0x7c,0x84], [0xee,0x77,0x77,0x99], [0xf6,0x7b,0x7b,0x8d],
[0xff,0xf2,0xf2,0x0d], [0xd6,0x6b,0x6b,0xbd], [0xde,0x6f,0x6f,0xb1], [0x91,0xc5,0xc5,0x54],
[0x60,0x30,0x30,0x50], [0x02,0x01,0x01,0x03], [0xce,0x67,0x67,0xa9], [0x56,0x2b,0x2b,0x7d],
[0xe7,0xfe,0xfe,0x19], [0xb5,0xd7,0xd7,0x62], [0x4d,0xab,0xab,0xe6], [0xec,0x76,0x76,0x9a],
[0x8f,0xca,0xca,0x45], [0x1f,0x82,0x82,0x9d], [0x89,0xc9,0xc9,0x40], [0xfa,0x7d,0x7d,0x87],
[0xef,0xfa,0xfa,0x15], [0xb2,0x59,0x59,0xeb], [0x8e,0x47,0x47,0xc9], [0xfb,0xf0,0xf0,0x0b],
[0x41,0xad,0xad,0xec], [0xb3,0xd4,0xd4,0x67], [0x5f,0xa2,0xa2,0xfd], [0x45,0xaf,0xaf,0xea],
[0x23,0x9c,0x9c,0xbf], [0x53,0xa4,0xa4,0xf7], [0xe4,0x72,0x72,0x96], [0x9b,0xc0,0xc0,0x5b],
[0x75,0xb7,0xb7,0xc2], [0xe1,0xfd,0xfd,0x1c], [0x3d,0x93,0x93,0xae], [0x4c,0x26,0x26,0x6a],
[0x6c,0x36,0x36,0x5a], [0x7e,0x3f,0x3f,0x41], [0xf5,0xf7,0xf7,0x02], [0x83,0xcc,0xcc,0x4f],
[0x68,0x34,0x34,0x5c], [0x51,0xa5,0xa5,0xf4], [0xd1,0xe5,0xe5,0x34], [0xf9,0xf1,0xf1,0x08],
[0xe2,0x71,0x71,0x93], [0xab,0xd8,0xd8,0x73], [0x62,0x31,0x31,0x53], [0x2a,0x15,0x15,0x3f],
[0x08,0x04,0x04,0x0c], [0x95,0xc7,0xc7,0x52], [0x46,0x23,0x23,0x65], [0x9d,0xc3,0xc3,0x5e],
[0x30,0x18,0x18,0x28], [0x37,0x96,0x96,0xa1], [0x0a,0x05,0x05,0x0f], [0x2f,0x9a,0x9a,0xb5],
[0x0e,0x07,0x07,0x09], [0x24,0x12,0x12,0x36], [0x1b,0x80,0x80,0x9b], [0xdf,0xe2,0xe2,0x3d],
[0xcd,0xeb,0xeb,0x26], [0x4e,0x27,0x27,0x69], [0x7f,0xb2,0xb2,0xcd], [0xea,0x75,0x75,0x9f],
[0x12,0x09,0x09,0x1b], [0x1d,0x83,0x83,0x9e], [0x58,0x2c,0x2c,0x74], [0x34,0x1a,0x1a,0x2e],
[0x36,0x1b,0x1b,0x2d], [0xdc,0x6e,0x6e,0xb2], [0xb4,0x5a,0x5a,0xee], [0x5b,0xa0,0xa0,0xfb],
[0xa4,0x52,0x52,0xf6], [0x76,0x3b,0x3b,0x4d], [0xb7,0xd6,0xd6,0x61], [0x7d,0xb3,0xb3,0xce],
[0x52,0x29,0x29,0x7b], [0xdd,0xe3,0xe3,0x3e], [0x5e,0x2f,0x2f,0x71], [0x13,0x84,0x84,0x97],
[0xa6,0x53,0x53,0xf5], [0xb9,0xd1,0xd1,0x68], [0x00,0x00,0x00,0x00], [0xc1,0xed,0xed,0x2c],
[0x40,0x20,0x20,0x60], [0xe3,0xfc,0xfc,0x1f], [0x79,0xb1,0xb1,0xc8], [0xb6,0x5b,0x5b,0xed],
[0xd4,0x6a,0x6a,0xbe], [0x8d,0xcb,0xcb,0x46], [0x67,0xbe,0xbe,0xd9], [0x72,0x39,0x39,0x4b],
[0x94,0x4a,0x4a,0xde], [0x98,0x4c,0x4c,0xd4], [0xb0,0x58,0x58,0xe8], [0x85,0xcf,0xcf,0x4a],
[0xbb,0xd0,0xd0,0x6b], [0xc5,0xef,0xef,0x2a], [0x4f,0xaa,0xaa,0xe5], [0xed,0xfb,0xfb,0x16],
[0x86,0x43,0x43,0xc5], [0x9a,0x4d,0x4d,0xd7], [0x66,0x33,0x33,0x55], [0x11,0x85,0x85,0x94],
[0x8a,0x45,0x45,0xcf], [0xe9,0xf9,0xf9,0x10], [0x04,0x02,0x02,0x06], [0xfe,0x7f,0x7f,0x81],
[0xa0,0x50,0x50,0xf0], [0x78,0x3c,0x3c,0x44], [0x25,0x9f,0x9f,0xba], [0x4b,0xa8,0xa8,0xe3],
[0xa2,0x51,0x51,0xf3], [0x5d,0xa3,0xa3,0xfe], [0x80,0x40,0x40,0xc0], [0x05,0x8f,0x8f,0x8a],
[0x3f,0x92,0x92,0xad], [0x21,0x9d,0x9d,0xbc], [0x70,0x38,0x38,0x48], [0xf1,0xf5,0xf5,0x04],
[0x63,0xbc,0xbc,0xdf], [0x77,0xb6,0xb6,0xc1], [0xaf,0xda,0xda,0x75], [0x42,0x21,0x21,0x63],
[0x20,0x10,0x10,0x30], [0xe5,0xff,0xff,0x1a], [0xfd,0xf3,0xf3,0x0e], [0xbf,0xd2,0xd2,0x6d],
[0x81,0xcd,0xcd,0x4c], [0x18,0x0c,0x0c,0x14], [0x26,0x13,0x13,0x35], [0xc3,0xec,0xec,0x2f],
[0xbe,0x5f,0x5f,0xe1], [0x35,0x97,0x97,0xa2], [0x88,0x44,0x44,0xcc], [0x2e,0x17,0x17,0x39],
[0x93,0xc4,0xc4,0x57], [0x55,0xa7,0xa7,0xf2], [0xfc,0x7e,0x7e,0x82], [0x7a,0x3d,0x3d,0x47],
[0xc8,0x64,0x64,0xac], [0xba,0x5d,0x5d,0xe7], [0x32,0x19,0x19,0x2b], [0xe6,0x73,0x73,0x95],
[0xc0,0x60,0x60,0xa0], [0x19,0x81,0x81,0x98], [0x9e,0x4f,0x4f,0xd1], [0xa3,0xdc,0xdc,0x7f],
[0x44,0x22,0x22,0x66], [0x54,0x2a,0x2a,0x7e], [0x3b,0x90,0x90,0xab], [0x0b,0x88,0x88,0x83],
[0x8c,0x46,0x46,0xca], [0xc7,0xee,0xee,0x29], [0x6b,0xb8,0xb8,0xd3], [0x28,0x14,0x14,0x3c],
[0xa7,0xde,0xde,0x79], [0xbc,0x5e,0x5e,0xe2], [0x16,0x0b,0x0b,0x1d], [0xad,0xdb,0xdb,0x76],
[0xdb,0xe0,0xe0,0x3b], [0x64,0x32,0x32,0x56], [0x74,0x3a,0x3a,0x4e], [0x14,0x0a,0x0a,0x1e],
[0x92,0x49,0x49,0xdb], [0x0c,0x06,0x06,0x0a], [0x48,0x24,0x24,0x6c], [0xb8,0x5c,0x5c,0xe4],
[0x9f,0xc2,0xc2,0x5d], [0xbd,0xd3,0xd3,0x6e], [0x43,0xac,0xac,0xef], [0xc4,0x62,0x62,0xa6],
[0x39,0x91,0x91,0xa8], [0x31,0x95,0x95,0xa4], [0xd3,0xe4,0xe4,0x37], [0xf2,0x79,0x79,0x8b],
[0xd5,0xe7,0xe7,0x32], [0x8b,0xc8,0xc8,0x43], [0x6e,0x37,0x37,0x59], [0xda,0x6d,0x6d,0xb7],
[0x01,0x8d,0x8d,0x8c], [0xb1,0xd5,0xd5,0x64], [0x9c,0x4e,0x4e,0xd2], [0x49,0xa9,0xa9,0xe0],
[0xd8,0x6c,0x6c,0xb4], [0xac,0x56,0x56,0xfa], [0xf3,0xf4,0xf4,0x07], [0xcf,0xea,0xea,0x25],
[0xca,0x65,0x65,0xaf], [0xf4,0x7a,0x7a,0x8e], [0x47,0xae,0xae,0xe9], [0x10,0x08,0x08,0x18],
[0x6f,0xba,0xba,0xd5], [0xf0,0x78,0x78,0x88], [0x4a,0x25,0x25,0x6f], [0x5c,0x2e,0x2e,0x72],
[0x38,0x1c,0x1c,0x24], [0x57,0xa6,0xa6,0xf1], [0x73,0xb4,0xb4,0xc7], [0x97,0xc6,0xc6,0x51],
[0xcb,0xe8,0xe8,0x23], [0xa1,0xdd,0xdd,0x7c], [0xe8,0x74,0x74,0x9c], [0x3e,0x1f,0x1f,0x21],
[0x96,0x4b,0x4b,0xdd], [0x61,0xbd,0xbd,0xdc], [0x0d,0x8b,0x8b,0x86], [0x0f,0x8a,0x8a,0x85],
[0xe0,0x70,0x70,0x90], [0x7c,0x3e,0x3e,0x42], [0x71,0xb5,0xb5,0xc4], [0xcc,0x66,0x66,0xaa],
[0x90,0x48,0x48,0xd8], [0x06,0x03,0x03,0x05], [0xf7,0xf6,0xf6,0x01], [0x1c,0x0e,0x0e,0x12],
[0xc2,0x61,0x61,0xa3], [0x6a,0x35,0x35,0x5f], [0xae,0x57,0x57,0xf9], [0x69,0xb9,0xb9,0xd0],
[0x17,0x86,0x86,0x91], [0x99,0xc1,0xc1,0x58], [0x3a,0x1d,0x1d,0x27], [0x27,0x9e,0x9e,0xb9],
[0xd9,0xe1,0xe1,0x38], [0xeb,0xf8,0xf8,0x13], [0x2b,0x98,0x98,0xb3], [0x22,0x11,0x11,0x33],
[0xd2,0x69,0x69,0xbb], [0xa9,0xd9,0xd9,0x70], [0x07,0x8e,0x8e,0x89], [0x33,0x94,0x94,0xa7],
[0x2d,0x9b,0x9b,0xb6], [0x3c,0x1e,0x1e,0x22], [0x15,0x87,0x87,0x92], [0xc9,0xe9,0xe9,0x20],
[0x87,0xce,0xce,0x49], [0xaa,0x55,0x55,0xff], [0x50,0x28,0x28,0x78], [0xa5,0xdf,0xdf,0x7a],
[0x03,0x8c,0x8c,0x8f], [0x59,0xa1,0xa1,0xf8], [0x09,0x89,0x89,0x80], [0x1a,0x0d,0x0d,0x17],
[0x65,0xbf,0xbf,0xda], [0xd7,0xe6,0xe6,0x31], [0x84,0x42,0x42,0xc6], [0xd0,0x68,0x68,0xb8],
[0x82,0x41,0x41,0xc3], [0x29,0x99,0x99,0xb0], [0x5a,0x2d,0x2d,0x77], [0x1e,0x0f,0x0f,0x11],
[0x7b,0xb0,0xb0,0xcb], [0xa8,0x54,0x54,0xfc], [0x6d,0xbb,0xbb,0xd6], [0x2c,0x16,0x16,0x3a]
);
my @T2 = (
[0xa5,0xc6,0x63,0x63], [0x84,0xf8,0x7c,0x7c], [0x99,0xee,0x77,0x77], [0x8d,0xf6,0x7b,0x7b],
[0x0d,0xff,0xf2,0xf2], [0xbd,0xd6,0x6b,0x6b], [0xb1,0xde,0x6f,0x6f], [0x54,0x91,0xc5,0xc5],
[0x50,0x60,0x30,0x30], [0x03,0x02,0x01,0x01], [0xa9,0xce,0x67,0x67], [0x7d,0x56,0x2b,0x2b],
[0x19,0xe7,0xfe,0xfe], [0x62,0xb5,0xd7,0xd7], [0xe6,0x4d,0xab,0xab], [0x9a,0xec,0x76,0x76],
[0x45,0x8f,0xca,0xca], [0x9d,0x1f,0x82,0x82], [0x40,0x89,0xc9,0xc9], [0x87,0xfa,0x7d,0x7d],
[0x15,0xef,0xfa,0xfa], [0xeb,0xb2,0x59,0x59], [0xc9,0x8e,0x47,0x47], [0x0b,0xfb,0xf0,0xf0],
[0xec,0x41,0xad,0xad], [0x67,0xb3,0xd4,0xd4], [0xfd,0x5f,0xa2,0xa2], [0xea,0x45,0xaf,0xaf],
[0xbf,0x23,0x9c,0x9c], [0xf7,0x53,0xa4,0xa4], [0x96,0xe4,0x72,0x72], [0x5b,0x9b,0xc0,0xc0],
[0xc2,0x75,0xb7,0xb7], [0x1c,0xe1,0xfd,0xfd], [0xae,0x3d,0x93,0x93], [0x6a,0x4c,0x26,0x26],
[0x5a,0x6c,0x36,0x36], [0x41,0x7e,0x3f,0x3f], [0x02,0xf5,0xf7,0xf7], [0x4f,0x83,0xcc,0xcc],
[0x5c,0x68,0x34,0x34], [0xf4,0x51,0xa5,0xa5], [0x34,0xd1,0xe5,0xe5], [0x08,0xf9,0xf1,0xf1],
[0x93,0xe2,0x71,0x71], [0x73,0xab,0xd8,0xd8], [0x53,0x62,0x31,0x31], [0x3f,0x2a,0x15,0x15],
[0x0c,0x08,0x04,0x04], [0x52,0x95,0xc7,0xc7], [0x65,0x46,0x23,0x23], [0x5e,0x9d,0xc3,0xc3],
[0x28,0x30,0x18,0x18], [0xa1,0x37,0x96,0x96], [0x0f,0x0a,0x05,0x05], [0xb5,0x2f,0x9a,0x9a],
[0x09,0x0e,0x07,0x07], [0x36,0x24,0x12,0x12], [0x9b,0x1b,0x80,0x80], [0x3d,0xdf,0xe2,0xe2],
[0x26,0xcd,0xeb,0xeb], [0x69,0x4e,0x27,0x27], [0xcd,0x7f,0xb2,0xb2], [0x9f,0xea,0x75,0x75],
[0x1b,0x12,0x09,0x09], [0x9e,0x1d,0x83,0x83], [0x74,0x58,0x2c,0x2c], [0x2e,0x34,0x1a,0x1a],
[0x2d,0x36,0x1b,0x1b], [0xb2,0xdc,0x6e,0x6e], [0xee,0xb4,0x5a,0x5a], [0xfb,0x5b,0xa0,0xa0],
[0xf6,0xa4,0x52,0x52], [0x4d,0x76,0x3b,0x3b], [0x61,0xb7,0xd6,0xd6], [0xce,0x7d,0xb3,0xb3],
[0x7b,0x52,0x29,0x29], [0x3e,0xdd,0xe3,0xe3], [0x71,0x5e,0x2f,0x2f], [0x97,0x13,0x84,0x84],
[0xf5,0xa6,0x53,0x53], [0x68,0xb9,0xd1,0xd1], [0x00,0x00,0x00,0x00], [0x2c,0xc1,0xed,0xed],
[0x60,0x40,0x20,0x20], [0x1f,0xe3,0xfc,0xfc], [0xc8,0x79,0xb1,0xb1], [0xed,0xb6,0x5b,0x5b],
[0xbe,0xd4,0x6a,0x6a], [0x46,0x8d,0xcb,0xcb], [0xd9,0x67,0xbe,0xbe], [0x4b,0x72,0x39,0x39],
[0xde,0x94,0x4a,0x4a], [0xd4,0x98,0x4c,0x4c], [0xe8,0xb0,0x58,0x58], [0x4a,0x85,0xcf,0xcf],
[0x6b,0xbb,0xd0,0xd0], [0x2a,0xc5,0xef,0xef], [0xe5,0x4f,0xaa,0xaa], [0x16,0xed,0xfb,0xfb],
[0xc5,0x86,0x43,0x43], [0xd7,0x9a,0x4d,0x4d], [0x55,0x66,0x33,0x33], [0x94,0x11,0x85,0x85],
[0xcf,0x8a,0x45,0x45], [0x10,0xe9,0xf9,0xf9], [0x06,0x04,0x02,0x02], [0x81,0xfe,0x7f,0x7f],
[0xf0,0xa0,0x50,0x50], [0x44,0x78,0x3c,0x3c], [0xba,0x25,0x9f,0x9f], [0xe3,0x4b,0xa8,0xa8],
[0xf3,0xa2,0x51,0x51], [0xfe,0x5d,0xa3,0xa3], [0xc0,0x80,0x40,0x40], [0x8a,0x05,0x8f,0x8f],
[0xad,0x3f,0x92,0x92], [0xbc,0x21,0x9d,0x9d], [0x48,0x70,0x38,0x38], [0x04,0xf1,0xf5,0xf5],
[0xdf,0x63,0xbc,0xbc], [0xc1,0x77,0xb6,0xb6], [0x75,0xaf,0xda,0xda], [0x63,0x42,0x21,0x21],
[0x30,0x20,0x10,0x10], [0x1a,0xe5,0xff,0xff], [0x0e,0xfd,0xf3,0xf3], [0x6d,0xbf,0xd2,0xd2],
[0x4c,0x81,0xcd,0xcd], [0x14,0x18,0x0c,0x0c], [0x35,0x26,0x13,0x13], [0x2f,0xc3,0xec,0xec],
[0xe1,0xbe,0x5f,0x5f], [0xa2,0x35,0x97,0x97], [0xcc,0x88,0x44,0x44], [0x39,0x2e,0x17,0x17],
[0x57,0x93,0xc4,0xc4], [0xf2,0x55,0xa7,0xa7], [0x82,0xfc,0x7e,0x7e], [0x47,0x7a,0x3d,0x3d],
[0xac,0xc8,0x64,0x64], [0xe7,0xba,0x5d,0x5d], [0x2b,0x32,0x19,0x19], [0x95,0xe6,0x73,0x73],
[0xa0,0xc0,0x60,0x60], [0x98,0x19,0x81,0x81], [0xd1,0x9e,0x4f,0x4f], [0x7f,0xa3,0xdc,0xdc],
[0x66,0x44,0x22,0x22], [0x7e,0x54,0x2a,0x2a], [0xab,0x3b,0x90,0x90], [0x83,0x0b,0x88,0x88],
[0xca,0x8c,0x46,0x46], [0x29,0xc7,0xee,0xee], [0xd3,0x6b,0xb8,0xb8], [0x3c,0x28,0x14,0x14],
[0x79,0xa7,0xde,0xde], [0xe2,0xbc,0x5e,0x5e], [0x1d,0x16,0x0b,0x0b], [0x76,0xad,0xdb,0xdb],
[0x3b,0xdb,0xe0,0xe0], [0x56,0x64,0x32,0x32], [0x4e,0x74,0x3a,0x3a], [0x1e,0x14,0x0a,0x0a],
[0xdb,0x92,0x49,0x49], [0x0a,0x0c,0x06,0x06], [0x6c,0x48,0x24,0x24], [0xe4,0xb8,0x5c,0x5c],
[0x5d,0x9f,0xc2,0xc2], [0x6e,0xbd,0xd3,0xd3], [0xef,0x43,0xac,0xac], [0xa6,0xc4,0x62,0x62],
[0xa8,0x39,0x91,0x91], [0xa4,0x31,0x95,0x95], [0x37,0xd3,0xe4,0xe4], [0x8b,0xf2,0x79,0x79],
[0x32,0xd5,0xe7,0xe7], [0x43,0x8b,0xc8,0xc8], [0x59,0x6e,0x37,0x37], [0xb7,0xda,0x6d,0x6d],
[0x8c,0x01,0x8d,0x8d], [0x64,0xb1,0xd5,0xd5], [0xd2,0x9c,0x4e,0x4e], [0xe0,0x49,0xa9,0xa9],
[0xb4,0xd8,0x6c,0x6c], [0xfa,0xac,0x56,0x56], [0x07,0xf3,0xf4,0xf4], [0x25,0xcf,0xea,0xea],
[0xaf,0xca,0x65,0x65], [0x8e,0xf4,0x7a,0x7a], [0xe9,0x47,0xae,0xae], [0x18,0x10,0x08,0x08],
[0xd5,0x6f,0xba,0xba], [0x88,0xf0,0x78,0x78], [0x6f,0x4a,0x25,0x25], [0x72,0x5c,0x2e,0x2e],
[0x24,0x38,0x1c,0x1c], [0xf1,0x57,0xa6,0xa6], [0xc7,0x73,0xb4,0xb4], [0x51,0x97,0xc6,0xc6],
[0x23,0xcb,0xe8,0xe8], [0x7c,0xa1,0xdd,0xdd], [0x9c,0xe8,0x74,0x74], [0x21,0x3e,0x1f,0x1f],
[0xdd,0x96,0x4b,0x4b], [0xdc,0x61,0xbd,0xbd], [0x86,0x0d,0x8b,0x8b], [0x85,0x0f,0x8a,0x8a],
[0x90,0xe0,0x70,0x70], [0x42,0x7c,0x3e,0x3e], [0xc4,0x71,0xb5,0xb5], [0xaa,0xcc,0x66,0x66],
[0xd8,0x90,0x48,0x48], [0x05,0x06,0x03,0x03], [0x01,0xf7,0xf6,0xf6], [0x12,0x1c,0x0e,0x0e],
[0xa3,0xc2,0x61,0x61], [0x5f,0x6a,0x35,0x35], [0xf9,0xae,0x57,0x57], [0xd0,0x69,0xb9,0xb9],
[0x91,0x17,0x86,0x86], [0x58,0x99,0xc1,0xc1], [0x27,0x3a,0x1d,0x1d], [0xb9,0x27,0x9e,0x9e],
[0x38,0xd9,0xe1,0xe1], [0x13,0xeb,0xf8,0xf8], [0xb3,0x2b,0x98,0x98], [0x33,0x22,0x11,0x11],
[0xbb,0xd2,0x69,0x69], [0x70,0xa9,0xd9,0xd9], [0x89,0x07,0x8e,0x8e], [0xa7,0x33,0x94,0x94],
[0xb6,0x2d,0x9b,0x9b], [0x22,0x3c,0x1e,0x1e], [0x92,0x15,0x87,0x87], [0x20,0xc9,0xe9,0xe9],
[0x49,0x87,0xce,0xce], [0xff,0xaa,0x55,0x55], [0x78,0x50,0x28,0x28], [0x7a,0xa5,0xdf,0xdf],
[0x8f,0x03,0x8c,0x8c], [0xf8,0x59,0xa1,0xa1], [0x80,0x09,0x89,0x89], [0x17,0x1a,0x0d,0x0d],
[0xda,0x65,0xbf,0xbf], [0x31,0xd7,0xe6,0xe6], [0xc6,0x84,0x42,0x42], [0xb8,0xd0,0x68,0x68],
[0xc3,0x82,0x41,0x41], [0xb0,0x29,0x99,0x99], [0x77,0x5a,0x2d,0x2d], [0x11,0x1e,0x0f,0x0f],
[0xcb,0x7b,0xb0,0xb0], [0xfc,0xa8,0x54,0x54], [0xd6,0x6d,0xbb,0xbb], [0x3a,0x2c,0x16,0x16]
);
my @T3 = (
[0x63,0xa5,0xc6,0x63], [0x7c,0x84,0xf8,0x7c], [0x77,0x99,0xee,0x77], [0x7b,0x8d,0xf6,0x7b],
[0xf2,0x0d,0xff,0xf2], [0x6b,0xbd,0xd6,0x6b], [0x6f,0xb1,0xde,0x6f], [0xc5,0x54,0x91,0xc5],
[0x30,0x50,0x60,0x30], [0x01,0x03,0x02,0x01], [0x67,0xa9,0xce,0x67], [0x2b,0x7d,0x56,0x2b],
[0xfe,0x19,0xe7,0xfe], [0xd7,0x62,0xb5,0xd7], [0xab,0xe6,0x4d,0xab], [0x76,0x9a,0xec,0x76],
[0xca,0x45,0x8f,0xca], [0x82,0x9d,0x1f,0x82], [0xc9,0x40,0x89,0xc9], [0x7d,0x87,0xfa,0x7d],
[0xfa,0x15,0xef,0xfa], [0x59,0xeb,0xb2,0x59], [0x47,0xc9,0x8e,0x47], [0xf0,0x0b,0xfb,0xf0],
[0xad,0xec,0x41,0xad], [0xd4,0x67,0xb3,0xd4], [0xa2,0xfd,0x5f,0xa2], [0xaf,0xea,0x45,0xaf],
[0x9c,0xbf,0x23,0x9c], [0xa4,0xf7,0x53,0xa4], [0x72,0x96,0xe4,0x72], [0xc0,0x5b,0x9b,0xc0],
[0xb7,0xc2,0x75,0xb7], [0xfd,0x1c,0xe1,0xfd], [0x93,0xae,0x3d,0x93], [0x26,0x6a,0x4c,0x26],
[0x36,0x5a,0x6c,0x36], [0x3f,0x41,0x7e,0x3f], [0xf7,0x02,0xf5,0xf7], [0xcc,0x4f,0x83,0xcc],
[0x34,0x5c,0x68,0x34], [0xa5,0xf4,0x51,0xa5], [0xe5,0x34,0xd1,0xe5], [0xf1,0x08,0xf9,0xf1],
[0x71,0x93,0xe2,0x71], [0xd8,0x73,0xab,0xd8], [0x31,0x53,0x62,0x31], [0x15,0x3f,0x2a,0x15],
[0x04,0x0c,0x08,0x04], [0xc7,0x52,0x95,0xc7], [0x23,0x65,0x46,0x23], [0xc3,0x5e,0x9d,0xc3],
[0x18,0x28,0x30,0x18], [0x96,0xa1,0x37,0x96], [0x05,0x0f,0x0a,0x05], [0x9a,0xb5,0x2f,0x9a],
[0x07,0x09,0x0e,0x07], [0x12,0x36,0x24,0x12], [0x80,0x9b,0x1b,0x80], [0xe2,0x3d,0xdf,0xe2],
[0xeb,0x26,0xcd,0xeb], [0x27,0x69,0x4e,0x27], [0xb2,0xcd,0x7f,0xb2], [0x75,0x9f,0xea,0x75],
[0x09,0x1b,0x12,0x09], [0x83,0x9e,0x1d,0x83], [0x2c,0x74,0x58,0x2c], [0x1a,0x2e,0x34,0x1a],
[0x1b,0x2d,0x36,0x1b], [0x6e,0xb2,0xdc,0x6e], [0x5a,0xee,0xb4,0x5a], [0xa0,0xfb,0x5b,0xa0],
[0x52,0xf6,0xa4,0x52], [0x3b,0x4d,0x76,0x3b], [0xd6,0x61,0xb7,0xd6], [0xb3,0xce,0x7d,0xb3],
[0x29,0x7b,0x52,0x29], [0xe3,0x3e,0xdd,0xe3], [0x2f,0x71,0x5e,0x2f], [0x84,0x97,0x13,0x84],
[0x53,0xf5,0xa6,0x53], [0xd1,0x68,0xb9,0xd1], [0x00,0x00,0x00,0x00], [0xed,0x2c,0xc1,0xed],
[0x20,0x60,0x40,0x20], [0xfc,0x1f,0xe3,0xfc], [0xb1,0xc8,0x79,0xb1], [0x5b,0xed,0xb6,0x5b],
[0x6a,0xbe,0xd4,0x6a], [0xcb,0x46,0x8d,0xcb], [0xbe,0xd9,0x67,0xbe], [0x39,0x4b,0x72,0x39],
[0x4a,0xde,0x94,0x4a], [0x4c,0xd4,0x98,0x4c], [0x58,0xe8,0xb0,0x58], [0xcf,0x4a,0x85,0xcf],
[0xd0,0x6b,0xbb,0xd0], [0xef,0x2a,0xc5,0xef], [0xaa,0xe5,0x4f,0xaa], [0xfb,0x16,0xed,0xfb],
[0x43,0xc5,0x86,0x43], [0x4d,0xd7,0x9a,0x4d], [0x33,0x55,0x66,0x33], [0x85,0x94,0x11,0x85],
[0x45,0xcf,0x8a,0x45], [0xf9,0x10,0xe9,0xf9], [0x02,0x06,0x04,0x02], [0x7f,0x81,0xfe,0x7f],
[0x50,0xf0,0xa0,0x50], [0x3c,0x44,0x78,0x3c], [0x9f,0xba,0x25,0x9f], [0xa8,0xe3,0x4b,0xa8],
[0x51,0xf3,0xa2,0x51], [0xa3,0xfe,0x5d,0xa3], [0x40,0xc0,0x80,0x40], [0x8f,0x8a,0x05,0x8f],
[0x92,0xad,0x3f,0x92], [0x9d,0xbc,0x21,0x9d], [0x38,0x48,0x70,0x38], [0xf5,0x04,0xf1,0xf5],
[0xbc,0xdf,0x63,0xbc], [0xb6,0xc1,0x77,0xb6], [0xda,0x75,0xaf,0xda], [0x21,0x63,0x42,0x21],
[0x10,0x30,0x20,0x10], [0xff,0x1a,0xe5,0xff], [0xf3,0x0e,0xfd,0xf3], [0xd2,0x6d,0xbf,0xd2],
[0xcd,0x4c,0x81,0xcd], [0x0c,0x14,0x18,0x0c], [0x13,0x35,0x26,0x13], [0xec,0x2f,0xc3,0xec],
[0x5f,0xe1,0xbe,0x5f], [0x97,0xa2,0x35,0x97], [0x44,0xcc,0x88,0x44], [0x17,0x39,0x2e,0x17],
[0xc4,0x57,0x93,0xc4], [0xa7,0xf2,0x55,0xa7], [0x7e,0x82,0xfc,0x7e], [0x3d,0x47,0x7a,0x3d],
[0x64,0xac,0xc8,0x64], [0x5d,0xe7,0xba,0x5d], [0x19,0x2b,0x32,0x19], [0x73,0x95,0xe6,0x73],
[0x60,0xa0,0xc0,0x60], [0x81,0x98,0x19,0x81], [0x4f,0xd1,0x9e,0x4f], [0xdc,0x7f,0xa3,0xdc],
[0x22,0x66,0x44,0x22], [0x2a,0x7e,0x54,0x2a], [0x90,0xab,0x3b,0x90], [0x88,0x83,0x0b,0x88],
[0x46,0xca,0x8c,0x46], [0xee,0x29,0xc7,0xee], [0xb8,0xd3,0x6b,0xb8], [0x14,0x3c,0x28,0x14],
[0xde,0x79,0xa7,0xde], [0x5e,0xe2,0xbc,0x5e], [0x0b,0x1d,0x16,0x0b], [0xdb,0x76,0xad,0xdb],
[0xe0,0x3b,0xdb,0xe0], [0x32,0x56,0x64,0x32], [0x3a,0x4e,0x74,0x3a], [0x0a,0x1e,0x14,0x0a],
[0x49,0xdb,0x92,0x49], [0x06,0x0a,0x0c,0x06], [0x24,0x6c,0x48,0x24], [0x5c,0xe4,0xb8,0x5c],
[0xc2,0x5d,0x9f,0xc2], [0xd3,0x6e,0xbd,0xd3], [0xac,0xef,0x43,0xac], [0x62,0xa6,0xc4,0x62],
[0x91,0xa8,0x39,0x91], [0x95,0xa4,0x31,0x95], [0xe4,0x37,0xd3,0xe4], [0x79,0x8b,0xf2,0x79],
[0xe7,0x32,0xd5,0xe7], [0xc8,0x43,0x8b,0xc8], [0x37,0x59,0x6e,0x37], [0x6d,0xb7,0xda,0x6d],
[0x8d,0x8c,0x01,0x8d], [0xd5,0x64,0xb1,0xd5], [0x4e,0xd2,0x9c,0x4e], [0xa9,0xe0,0x49,0xa9],
[0x6c,0xb4,0xd8,0x6c], [0x56,0xfa,0xac,0x56], [0xf4,0x07,0xf3,0xf4], [0xea,0x25,0xcf,0xea],
[0x65,0xaf,0xca,0x65], [0x7a,0x8e,0xf4,0x7a], [0xae,0xe9,0x47,0xae], [0x08,0x18,0x10,0x08],
[0xba,0xd5,0x6f,0xba], [0x78,0x88,0xf0,0x78], [0x25,0x6f,0x4a,0x25], [0x2e,0x72,0x5c,0x2e],
[0x1c,0x24,0x38,0x1c], [0xa6,0xf1,0x57,0xa6], [0xb4,0xc7,0x73,0xb4], [0xc6,0x51,0x97,0xc6],
[0xe8,0x23,0xcb,0xe8], [0xdd,0x7c,0xa1,0xdd], [0x74,0x9c,0xe8,0x74], [0x1f,0x21,0x3e,0x1f],
[0x4b,0xdd,0x96,0x4b], [0xbd,0xdc,0x61,0xbd], [0x8b,0x86,0x0d,0x8b], [0x8a,0x85,0x0f,0x8a],
[0x70,0x90,0xe0,0x70], [0x3e,0x42,0x7c,0x3e], [0xb5,0xc4,0x71,0xb5], [0x66,0xaa,0xcc,0x66],
[0x48,0xd8,0x90,0x48], [0x03,0x05,0x06,0x03], [0xf6,0x01,0xf7,0xf6], [0x0e,0x12,0x1c,0x0e],
[0x61,0xa3,0xc2,0x61], [0x35,0x5f,0x6a,0x35], [0x57,0xf9,0xae,0x57], [0xb9,0xd0,0x69,0xb9],
[0x86,0x91,0x17,0x86], [0xc1,0x58,0x99,0xc1], [0x1d,0x27,0x3a,0x1d], [0x9e,0xb9,0x27,0x9e],
[0xe1,0x38,0xd9,0xe1], [0xf8,0x13,0xeb,0xf8], [0x98,0xb3,0x2b,0x98], [0x11,0x33,0x22,0x11],
[0x69,0xbb,0xd2,0x69], [0xd9,0x70,0xa9,0xd9], [0x8e,0x89,0x07,0x8e], [0x94,0xa7,0x33,0x94],
[0x9b,0xb6,0x2d,0x9b], [0x1e,0x22,0x3c,0x1e], [0x87,0x92,0x15,0x87], [0xe9,0x20,0xc9,0xe9],
[0xce,0x49,0x87,0xce], [0x55,0xff,0xaa,0x55], [0x28,0x78,0x50,0x28], [0xdf,0x7a,0xa5,0xdf],
[0x8c,0x8f,0x03,0x8c], [0xa1,0xf8,0x59,0xa1], [0x89,0x80,0x09,0x89], [0x0d,0x17,0x1a,0x0d],
[0xbf,0xda,0x65,0xbf], [0xe6,0x31,0xd7,0xe6], [0x42,0xc6,0x84,0x42], [0x68,0xb8,0xd0,0x68],
[0x41,0xc3,0x82,0x41], [0x99,0xb0,0x29,0x99], [0x2d,0x77,0x5a,0x2d], [0x0f,0x11,0x1e,0x0f],
[0xb0,0xcb,0x7b,0xb0], [0x54,0xfc,0xa8,0x54], [0xbb,0xd6,0x6d,0xbb], [0x16,0x3a,0x2c,0x16]
);
my @T4 = (
[0x63,0x63,0xa5,0xc6], [0x7c,0x7c,0x84,0xf8], [0x77,0x77,0x99,0xee], [0x7b,0x7b,0x8d,0xf6],
[0xf2,0xf2,0x0d,0xff], [0x6b,0x6b,0xbd,0xd6], [0x6f,0x6f,0xb1,0xde], [0xc5,0xc5,0x54,0x91],
[0x30,0x30,0x50,0x60], [0x01,0x01,0x03,0x02], [0x67,0x67,0xa9,0xce], [0x2b,0x2b,0x7d,0x56],
[0xfe,0xfe,0x19,0xe7], [0xd7,0xd7,0x62,0xb5], [0xab,0xab,0xe6,0x4d], [0x76,0x76,0x9a,0xec],
[0xca,0xca,0x45,0x8f], [0x82,0x82,0x9d,0x1f], [0xc9,0xc9,0x40,0x89], [0x7d,0x7d,0x87,0xfa],
[0xfa,0xfa,0x15,0xef], [0x59,0x59,0xeb,0xb2], [0x47,0x47,0xc9,0x8e], [0xf0,0xf0,0x0b,0xfb],
[0xad,0xad,0xec,0x41], [0xd4,0xd4,0x67,0xb3], [0xa2,0xa2,0xfd,0x5f], [0xaf,0xaf,0xea,0x45],
[0x9c,0x9c,0xbf,0x23], [0xa4,0xa4,0xf7,0x53], [0x72,0x72,0x96,0xe4], [0xc0,0xc0,0x5b,0x9b],
[0xb7,0xb7,0xc2,0x75], [0xfd,0xfd,0x1c,0xe1], [0x93,0x93,0xae,0x3d], [0x26,0x26,0x6a,0x4c],
[0x36,0x36,0x5a,0x6c], [0x3f,0x3f,0x41,0x7e], [0xf7,0xf7,0x02,0xf5], [0xcc,0xcc,0x4f,0x83],
[0x34,0x34,0x5c,0x68], [0xa5,0xa5,0xf4,0x51], [0xe5,0xe5,0x34,0xd1], [0xf1,0xf1,0x08,0xf9],
[0x71,0x71,0x93,0xe2], [0xd8,0xd8,0x73,0xab], [0x31,0x31,0x53,0x62], [0x15,0x15,0x3f,0x2a],
[0x04,0x04,0x0c,0x08], [0xc7,0xc7,0x52,0x95], [0x23,0x23,0x65,0x46], [0xc3,0xc3,0x5e,0x9d],
[0x18,0x18,0x28,0x30], [0x96,0x96,0xa1,0x37], [0x05,0x05,0x0f,0x0a], [0x9a,0x9a,0xb5,0x2f],
[0x07,0x07,0x09,0x0e], [0x12,0x12,0x36,0x24], [0x80,0x80,0x9b,0x1b], [0xe2,0xe2,0x3d,0xdf],
[0xeb,0xeb,0x26,0xcd], [0x27,0x27,0x69,0x4e], [0xb2,0xb2,0xcd,0x7f], [0x75,0x75,0x9f,0xea],
[0x09,0x09,0x1b,0x12], [0x83,0x83,0x9e,0x1d], [0x2c,0x2c,0x74,0x58], [0x1a,0x1a,0x2e,0x34],
[0x1b,0x1b,0x2d,0x36], [0x6e,0x6e,0xb2,0xdc], [0x5a,0x5a,0xee,0xb4], [0xa0,0xa0,0xfb,0x5b],
[0x52,0x52,0xf6,0xa4], [0x3b,0x3b,0x4d,0x76], [0xd6,0xd6,0x61,0xb7], [0xb3,0xb3,0xce,0x7d],
[0x29,0x29,0x7b,0x52], [0xe3,0xe3,0x3e,0xdd], [0x2f,0x2f,0x71,0x5e], [0x84,0x84,0x97,0x13],
[0x53,0x53,0xf5,0xa6], [0xd1,0xd1,0x68,0xb9], [0x00,0x00,0x00,0x00], [0xed,0xed,0x2c,0xc1],
[0x20,0x20,0x60,0x40], [0xfc,0xfc,0x1f,0xe3], [0xb1,0xb1,0xc8,0x79], [0x5b,0x5b,0xed,0xb6],
[0x6a,0x6a,0xbe,0xd4], [0xcb,0xcb,0x46,0x8d], [0xbe,0xbe,0xd9,0x67], [0x39,0x39,0x4b,0x72],
[0x4a,0x4a,0xde,0x94], [0x4c,0x4c,0xd4,0x98], [0x58,0x58,0xe8,0xb0], [0xcf,0xcf,0x4a,0x85],
[0xd0,0xd0,0x6b,0xbb], [0xef,0xef,0x2a,0xc5], [0xaa,0xaa,0xe5,0x4f], [0xfb,0xfb,0x16,0xed],
[0x43,0x43,0xc5,0x86], [0x4d,0x4d,0xd7,0x9a], [0x33,0x33,0x55,0x66], [0x85,0x85,0x94,0x11],
[0x45,0x45,0xcf,0x8a], [0xf9,0xf9,0x10,0xe9], [0x02,0x02,0x06,0x04], [0x7f,0x7f,0x81,0xfe],
[0x50,0x50,0xf0,0xa0], [0x3c,0x3c,0x44,0x78], [0x9f,0x9f,0xba,0x25], [0xa8,0xa8,0xe3,0x4b],
[0x51,0x51,0xf3,0xa2], [0xa3,0xa3,0xfe,0x5d], [0x40,0x40,0xc0,0x80], [0x8f,0x8f,0x8a,0x05],
[0x92,0x92,0xad,0x3f], [0x9d,0x9d,0xbc,0x21], [0x38,0x38,0x48,0x70], [0xf5,0xf5,0x04,0xf1],
[0xbc,0xbc,0xdf,0x63], [0xb6,0xb6,0xc1,0x77], [0xda,0xda,0x75,0xaf], [0x21,0x21,0x63,0x42],
[0x10,0x10,0x30,0x20], [0xff,0xff,0x1a,0xe5], [0xf3,0xf3,0x0e,0xfd], [0xd2,0xd2,0x6d,0xbf],
[0xcd,0xcd,0x4c,0x81], [0x0c,0x0c,0x14,0x18], [0x13,0x13,0x35,0x26], [0xec,0xec,0x2f,0xc3],
[0x5f,0x5f,0xe1,0xbe], [0x97,0x97,0xa2,0x35], [0x44,0x44,0xcc,0x88], [0x17,0x17,0x39,0x2e],
[0xc4,0xc4,0x57,0x93], [0xa7,0xa7,0xf2,0x55], [0x7e,0x7e,0x82,0xfc], [0x3d,0x3d,0x47,0x7a],
[0x64,0x64,0xac,0xc8], [0x5d,0x5d,0xe7,0xba], [0x19,0x19,0x2b,0x32], [0x73,0x73,0x95,0xe6],
[0x60,0x60,0xa0,0xc0], [0x81,0x81,0x98,0x19], [0x4f,0x4f,0xd1,0x9e], [0xdc,0xdc,0x7f,0xa3],
[0x22,0x22,0x66,0x44], [0x2a,0x2a,0x7e,0x54], [0x90,0x90,0xab,0x3b], [0x88,0x88,0x83,0x0b],
[0x46,0x46,0xca,0x8c], [0xee,0xee,0x29,0xc7], [0xb8,0xb8,0xd3,0x6b], [0x14,0x14,0x3c,0x28],
[0xde,0xde,0x79,0xa7], [0x5e,0x5e,0xe2,0xbc], [0x0b,0x0b,0x1d,0x16], [0xdb,0xdb,0x76,0xad],
[0xe0,0xe0,0x3b,0xdb], [0x32,0x32,0x56,0x64], [0x3a,0x3a,0x4e,0x74], [0x0a,0x0a,0x1e,0x14],
[0x49,0x49,0xdb,0x92], [0x06,0x06,0x0a,0x0c], [0x24,0x24,0x6c,0x48], [0x5c,0x5c,0xe4,0xb8],
[0xc2,0xc2,0x5d,0x9f], [0xd3,0xd3,0x6e,0xbd], [0xac,0xac,0xef,0x43], [0x62,0x62,0xa6,0xc4],
[0x91,0x91,0xa8,0x39], [0x95,0x95,0xa4,0x31], [0xe4,0xe4,0x37,0xd3], [0x79,0x79,0x8b,0xf2],
[0xe7,0xe7,0x32,0xd5], [0xc8,0xc8,0x43,0x8b], [0x37,0x37,0x59,0x6e], [0x6d,0x6d,0xb7,0xda],
[0x8d,0x8d,0x8c,0x01], [0xd5,0xd5,0x64,0xb1], [0x4e,0x4e,0xd2,0x9c], [0xa9,0xa9,0xe0,0x49],
[0x6c,0x6c,0xb4,0xd8], [0x56,0x56,0xfa,0xac], [0xf4,0xf4,0x07,0xf3], [0xea,0xea,0x25,0xcf],
[0x65,0x65,0xaf,0xca], [0x7a,0x7a,0x8e,0xf4], [0xae,0xae,0xe9,0x47], [0x08,0x08,0x18,0x10],
[0xba,0xba,0xd5,0x6f], [0x78,0x78,0x88,0xf0], [0x25,0x25,0x6f,0x4a], [0x2e,0x2e,0x72,0x5c],
[0x1c,0x1c,0x24,0x38], [0xa6,0xa6,0xf1,0x57], [0xb4,0xb4,0xc7,0x73], [0xc6,0xc6,0x51,0x97],
[0xe8,0xe8,0x23,0xcb], [0xdd,0xdd,0x7c,0xa1], [0x74,0x74,0x9c,0xe8], [0x1f,0x1f,0x21,0x3e],
[0x4b,0x4b,0xdd,0x96], [0xbd,0xbd,0xdc,0x61], [0x8b,0x8b,0x86,0x0d], [0x8a,0x8a,0x85,0x0f],
[0x70,0x70,0x90,0xe0], [0x3e,0x3e,0x42,0x7c], [0xb5,0xb5,0xc4,0x71], [0x66,0x66,0xaa,0xcc],
[0x48,0x48,0xd8,0x90], [0x03,0x03,0x05,0x06], [0xf6,0xf6,0x01,0xf7], [0x0e,0x0e,0x12,0x1c],
[0x61,0x61,0xa3,0xc2], [0x35,0x35,0x5f,0x6a], [0x57,0x57,0xf9,0xae], [0xb9,0xb9,0xd0,0x69],
[0x86,0x86,0x91,0x17], [0xc1,0xc1,0x58,0x99], [0x1d,0x1d,0x27,0x3a], [0x9e,0x9e,0xb9,0x27],
[0xe1,0xe1,0x38,0xd9], [0xf8,0xf8,0x13,0xeb], [0x98,0x98,0xb3,0x2b], [0x11,0x11,0x33,0x22],
[0x69,0x69,0xbb,0xd2], [0xd9,0xd9,0x70,0xa9], [0x8e,0x8e,0x89,0x07], [0x94,0x94,0xa7,0x33],
[0x9b,0x9b,0xb6,0x2d], [0x1e,0x1e,0x22,0x3c], [0x87,0x87,0x92,0x15], [0xe9,0xe9,0x20,0xc9],
[0xce,0xce,0x49,0x87], [0x55,0x55,0xff,0xaa], [0x28,0x28,0x78,0x50], [0xdf,0xdf,0x7a,0xa5],
[0x8c,0x8c,0x8f,0x03], [0xa1,0xa1,0xf8,0x59], [0x89,0x89,0x80,0x09], [0x0d,0x0d,0x17,0x1a],
[0xbf,0xbf,0xda,0x65], [0xe6,0xe6,0x31,0xd7], [0x42,0x42,0xc6,0x84], [0x68,0x68,0xb8,0xd0],
[0x41,0x41,0xc3,0x82], [0x99,0x99,0xb0,0x29], [0x2d,0x2d,0x77,0x5a], [0x0f,0x0f,0x11,0x1e],
[0xb0,0xb0,0xcb,0x7b], [0x54,0x54,0xfc,0xa8], [0xbb,0xbb,0xd6,0x6d], [0x16,0x16,0x3a,0x2c]
);
my @T5 = (
[0x51,0xf4,0xa7,0x50], [0x7e,0x41,0x65,0x53], [0x1a,0x17,0xa4,0xc3], [0x3a,0x27,0x5e,0x96],
[0x3b,0xab,0x6b,0xcb], [0x1f,0x9d,0x45,0xf1], [0xac,0xfa,0x58,0xab], [0x4b,0xe3,0x03,0x93],
[0x20,0x30,0xfa,0x55], [0xad,0x76,0x6d,0xf6], [0x88,0xcc,0x76,0x91], [0xf5,0x02,0x4c,0x25],
[0x4f,0xe5,0xd7,0xfc], [0xc5,0x2a,0xcb,0xd7], [0x26,0x35,0x44,0x80], [0xb5,0x62,0xa3,0x8f],
[0xde,0xb1,0x5a,0x49], [0x25,0xba,0x1b,0x67], [0x45,0xea,0x0e,0x98], [0x5d,0xfe,0xc0,0xe1],
[0xc3,0x2f,0x75,0x02], [0x81,0x4c,0xf0,0x12], [0x8d,0x46,0x97,0xa3], [0x6b,0xd3,0xf9,0xc6],
[0x03,0x8f,0x5f,0xe7], [0x15,0x92,0x9c,0x95], [0xbf,0x6d,0x7a,0xeb], [0x95,0x52,0x59,0xda],
[0xd4,0xbe,0x83,0x2d], [0x58,0x74,0x21,0xd3], [0x49,0xe0,0x69,0x29], [0x8e,0xc9,0xc8,0x44],
[0x75,0xc2,0x89,0x6a], [0xf4,0x8e,0x79,0x78], [0x99,0x58,0x3e,0x6b], [0x27,0xb9,0x71,0xdd],
[0xbe,0xe1,0x4f,0xb6], [0xf0,0x88,0xad,0x17], [0xc9,0x20,0xac,0x66], [0x7d,0xce,0x3a,0xb4],
[0x63,0xdf,0x4a,0x18], [0xe5,0x1a,0x31,0x82], [0x97,0x51,0x33,0x60], [0x62,0x53,0x7f,0x45],
[0xb1,0x64,0x77,0xe0], [0xbb,0x6b,0xae,0x84], [0xfe,0x81,0xa0,0x1c], [0xf9,0x08,0x2b,0x94],
[0x70,0x48,0x68,0x58], [0x8f,0x45,0xfd,0x19], [0x94,0xde,0x6c,0x87], [0x52,0x7b,0xf8,0xb7],
[0xab,0x73,0xd3,0x23], [0x72,0x4b,0x02,0xe2], [0xe3,0x1f,0x8f,0x57], [0x66,0x55,0xab,0x2a],
[0xb2,0xeb,0x28,0x07], [0x2f,0xb5,0xc2,0x03], [0x86,0xc5,0x7b,0x9a], [0xd3,0x37,0x08,0xa5],
[0x30,0x28,0x87,0xf2], [0x23,0xbf,0xa5,0xb2], [0x02,0x03,0x6a,0xba], [0xed,0x16,0x82,0x5c],
[0x8a,0xcf,0x1c,0x2b], [0xa7,0x79,0xb4,0x92], [0xf3,0x07,0xf2,0xf0], [0x4e,0x69,0xe2,0xa1],
[0x65,0xda,0xf4,0xcd], [0x06,0x05,0xbe,0xd5], [0xd1,0x34,0x62,0x1f], [0xc4,0xa6,0xfe,0x8a],
[0x34,0x2e,0x53,0x9d], [0xa2,0xf3,0x55,0xa0], [0x05,0x8a,0xe1,0x32], [0xa4,0xf6,0xeb,0x75],
[0x0b,0x83,0xec,0x39], [0x40,0x60,0xef,0xaa], [0x5e,0x71,0x9f,0x06], [0xbd,0x6e,0x10,0x51],
[0x3e,0x21,0x8a,0xf9], [0x96,0xdd,0x06,0x3d], [0xdd,0x3e,0x05,0xae], [0x4d,0xe6,0xbd,0x46],
[0x91,0x54,0x8d,0xb5], [0x71,0xc4,0x5d,0x05], [0x04,0x06,0xd4,0x6f], [0x60,0x50,0x15,0xff],
[0x19,0x98,0xfb,0x24], [0xd6,0xbd,0xe9,0x97], [0x89,0x40,0x43,0xcc], [0x67,0xd9,0x9e,0x77],
[0xb0,0xe8,0x42,0xbd], [0x07,0x89,0x8b,0x88], [0xe7,0x19,0x5b,0x38], [0x79,0xc8,0xee,0xdb],
[0xa1,0x7c,0x0a,0x47], [0x7c,0x42,0x0f,0xe9], [0xf8,0x84,0x1e,0xc9], [0x00,0x00,0x00,0x00],
[0x09,0x80,0x86,0x83], [0x32,0x2b,0xed,0x48], [0x1e,0x11,0x70,0xac], [0x6c,0x5a,0x72,0x4e],
[0xfd,0x0e,0xff,0xfb], [0x0f,0x85,0x38,0x56], [0x3d,0xae,0xd5,0x1e], [0x36,0x2d,0x39,0x27],
[0x0a,0x0f,0xd9,0x64], [0x68,0x5c,0xa6,0x21], [0x9b,0x5b,0x54,0xd1], [0x24,0x36,0x2e,0x3a],
[0x0c,0x0a,0x67,0xb1], [0x93,0x57,0xe7,0x0f], [0xb4,0xee,0x96,0xd2], [0x1b,0x9b,0x91,0x9e],
[0x80,0xc0,0xc5,0x4f], [0x61,0xdc,0x20,0xa2], [0x5a,0x77,0x4b,0x69], [0x1c,0x12,0x1a,0x16],
[0xe2,0x93,0xba,0x0a], [0xc0,0xa0,0x2a,0xe5], [0x3c,0x22,0xe0,0x43], [0x12,0x1b,0x17,0x1d],
[0x0e,0x09,0x0d,0x0b], [0xf2,0x8b,0xc7,0xad], [0x2d,0xb6,0xa8,0xb9], [0x14,0x1e,0xa9,0xc8],
[0x57,0xf1,0x19,0x85], [0xaf,0x75,0x07,0x4c], [0xee,0x99,0xdd,0xbb], [0xa3,0x7f,0x60,0xfd],
[0xf7,0x01,0x26,0x9f], [0x5c,0x72,0xf5,0xbc], [0x44,0x66,0x3b,0xc5], [0x5b,0xfb,0x7e,0x34],
[0x8b,0x43,0x29,0x76], [0xcb,0x23,0xc6,0xdc], [0xb6,0xed,0xfc,0x68], [0xb8,0xe4,0xf1,0x63],
[0xd7,0x31,0xdc,0xca], [0x42,0x63,0x85,0x10], [0x13,0x97,0x22,0x40], [0x84,0xc6,0x11,0x20],
[0x85,0x4a,0x24,0x7d], [0xd2,0xbb,0x3d,0xf8], [0xae,0xf9,0x32,0x11], [0xc7,0x29,0xa1,0x6d],
[0x1d,0x9e,0x2f,0x4b], [0xdc,0xb2,0x30,0xf3], [0x0d,0x86,0x52,0xec], [0x77,0xc1,0xe3,0xd0],
[0x2b,0xb3,0x16,0x6c], [0xa9,0x70,0xb9,0x99], [0x11,0x94,0x48,0xfa], [0x47,0xe9,0x64,0x22],
[0xa8,0xfc,0x8c,0xc4], [0xa0,0xf0,0x3f,0x1a], [0x56,0x7d,0x2c,0xd8], [0x22,0x33,0x90,0xef],
[0x87,0x49,0x4e,0xc7], [0xd9,0x38,0xd1,0xc1], [0x8c,0xca,0xa2,0xfe], [0x98,0xd4,0x0b,0x36],
[0xa6,0xf5,0x81,0xcf], [0xa5,0x7a,0xde,0x28], [0xda,0xb7,0x8e,0x26], [0x3f,0xad,0xbf,0xa4],
[0x2c,0x3a,0x9d,0xe4], [0x50,0x78,0x92,0x0d], [0x6a,0x5f,0xcc,0x9b], [0x54,0x7e,0x46,0x62],
[0xf6,0x8d,0x13,0xc2], [0x90,0xd8,0xb8,0xe8], [0x2e,0x39,0xf7,0x5e], [0x82,0xc3,0xaf,0xf5],
[0x9f,0x5d,0x80,0xbe], [0x69,0xd0,0x93,0x7c], [0x6f,0xd5,0x2d,0xa9], [0xcf,0x25,0x12,0xb3],
[0xc8,0xac,0x99,0x3b], [0x10,0x18,0x7d,0xa7], [0xe8,0x9c,0x63,0x6e], [0xdb,0x3b,0xbb,0x7b],
[0xcd,0x26,0x78,0x09], [0x6e,0x59,0x18,0xf4], [0xec,0x9a,0xb7,0x01], [0x83,0x4f,0x9a,0xa8],
[0xe6,0x95,0x6e,0x65], [0xaa,0xff,0xe6,0x7e], [0x21,0xbc,0xcf,0x08], [0xef,0x15,0xe8,0xe6],
[0xba,0xe7,0x9b,0xd9], [0x4a,0x6f,0x36,0xce], [0xea,0x9f,0x09,0xd4], [0x29,0xb0,0x7c,0xd6],
[0x31,0xa4,0xb2,0xaf], [0x2a,0x3f,0x23,0x31], [0xc6,0xa5,0x94,0x30], [0x35,0xa2,0x66,0xc0],
[0x74,0x4e,0xbc,0x37], [0xfc,0x82,0xca,0xa6], [0xe0,0x90,0xd0,0xb0], [0x33,0xa7,0xd8,0x15],
[0xf1,0x04,0x98,0x4a], [0x41,0xec,0xda,0xf7], [0x7f,0xcd,0x50,0x0e], [0x17,0x91,0xf6,0x2f],
[0x76,0x4d,0xd6,0x8d], [0x43,0xef,0xb0,0x4d], [0xcc,0xaa,0x4d,0x54], [0xe4,0x96,0x04,0xdf],
[0x9e,0xd1,0xb5,0xe3], [0x4c,0x6a,0x88,0x1b], [0xc1,0x2c,0x1f,0xb8], [0x46,0x65,0x51,0x7f],
[0x9d,0x5e,0xea,0x04], [0x01,0x8c,0x35,0x5d], [0xfa,0x87,0x74,0x73], [0xfb,0x0b,0x41,0x2e],
[0xb3,0x67,0x1d,0x5a], [0x92,0xdb,0xd2,0x52], [0xe9,0x10,0x56,0x33], [0x6d,0xd6,0x47,0x13],
[0x9a,0xd7,0x61,0x8c], [0x37,0xa1,0x0c,0x7a], [0x59,0xf8,0x14,0x8e], [0xeb,0x13,0x3c,0x89],
[0xce,0xa9,0x27,0xee], [0xb7,0x61,0xc9,0x35], [0xe1,0x1c,0xe5,0xed], [0x7a,0x47,0xb1,0x3c],
[0x9c,0xd2,0xdf,0x59], [0x55,0xf2,0x73,0x3f], [0x18,0x14,0xce,0x79], [0x73,0xc7,0x37,0xbf],
[0x53,0xf7,0xcd,0xea], [0x5f,0xfd,0xaa,0x5b], [0xdf,0x3d,0x6f,0x14], [0x78,0x44,0xdb,0x86],
[0xca,0xaf,0xf3,0x81], [0xb9,0x68,0xc4,0x3e], [0x38,0x24,0x34,0x2c], [0xc2,0xa3,0x40,0x5f],
[0x16,0x1d,0xc3,0x72], [0xbc,0xe2,0x25,0x0c], [0x28,0x3c,0x49,0x8b], [0xff,0x0d,0x95,0x41],
[0x39,0xa8,0x01,0x71], [0x08,0x0c,0xb3,0xde], [0xd8,0xb4,0xe4,0x9c], [0x64,0x56,0xc1,0x90],
[0x7b,0xcb,0x84,0x61], [0xd5,0x32,0xb6,0x70], [0x48,0x6c,0x5c,0x74], [0xd0,0xb8,0x57,0x42]
);
my @T6 = (
[0x50,0x51,0xf4,0xa7], [0x53,0x7e,0x41,0x65], [0xc3,0x1a,0x17,0xa4], [0x96,0x3a,0x27,0x5e],
[0xcb,0x3b,0xab,0x6b], [0xf1,0x1f,0x9d,0x45], [0xab,0xac,0xfa,0x58], [0x93,0x4b,0xe3,0x03],
[0x55,0x20,0x30,0xfa], [0xf6,0xad,0x76,0x6d], [0x91,0x88,0xcc,0x76], [0x25,0xf5,0x02,0x4c],
[0xfc,0x4f,0xe5,0xd7], [0xd7,0xc5,0x2a,0xcb], [0x80,0x26,0x35,0x44], [0x8f,0xb5,0x62,0xa3],
[0x49,0xde,0xb1,0x5a], [0x67,0x25,0xba,0x1b], [0x98,0x45,0xea,0x0e], [0xe1,0x5d,0xfe,0xc0],
[0x02,0xc3,0x2f,0x75], [0x12,0x81,0x4c,0xf0], [0xa3,0x8d,0x46,0x97], [0xc6,0x6b,0xd3,0xf9],
[0xe7,0x03,0x8f,0x5f], [0x95,0x15,0x92,0x9c], [0xeb,0xbf,0x6d,0x7a], [0xda,0x95,0x52,0x59],
[0x2d,0xd4,0xbe,0x83], [0xd3,0x58,0x74,0x21], [0x29,0x49,0xe0,0x69], [0x44,0x8e,0xc9,0xc8],
[0x6a,0x75,0xc2,0x89], [0x78,0xf4,0x8e,0x79], [0x6b,0x99,0x58,0x3e], [0xdd,0x27,0xb9,0x71],
[0xb6,0xbe,0xe1,0x4f], [0x17,0xf0,0x88,0xad], [0x66,0xc9,0x20,0xac], [0xb4,0x7d,0xce,0x3a],
[0x18,0x63,0xdf,0x4a], [0x82,0xe5,0x1a,0x31], [0x60,0x97,0x51,0x33], [0x45,0x62,0x53,0x7f],
[0xe0,0xb1,0x64,0x77], [0x84,0xbb,0x6b,0xae], [0x1c,0xfe,0x81,0xa0], [0x94,0xf9,0x08,0x2b],
[0x58,0x70,0x48,0x68], [0x19,0x8f,0x45,0xfd], [0x87,0x94,0xde,0x6c], [0xb7,0x52,0x7b,0xf8],
[0x23,0xab,0x73,0xd3], [0xe2,0x72,0x4b,0x02], [0x57,0xe3,0x1f,0x8f], [0x2a,0x66,0x55,0xab],
[0x07,0xb2,0xeb,0x28], [0x03,0x2f,0xb5,0xc2], [0x9a,0x86,0xc5,0x7b], [0xa5,0xd3,0x37,0x08],
[0xf2,0x30,0x28,0x87], [0xb2,0x23,0xbf,0xa5], [0xba,0x02,0x03,0x6a], [0x5c,0xed,0x16,0x82],
[0x2b,0x8a,0xcf,0x1c], [0x92,0xa7,0x79,0xb4], [0xf0,0xf3,0x07,0xf2], [0xa1,0x4e,0x69,0xe2],
[0xcd,0x65,0xda,0xf4], [0xd5,0x06,0x05,0xbe], [0x1f,0xd1,0x34,0x62], [0x8a,0xc4,0xa6,0xfe],
[0x9d,0x34,0x2e,0x53], [0xa0,0xa2,0xf3,0x55], [0x32,0x05,0x8a,0xe1], [0x75,0xa4,0xf6,0xeb],
[0x39,0x0b,0x83,0xec], [0xaa,0x40,0x60,0xef], [0x06,0x5e,0x71,0x9f], [0x51,0xbd,0x6e,0x10],
[0xf9,0x3e,0x21,0x8a], [0x3d,0x96,0xdd,0x06], [0xae,0xdd,0x3e,0x05], [0x46,0x4d,0xe6,0xbd],
[0xb5,0x91,0x54,0x8d], [0x05,0x71,0xc4,0x5d], [0x6f,0x04,0x06,0xd4], [0xff,0x60,0x50,0x15],
[0x24,0x19,0x98,0xfb], [0x97,0xd6,0xbd,0xe9], [0xcc,0x89,0x40,0x43], [0x77,0x67,0xd9,0x9e],
[0xbd,0xb0,0xe8,0x42], [0x88,0x07,0x89,0x8b], [0x38,0xe7,0x19,0x5b], [0xdb,0x79,0xc8,0xee],
[0x47,0xa1,0x7c,0x0a], [0xe9,0x7c,0x42,0x0f], [0xc9,0xf8,0x84,0x1e], [0x00,0x00,0x00,0x00],
[0x83,0x09,0x80,0x86], [0x48,0x32,0x2b,0xed], [0xac,0x1e,0x11,0x70], [0x4e,0x6c,0x5a,0x72],
[0xfb,0xfd,0x0e,0xff], [0x56,0x0f,0x85,0x38], [0x1e,0x3d,0xae,0xd5], [0x27,0x36,0x2d,0x39],
[0x64,0x0a,0x0f,0xd9], [0x21,0x68,0x5c,0xa6], [0xd1,0x9b,0x5b,0x54], [0x3a,0x24,0x36,0x2e],
[0xb1,0x0c,0x0a,0x67], [0x0f,0x93,0x57,0xe7], [0xd2,0xb4,0xee,0x96], [0x9e,0x1b,0x9b,0x91],
[0x4f,0x80,0xc0,0xc5], [0xa2,0x61,0xdc,0x20], [0x69,0x5a,0x77,0x4b], [0x16,0x1c,0x12,0x1a],
[0x0a,0xe2,0x93,0xba], [0xe5,0xc0,0xa0,0x2a], [0x43,0x3c,0x22,0xe0], [0x1d,0x12,0x1b,0x17],
[0x0b,0x0e,0x09,0x0d], [0xad,0xf2,0x8b,0xc7], [0xb9,0x2d,0xb6,0xa8], [0xc8,0x14,0x1e,0xa9],
[0x85,0x57,0xf1,0x19], [0x4c,0xaf,0x75,0x07], [0xbb,0xee,0x99,0xdd], [0xfd,0xa3,0x7f,0x60],
[0x9f,0xf7,0x01,0x26], [0xbc,0x5c,0x72,0xf5], [0xc5,0x44,0x66,0x3b], [0x34,0x5b,0xfb,0x7e],
[0x76,0x8b,0x43,0x29], [0xdc,0xcb,0x23,0xc6], [0x68,0xb6,0xed,0xfc], [0x63,0xb8,0xe4,0xf1],
[0xca,0xd7,0x31,0xdc], [0x10,0x42,0x63,0x85], [0x40,0x13,0x97,0x22], [0x20,0x84,0xc6,0x11],
[0x7d,0x85,0x4a,0x24], [0xf8,0xd2,0xbb,0x3d], [0x11,0xae,0xf9,0x32], [0x6d,0xc7,0x29,0xa1],
[0x4b,0x1d,0x9e,0x2f], [0xf3,0xdc,0xb2,0x30], [0xec,0x0d,0x86,0x52], [0xd0,0x77,0xc1,0xe3],
[0x6c,0x2b,0xb3,0x16], [0x99,0xa9,0x70,0xb9], [0xfa,0x11,0x94,0x48], [0x22,0x47,0xe9,0x64],
[0xc4,0xa8,0xfc,0x8c], [0x1a,0xa0,0xf0,0x3f], [0xd8,0x56,0x7d,0x2c], [0xef,0x22,0x33,0x90],
[0xc7,0x87,0x49,0x4e], [0xc1,0xd9,0x38,0xd1], [0xfe,0x8c,0xca,0xa2], [0x36,0x98,0xd4,0x0b],
[0xcf,0xa6,0xf5,0x81], [0x28,0xa5,0x7a,0xde], [0x26,0xda,0xb7,0x8e], [0xa4,0x3f,0xad,0xbf],
[0xe4,0x2c,0x3a,0x9d], [0x0d,0x50,0x78,0x92], [0x9b,0x6a,0x5f,0xcc], [0x62,0x54,0x7e,0x46],
[0xc2,0xf6,0x8d,0x13], [0xe8,0x90,0xd8,0xb8], [0x5e,0x2e,0x39,0xf7], [0xf5,0x82,0xc3,0xaf],
[0xbe,0x9f,0x5d,0x80], [0x7c,0x69,0xd0,0x93], [0xa9,0x6f,0xd5,0x2d], [0xb3,0xcf,0x25,0x12],
[0x3b,0xc8,0xac,0x99], [0xa7,0x10,0x18,0x7d], [0x6e,0xe8,0x9c,0x63], [0x7b,0xdb,0x3b,0xbb],
[0x09,0xcd,0x26,0x78], [0xf4,0x6e,0x59,0x18], [0x01,0xec,0x9a,0xb7], [0xa8,0x83,0x4f,0x9a],
[0x65,0xe6,0x95,0x6e], [0x7e,0xaa,0xff,0xe6], [0x08,0x21,0xbc,0xcf], [0xe6,0xef,0x15,0xe8],
[0xd9,0xba,0xe7,0x9b], [0xce,0x4a,0x6f,0x36], [0xd4,0xea,0x9f,0x09], [0xd6,0x29,0xb0,0x7c],
[0xaf,0x31,0xa4,0xb2], [0x31,0x2a,0x3f,0x23], [0x30,0xc6,0xa5,0x94], [0xc0,0x35,0xa2,0x66],
[0x37,0x74,0x4e,0xbc], [0xa6,0xfc,0x82,0xca], [0xb0,0xe0,0x90,0xd0], [0x15,0x33,0xa7,0xd8],
[0x4a,0xf1,0x04,0x98], [0xf7,0x41,0xec,0xda], [0x0e,0x7f,0xcd,0x50], [0x2f,0x17,0x91,0xf6],
[0x8d,0x76,0x4d,0xd6], [0x4d,0x43,0xef,0xb0], [0x54,0xcc,0xaa,0x4d], [0xdf,0xe4,0x96,0x04],
[0xe3,0x9e,0xd1,0xb5], [0x1b,0x4c,0x6a,0x88], [0xb8,0xc1,0x2c,0x1f], [0x7f,0x46,0x65,0x51],
[0x04,0x9d,0x5e,0xea], [0x5d,0x01,0x8c,0x35], [0x73,0xfa,0x87,0x74], [0x2e,0xfb,0x0b,0x41],
[0x5a,0xb3,0x67,0x1d], [0x52,0x92,0xdb,0xd2], [0x33,0xe9,0x10,0x56], [0x13,0x6d,0xd6,0x47],
[0x8c,0x9a,0xd7,0x61], [0x7a,0x37,0xa1,0x0c], [0x8e,0x59,0xf8,0x14], [0x89,0xeb,0x13,0x3c],
[0xee,0xce,0xa9,0x27], [0x35,0xb7,0x61,0xc9], [0xed,0xe1,0x1c,0xe5], [0x3c,0x7a,0x47,0xb1],
[0x59,0x9c,0xd2,0xdf], [0x3f,0x55,0xf2,0x73], [0x79,0x18,0x14,0xce], [0xbf,0x73,0xc7,0x37],
[0xea,0x53,0xf7,0xcd], [0x5b,0x5f,0xfd,0xaa], [0x14,0xdf,0x3d,0x6f], [0x86,0x78,0x44,0xdb],
[0x81,0xca,0xaf,0xf3], [0x3e,0xb9,0x68,0xc4], [0x2c,0x38,0x24,0x34], [0x5f,0xc2,0xa3,0x40],
[0x72,0x16,0x1d,0xc3], [0x0c,0xbc,0xe2,0x25], [0x8b,0x28,0x3c,0x49], [0x41,0xff,0x0d,0x95],
[0x71,0x39,0xa8,0x01], [0xde,0x08,0x0c,0xb3], [0x9c,0xd8,0xb4,0xe4], [0x90,0x64,0x56,0xc1],
[0x61,0x7b,0xcb,0x84], [0x70,0xd5,0x32,0xb6], [0x74,0x48,0x6c,0x5c], [0x42,0xd0,0xb8,0x57]
);
my @T7 = (
[0xa7,0x50,0x51,0xf4], [0x65,0x53,0x7e,0x41], [0xa4,0xc3,0x1a,0x17], [0x5e,0x96,0x3a,0x27],
[0x6b,0xcb,0x3b,0xab], [0x45,0xf1,0x1f,0x9d], [0x58,0xab,0xac,0xfa], [0x03,0x93,0x4b,0xe3],
[0xfa,0x55,0x20,0x30], [0x6d,0xf6,0xad,0x76], [0x76,0x91,0x88,0xcc], [0x4c,0x25,0xf5,0x02],
[0xd7,0xfc,0x4f,0xe5], [0xcb,0xd7,0xc5,0x2a], [0x44,0x80,0x26,0x35], [0xa3,0x8f,0xb5,0x62],
[0x5a,0x49,0xde,0xb1], [0x1b,0x67,0x25,0xba], [0x0e,0x98,0x45,0xea], [0xc0,0xe1,0x5d,0xfe],
[0x75,0x02,0xc3,0x2f], [0xf0,0x12,0x81,0x4c], [0x97,0xa3,0x8d,0x46], [0xf9,0xc6,0x6b,0xd3],
[0x5f,0xe7,0x03,0x8f], [0x9c,0x95,0x15,0x92], [0x7a,0xeb,0xbf,0x6d], [0x59,0xda,0x95,0x52],
[0x83,0x2d,0xd4,0xbe], [0x21,0xd3,0x58,0x74], [0x69,0x29,0x49,0xe0], [0xc8,0x44,0x8e,0xc9],
[0x89,0x6a,0x75,0xc2], [0x79,0x78,0xf4,0x8e], [0x3e,0x6b,0x99,0x58], [0x71,0xdd,0x27,0xb9],
[0x4f,0xb6,0xbe,0xe1], [0xad,0x17,0xf0,0x88], [0xac,0x66,0xc9,0x20], [0x3a,0xb4,0x7d,0xce],
[0x4a,0x18,0x63,0xdf], [0x31,0x82,0xe5,0x1a], [0x33,0x60,0x97,0x51], [0x7f,0x45,0x62,0x53],
[0x77,0xe0,0xb1,0x64], [0xae,0x84,0xbb,0x6b], [0xa0,0x1c,0xfe,0x81], [0x2b,0x94,0xf9,0x08],
[0x68,0x58,0x70,0x48], [0xfd,0x19,0x8f,0x45], [0x6c,0x87,0x94,0xde], [0xf8,0xb7,0x52,0x7b],
[0xd3,0x23,0xab,0x73], [0x02,0xe2,0x72,0x4b], [0x8f,0x57,0xe3,0x1f], [0xab,0x2a,0x66,0x55],
[0x28,0x07,0xb2,0xeb], [0xc2,0x03,0x2f,0xb5], [0x7b,0x9a,0x86,0xc5], [0x08,0xa5,0xd3,0x37],
[0x87,0xf2,0x30,0x28], [0xa5,0xb2,0x23,0xbf], [0x6a,0xba,0x02,0x03], [0x82,0x5c,0xed,0x16],
[0x1c,0x2b,0x8a,0xcf], [0xb4,0x92,0xa7,0x79], [0xf2,0xf0,0xf3,0x07], [0xe2,0xa1,0x4e,0x69],
[0xf4,0xcd,0x65,0xda], [0xbe,0xd5,0x06,0x05], [0x62,0x1f,0xd1,0x34], [0xfe,0x8a,0xc4,0xa6],
[0x53,0x9d,0x34,0x2e], [0x55,0xa0,0xa2,0xf3], [0xe1,0x32,0x05,0x8a], [0xeb,0x75,0xa4,0xf6],
[0xec,0x39,0x0b,0x83], [0xef,0xaa,0x40,0x60], [0x9f,0x06,0x5e,0x71], [0x10,0x51,0xbd,0x6e],
[0x8a,0xf9,0x3e,0x21], [0x06,0x3d,0x96,0xdd], [0x05,0xae,0xdd,0x3e], [0xbd,0x46,0x4d,0xe6],
[0x8d,0xb5,0x91,0x54], [0x5d,0x05,0x71,0xc4], [0xd4,0x6f,0x04,0x06], [0x15,0xff,0x60,0x50],
[0xfb,0x24,0x19,0x98], [0xe9,0x97,0xd6,0xbd], [0x43,0xcc,0x89,0x40], [0x9e,0x77,0x67,0xd9],
[0x42,0xbd,0xb0,0xe8], [0x8b,0x88,0x07,0x89], [0x5b,0x38,0xe7,0x19], [0xee,0xdb,0x79,0xc8],
[0x0a,0x47,0xa1,0x7c], [0x0f,0xe9,0x7c,0x42], [0x1e,0xc9,0xf8,0x84], [0x00,0x00,0x00,0x00],
[0x86,0x83,0x09,0x80], [0xed,0x48,0x32,0x2b], [0x70,0xac,0x1e,0x11], [0x72,0x4e,0x6c,0x5a],
[0xff,0xfb,0xfd,0x0e], [0x38,0x56,0x0f,0x85], [0xd5,0x1e,0x3d,0xae], [0x39,0x27,0x36,0x2d],
[0xd9,0x64,0x0a,0x0f], [0xa6,0x21,0x68,0x5c], [0x54,0xd1,0x9b,0x5b], [0x2e,0x3a,0x24,0x36],
[0x67,0xb1,0x0c,0x0a], [0xe7,0x0f,0x93,0x57], [0x96,0xd2,0xb4,0xee], [0x91,0x9e,0x1b,0x9b],
[0xc5,0x4f,0x80,0xc0], [0x20,0xa2,0x61,0xdc], [0x4b,0x69,0x5a,0x77], [0x1a,0x16,0x1c,0x12],
[0xba,0x0a,0xe2,0x93], [0x2a,0xe5,0xc0,0xa0], [0xe0,0x43,0x3c,0x22], [0x17,0x1d,0x12,0x1b],
[0x0d,0x0b,0x0e,0x09], [0xc7,0xad,0xf2,0x8b], [0xa8,0xb9,0x2d,0xb6], [0xa9,0xc8,0x14,0x1e],
[0x19,0x85,0x57,0xf1], [0x07,0x4c,0xaf,0x75], [0xdd,0xbb,0xee,0x99], [0x60,0xfd,0xa3,0x7f],
[0x26,0x9f,0xf7,0x01], [0xf5,0xbc,0x5c,0x72], [0x3b,0xc5,0x44,0x66], [0x7e,0x34,0x5b,0xfb],
[0x29,0x76,0x8b,0x43], [0xc6,0xdc,0xcb,0x23], [0xfc,0x68,0xb6,0xed], [0xf1,0x63,0xb8,0xe4],
[0xdc,0xca,0xd7,0x31], [0x85,0x10,0x42,0x63], [0x22,0x40,0x13,0x97], [0x11,0x20,0x84,0xc6],
[0x24,0x7d,0x85,0x4a], [0x3d,0xf8,0xd2,0xbb], [0x32,0x11,0xae,0xf9], [0xa1,0x6d,0xc7,0x29],
[0x2f,0x4b,0x1d,0x9e], [0x30,0xf3,0xdc,0xb2], [0x52,0xec,0x0d,0x86], [0xe3,0xd0,0x77,0xc1],
[0x16,0x6c,0x2b,0xb3], [0xb9,0x99,0xa9,0x70], [0x48,0xfa,0x11,0x94], [0x64,0x22,0x47,0xe9],
[0x8c,0xc4,0xa8,0xfc], [0x3f,0x1a,0xa0,0xf0], [0x2c,0xd8,0x56,0x7d], [0x90,0xef,0x22,0x33],
[0x4e,0xc7,0x87,0x49], [0xd1,0xc1,0xd9,0x38], [0xa2,0xfe,0x8c,0xca], [0x0b,0x36,0x98,0xd4],
[0x81,0xcf,0xa6,0xf5], [0xde,0x28,0xa5,0x7a], [0x8e,0x26,0xda,0xb7], [0xbf,0xa4,0x3f,0xad],
[0x9d,0xe4,0x2c,0x3a], [0x92,0x0d,0x50,0x78], [0xcc,0x9b,0x6a,0x5f], [0x46,0x62,0x54,0x7e],
[0x13,0xc2,0xf6,0x8d], [0xb8,0xe8,0x90,0xd8], [0xf7,0x5e,0x2e,0x39], [0xaf,0xf5,0x82,0xc3],
[0x80,0xbe,0x9f,0x5d], [0x93,0x7c,0x69,0xd0], [0x2d,0xa9,0x6f,0xd5], [0x12,0xb3,0xcf,0x25],
[0x99,0x3b,0xc8,0xac], [0x7d,0xa7,0x10,0x18], [0x63,0x6e,0xe8,0x9c], [0xbb,0x7b,0xdb,0x3b],
[0x78,0x09,0xcd,0x26], [0x18,0xf4,0x6e,0x59], [0xb7,0x01,0xec,0x9a], [0x9a,0xa8,0x83,0x4f],
[0x6e,0x65,0xe6,0x95], [0xe6,0x7e,0xaa,0xff], [0xcf,0x08,0x21,0xbc], [0xe8,0xe6,0xef,0x15],
[0x9b,0xd9,0xba,0xe7], [0x36,0xce,0x4a,0x6f], [0x09,0xd4,0xea,0x9f], [0x7c,0xd6,0x29,0xb0],
[0xb2,0xaf,0x31,0xa4], [0x23,0x31,0x2a,0x3f], [0x94,0x30,0xc6,0xa5], [0x66,0xc0,0x35,0xa2],
[0xbc,0x37,0x74,0x4e], [0xca,0xa6,0xfc,0x82], [0xd0,0xb0,0xe0,0x90], [0xd8,0x15,0x33,0xa7],
[0x98,0x4a,0xf1,0x04], [0xda,0xf7,0x41,0xec], [0x50,0x0e,0x7f,0xcd], [0xf6,0x2f,0x17,0x91],
[0xd6,0x8d,0x76,0x4d], [0xb0,0x4d,0x43,0xef], [0x4d,0x54,0xcc,0xaa], [0x04,0xdf,0xe4,0x96],
[0xb5,0xe3,0x9e,0xd1], [0x88,0x1b,0x4c,0x6a], [0x1f,0xb8,0xc1,0x2c], [0x51,0x7f,0x46,0x65],
[0xea,0x04,0x9d,0x5e], [0x35,0x5d,0x01,0x8c], [0x74,0x73,0xfa,0x87], [0x41,0x2e,0xfb,0x0b],
[0x1d,0x5a,0xb3,0x67], [0xd2,0x52,0x92,0xdb], [0x56,0x33,0xe9,0x10], [0x47,0x13,0x6d,0xd6],
[0x61,0x8c,0x9a,0xd7], [0x0c,0x7a,0x37,0xa1], [0x14,0x8e,0x59,0xf8], [0x3c,0x89,0xeb,0x13],
[0x27,0xee,0xce,0xa9], [0xc9,0x35,0xb7,0x61], [0xe5,0xed,0xe1,0x1c], [0xb1,0x3c,0x7a,0x47],
[0xdf,0x59,0x9c,0xd2], [0x73,0x3f,0x55,0xf2], [0xce,0x79,0x18,0x14], [0x37,0xbf,0x73,0xc7],
[0xcd,0xea,0x53,0xf7], [0xaa,0x5b,0x5f,0xfd], [0x6f,0x14,0xdf,0x3d], [0xdb,0x86,0x78,0x44],
[0xf3,0x81,0xca,0xaf], [0xc4,0x3e,0xb9,0x68], [0x34,0x2c,0x38,0x24], [0x40,0x5f,0xc2,0xa3],
[0xc3,0x72,0x16,0x1d], [0x25,0x0c,0xbc,0xe2], [0x49,0x8b,0x28,0x3c], [0x95,0x41,0xff,0x0d],
[0x01,0x71,0x39,0xa8], [0xb3,0xde,0x08,0x0c], [0xe4,0x9c,0xd8,0xb4], [0xc1,0x90,0x64,0x56],
[0x84,0x61,0x7b,0xcb], [0xb6,0x70,0xd5,0x32], [0x5c,0x74,0x48,0x6c], [0x57,0x42,0xd0,0xb8]
);
my @T8 = (
[0xf4,0xa7,0x50,0x51], [0x41,0x65,0x53,0x7e], [0x17,0xa4,0xc3,0x1a], [0x27,0x5e,0x96,0x3a],
[0xab,0x6b,0xcb,0x3b], [0x9d,0x45,0xf1,0x1f], [0xfa,0x58,0xab,0xac], [0xe3,0x03,0x93,0x4b],
[0x30,0xfa,0x55,0x20], [0x76,0x6d,0xf6,0xad], [0xcc,0x76,0x91,0x88], [0x02,0x4c,0x25,0xf5],
[0xe5,0xd7,0xfc,0x4f], [0x2a,0xcb,0xd7,0xc5], [0x35,0x44,0x80,0x26], [0x62,0xa3,0x8f,0xb5],
[0xb1,0x5a,0x49,0xde], [0xba,0x1b,0x67,0x25], [0xea,0x0e,0x98,0x45], [0xfe,0xc0,0xe1,0x5d],
[0x2f,0x75,0x02,0xc3], [0x4c,0xf0,0x12,0x81], [0x46,0x97,0xa3,0x8d], [0xd3,0xf9,0xc6,0x6b],
[0x8f,0x5f,0xe7,0x03], [0x92,0x9c,0x95,0x15], [0x6d,0x7a,0xeb,0xbf], [0x52,0x59,0xda,0x95],
[0xbe,0x83,0x2d,0xd4], [0x74,0x21,0xd3,0x58], [0xe0,0x69,0x29,0x49], [0xc9,0xc8,0x44,0x8e],
[0xc2,0x89,0x6a,0x75], [0x8e,0x79,0x78,0xf4], [0x58,0x3e,0x6b,0x99], [0xb9,0x71,0xdd,0x27],
[0xe1,0x4f,0xb6,0xbe], [0x88,0xad,0x17,0xf0], [0x20,0xac,0x66,0xc9], [0xce,0x3a,0xb4,0x7d],
[0xdf,0x4a,0x18,0x63], [0x1a,0x31,0x82,0xe5], [0x51,0x33,0x60,0x97], [0x53,0x7f,0x45,0x62],
[0x64,0x77,0xe0,0xb1], [0x6b,0xae,0x84,0xbb], [0x81,0xa0,0x1c,0xfe], [0x08,0x2b,0x94,0xf9],
[0x48,0x68,0x58,0x70], [0x45,0xfd,0x19,0x8f], [0xde,0x6c,0x87,0x94], [0x7b,0xf8,0xb7,0x52],
[0x73,0xd3,0x23,0xab], [0x4b,0x02,0xe2,0x72], [0x1f,0x8f,0x57,0xe3], [0x55,0xab,0x2a,0x66],
[0xeb,0x28,0x07,0xb2], [0xb5,0xc2,0x03,0x2f], [0xc5,0x7b,0x9a,0x86], [0x37,0x08,0xa5,0xd3],
[0x28,0x87,0xf2,0x30], [0xbf,0xa5,0xb2,0x23], [0x03,0x6a,0xba,0x02], [0x16,0x82,0x5c,0xed],
[0xcf,0x1c,0x2b,0x8a], [0x79,0xb4,0x92,0xa7], [0x07,0xf2,0xf0,0xf3], [0x69,0xe2,0xa1,0x4e],
[0xda,0xf4,0xcd,0x65], [0x05,0xbe,0xd5,0x06], [0x34,0x62,0x1f,0xd1], [0xa6,0xfe,0x8a,0xc4],
[0x2e,0x53,0x9d,0x34], [0xf3,0x55,0xa0,0xa2], [0x8a,0xe1,0x32,0x05], [0xf6,0xeb,0x75,0xa4],
[0x83,0xec,0x39,0x0b], [0x60,0xef,0xaa,0x40], [0x71,0x9f,0x06,0x5e], [0x6e,0x10,0x51,0xbd],
[0x21,0x8a,0xf9,0x3e], [0xdd,0x06,0x3d,0x96], [0x3e,0x05,0xae,0xdd], [0xe6,0xbd,0x46,0x4d],
[0x54,0x8d,0xb5,0x91], [0xc4,0x5d,0x05,0x71], [0x06,0xd4,0x6f,0x04], [0x50,0x15,0xff,0x60],
[0x98,0xfb,0x24,0x19], [0xbd,0xe9,0x97,0xd6], [0x40,0x43,0xcc,0x89], [0xd9,0x9e,0x77,0x67],
[0xe8,0x42,0xbd,0xb0], [0x89,0x8b,0x88,0x07], [0x19,0x5b,0x38,0xe7], [0xc8,0xee,0xdb,0x79],
[0x7c,0x0a,0x47,0xa1], [0x42,0x0f,0xe9,0x7c], [0x84,0x1e,0xc9,0xf8], [0x00,0x00,0x00,0x00],
[0x80,0x86,0x83,0x09], [0x2b,0xed,0x48,0x32], [0x11,0x70,0xac,0x1e], [0x5a,0x72,0x4e,0x6c],
[0x0e,0xff,0xfb,0xfd], [0x85,0x38,0x56,0x0f], [0xae,0xd5,0x1e,0x3d], [0x2d,0x39,0x27,0x36],
[0x0f,0xd9,0x64,0x0a], [0x5c,0xa6,0x21,0x68], [0x5b,0x54,0xd1,0x9b], [0x36,0x2e,0x3a,0x24],
[0x0a,0x67,0xb1,0x0c], [0x57,0xe7,0x0f,0x93], [0xee,0x96,0xd2,0xb4], [0x9b,0x91,0x9e,0x1b],
[0xc0,0xc5,0x4f,0x80], [0xdc,0x20,0xa2,0x61], [0x77,0x4b,0x69,0x5a], [0x12,0x1a,0x16,0x1c],
[0x93,0xba,0x0a,0xe2], [0xa0,0x2a,0xe5,0xc0], [0x22,0xe0,0x43,0x3c], [0x1b,0x17,0x1d,0x12],
[0x09,0x0d,0x0b,0x0e], [0x8b,0xc7,0xad,0xf2], [0xb6,0xa8,0xb9,0x2d], [0x1e,0xa9,0xc8,0x14],
[0xf1,0x19,0x85,0x57], [0x75,0x07,0x4c,0xaf], [0x99,0xdd,0xbb,0xee], [0x7f,0x60,0xfd,0xa3],
[0x01,0x26,0x9f,0xf7], [0x72,0xf5,0xbc,0x5c], [0x66,0x3b,0xc5,0x44], [0xfb,0x7e,0x34,0x5b],
[0x43,0x29,0x76,0x8b], [0x23,0xc6,0xdc,0xcb], [0xed,0xfc,0x68,0xb6], [0xe4,0xf1,0x63,0xb8],
[0x31,0xdc,0xca,0xd7], [0x63,0x85,0x10,0x42], [0x97,0x22,0x40,0x13], [0xc6,0x11,0x20,0x84],
[0x4a,0x24,0x7d,0x85], [0xbb,0x3d,0xf8,0xd2], [0xf9,0x32,0x11,0xae], [0x29,0xa1,0x6d,0xc7],
[0x9e,0x2f,0x4b,0x1d], [0xb2,0x30,0xf3,0xdc], [0x86,0x52,0xec,0x0d], [0xc1,0xe3,0xd0,0x77],
[0xb3,0x16,0x6c,0x2b], [0x70,0xb9,0x99,0xa9], [0x94,0x48,0xfa,0x11], [0xe9,0x64,0x22,0x47],
[0xfc,0x8c,0xc4,0xa8], [0xf0,0x3f,0x1a,0xa0], [0x7d,0x2c,0xd8,0x56], [0x33,0x90,0xef,0x22],
[0x49,0x4e,0xc7,0x87], [0x38,0xd1,0xc1,0xd9], [0xca,0xa2,0xfe,0x8c], [0xd4,0x0b,0x36,0x98],
[0xf5,0x81,0xcf,0xa6], [0x7a,0xde,0x28,0xa5], [0xb7,0x8e,0x26,0xda], [0xad,0xbf,0xa4,0x3f],
[0x3a,0x9d,0xe4,0x2c], [0x78,0x92,0x0d,0x50], [0x5f,0xcc,0x9b,0x6a], [0x7e,0x46,0x62,0x54],
[0x8d,0x13,0xc2,0xf6], [0xd8,0xb8,0xe8,0x90], [0x39,0xf7,0x5e,0x2e], [0xc3,0xaf,0xf5,0x82],
[0x5d,0x80,0xbe,0x9f], [0xd0,0x93,0x7c,0x69], [0xd5,0x2d,0xa9,0x6f], [0x25,0x12,0xb3,0xcf],
[0xac,0x99,0x3b,0xc8], [0x18,0x7d,0xa7,0x10], [0x9c,0x63,0x6e,0xe8], [0x3b,0xbb,0x7b,0xdb],
[0x26,0x78,0x09,0xcd], [0x59,0x18,0xf4,0x6e], [0x9a,0xb7,0x01,0xec], [0x4f,0x9a,0xa8,0x83],
[0x95,0x6e,0x65,0xe6], [0xff,0xe6,0x7e,0xaa], [0xbc,0xcf,0x08,0x21], [0x15,0xe8,0xe6,0xef],
[0xe7,0x9b,0xd9,0xba], [0x6f,0x36,0xce,0x4a], [0x9f,0x09,0xd4,0xea], [0xb0,0x7c,0xd6,0x29],
[0xa4,0xb2,0xaf,0x31], [0x3f,0x23,0x31,0x2a], [0xa5,0x94,0x30,0xc6], [0xa2,0x66,0xc0,0x35],
[0x4e,0xbc,0x37,0x74], [0x82,0xca,0xa6,0xfc], [0x90,0xd0,0xb0,0xe0], [0xa7,0xd8,0x15,0x33],
[0x04,0x98,0x4a,0xf1], [0xec,0xda,0xf7,0x41], [0xcd,0x50,0x0e,0x7f], [0x91,0xf6,0x2f,0x17],
[0x4d,0xd6,0x8d,0x76], [0xef,0xb0,0x4d,0x43], [0xaa,0x4d,0x54,0xcc], [0x96,0x04,0xdf,0xe4],
[0xd1,0xb5,0xe3,0x9e], [0x6a,0x88,0x1b,0x4c], [0x2c,0x1f,0xb8,0xc1], [0x65,0x51,0x7f,0x46],
[0x5e,0xea,0x04,0x9d], [0x8c,0x35,0x5d,0x01], [0x87,0x74,0x73,0xfa], [0x0b,0x41,0x2e,0xfb],
[0x67,0x1d,0x5a,0xb3], [0xdb,0xd2,0x52,0x92], [0x10,0x56,0x33,0xe9], [0xd6,0x47,0x13,0x6d],
[0xd7,0x61,0x8c,0x9a], [0xa1,0x0c,0x7a,0x37], [0xf8,0x14,0x8e,0x59], [0x13,0x3c,0x89,0xeb],
[0xa9,0x27,0xee,0xce], [0x61,0xc9,0x35,0xb7], [0x1c,0xe5,0xed,0xe1], [0x47,0xb1,0x3c,0x7a],
[0xd2,0xdf,0x59,0x9c], [0xf2,0x73,0x3f,0x55], [0x14,0xce,0x79,0x18], [0xc7,0x37,0xbf,0x73],
[0xf7,0xcd,0xea,0x53], [0xfd,0xaa,0x5b,0x5f], [0x3d,0x6f,0x14,0xdf], [0x44,0xdb,0x86,0x78],
[0xaf,0xf3,0x81,0xca], [0x68,0xc4,0x3e,0xb9], [0x24,0x34,0x2c,0x38], [0xa3,0x40,0x5f,0xc2],
[0x1d,0xc3,0x72,0x16], [0xe2,0x25,0x0c,0xbc], [0x3c,0x49,0x8b,0x28], [0x0d,0x95,0x41,0xff],
[0xa8,0x01,0x71,0x39], [0x0c,0xb3,0xde,0x08], [0xb4,0xe4,0x9c,0xd8], [0x56,0xc1,0x90,0x64],
[0xcb,0x84,0x61,0x7b], [0x32,0xb6,0x70,0xd5], [0x6c,0x5c,0x74,0x48], [0xb8,0x57,0x42,0xd0]
);
my @S5 = (
0x52,0x09,0x6a,0xd5,
0x30,0x36,0xa5,0x38,
0xbf,0x40,0xa3,0x9e,
0x81,0xf3,0xd7,0xfb,
0x7c,0xe3,0x39,0x82,
0x9b,0x2f,0xff,0x87,
0x34,0x8e,0x43,0x44,
0xc4,0xde,0xe9,0xcb,
0x54,0x7b,0x94,0x32,
0xa6,0xc2,0x23,0x3d,
0xee,0x4c,0x95,0x0b,
0x42,0xfa,0xc3,0x4e,
0x08,0x2e,0xa1,0x66,
0x28,0xd9,0x24,0xb2,
0x76,0x5b,0xa2,0x49,
0x6d,0x8b,0xd1,0x25,
0x72,0xf8,0xf6,0x64,
0x86,0x68,0x98,0x16,
0xd4,0xa4,0x5c,0xcc,
0x5d,0x65,0xb6,0x92,
0x6c,0x70,0x48,0x50,
0xfd,0xed,0xb9,0xda,
0x5e,0x15,0x46,0x57,
0xa7,0x8d,0x9d,0x84,
0x90,0xd8,0xab,0x00,
0x8c,0xbc,0xd3,0x0a,
0xf7,0xe4,0x58,0x05,
0xb8,0xb3,0x45,0x06,
0xd0,0x2c,0x1e,0x8f,
0xca,0x3f,0x0f,0x02,
0xc1,0xaf,0xbd,0x03,
0x01,0x13,0x8a,0x6b,
0x3a,0x91,0x11,0x41,
0x4f,0x67,0xdc,0xea,
0x97,0xf2,0xcf,0xce,
0xf0,0xb4,0xe6,0x73,
0x96,0xac,0x74,0x22,
0xe7,0xad,0x35,0x85,
0xe2,0xf9,0x37,0xe8,
0x1c,0x75,0xdf,0x6e,
0x47,0xf1,0x1a,0x71,
0x1d,0x29,0xc5,0x89,
0x6f,0xb7,0x62,0x0e,
0xaa,0x18,0xbe,0x1b,
0xfc,0x56,0x3e,0x4b,
0xc6,0xd2,0x79,0x20,
0x9a,0xdb,0xc0,0xfe,
0x78,0xcd,0x5a,0xf4,
0x1f,0xdd,0xa8,0x33,
0x88,0x07,0xc7,0x31,
0xb1,0x12,0x10,0x59,
0x27,0x80,0xec,0x5f,
0x60,0x51,0x7f,0xa9,
0x19,0xb5,0x4a,0x0d,
0x2d,0xe5,0x7a,0x9f,
0x93,0xc9,0x9c,0xef,
0xa0,0xe0,0x3b,0x4d,
0xae,0x2a,0xf5,0xb0,
0xc8,0xeb,0xbb,0x3c,
0x83,0x53,0x99,0x61,
0x17,0x2b,0x04,0x7e,
0xba,0x77,0xd6,0x26,
0xe1,0x69,0x14,0x63,
0x55,0x21,0x0c,0x7d
);
my @U1 = (
[0x00,0x00,0x00,0x00], [0x0e,0x09,0x0d,0x0b], [0x1c,0x12,0x1a,0x16], [0x12,0x1b,0x17,0x1d],
[0x38,0x24,0x34,0x2c], [0x36,0x2d,0x39,0x27], [0x24,0x36,0x2e,0x3a], [0x2a,0x3f,0x23,0x31],
[0x70,0x48,0x68,0x58], [0x7e,0x41,0x65,0x53], [0x6c,0x5a,0x72,0x4e], [0x62,0x53,0x7f,0x45],
[0x48,0x6c,0x5c,0x74], [0x46,0x65,0x51,0x7f], [0x54,0x7e,0x46,0x62], [0x5a,0x77,0x4b,0x69],
[0xe0,0x90,0xd0,0xb0], [0xee,0x99,0xdd,0xbb], [0xfc,0x82,0xca,0xa6], [0xf2,0x8b,0xc7,0xad],
[0xd8,0xb4,0xe4,0x9c], [0xd6,0xbd,0xe9,0x97], [0xc4,0xa6,0xfe,0x8a], [0xca,0xaf,0xf3,0x81],
[0x90,0xd8,0xb8,0xe8], [0x9e,0xd1,0xb5,0xe3], [0x8c,0xca,0xa2,0xfe], [0x82,0xc3,0xaf,0xf5],
[0xa8,0xfc,0x8c,0xc4], [0xa6,0xf5,0x81,0xcf], [0xb4,0xee,0x96,0xd2], [0xba,0xe7,0x9b,0xd9],
[0xdb,0x3b,0xbb,0x7b], [0xd5,0x32,0xb6,0x70], [0xc7,0x29,0xa1,0x6d], [0xc9,0x20,0xac,0x66],
[0xe3,0x1f,0x8f,0x57], [0xed,0x16,0x82,0x5c], [0xff,0x0d,0x95,0x41], [0xf1,0x04,0x98,0x4a],
[0xab,0x73,0xd3,0x23], [0xa5,0x7a,0xde,0x28], [0xb7,0x61,0xc9,0x35], [0xb9,0x68,0xc4,0x3e],
[0x93,0x57,0xe7,0x0f], [0x9d,0x5e,0xea,0x04], [0x8f,0x45,0xfd,0x19], [0x81,0x4c,0xf0,0x12],
[0x3b,0xab,0x6b,0xcb], [0x35,0xa2,0x66,0xc0], [0x27,0xb9,0x71,0xdd], [0x29,0xb0,0x7c,0xd6],
[0x03,0x8f,0x5f,0xe7], [0x0d,0x86,0x52,0xec], [0x1f,0x9d,0x45,0xf1], [0x11,0x94,0x48,0xfa],
[0x4b,0xe3,0x03,0x93], [0x45,0xea,0x0e,0x98], [0x57,0xf1,0x19,0x85], [0x59,0xf8,0x14,0x8e],
[0x73,0xc7,0x37,0xbf], [0x7d,0xce,0x3a,0xb4], [0x6f,0xd5,0x2d,0xa9], [0x61,0xdc,0x20,0xa2],
[0xad,0x76,0x6d,0xf6], [0xa3,0x7f,0x60,0xfd], [0xb1,0x64,0x77,0xe0], [0xbf,0x6d,0x7a,0xeb],
[0x95,0x52,0x59,0xda], [0x9b,0x5b,0x54,0xd1], [0x89,0x40,0x43,0xcc], [0x87,0x49,0x4e,0xc7],
[0xdd,0x3e,0x05,0xae], [0xd3,0x37,0x08,0xa5], [0xc1,0x2c,0x1f,0xb8], [0xcf,0x25,0x12,0xb3],
[0xe5,0x1a,0x31,0x82], [0xeb,0x13,0x3c,0x89], [0xf9,0x08,0x2b,0x94], [0xf7,0x01,0x26,0x9f],
[0x4d,0xe6,0xbd,0x46], [0x43,0xef,0xb0,0x4d], [0x51,0xf4,0xa7,0x50], [0x5f,0xfd,0xaa,0x5b],
[0x75,0xc2,0x89,0x6a], [0x7b,0xcb,0x84,0x61], [0x69,0xd0,0x93,0x7c], [0x67,0xd9,0x9e,0x77],
[0x3d,0xae,0xd5,0x1e], [0x33,0xa7,0xd8,0x15], [0x21,0xbc,0xcf,0x08], [0x2f,0xb5,0xc2,0x03],
[0x05,0x8a,0xe1,0x32], [0x0b,0x83,0xec,0x39], [0x19,0x98,0xfb,0x24], [0x17,0x91,0xf6,0x2f],
[0x76,0x4d,0xd6,0x8d], [0x78,0x44,0xdb,0x86], [0x6a,0x5f,0xcc,0x9b], [0x64,0x56,0xc1,0x90],
[0x4e,0x69,0xe2,0xa1], [0x40,0x60,0xef,0xaa], [0x52,0x7b,0xf8,0xb7], [0x5c,0x72,0xf5,0xbc],
[0x06,0x05,0xbe,0xd5], [0x08,0x0c,0xb3,0xde], [0x1a,0x17,0xa4,0xc3], [0x14,0x1e,0xa9,0xc8],
[0x3e,0x21,0x8a,0xf9], [0x30,0x28,0x87,0xf2], [0x22,0x33,0x90,0xef], [0x2c,0x3a,0x9d,0xe4],
[0x96,0xdd,0x06,0x3d], [0x98,0xd4,0x0b,0x36], [0x8a,0xcf,0x1c,0x2b], [0x84,0xc6,0x11,0x20],
[0xae,0xf9,0x32,0x11], [0xa0,0xf0,0x3f,0x1a], [0xb2,0xeb,0x28,0x07], [0xbc,0xe2,0x25,0x0c],
[0xe6,0x95,0x6e,0x65], [0xe8,0x9c,0x63,0x6e], [0xfa,0x87,0x74,0x73], [0xf4,0x8e,0x79,0x78],
[0xde,0xb1,0x5a,0x49], [0xd0,0xb8,0x57,0x42], [0xc2,0xa3,0x40,0x5f], [0xcc,0xaa,0x4d,0x54],
[0x41,0xec,0xda,0xf7], [0x4f,0xe5,0xd7,0xfc], [0x5d,0xfe,0xc0,0xe1], [0x53,0xf7,0xcd,0xea],
[0x79,0xc8,0xee,0xdb], [0x77,0xc1,0xe3,0xd0], [0x65,0xda,0xf4,0xcd], [0x6b,0xd3,0xf9,0xc6],
[0x31,0xa4,0xb2,0xaf], [0x3f,0xad,0xbf,0xa4], [0x2d,0xb6,0xa8,0xb9], [0x23,0xbf,0xa5,0xb2],
[0x09,0x80,0x86,0x83], [0x07,0x89,0x8b,0x88], [0x15,0x92,0x9c,0x95], [0x1b,0x9b,0x91,0x9e],
[0xa1,0x7c,0x0a,0x47], [0xaf,0x75,0x07,0x4c], [0xbd,0x6e,0x10,0x51], [0xb3,0x67,0x1d,0x5a],
[0x99,0x58,0x3e,0x6b], [0x97,0x51,0x33,0x60], [0x85,0x4a,0x24,0x7d], [0x8b,0x43,0x29,0x76],
[0xd1,0x34,0x62,0x1f], [0xdf,0x3d,0x6f,0x14], [0xcd,0x26,0x78,0x09], [0xc3,0x2f,0x75,0x02],
[0xe9,0x10,0x56,0x33], [0xe7,0x19,0x5b,0x38], [0xf5,0x02,0x4c,0x25], [0xfb,0x0b,0x41,0x2e],
[0x9a,0xd7,0x61,0x8c], [0x94,0xde,0x6c,0x87], [0x86,0xc5,0x7b,0x9a], [0x88,0xcc,0x76,0x91],
[0xa2,0xf3,0x55,0xa0], [0xac,0xfa,0x58,0xab], [0xbe,0xe1,0x4f,0xb6], [0xb0,0xe8,0x42,0xbd],
[0xea,0x9f,0x09,0xd4], [0xe4,0x96,0x04,0xdf], [0xf6,0x8d,0x13,0xc2], [0xf8,0x84,0x1e,0xc9],
[0xd2,0xbb,0x3d,0xf8], [0xdc,0xb2,0x30,0xf3], [0xce,0xa9,0x27,0xee], [0xc0,0xa0,0x2a,0xe5],
[0x7a,0x47,0xb1,0x3c], [0x74,0x4e,0xbc,0x37], [0x66,0x55,0xab,0x2a], [0x68,0x5c,0xa6,0x21],
[0x42,0x63,0x85,0x10], [0x4c,0x6a,0x88,0x1b], [0x5e,0x71,0x9f,0x06], [0x50,0x78,0x92,0x0d],
[0x0a,0x0f,0xd9,0x64], [0x04,0x06,0xd4,0x6f], [0x16,0x1d,0xc3,0x72], [0x18,0x14,0xce,0x79],
[0x32,0x2b,0xed,0x48], [0x3c,0x22,0xe0,0x43], [0x2e,0x39,0xf7,0x5e], [0x20,0x30,0xfa,0x55],
[0xec,0x9a,0xb7,0x01], [0xe2,0x93,0xba,0x0a], [0xf0,0x88,0xad,0x17], [0xfe,0x81,0xa0,0x1c],
[0xd4,0xbe,0x83,0x2d], [0xda,0xb7,0x8e,0x26], [0xc8,0xac,0x99,0x3b], [0xc6,0xa5,0x94,0x30],
[0x9c,0xd2,0xdf,0x59], [0x92,0xdb,0xd2,0x52], [0x80,0xc0,0xc5,0x4f], [0x8e,0xc9,0xc8,0x44],
[0xa4,0xf6,0xeb,0x75], [0xaa,0xff,0xe6,0x7e], [0xb8,0xe4,0xf1,0x63], [0xb6,0xed,0xfc,0x68],
[0x0c,0x0a,0x67,0xb1], [0x02,0x03,0x6a,0xba], [0x10,0x18,0x7d,0xa7], [0x1e,0x11,0x70,0xac],
[0x34,0x2e,0x53,0x9d], [0x3a,0x27,0x5e,0x96], [0x28,0x3c,0x49,0x8b], [0x26,0x35,0x44,0x80],
[0x7c,0x42,0x0f,0xe9], [0x72,0x4b,0x02,0xe2], [0x60,0x50,0x15,0xff], [0x6e,0x59,0x18,0xf4],
[0x44,0x66,0x3b,0xc5], [0x4a,0x6f,0x36,0xce], [0x58,0x74,0x21,0xd3], [0x56,0x7d,0x2c,0xd8],
[0x37,0xa1,0x0c,0x7a], [0x39,0xa8,0x01,0x71], [0x2b,0xb3,0x16,0x6c], [0x25,0xba,0x1b,0x67],
[0x0f,0x85,0x38,0x56], [0x01,0x8c,0x35,0x5d], [0x13,0x97,0x22,0x40], [0x1d,0x9e,0x2f,0x4b],
[0x47,0xe9,0x64,0x22], [0x49,0xe0,0x69,0x29], [0x5b,0xfb,0x7e,0x34], [0x55,0xf2,0x73,0x3f],
[0x7f,0xcd,0x50,0x0e], [0x71,0xc4,0x5d,0x05], [0x63,0xdf,0x4a,0x18], [0x6d,0xd6,0x47,0x13],
[0xd7,0x31,0xdc,0xca], [0xd9,0x38,0xd1,0xc1], [0xcb,0x23,0xc6,0xdc], [0xc5,0x2a,0xcb,0xd7],
[0xef,0x15,0xe8,0xe6], [0xe1,0x1c,0xe5,0xed], [0xf3,0x07,0xf2,0xf0], [0xfd,0x0e,0xff,0xfb],
[0xa7,0x79,0xb4,0x92], [0xa9,0x70,0xb9,0x99], [0xbb,0x6b,0xae,0x84], [0xb5,0x62,0xa3,0x8f],
[0x9f,0x5d,0x80,0xbe], [0x91,0x54,0x8d,0xb5], [0x83,0x4f,0x9a,0xa8], [0x8d,0x46,0x97,0xa3]
);
my @U2 = (
[0x00,0x00,0x00,0x00], [0x0b,0x0e,0x09,0x0d], [0x16,0x1c,0x12,0x1a], [0x1d,0x12,0x1b,0x17],
[0x2c,0x38,0x24,0x34], [0x27,0x36,0x2d,0x39], [0x3a,0x24,0x36,0x2e], [0x31,0x2a,0x3f,0x23],
[0x58,0x70,0x48,0x68], [0x53,0x7e,0x41,0x65], [0x4e,0x6c,0x5a,0x72], [0x45,0x62,0x53,0x7f],
[0x74,0x48,0x6c,0x5c], [0x7f,0x46,0x65,0x51], [0x62,0x54,0x7e,0x46], [0x69,0x5a,0x77,0x4b],
[0xb0,0xe0,0x90,0xd0], [0xbb,0xee,0x99,0xdd], [0xa6,0xfc,0x82,0xca], [0xad,0xf2,0x8b,0xc7],
[0x9c,0xd8,0xb4,0xe4], [0x97,0xd6,0xbd,0xe9], [0x8a,0xc4,0xa6,0xfe], [0x81,0xca,0xaf,0xf3],
[0xe8,0x90,0xd8,0xb8], [0xe3,0x9e,0xd1,0xb5], [0xfe,0x8c,0xca,0xa2], [0xf5,0x82,0xc3,0xaf],
[0xc4,0xa8,0xfc,0x8c], [0xcf,0xa6,0xf5,0x81], [0xd2,0xb4,0xee,0x96], [0xd9,0xba,0xe7,0x9b],
[0x7b,0xdb,0x3b,0xbb], [0x70,0xd5,0x32,0xb6], [0x6d,0xc7,0x29,0xa1], [0x66,0xc9,0x20,0xac],
[0x57,0xe3,0x1f,0x8f], [0x5c,0xed,0x16,0x82], [0x41,0xff,0x0d,0x95], [0x4a,0xf1,0x04,0x98],
[0x23,0xab,0x73,0xd3], [0x28,0xa5,0x7a,0xde], [0x35,0xb7,0x61,0xc9], [0x3e,0xb9,0x68,0xc4],
[0x0f,0x93,0x57,0xe7], [0x04,0x9d,0x5e,0xea], [0x19,0x8f,0x45,0xfd], [0x12,0x81,0x4c,0xf0],
[0xcb,0x3b,0xab,0x6b], [0xc0,0x35,0xa2,0x66], [0xdd,0x27,0xb9,0x71], [0xd6,0x29,0xb0,0x7c],
[0xe7,0x03,0x8f,0x5f], [0xec,0x0d,0x86,0x52], [0xf1,0x1f,0x9d,0x45], [0xfa,0x11,0x94,0x48],
[0x93,0x4b,0xe3,0x03], [0x98,0x45,0xea,0x0e], [0x85,0x57,0xf1,0x19], [0x8e,0x59,0xf8,0x14],
[0xbf,0x73,0xc7,0x37], [0xb4,0x7d,0xce,0x3a], [0xa9,0x6f,0xd5,0x2d], [0xa2,0x61,0xdc,0x20],
[0xf6,0xad,0x76,0x6d], [0xfd,0xa3,0x7f,0x60], [0xe0,0xb1,0x64,0x77], [0xeb,0xbf,0x6d,0x7a],
[0xda,0x95,0x52,0x59], [0xd1,0x9b,0x5b,0x54], [0xcc,0x89,0x40,0x43], [0xc7,0x87,0x49,0x4e],
[0xae,0xdd,0x3e,0x05], [0xa5,0xd3,0x37,0x08], [0xb8,0xc1,0x2c,0x1f], [0xb3,0xcf,0x25,0x12],
[0x82,0xe5,0x1a,0x31], [0x89,0xeb,0x13,0x3c], [0x94,0xf9,0x08,0x2b], [0x9f,0xf7,0x01,0x26],
[0x46,0x4d,0xe6,0xbd], [0x4d,0x43,0xef,0xb0], [0x50,0x51,0xf4,0xa7], [0x5b,0x5f,0xfd,0xaa],
[0x6a,0x75,0xc2,0x89], [0x61,0x7b,0xcb,0x84], [0x7c,0x69,0xd0,0x93], [0x77,0x67,0xd9,0x9e],
[0x1e,0x3d,0xae,0xd5], [0x15,0x33,0xa7,0xd8], [0x08,0x21,0xbc,0xcf], [0x03,0x2f,0xb5,0xc2],
[0x32,0x05,0x8a,0xe1], [0x39,0x0b,0x83,0xec], [0x24,0x19,0x98,0xfb], [0x2f,0x17,0x91,0xf6],
[0x8d,0x76,0x4d,0xd6], [0x86,0x78,0x44,0xdb], [0x9b,0x6a,0x5f,0xcc], [0x90,0x64,0x56,0xc1],
[0xa1,0x4e,0x69,0xe2], [0xaa,0x40,0x60,0xef], [0xb7,0x52,0x7b,0xf8], [0xbc,0x5c,0x72,0xf5],
[0xd5,0x06,0x05,0xbe], [0xde,0x08,0x0c,0xb3], [0xc3,0x1a,0x17,0xa4], [0xc8,0x14,0x1e,0xa9],
[0xf9,0x3e,0x21,0x8a], [0xf2,0x30,0x28,0x87], [0xef,0x22,0x33,0x90], [0xe4,0x2c,0x3a,0x9d],
[0x3d,0x96,0xdd,0x06], [0x36,0x98,0xd4,0x0b], [0x2b,0x8a,0xcf,0x1c], [0x20,0x84,0xc6,0x11],
[0x11,0xae,0xf9,0x32], [0x1a,0xa0,0xf0,0x3f], [0x07,0xb2,0xeb,0x28], [0x0c,0xbc,0xe2,0x25],
[0x65,0xe6,0x95,0x6e], [0x6e,0xe8,0x9c,0x63], [0x73,0xfa,0x87,0x74], [0x78,0xf4,0x8e,0x79],
[0x49,0xde,0xb1,0x5a], [0x42,0xd0,0xb8,0x57], [0x5f,0xc2,0xa3,0x40], [0x54,0xcc,0xaa,0x4d],
[0xf7,0x41,0xec,0xda], [0xfc,0x4f,0xe5,0xd7], [0xe1,0x5d,0xfe,0xc0], [0xea,0x53,0xf7,0xcd],
[0xdb,0x79,0xc8,0xee], [0xd0,0x77,0xc1,0xe3], [0xcd,0x65,0xda,0xf4], [0xc6,0x6b,0xd3,0xf9],
[0xaf,0x31,0xa4,0xb2], [0xa4,0x3f,0xad,0xbf], [0xb9,0x2d,0xb6,0xa8], [0xb2,0x23,0xbf,0xa5],
[0x83,0x09,0x80,0x86], [0x88,0x07,0x89,0x8b], [0x95,0x15,0x92,0x9c], [0x9e,0x1b,0x9b,0x91],
[0x47,0xa1,0x7c,0x0a], [0x4c,0xaf,0x75,0x07], [0x51,0xbd,0x6e,0x10], [0x5a,0xb3,0x67,0x1d],
[0x6b,0x99,0x58,0x3e], [0x60,0x97,0x51,0x33], [0x7d,0x85,0x4a,0x24], [0x76,0x8b,0x43,0x29],
[0x1f,0xd1,0x34,0x62], [0x14,0xdf,0x3d,0x6f], [0x09,0xcd,0x26,0x78], [0x02,0xc3,0x2f,0x75],
[0x33,0xe9,0x10,0x56], [0x38,0xe7,0x19,0x5b], [0x25,0xf5,0x02,0x4c], [0x2e,0xfb,0x0b,0x41],
[0x8c,0x9a,0xd7,0x61], [0x87,0x94,0xde,0x6c], [0x9a,0x86,0xc5,0x7b], [0x91,0x88,0xcc,0x76],
[0xa0,0xa2,0xf3,0x55], [0xab,0xac,0xfa,0x58], [0xb6,0xbe,0xe1,0x4f], [0xbd,0xb0,0xe8,0x42],
[0xd4,0xea,0x9f,0x09], [0xdf,0xe4,0x96,0x04], [0xc2,0xf6,0x8d,0x13], [0xc9,0xf8,0x84,0x1e],
[0xf8,0xd2,0xbb,0x3d], [0xf3,0xdc,0xb2,0x30], [0xee,0xce,0xa9,0x27], [0xe5,0xc0,0xa0,0x2a],
[0x3c,0x7a,0x47,0xb1], [0x37,0x74,0x4e,0xbc], [0x2a,0x66,0x55,0xab], [0x21,0x68,0x5c,0xa6],
[0x10,0x42,0x63,0x85], [0x1b,0x4c,0x6a,0x88], [0x06,0x5e,0x71,0x9f], [0x0d,0x50,0x78,0x92],
[0x64,0x0a,0x0f,0xd9], [0x6f,0x04,0x06,0xd4], [0x72,0x16,0x1d,0xc3], [0x79,0x18,0x14,0xce],
[0x48,0x32,0x2b,0xed], [0x43,0x3c,0x22,0xe0], [0x5e,0x2e,0x39,0xf7], [0x55,0x20,0x30,0xfa],
[0x01,0xec,0x9a,0xb7], [0x0a,0xe2,0x93,0xba], [0x17,0xf0,0x88,0xad], [0x1c,0xfe,0x81,0xa0],
[0x2d,0xd4,0xbe,0x83], [0x26,0xda,0xb7,0x8e], [0x3b,0xc8,0xac,0x99], [0x30,0xc6,0xa5,0x94],
[0x59,0x9c,0xd2,0xdf], [0x52,0x92,0xdb,0xd2], [0x4f,0x80,0xc0,0xc5], [0x44,0x8e,0xc9,0xc8],
[0x75,0xa4,0xf6,0xeb], [0x7e,0xaa,0xff,0xe6], [0x63,0xb8,0xe4,0xf1], [0x68,0xb6,0xed,0xfc],
[0xb1,0x0c,0x0a,0x67], [0xba,0x02,0x03,0x6a], [0xa7,0x10,0x18,0x7d], [0xac,0x1e,0x11,0x70],
[0x9d,0x34,0x2e,0x53], [0x96,0x3a,0x27,0x5e], [0x8b,0x28,0x3c,0x49], [0x80,0x26,0x35,0x44],
[0xe9,0x7c,0x42,0x0f], [0xe2,0x72,0x4b,0x02], [0xff,0x60,0x50,0x15], [0xf4,0x6e,0x59,0x18],
[0xc5,0x44,0x66,0x3b], [0xce,0x4a,0x6f,0x36], [0xd3,0x58,0x74,0x21], [0xd8,0x56,0x7d,0x2c],
[0x7a,0x37,0xa1,0x0c], [0x71,0x39,0xa8,0x01], [0x6c,0x2b,0xb3,0x16], [0x67,0x25,0xba,0x1b],
[0x56,0x0f,0x85,0x38], [0x5d,0x01,0x8c,0x35], [0x40,0x13,0x97,0x22], [0x4b,0x1d,0x9e,0x2f],
[0x22,0x47,0xe9,0x64], [0x29,0x49,0xe0,0x69], [0x34,0x5b,0xfb,0x7e], [0x3f,0x55,0xf2,0x73],
[0x0e,0x7f,0xcd,0x50], [0x05,0x71,0xc4,0x5d], [0x18,0x63,0xdf,0x4a], [0x13,0x6d,0xd6,0x47],
[0xca,0xd7,0x31,0xdc], [0xc1,0xd9,0x38,0xd1], [0xdc,0xcb,0x23,0xc6], [0xd7,0xc5,0x2a,0xcb],
[0xe6,0xef,0x15,0xe8], [0xed,0xe1,0x1c,0xe5], [0xf0,0xf3,0x07,0xf2], [0xfb,0xfd,0x0e,0xff],
[0x92,0xa7,0x79,0xb4], [0x99,0xa9,0x70,0xb9], [0x84,0xbb,0x6b,0xae], [0x8f,0xb5,0x62,0xa3],
[0xbe,0x9f,0x5d,0x80], [0xb5,0x91,0x54,0x8d], [0xa8,0x83,0x4f,0x9a], [0xa3,0x8d,0x46,0x97]
);
my @U3 = (
[0x00,0x00,0x00,0x00], [0x0d,0x0b,0x0e,0x09], [0x1a,0x16,0x1c,0x12], [0x17,0x1d,0x12,0x1b],
[0x34,0x2c,0x38,0x24], [0x39,0x27,0x36,0x2d], [0x2e,0x3a,0x24,0x36], [0x23,0x31,0x2a,0x3f],
[0x68,0x58,0x70,0x48], [0x65,0x53,0x7e,0x41], [0x72,0x4e,0x6c,0x5a], [0x7f,0x45,0x62,0x53],
[0x5c,0x74,0x48,0x6c], [0x51,0x7f,0x46,0x65], [0x46,0x62,0x54,0x7e], [0x4b,0x69,0x5a,0x77],
[0xd0,0xb0,0xe0,0x90], [0xdd,0xbb,0xee,0x99], [0xca,0xa6,0xfc,0x82], [0xc7,0xad,0xf2,0x8b],
[0xe4,0x9c,0xd8,0xb4], [0xe9,0x97,0xd6,0xbd], [0xfe,0x8a,0xc4,0xa6], [0xf3,0x81,0xca,0xaf],
[0xb8,0xe8,0x90,0xd8], [0xb5,0xe3,0x9e,0xd1], [0xa2,0xfe,0x8c,0xca], [0xaf,0xf5,0x82,0xc3],
[0x8c,0xc4,0xa8,0xfc], [0x81,0xcf,0xa6,0xf5], [0x96,0xd2,0xb4,0xee], [0x9b,0xd9,0xba,0xe7],
[0xbb,0x7b,0xdb,0x3b], [0xb6,0x70,0xd5,0x32], [0xa1,0x6d,0xc7,0x29], [0xac,0x66,0xc9,0x20],
[0x8f,0x57,0xe3,0x1f], [0x82,0x5c,0xed,0x16], [0x95,0x41,0xff,0x0d], [0x98,0x4a,0xf1,0x04],
[0xd3,0x23,0xab,0x73], [0xde,0x28,0xa5,0x7a], [0xc9,0x35,0xb7,0x61], [0xc4,0x3e,0xb9,0x68],
[0xe7,0x0f,0x93,0x57], [0xea,0x04,0x9d,0x5e], [0xfd,0x19,0x8f,0x45], [0xf0,0x12,0x81,0x4c],
[0x6b,0xcb,0x3b,0xab], [0x66,0xc0,0x35,0xa2], [0x71,0xdd,0x27,0xb9], [0x7c,0xd6,0x29,0xb0],
[0x5f,0xe7,0x03,0x8f], [0x52,0xec,0x0d,0x86], [0x45,0xf1,0x1f,0x9d], [0x48,0xfa,0x11,0x94],
[0x03,0x93,0x4b,0xe3], [0x0e,0x98,0x45,0xea], [0x19,0x85,0x57,0xf1], [0x14,0x8e,0x59,0xf8],
[0x37,0xbf,0x73,0xc7], [0x3a,0xb4,0x7d,0xce], [0x2d,0xa9,0x6f,0xd5], [0x20,0xa2,0x61,0xdc],
[0x6d,0xf6,0xad,0x76], [0x60,0xfd,0xa3,0x7f], [0x77,0xe0,0xb1,0x64], [0x7a,0xeb,0xbf,0x6d],
[0x59,0xda,0x95,0x52], [0x54,0xd1,0x9b,0x5b], [0x43,0xcc,0x89,0x40], [0x4e,0xc7,0x87,0x49],
[0x05,0xae,0xdd,0x3e], [0x08,0xa5,0xd3,0x37], [0x1f,0xb8,0xc1,0x2c], [0x12,0xb3,0xcf,0x25],
[0x31,0x82,0xe5,0x1a], [0x3c,0x89,0xeb,0x13], [0x2b,0x94,0xf9,0x08], [0x26,0x9f,0xf7,0x01],
[0xbd,0x46,0x4d,0xe6], [0xb0,0x4d,0x43,0xef], [0xa7,0x50,0x51,0xf4], [0xaa,0x5b,0x5f,0xfd],
[0x89,0x6a,0x75,0xc2], [0x84,0x61,0x7b,0xcb], [0x93,0x7c,0x69,0xd0], [0x9e,0x77,0x67,0xd9],
[0xd5,0x1e,0x3d,0xae], [0xd8,0x15,0x33,0xa7], [0xcf,0x08,0x21,0xbc], [0xc2,0x03,0x2f,0xb5],
[0xe1,0x32,0x05,0x8a], [0xec,0x39,0x0b,0x83], [0xfb,0x24,0x19,0x98], [0xf6,0x2f,0x17,0x91],
[0xd6,0x8d,0x76,0x4d], [0xdb,0x86,0x78,0x44], [0xcc,0x9b,0x6a,0x5f], [0xc1,0x90,0x64,0x56],
[0xe2,0xa1,0x4e,0x69], [0xef,0xaa,0x40,0x60], [0xf8,0xb7,0x52,0x7b], [0xf5,0xbc,0x5c,0x72],
[0xbe,0xd5,0x06,0x05], [0xb3,0xde,0x08,0x0c], [0xa4,0xc3,0x1a,0x17], [0xa9,0xc8,0x14,0x1e],
[0x8a,0xf9,0x3e,0x21], [0x87,0xf2,0x30,0x28], [0x90,0xef,0x22,0x33], [0x9d,0xe4,0x2c,0x3a],
[0x06,0x3d,0x96,0xdd], [0x0b,0x36,0x98,0xd4], [0x1c,0x2b,0x8a,0xcf], [0x11,0x20,0x84,0xc6],
[0x32,0x11,0xae,0xf9], [0x3f,0x1a,0xa0,0xf0], [0x28,0x07,0xb2,0xeb], [0x25,0x0c,0xbc,0xe2],
[0x6e,0x65,0xe6,0x95], [0x63,0x6e,0xe8,0x9c], [0x74,0x73,0xfa,0x87], [0x79,0x78,0xf4,0x8e],
[0x5a,0x49,0xde,0xb1], [0x57,0x42,0xd0,0xb8], [0x40,0x5f,0xc2,0xa3], [0x4d,0x54,0xcc,0xaa],
[0xda,0xf7,0x41,0xec], [0xd7,0xfc,0x4f,0xe5], [0xc0,0xe1,0x5d,0xfe], [0xcd,0xea,0x53,0xf7],
[0xee,0xdb,0x79,0xc8], [0xe3,0xd0,0x77,0xc1], [0xf4,0xcd,0x65,0xda], [0xf9,0xc6,0x6b,0xd3],
[0xb2,0xaf,0x31,0xa4], [0xbf,0xa4,0x3f,0xad], [0xa8,0xb9,0x2d,0xb6], [0xa5,0xb2,0x23,0xbf],
[0x86,0x83,0x09,0x80], [0x8b,0x88,0x07,0x89], [0x9c,0x95,0x15,0x92], [0x91,0x9e,0x1b,0x9b],
[0x0a,0x47,0xa1,0x7c], [0x07,0x4c,0xaf,0x75], [0x10,0x51,0xbd,0x6e], [0x1d,0x5a,0xb3,0x67],
[0x3e,0x6b,0x99,0x58], [0x33,0x60,0x97,0x51], [0x24,0x7d,0x85,0x4a], [0x29,0x76,0x8b,0x43],
[0x62,0x1f,0xd1,0x34], [0x6f,0x14,0xdf,0x3d], [0x78,0x09,0xcd,0x26], [0x75,0x02,0xc3,0x2f],
[0x56,0x33,0xe9,0x10], [0x5b,0x38,0xe7,0x19], [0x4c,0x25,0xf5,0x02], [0x41,0x2e,0xfb,0x0b],
[0x61,0x8c,0x9a,0xd7], [0x6c,0x87,0x94,0xde], [0x7b,0x9a,0x86,0xc5], [0x76,0x91,0x88,0xcc],
[0x55,0xa0,0xa2,0xf3], [0x58,0xab,0xac,0xfa], [0x4f,0xb6,0xbe,0xe1], [0x42,0xbd,0xb0,0xe8],
[0x09,0xd4,0xea,0x9f], [0x04,0xdf,0xe4,0x96], [0x13,0xc2,0xf6,0x8d], [0x1e,0xc9,0xf8,0x84],
[0x3d,0xf8,0xd2,0xbb], [0x30,0xf3,0xdc,0xb2], [0x27,0xee,0xce,0xa9], [0x2a,0xe5,0xc0,0xa0],
[0xb1,0x3c,0x7a,0x47], [0xbc,0x37,0x74,0x4e], [0xab,0x2a,0x66,0x55], [0xa6,0x21,0x68,0x5c],
[0x85,0x10,0x42,0x63], [0x88,0x1b,0x4c,0x6a], [0x9f,0x06,0x5e,0x71], [0x92,0x0d,0x50,0x78],
[0xd9,0x64,0x0a,0x0f], [0xd4,0x6f,0x04,0x06], [0xc3,0x72,0x16,0x1d], [0xce,0x79,0x18,0x14],
[0xed,0x48,0x32,0x2b], [0xe0,0x43,0x3c,0x22], [0xf7,0x5e,0x2e,0x39], [0xfa,0x55,0x20,0x30],
[0xb7,0x01,0xec,0x9a], [0xba,0x0a,0xe2,0x93], [0xad,0x17,0xf0,0x88], [0xa0,0x1c,0xfe,0x81],
[0x83,0x2d,0xd4,0xbe], [0x8e,0x26,0xda,0xb7], [0x99,0x3b,0xc8,0xac], [0x94,0x30,0xc6,0xa5],
[0xdf,0x59,0x9c,0xd2], [0xd2,0x52,0x92,0xdb], [0xc5,0x4f,0x80,0xc0], [0xc8,0x44,0x8e,0xc9],
[0xeb,0x75,0xa4,0xf6], [0xe6,0x7e,0xaa,0xff], [0xf1,0x63,0xb8,0xe4], [0xfc,0x68,0xb6,0xed],
[0x67,0xb1,0x0c,0x0a], [0x6a,0xba,0x02,0x03], [0x7d,0xa7,0x10,0x18], [0x70,0xac,0x1e,0x11],
[0x53,0x9d,0x34,0x2e], [0x5e,0x96,0x3a,0x27], [0x49,0x8b,0x28,0x3c], [0x44,0x80,0x26,0x35],
[0x0f,0xe9,0x7c,0x42], [0x02,0xe2,0x72,0x4b], [0x15,0xff,0x60,0x50], [0x18,0xf4,0x6e,0x59],
[0x3b,0xc5,0x44,0x66], [0x36,0xce,0x4a,0x6f], [0x21,0xd3,0x58,0x74], [0x2c,0xd8,0x56,0x7d],
[0x0c,0x7a,0x37,0xa1], [0x01,0x71,0x39,0xa8], [0x16,0x6c,0x2b,0xb3], [0x1b,0x67,0x25,0xba],
[0x38,0x56,0x0f,0x85], [0x35,0x5d,0x01,0x8c], [0x22,0x40,0x13,0x97], [0x2f,0x4b,0x1d,0x9e],
[0x64,0x22,0x47,0xe9], [0x69,0x29,0x49,0xe0], [0x7e,0x34,0x5b,0xfb], [0x73,0x3f,0x55,0xf2],
[0x50,0x0e,0x7f,0xcd], [0x5d,0x05,0x71,0xc4], [0x4a,0x18,0x63,0xdf], [0x47,0x13,0x6d,0xd6],
[0xdc,0xca,0xd7,0x31], [0xd1,0xc1,0xd9,0x38], [0xc6,0xdc,0xcb,0x23], [0xcb,0xd7,0xc5,0x2a],
[0xe8,0xe6,0xef,0x15], [0xe5,0xed,0xe1,0x1c], [0xf2,0xf0,0xf3,0x07], [0xff,0xfb,0xfd,0x0e],
[0xb4,0x92,0xa7,0x79], [0xb9,0x99,0xa9,0x70], [0xae,0x84,0xbb,0x6b], [0xa3,0x8f,0xb5,0x62],
[0x80,0xbe,0x9f,0x5d], [0x8d,0xb5,0x91,0x54], [0x9a,0xa8,0x83,0x4f], [0x97,0xa3,0x8d,0x46]
);
my @U4 = (
[0x00,0x00,0x00,0x00], [0x09,0x0d,0x0b,0x0e], [0x12,0x1a,0x16,0x1c], [0x1b,0x17,0x1d,0x12],
[0x24,0x34,0x2c,0x38], [0x2d,0x39,0x27,0x36], [0x36,0x2e,0x3a,0x24], [0x3f,0x23,0x31,0x2a],
[0x48,0x68,0x58,0x70], [0x41,0x65,0x53,0x7e], [0x5a,0x72,0x4e,0x6c], [0x53,0x7f,0x45,0x62],
[0x6c,0x5c,0x74,0x48], [0x65,0x51,0x7f,0x46], [0x7e,0x46,0x62,0x54], [0x77,0x4b,0x69,0x5a],
[0x90,0xd0,0xb0,0xe0], [0x99,0xdd,0xbb,0xee], [0x82,0xca,0xa6,0xfc], [0x8b,0xc7,0xad,0xf2],
[0xb4,0xe4,0x9c,0xd8], [0xbd,0xe9,0x97,0xd6], [0xa6,0xfe,0x8a,0xc4], [0xaf,0xf3,0x81,0xca],
[0xd8,0xb8,0xe8,0x90], [0xd1,0xb5,0xe3,0x9e], [0xca,0xa2,0xfe,0x8c], [0xc3,0xaf,0xf5,0x82],
[0xfc,0x8c,0xc4,0xa8], [0xf5,0x81,0xcf,0xa6], [0xee,0x96,0xd2,0xb4], [0xe7,0x9b,0xd9,0xba],
[0x3b,0xbb,0x7b,0xdb], [0x32,0xb6,0x70,0xd5], [0x29,0xa1,0x6d,0xc7], [0x20,0xac,0x66,0xc9],
[0x1f,0x8f,0x57,0xe3], [0x16,0x82,0x5c,0xed], [0x0d,0x95,0x41,0xff], [0x04,0x98,0x4a,0xf1],
[0x73,0xd3,0x23,0xab], [0x7a,0xde,0x28,0xa5], [0x61,0xc9,0x35,0xb7], [0x68,0xc4,0x3e,0xb9],
[0x57,0xe7,0x0f,0x93], [0x5e,0xea,0x04,0x9d], [0x45,0xfd,0x19,0x8f], [0x4c,0xf0,0x12,0x81],
[0xab,0x6b,0xcb,0x3b], [0xa2,0x66,0xc0,0x35], [0xb9,0x71,0xdd,0x27], [0xb0,0x7c,0xd6,0x29],
[0x8f,0x5f,0xe7,0x03], [0x86,0x52,0xec,0x0d], [0x9d,0x45,0xf1,0x1f], [0x94,0x48,0xfa,0x11],
[0xe3,0x03,0x93,0x4b], [0xea,0x0e,0x98,0x45], [0xf1,0x19,0x85,0x57], [0xf8,0x14,0x8e,0x59],
[0xc7,0x37,0xbf,0x73], [0xce,0x3a,0xb4,0x7d], [0xd5,0x2d,0xa9,0x6f], [0xdc,0x20,0xa2,0x61],
[0x76,0x6d,0xf6,0xad], [0x7f,0x60,0xfd,0xa3], [0x64,0x77,0xe0,0xb1], [0x6d,0x7a,0xeb,0xbf],
[0x52,0x59,0xda,0x95], [0x5b,0x54,0xd1,0x9b], [0x40,0x43,0xcc,0x89], [0x49,0x4e,0xc7,0x87],
[0x3e,0x05,0xae,0xdd], [0x37,0x08,0xa5,0xd3], [0x2c,0x1f,0xb8,0xc1], [0x25,0x12,0xb3,0xcf],
[0x1a,0x31,0x82,0xe5], [0x13,0x3c,0x89,0xeb], [0x08,0x2b,0x94,0xf9], [0x01,0x26,0x9f,0xf7],
[0xe6,0xbd,0x46,0x4d], [0xef,0xb0,0x4d,0x43], [0xf4,0xa7,0x50,0x51], [0xfd,0xaa,0x5b,0x5f],
[0xc2,0x89,0x6a,0x75], [0xcb,0x84,0x61,0x7b], [0xd0,0x93,0x7c,0x69], [0xd9,0x9e,0x77,0x67],
[0xae,0xd5,0x1e,0x3d], [0xa7,0xd8,0x15,0x33], [0xbc,0xcf,0x08,0x21], [0xb5,0xc2,0x03,0x2f],
[0x8a,0xe1,0x32,0x05], [0x83,0xec,0x39,0x0b], [0x98,0xfb,0x24,0x19], [0x91,0xf6,0x2f,0x17],
[0x4d,0xd6,0x8d,0x76], [0x44,0xdb,0x86,0x78], [0x5f,0xcc,0x9b,0x6a], [0x56,0xc1,0x90,0x64],
[0x69,0xe2,0xa1,0x4e], [0x60,0xef,0xaa,0x40], [0x7b,0xf8,0xb7,0x52], [0x72,0xf5,0xbc,0x5c],
[0x05,0xbe,0xd5,0x06], [0x0c,0xb3,0xde,0x08], [0x17,0xa4,0xc3,0x1a], [0x1e,0xa9,0xc8,0x14],
[0x21,0x8a,0xf9,0x3e], [0x28,0x87,0xf2,0x30], [0x33,0x90,0xef,0x22], [0x3a,0x9d,0xe4,0x2c],
[0xdd,0x06,0x3d,0x96], [0xd4,0x0b,0x36,0x98], [0xcf,0x1c,0x2b,0x8a], [0xc6,0x11,0x20,0x84],
[0xf9,0x32,0x11,0xae], [0xf0,0x3f,0x1a,0xa0], [0xeb,0x28,0x07,0xb2], [0xe2,0x25,0x0c,0xbc],
[0x95,0x6e,0x65,0xe6], [0x9c,0x63,0x6e,0xe8], [0x87,0x74,0x73,0xfa], [0x8e,0x79,0x78,0xf4],
[0xb1,0x5a,0x49,0xde], [0xb8,0x57,0x42,0xd0], [0xa3,0x40,0x5f,0xc2], [0xaa,0x4d,0x54,0xcc],
[0xec,0xda,0xf7,0x41], [0xe5,0xd7,0xfc,0x4f], [0xfe,0xc0,0xe1,0x5d], [0xf7,0xcd,0xea,0x53],
[0xc8,0xee,0xdb,0x79], [0xc1,0xe3,0xd0,0x77], [0xda,0xf4,0xcd,0x65], [0xd3,0xf9,0xc6,0x6b],
[0xa4,0xb2,0xaf,0x31], [0xad,0xbf,0xa4,0x3f], [0xb6,0xa8,0xb9,0x2d], [0xbf,0xa5,0xb2,0x23],
[0x80,0x86,0x83,0x09], [0x89,0x8b,0x88,0x07], [0x92,0x9c,0x95,0x15], [0x9b,0x91,0x9e,0x1b],
[0x7c,0x0a,0x47,0xa1], [0x75,0x07,0x4c,0xaf], [0x6e,0x10,0x51,0xbd], [0x67,0x1d,0x5a,0xb3],
[0x58,0x3e,0x6b,0x99], [0x51,0x33,0x60,0x97], [0x4a,0x24,0x7d,0x85], [0x43,0x29,0x76,0x8b],
[0x34,0x62,0x1f,0xd1], [0x3d,0x6f,0x14,0xdf], [0x26,0x78,0x09,0xcd], [0x2f,0x75,0x02,0xc3],
[0x10,0x56,0x33,0xe9], [0x19,0x5b,0x38,0xe7], [0x02,0x4c,0x25,0xf5], [0x0b,0x41,0x2e,0xfb],
[0xd7,0x61,0x8c,0x9a], [0xde,0x6c,0x87,0x94], [0xc5,0x7b,0x9a,0x86], [0xcc,0x76,0x91,0x88],
[0xf3,0x55,0xa0,0xa2], [0xfa,0x58,0xab,0xac], [0xe1,0x4f,0xb6,0xbe], [0xe8,0x42,0xbd,0xb0],
[0x9f,0x09,0xd4,0xea], [0x96,0x04,0xdf,0xe4], [0x8d,0x13,0xc2,0xf6], [0x84,0x1e,0xc9,0xf8],
[0xbb,0x3d,0xf8,0xd2], [0xb2,0x30,0xf3,0xdc], [0xa9,0x27,0xee,0xce], [0xa0,0x2a,0xe5,0xc0],
[0x47,0xb1,0x3c,0x7a], [0x4e,0xbc,0x37,0x74], [0x55,0xab,0x2a,0x66], [0x5c,0xa6,0x21,0x68],
[0x63,0x85,0x10,0x42], [0x6a,0x88,0x1b,0x4c], [0x71,0x9f,0x06,0x5e], [0x78,0x92,0x0d,0x50],
[0x0f,0xd9,0x64,0x0a], [0x06,0xd4,0x6f,0x04], [0x1d,0xc3,0x72,0x16], [0x14,0xce,0x79,0x18],
[0x2b,0xed,0x48,0x32], [0x22,0xe0,0x43,0x3c], [0x39,0xf7,0x5e,0x2e], [0x30,0xfa,0x55,0x20],
[0x9a,0xb7,0x01,0xec], [0x93,0xba,0x0a,0xe2], [0x88,0xad,0x17,0xf0], [0x81,0xa0,0x1c,0xfe],
[0xbe,0x83,0x2d,0xd4], [0xb7,0x8e,0x26,0xda], [0xac,0x99,0x3b,0xc8], [0xa5,0x94,0x30,0xc6],
[0xd2,0xdf,0x59,0x9c], [0xdb,0xd2,0x52,0x92], [0xc0,0xc5,0x4f,0x80], [0xc9,0xc8,0x44,0x8e],
[0xf6,0xeb,0x75,0xa4], [0xff,0xe6,0x7e,0xaa], [0xe4,0xf1,0x63,0xb8], [0xed,0xfc,0x68,0xb6],
[0x0a,0x67,0xb1,0x0c], [0x03,0x6a,0xba,0x02], [0x18,0x7d,0xa7,0x10], [0x11,0x70,0xac,0x1e],
[0x2e,0x53,0x9d,0x34], [0x27,0x5e,0x96,0x3a], [0x3c,0x49,0x8b,0x28], [0x35,0x44,0x80,0x26],
[0x42,0x0f,0xe9,0x7c], [0x4b,0x02,0xe2,0x72], [0x50,0x15,0xff,0x60], [0x59,0x18,0xf4,0x6e],
[0x66,0x3b,0xc5,0x44], [0x6f,0x36,0xce,0x4a], [0x74,0x21,0xd3,0x58], [0x7d,0x2c,0xd8,0x56],
[0xa1,0x0c,0x7a,0x37], [0xa8,0x01,0x71,0x39], [0xb3,0x16,0x6c,0x2b], [0xba,0x1b,0x67,0x25],
[0x85,0x38,0x56,0x0f], [0x8c,0x35,0x5d,0x01], [0x97,0x22,0x40,0x13], [0x9e,0x2f,0x4b,0x1d],
[0xe9,0x64,0x22,0x47], [0xe0,0x69,0x29,0x49], [0xfb,0x7e,0x34,0x5b], [0xf2,0x73,0x3f,0x55],
[0xcd,0x50,0x0e,0x7f], [0xc4,0x5d,0x05,0x71], [0xdf,0x4a,0x18,0x63], [0xd6,0x47,0x13,0x6d],
[0x31,0xdc,0xca,0xd7], [0x38,0xd1,0xc1,0xd9], [0x23,0xc6,0xdc,0xcb], [0x2a,0xcb,0xd7,0xc5],
[0x15,0xe8,0xe6,0xef], [0x1c,0xe5,0xed,0xe1], [0x07,0xf2,0xf0,0xf3], [0x0e,0xff,0xfb,0xfd],
[0x79,0xb4,0x92,0xa7], [0x70,0xb9,0x99,0xa9], [0x6b,0xae,0x84,0xbb], [0x62,0xa3,0x8f,0xb5],
[0x5d,0x80,0xbe,0x9f], [0x54,0x8d,0xb5,0x91], [0x4f,0x9a,0xa8,0x83], [0x46,0x97,0xa3,0x8d]
);
# alg-ref.h
# define MAXBC (256/32)
# define MAXKC (256/32)
# define MAXROUNDS 14
sub MAXBC() { 8 }
sub MAXKC() { 8 }
sub MAXROUNDS() { 14 }
# alg-ref.c
use constant shifts => [
[[0, 0], [1, 3], [2, 2], [3, 1]],
[[0, 0], [1, 5], [2, 4], [3, 3]],
[[0, 0], [1, 7], [3, 5], [4, 4]]
];
#word8 mul(word8 a, word8 b) {
# /* multiply two elements of GF(2^m)
# * needed for MixColumn and InvMixColumn
# */
# if (a && b) return Alogtable[(Logtable[a] + Logtable[b])%255];
# else return 0;
#}
sub mul($$) {
$_[0] && $_[1] ? Algotable->[(Logtable->[$_[0]] + Logtable->[$_[1]]) % 255] : 0
}
#void KeyAddition(word8 a[4][MAXBC], word8 rk[4][MAXBC], word8 BC) {
# /* Exor corresponding text input and round key input bytes
# */
# int i, j;
#
# for(i = 0; i < 4; i++)
# for(j = 0; j < BC; j++) a[i][j] ^= rk[i][j];
#}
#sub KeyAddition(@) {
# my @a = @_[0..3];
# my $rk = $_[4];
# my $BC = $_[5];
# my $i;
# for $i (0..3) {
# for my $j (0 .. $BC-1) {
# $a[$i][$j] ^= $rk->[$i][$j]
# }
# }
# @_[0..3] = @a; # return by reference
#}
sub KeyAddition {
for my $j (0..($_[5]-1)) {
$_[0][$j] ^= $_[4][0][$j];
$_[1][$j] ^= $_[4][1][$j];
$_[2][$j] ^= $_[4][2][$j];
$_[3][$j] ^= $_[4][3][$j];
}
}
#void ShiftRow(word8 a[4][MAXBC], word8 d, word8 BC) {
# /* Row 0 remains unchanged
# * The other three rows are shifted a variable amount
# */
# word8 tmp[MAXBC];
# int i, j;
#
# for(i = 1; i < 4; i++) {
# for(j = 0; j < BC; j++) tmp[j] = a[i][(j + shifts[SC][i][d]) % BC];
# for(j = 0; j < BC; j++) a[i][j] = tmp[j];
# }
#}
#sub ShiftRow(@) {
# my @a = @_[0..3];
# my ($d,$BC) = @_[4,5];
# my @tmp;
# my $i;
# # define SC ((BC - 4) >> 1)
# my $SC = ($BC-4)>>1;
# for $i (1..3) {
# my $j;
# for $j (0..$BC-1) { $tmp[$j] = $a[$i][($j + shifts->[$SC][$i][$d]) % $BC] }
# for $j (0..$BC-1) { $a[$i][$j] = $tmp[$j] }
# }
# @_[0..3] = @a; # return by reference
#}
sub ShiftRow(@) {
my @tmp;
for my $i (1..3) {
my $j;
for $j (0..$_[5]-1) { $tmp[$j] = $_[$i][($j + shifts->[($_[5]-4)>>1][$i][$_[4]]) % $_[5]] }
for $j (0..$_[5]-1) { $_[$i][$j] = $tmp[$j] }
}
}
#void Substitution(word8 a[4][MAXBC], word8 box[256], word8 BC) {
# /* Replace every byte of the input by the byte at that place
# * in the nonlinear S-box
# */
# int i, j;
#
# for(i = 0; i < 4; i++)
# for(j = 0; j < BC; j++) a[i][j] = box[a[i][j]] ;
#}
sub Substitution (@) {
die "Substitution" unless @_ == 261;
my @a = @_[0..3];
my @box = @_[4..259];
my $BC = $_[260];
my $i;
for $i (0..3) {
my $j;
for $j (0..$BC-1) { $a[$i][$j] = $box[$a[$i][$j]] }
}
@_[0..3] = @a; # return by reference
}
#void MixColumn(word8 a[4][MAXBC], word8 BC) {
# /* Mix the four bytes of every column in a linear way
# */
# word8 b[4][MAXBC];
# int i, j;
#
# for(j = 0; j < BC; j++)
# for(i = 0; i < 4; i++)
# b[i][j] = mul(2,a[i][j])
# ^ mul(3,a[(i + 1) % 4][j])
# ^ a[(i + 2) % 4][j]
# ^ a[(i + 3) % 4][j];
# for(i = 0; i < 4; i++)
# for(j = 0; j < BC; j++) a[i][j] = b[i][j];
#}
sub MixColumn (@) {
my @a = @_[0..3];
my $BC = $_[4];
my @b;
my ($j,$i);
for $j (0..$BC-1) {
for $i (0..3) {
$b[$i][$j] = mul(2,$a[$i][$j])
^ mul(3,$a[($i+1) % 4][$j])
^ $a[($i+2) % 4][$j]
^ $a[($i+3) % 4][$j]
}
}
for $i (0..3) {
for $j (0..$BC-1) {
$a[$i][$j] = $b[$i][$j];
}
}
@_[0..3] = @a; # return by reference
}
#void InvMixColumn(word8 a[4][MAXBC], word8 BC) {
# /* Mix the four bytes of every column in a linear way
# * This is the opposite operation of Mixcolumn
# */
# word8 b[4][MAXBC];
# int i, j;
#
# for(j = 0; j < BC; j++)
# for(i = 0; i < 4; i++)
# b[i][j] = mul(0xe,a[i][j])
# ^ mul(0xb,a[(i + 1) % 4][j])
# ^ mul(0xd,a[(i + 2) % 4][j])
# ^ mul(0x9,a[(i + 3) % 4][j]);
# for(i = 0; i < 4; i++)
# for(j = 0; j < BC; j++) a[i][j] = b[i][j];
#}
sub InvMixColumn (@) {
my @a = @_[0..3];
my $BC = $_[4];
my @b;
my ($i,$j);
for $j (0..$BC-1) {
for $i (0..3) {
$b[$i][$j] = mul(0xe,$a[$i][$j])
^ mul(0xb,$a[($i+1) % 4][$j])
^ mul(0xd,$a[($i+2) % 4][$j])
^ mul(0x9,$a[($i+3) % 4][$j])
}
}
for $i (0..3) {
for $j (0..$BC-1) {
$a[$i][$j] = $b[$i][$j];
}
}
@_[0..3] = @a; # return by reference
}
#int rijndaelKeySched (word8 k[4][MAXKC], int keyBits, int blockBits, word8 W[MAXROUNDS+1][4][MAXBC]) {
# /* Calculate the necessary round keys
# * The number of calculations depends on keyBits and blockBits
# */
# int KC, BC, ROUNDS;
# int i, j, t, rconpointer = 0;
# word8 tk[4][MAXKC];
sub rijndaelKeySched (@) {
my @k = @_[0..3];
my $keyBits = $_[4];
my $blockBits = $_[5];
# my @W = @_[6..$#_]; # the rest
my $W = $_[6];
my @tk;
my $rconpointer = 0;
#
# switch (keyBits) {
# case 128: KC = 4; break;
# case 192: KC = 6; break;
# case 256: KC = 8; break;
# default : return (-1);
# }
#
# switch (blockBits) {
# case 128: BC = 4; break;
# case 192: BC = 6; break;
# case 256: BC = 8; break;
# default : return (-2);
# }
#
# switch (keyBits >= blockBits ? keyBits : blockBits) {
# case 128: ROUNDS = 10; break;
# case 192: ROUNDS = 12; break;
# case 256: ROUNDS = 14; break;
# default : return (-3); /* this cannot happen */
# }
my $KC = $keyBits == 128 ? 4 : $keyBits == 192 ? 6 : $keyBits == 256 ? 8 : return -1;
my $BC = $blockBits == 128 ? 4 : $blockBits == 192 ? 6 : $blockBits == 256 ? 8 : return -2;
my $ROUNDS;
{ my $tmp = $keyBits >= $blockBits ? $keyBits : $blockBits;
$ROUNDS = $tmp == 128 ? 10 : $tmp == 192 ? 12 : $tmp == 256 ? 14 : return -3; # this cannot happen
}
#
#
# for(j = 0; j < KC; j++)
# for(i = 0; i < 4; i++)
# tk[i][j] = k[i][j];
# t = 0;
# /* copy values into round key array */
# for(j = 0; (j < KC) && (t < (ROUNDS+1)*BC); j++, t++)
# for(i = 0; i < 4; i++) W[t / BC][i][t % BC] = tk[i][j];
#
my ($j,$i);
for $j (0..$KC-1) {
for $i (0..3) {
$tk[$i][$j] = $k[$i][$j];
}
}
my $t = 0;
for ($j = 0; ($j <$KC) and ($t < ($ROUNDS+1)*$BC); $j++, $t++) {
for $i (0..3) {
$W->[$t/$BC][$i][$t % $BC] = $tk[$i][$j]
}
}
# while (t < (ROUNDS+1)*BC) { /* while not enough round key material calculated */
# /* calculate new values */
# for(i = 0; i < 4; i++)
# tk[i][0] ^= S[tk[(i+1)%4][KC-1]];
# tk[0][0] ^= rcon[rconpointer++];
#
# if (KC != 8)
# for(j = 1; j < KC; j++)
# for(i = 0; i < 4; i++) tk[i][j] ^= tk[i][j-1];
# else {
# for(j = 1; j < KC/2; j++)
# for(i = 0; i < 4; i++) tk[i][j] ^= tk[i][j-1];
# for(i = 0; i < 4; i++) tk[i][KC/2] ^= S[tk[i][KC/2 - 1]];
# for(j = KC/2 + 1; j < KC; j++)
# for(i = 0; i < 4; i++) tk[i][j] ^= tk[i][j-1];
# }
while ($t < ($ROUNDS+1)*$BC) {
for $i (0..3) {
$tk[$i][0] ^= $S[$tk[($i+1) % 4][$KC-1]];
}
$tk[0][0] ^= $rcon[$rconpointer++];
if ($KC != 8) {
for $j (1..$KC-1) {
for $i (0..3) { $tk[$i][$j] ^= $tk[$i][$j-1] }
}
} else {
for ($j = 1; $j < $KC/2; $j++) {
for $i (0..3) { $tk[$i][$j] ^= $tk[$i][$j-1] }
}
for $i (0..3) { $tk[$i][$KC/2] ^= $S[$tk[$i][$KC/2-1]] }
for ($j = $KC/2+1; $j < $KC; $j++) {
for $i (0..3) { $tk[$i][$j] ^= $tk[$i][$j-1] }
}
}
# /* copy values into round key array */
# for(j = 0; (j < KC) && (t < (ROUNDS+1)*BC); j++, t++)
# for(i = 0; i < 4; i++) W[t / BC][i][t % BC] = tk[i][j];
# }
#
# return 0;
#}
for ($j=0; ($j<$KC) and ($t < ($ROUNDS+1)*$BC); $j++, $t++) {
for $i (0..3) { $W->[$t/$BC][$i][$t % $BC] = $tk[$i][$j] }
}
}
# @_[6..$#_] = @W; # return by reference
$_[6] = $W;
return 0;
}
#int rijndaelEncrypt (word8 a[4][MAXBC], int keyBits, int blockBits, word8 rk[MAXROUNDS+1][4][MAXBC])
#{
# /* Encryption of one block.
# */
# int r, BC, ROUNDS;
sub rijndaelEncrypt (@) {
my @a = @_[0..3];
my $keyBits = $_[4];
my $blockBits = $_[5];
#my @rk = $_[6..$#_]; # rest
my $rk = $_[6];
my $r;
#
# switch (blockBits) {
# case 128: BC = 4; break;
# case 192: BC = 6; break;
# case 256: BC = 8; break;
# default : return (-2);
# }
#
# switch (keyBits >= blockBits ? keyBits : blockBits) {
# case 128: ROUNDS = 10; break;
# case 192: ROUNDS = 12; break;
# case 256: ROUNDS = 14; break;
# default : return (-3); /* this cannot happen */
# }
my $BC = $blockBits == 128 ? 4 : $blockBits == 192 ? 6 : $blockBits == 256 ? 8 : return -2;
my $ROUNDS;
{ my $tmp = $keyBits >= $blockBits ? $keyBits : $blockBits;
$ROUNDS = $tmp == 128 ? 10 : $tmp == 192 ? 12 : $tmp == 256 ? 14 : return -3; # this cannot happen
}
#
# /* begin with a key addition
# */
# KeyAddition(a,rk[0],BC);
KeyAddition(@a,$rk->[0],$BC);
#
# /* ROUNDS-1 ordinary rounds
# */
# for(r = 1; r < ROUNDS; r++) {
# Substitution(a,S,BC);
# ShiftRow(a,0,BC);
# MixColumn(a,BC);
# KeyAddition(a,rk[r],BC);
# }
for $r (1..$ROUNDS-1) {
Substitution(@a,@S,$BC);
ShiftRow(@a,0,$BC);
MixColumn(@a,$BC);
KeyAddition(@a,$rk->[$r],$BC);
}
#
# /* Last round is special: there is no MixColumn
# */
# Substitution(a,S,BC);
# ShiftRow(a,0,BC);
# KeyAddition(a,rk[ROUNDS],BC);
#
# return 0;
#}
Substitution(@a,@S,$BC);
ShiftRow(@a,0,$BC);
KeyAddition(@a,$rk->[$ROUNDS],$BC);
@_[0..3] = @a;
return 0;
}
#int rijndaelEncryptRound (word8 a[4][MAXBC], int keyBits, int blockBits,
# word8 rk[MAXROUNDS+1][4][MAXBC], int rounds)
#/* Encrypt only a certain number of rounds.
# * Only used in the Intermediate Value Known Answer Test.
# */
#{
# int r, BC, ROUNDS;
sub rijndaelEncryptRound (@) {
my $rounds = pop; # last element
my @a = @_[0..3];
my $keyBits = $_[4];
my $blockBits = $_[5];
# my @rk = $_[6..$#_]; # rest
my $rk = $_[6];
my $r;
#
# switch (blockBits) {
# case 128: BC = 4; break;
# case 192: BC = 6; break;
# case 256: BC = 8; break;
# default : return (-2);
# }
#
# switch (keyBits >= blockBits ? keyBits : blockBits) {
# case 128: ROUNDS = 10; break;
# case 192: ROUNDS = 12; break;
# case 256: ROUNDS = 14; break;
# default : return (-3); /* this cannot happen */
# }
my $BC = $blockBits == 128 ? 4 : $blockBits == 192 ? 6 : $blockBits == 256 ? 8 : return -2;
my $ROUNDS;
{ my $tmp = $keyBits >= $blockBits ? $keyBits : $blockBits;
$ROUNDS = $tmp == 128 ? 10 : $tmp == 192 ? 12 : $tmp == 256 ? 14 : return -3; # this cannot happen
}
#
# /* make number of rounds sane */
# if (rounds > ROUNDS) rounds = ROUNDS;
$rounds = $ROUNDS if $rounds > $ROUNDS;
#
# /* begin with a key addition
# */
# KeyAddition(a,rk[0],BC);
KeyAddition(@a,$rk->[0],$BC);
#
# /* at most ROUNDS-1 ordinary rounds
# */
# for(r = 1; (r <= rounds) && (r < ROUNDS); r++) {
# Substitution(a,S,BC);
# ShiftRow(a,0,BC);
# MixColumn(a,BC);
# KeyAddition(a,rk[r],BC);
# }
for ($r = 1; $r <= $rounds and $r < $ROUNDS; $r++) {
Substitution(@a,@S,$BC);
ShiftRow(@a,0,$BC);
MixColumn(@a,$BC);
KeyAddition(@a,$rk->[$r],$BC);
}
#
# /* if necessary, do the last, special, round:
# */
# if (rounds == ROUNDS) {
# Substitution(a,S,BC);
# ShiftRow(a,0,BC);
# KeyAddition(a,rk[ROUNDS],BC);
# }
if ($rounds == $ROUNDS) {
Substitution(@a,@S,$BC);
ShiftRow(@a,0,$BC);
KeyAddition(@a,$rk->[$ROUNDS],$BC);
}
#
# return 0;
@_[0..3] = @a;
return 0;
#}
}
#int rijndaelDecrypt (word8 a[4][MAXBC], int keyBits, int blockBits, word8 rk[MAXROUNDS+1][4][MAXBC])
#{
# int r, BC, ROUNDS;
sub rijndaelDecrypt (@) {
my @a = @_[0..3];
my $keyBits = $_[4];
my $blockBits = $_[5];
my $rk = $_[6];
my $r;
#
# switch (blockBits) {
# case 128: BC = 4; break;
# case 192: BC = 6; break;
# case 256: BC = 8; break;
# default : return (-2);
# }
#
# switch (keyBits >= blockBits ? keyBits : blockBits) {
# case 128: ROUNDS = 10; break;
# case 192: ROUNDS = 12; break;
# case 256: ROUNDS = 14; break;
# default : return (-3); /* this cannot happen */
# }
my $BC = $blockBits == 128 ? 4 : $blockBits == 192 ? 6 : $blockBits == 256 ? 8 : return -2;
my $ROUNDS;
{
my $tmp = $keyBits >= $blockBits ? $keyBits : $blockBits;
$ROUNDS = $tmp == 128 ? 10 : $tmp == 192 ? 12 : $tmp == 256 ? 14 : return -3; # this cannot happen
}
#
# /* To decrypt: apply the inverse operations of the encrypt routine,
# * in opposite order
# *
# * (KeyAddition is an involution: it 's equal to its inverse)
# * (the inverse of Substitution with table S is Substitution with the inverse table of S)
# * (the inverse of Shiftrow is Shiftrow over a suitable distance)
# */
#
# /* First the special round:
# * without InvMixColumn
# * with extra KeyAddition
# */
# KeyAddition(a,rk[ROUNDS],BC);
# Substitution(a,Si,BC);
# ShiftRow(a,1,BC);
KeyAddition(@a,$rk->[$ROUNDS],$BC);
Substitution(@a,@Si,$BC);
ShiftRow(@a,1,$BC);
#
# /* ROUNDS-1 ordinary rounds
# */
# for(r = ROUNDS-1; r > 0; r--) {
# KeyAddition(a,rk[r],BC);
# InvMixColumn(a,BC);
# Substitution(a,Si,BC);
# ShiftRow(a,1,BC);
# }
for ($r = $ROUNDS-1; $r > 0; $r--) {
KeyAddition(@a,$rk->[$r],$BC);
InvMixColumn(@a,$BC);
Substitution(@a,@Si,$BC);
ShiftRow(@a,1,$BC);
}
#
# /* End with the extra key addition
# */
#
# KeyAddition(a,rk[0],BC);
KeyAddition(@a,$rk->[0],$BC);
#
# return 0;
#}
@_[0..3] = @a;
return 0;
}
#int rijndaelDecryptRound (word8 a[4][MAXBC], int keyBits, int blockBits,
# word8 rk[MAXROUNDS+1][4][MAXBC], int rounds)
#/* Decrypt only a certain number of rounds.
# * Only used in the Intermediate Value Known Answer Test.
# * Operations rearranged such that the intermediate values
# * of decryption correspond with the intermediate values
# * of encryption.
# */
#{
# int r, BC, ROUNDS;
sub rijndaelDecryptRound (@) {
my @a = @_[0..3];
my $keyBits = $_[4];
my $blockBits = $_[5];
my $rk = $_[6];
my $rounds = $_[7];
my $r;
#
# switch (blockBits) {
# case 128: BC = 4; break;
# case 192: BC = 6; break;
# case 256: BC = 8; break;
# default : return (-2);
# }
#
# switch (keyBits >= blockBits ? keyBits : blockBits) {
# case 128: ROUNDS = 10; break;
# case 192: ROUNDS = 12; break;
# case 256: ROUNDS = 14; break;
# default : return (-3); /* this cannot happen */
# }
#
my $BC = $blockBits == 128 ? 4 : $blockBits == 192 ? 6 : $blockBits == 256 ? 8 : return -2;
my $ROUNDS;
{
my $tmp = $keyBits >= $blockBits ? $keyBits : $blockBits;
$ROUNDS = $tmp == 128 ? 10 : $tmp == 192 ? 12 : $tmp == 256 ? 14 : return -3; # this cannot happen
}
#
# /* make number of rounds sane */
# if (rounds > ROUNDS) rounds = ROUNDS;
$rounds = $ROUNDS if $rounds > $ROUNDS;
#
# /* First the special round:
# * without InvMixColumn
# * with extra KeyAddition
# */
# KeyAddition(a,rk[ROUNDS],BC);
# Substitution(a,Si,BC);
# ShiftRow(a,1,BC);
KeyAddition(@a,$rk->[$ROUNDS],$BC);
Substitution(@a,@Si,$BC);
ShiftRow(@a,1,$BC);
#
# /* ROUNDS-1 ordinary rounds
# */
# for(r = ROUNDS-1; r > rounds; r--) {
# KeyAddition(a,rk[r],BC);
# InvMixColumn(a,BC);
# Substitution(a,Si,BC);
# ShiftRow(a,1,BC);
# }
for ($r = $ROUNDS-1; $r > $rounds; $r--) {
KeyAddition(@a,$rk->[$r],$BC);
InvMixColumn(@a,$BC);
Substitution(@a,@Si,$BC);
ShiftRow(@a,1,$BC);
}
#
# if (rounds == 0) {
# /* End with the extra key addition
# */
# KeyAddition(a,rk[0],BC);
# }
if ($rounds == 0) {
KeyAddition(@a,$rk->[0],$BC);
}
#
# return 0;
#}
@_[0..3] = @a;
return 0
}
##################################
# api-ref.c
# define DIR_ENCRYPT 0 /* Are we encrpyting? */
sub DIR_ENCRYPT() { 0 }
# define DIR_DECRYPT 1 /* Are we decrpyting? */
sub DIR_DECRYPT() { 1 }
# define MODE_ECB 1 /* Are we ciphering in ECB mode? */
sub MODE_ECB() { 1 }
# define MODE_CBC 2 /* Are we ciphering in CBC mode? */
sub MODE_CBC() { 2 }
# define MODE_CFB1 3 /* Are we ciphering in 1-bit CFB mode? */
sub MODE_CFB1() { 3 }
# define TRUE 1
sub TRUE() { 1 }
# define FALSE 0
sub FALSE() { 0 }
# define BITSPERBLOCK 128 /* Default number of bits in a cipher block */
sub BITSPERBLOCK() { 128 }
# /* Error Codes - CHANGE POSSIBLE: inclusion of additional error codes */
#define BAD_KEY_DIR -1 /* Key direction is invalid, e.g., unknown value */
#define BAD_KEY_MAT -2 /* Key material not of correct length */
#define BAD_KEY_INSTANCE -3 /* Key passed is not valid */
#define BAD_CIPHER_MODE -4 /* Params struct passed to cipherInit invalid */
#define BAD_CIPHER_STATE -5 /* Cipher in wrong state (e.g., not initialized) */
#define BAD_CIPHER_INSTANCE -7
# /* CHANGE POSSIBLE: inclusion of algorithm specific defines */
#define MAX_KEY_SIZE 64 /* # of ASCII char's needed to represent a key */
sub MAX_KEY_SIZE() { 64 }
#define MAX_IV_SIZE BITSPERBLOCK/8 /* # bytes needed to represent an IV */
sub MAX_IV_SIZE() { BITSPERBLOCK/8 }
#int makeKey(keyInstance *key, BYTE direction, int keyLen, char *keyMaterial)
#{
# word8 k[4][MAXKC];
# int i, j, t;
sub makeKey($$$$) {
my ($key, $direction, $keyLen, $keyMaterial) = @_;
#$keyLen = length $keyMaterial; # hey, it's perl :-)
my @k;
#
# if (key == NULL) {
# return BAD_KEY_INSTANCE;
# }
unless ( defined $key and ref $key eq 'HASH') {
die "BAD_KEY_INSTANCE";
}
#
# if ((direction == DIR_ENCRYPT) || (direction == DIR_DECRYPT)) {
# key->direction = direction;
# } else {
# return BAD_KEY_DIR;
# }
if ($direction == DIR_ENCRYPT or $direction == DIR_DECRYPT) {
$key->{direction} = $direction
} else {
die "BAD_KEY_DIR";
}
#
# if ((keyLen == 128) || (keyLen == 192) || (keyLen == 256)) {
# key->keyLen = keyLen;
# } else {
# return BAD_KEY_MAT;
# }
if ($keyLen == 128 or $keyLen == 192 or $keyLen == 256) {
$key->{keyLen} = $keyLen
} else {
die "BAD_KEY_MAT";
}
#
# if ( keyMaterial ) {
# strncpy(key->keyMaterial, keyMaterial, keyLen/4);
# }
if (defined $keyMaterial) {
$key->{keyMaterial} = substr ($keyMaterial,0,$keyLen/4)
}
#
# /* initialize key schedule: */
# for(i = 0; i < key->keyLen/8; i++) {
# t = key->keyMaterial[2*i];
# if ((t >= '0') && (t <= '9')) j = (t - '0') << 4;
# else if ((t >= 'a') && (t <= 'f')) j = (t - 'a' + 10) << 4;
# else if ((t >= 'A') && (t <= 'F')) j = (t - 'A' + 10) << 4;
# else return BAD_KEY_MAT;
#
# t = key->keyMaterial[2*i+1];
# if ((t >= '0') && (t <= '9')) j ^= (t - '0');
# else if ((t >= 'a') && (t <= 'f')) j ^= (t - 'a' + 10);
# else if ((t >= 'A') && (t <= 'F')) j ^= (t - 'A' + 10);
# else return BAD_KEY_MAT;
#
# k[i % 4][i / 4] = (word8) j;
# }
my $i;
my @keyMaterial = unpack 'A2'x(length($key->{keyMaterial})/2), $key->{keyMaterial};
for $i (0..$keyLen/8-1) {
$k[$i % 4][$i / 4] = hex $keyMaterial[$i];
}
#
# rijndaelKeySched (k, key->keyLen, key->blockLen, key->keySched);
#my @W;
#rijndaelKeySched(@k, $key->{keyLen}, $key->{blockLen}, @W);
rijndaelKeySched(@k, $key->{keyLen}, $key->{blockLen}, $key->{keySched});
# $key->{keySched} = \@W;
#
# return TRUE;
#}
$_[0] = $key;
return TRUE;
}
#int cipherInit(cipherInstance *cipher, BYTE mode, char *IV)
#{
# int i, j, t;
sub cipherInit($$;$) {
my ($cipher, $mode, $IV) = @_;
my $i;
#
# if ((mode == MODE_ECB) || (mode == MODE_CBC) || (mode == MODE_CFB1)) {
# cipher->mode = mode;
# } else {
# return BAD_CIPHER_MODE;
# }
if ($mode == MODE_ECB or $mode == MODE_CBC or $mode == MODE_CFB1) {
$cipher->{mode} = $mode
} else {
die "BAD_CIPHER_MODE";
}
#
# if (IV != NULL) {
# for(i = 0; i < cipher->blockLen/8; i++) {
# t = IV[2*i];
# if ((t >= '0') && (t <= '9')) j = (t - '0') << 4;
# else if ((t >= 'a') && (t <= 'f')) j = (t - 'a' + 10) << 4;
# else if ((t >= 'A') && (t <= 'F')) j = (t - 'A' + 10) << 4;
# else return BAD_CIPHER_INSTANCE;
#
# t = IV[2*i+1];
# if ((t >= '0') && (t <= '9')) j ^= (t - '0');
# else if ((t >= 'a') && (t <= 'f')) j ^= (t - 'a' + 10);
# else if ((t >= 'A') && (t <= 'F')) j ^= (t - 'A' + 10);
# else return BAD_CIPHER_INSTANCE;
#
# cipher->IV[i] = (BYTE) j;
# }
# }
if (defined $IV) {
# my @block = unpack 'C'x(length $IV), $IV;
# for $i (0..$cipher->{blockLen}/8-1) {
# $cipher->{IV}[$i] = $block[$i];
# }
$cipher->{IV} = [ unpack 'C'x(length $IV), $IV ]
}
#
# return TRUE;
#}
$_[0] = $cipher;
return TRUE;
}
#int blockEncrypt(cipherInstance *cipher,
# keyInstance *key, BYTE *input, int inputLen, BYTE *outBuffer)
#{
# int i, j, t, numBlocks;
# word8 block[4][MAXBC];
sub blockEncrypt($$$$$) {
my ($cipher, $key, $input, $inputLen, $outBuffer) = @_;
my ($i,$j,$t,$numBlocks,@block);
#
#
# /* check parameter consistency: */
# if (key == NULL ||
# key->direction != DIR_ENCRYPT ||
# (key->keyLen != 128 && key->keyLen != 192 && key->keyLen != 256)) {
# return BAD_KEY_MAT;
# }
if (not defined $key or $key->{direction} != DIR_ENCRYPT or
($key->{keyLen} != 128 and $key->{keyLen} != 192 and $key->{keyLen} != 256)) {
die "BAD_KEY_MAT"
}
# if (cipher == NULL ||
# (cipher->mode != MODE_ECB && cipher->mode != MODE_CBC && cipher->mode != MODE_CFB1) ||
# (cipher->blockLen != 128 && cipher->blockLen != 192 && cipher->blockLen != 256)) {
# return BAD_CIPHER_STATE;
# }
if (not defined $cipher or ($cipher->{mode} != MODE_ECB and $cipher->{mode} != MODE_CBC and $cipher->{mode} != MODE_CFB1) or
($cipher->{blockLen} != 128 and $cipher->{blockLen} != 192 and $cipher->{blockLen} != 256)) {
die "BAD_CIPHER_STATE";
}
#
#
# numBlocks = inputLen/cipher->blockLen;
$numBlocks = $inputLen/$cipher->{blockLen};
#
# switch (cipher->mode) {
# case MODE_ECB:
# for (i = 0; i < numBlocks; i++) {
# for (j = 0; j < cipher->blockLen/32; j++) {
# for(t = 0; t < 4; t++)
# /* parse input stream into rectangular array */
# block[t][j] = input[4*j+t] & 0xFF;
# }
# rijndaelEncrypt (block, key->keyLen, cipher->blockLen, key->keySched);
# for (j = 0; j < cipher->blockLen/32; j++) {
# /* parse rectangular array into output ciphertext bytes */
# for(t = 0; t < 4; t++)
# outBuffer[4*j+t] = (BYTE) block[t][j];
# }
# }
# break;
if ($cipher->{mode} == MODE_ECB) {
for $i (0..$numBlocks-1) {
for $j (0..$cipher->{blockLen}/32-1) {
for $t (0..3) {
$block[$t][$j] = $input->[4*$j+$t] & 0xFF;
}
}
rijndaelEncrypt(@block, $key->{keyLen}, $cipher->{blockLen}, $key->{keySched});
for $j (0..$cipher->{blockLen}/32-1) {
for $t (0..3) {
$outBuffer->[4*$j+$t] = $block[$t][$j];
}
}
}
}
#
# case MODE_CBC:
# for (j = 0; j < cipher->blockLen/32; j++) {
# for(t = 0; t < 4; t++)
# /* parse initial value into rectangular array */
# block[t][j] = cipher->IV[t+4*j] & 0xFF;
# }
# for (i = 0; i < numBlocks; i++) {
# for (j = 0; j < cipher->blockLen/32; j++) {
# for(t = 0; t < 4; t++)
# /* parse input stream into rectangular array and exor with
# IV or the previous ciphertext */
# block[t][j] ^= input[4*j+t] & 0xFF;
# }
# rijndaelEncrypt (block, key->keyLen, cipher->blockLen, key->keySched);
# for (j = 0; j < cipher->blockLen/32; j++) {
# /* parse rectangular array into output ciphertext bytes */
# for(t = 0; t < 4; t++)
# outBuffer[4*j+t] = (BYTE) block[t][j];
# }
# }
# break;
elsif ($cipher->{mode} == MODE_CBC) {
for $j (0..$cipher->{blockLen}/32-1) {
for $t (0..3) {
$block[$t][$j] = $cipher->{IV}[$t+4*$j] & 0xFF
}
}
for $i (0..$numBlocks-1) {
for $j (0..$cipher->{blockLen}/32-1) {
for $t (0..3) {
$block[$t][$j] ^= $input->[4*$j+$t] & 0xFF;
}
}
rijndaelEncrypt(@block,$key->{keyLen},$cipher->{blockLen}, $key->{keySched});
for $j (0..$cipher->{blockLen}/32-1) {
for $t (0..3) {
$outBuffer->[4*$j+$t] = $block[$t][$j];
}
}
}
}
#
# default: return BAD_CIPHER_STATE;
# }
else { die "BAD_CIPHER_STATE" }
#
# return numBlocks*cipher->blockLen;
#}
# @_ = ($cipher, $key, $input, $inputLen, $outBuffer);
$_[4] = $outBuffer;
return $numBlocks * $cipher->{blockLen};
}
#int blockDecrypt(cipherInstance *cipher,
# keyInstance *key, BYTE *input, int inputLen, BYTE *outBuffer)
#{
# int i, j, t, numBlocks;
# word8 block[4][MAXBC];
sub blockDecrypt($$$$$) {
my ($cipher, $key, $input, $inputLen, $outBuffer) = @_;
my ($i,$j,$t,$numBlocks,@block);
#
# if (cipher == NULL ||
# key == NULL ||
# key->direction == DIR_ENCRYPT ||
# cipher->blockLen != key->blockLen) {
# return BAD_CIPHER_STATE;
# }
if (not defined $cipher or not defined $key or $key->{direction} == DIR_ENCRYPT or $cipher->{blockLen} != $key->{blockLen}) {
die "BAD_CIPHER_STATE";
}
#
# /* check parameter consistency: */
# if (key == NULL ||
# key->direction != DIR_DECRYPT ||
# (key->keyLen != 128 && key->keyLen != 192 && key->keyLen != 256)) {
# return BAD_KEY_MAT;
# }
if (not defined $key or $key->{direction} != DIR_DECRYPT or
($key->{keyLen} != 128 and $key->{keyLen} != 192 and $key->{keyLen} != 256)) {
die "BAD_KEY_MAT";
}
# if (cipher == NULL ||
# (cipher->mode != MODE_ECB && cipher->mode != MODE_CBC && cipher->mode != MODE_CFB1) ||
# (cipher->blockLen != 128 && cipher->blockLen != 192 && cipher->blockLen != 256)) {
# return BAD_CIPHER_STATE;
# }
if (not defined $cipher or ($cipher->{mode} != MODE_ECB and $cipher->{mode} != MODE_CBC and $cipher->{mode} != MODE_CFB1) or
($cipher->{blockLen} != 128 and $cipher->{blockLen} != 192 and $cipher->{blockLen} != 256)) {
die "BAD_CIPHER_STATE";
}
#
#
# numBlocks = inputLen/cipher->blockLen;
$numBlocks = $inputLen / $cipher->{blockLen};
#
# switch (cipher->mode) {
# case MODE_ECB:
# for (i = 0; i < numBlocks; i++) {
# for (j = 0; j < cipher->blockLen/32; j++) {
# for(t = 0; t < 4; t++)
# /* parse input stream into rectangular array */
# block[t][j] = input[4*j+t] & 0xFF;
# }
# rijndaelDecrypt (block, key->keyLen, cipher->blockLen, key->keySched);
# for (j = 0; j < cipher->blockLen/32; j++) {
# /* parse rectangular array into output ciphertext bytes */
# for(t = 0; t < 4; t++)
# outBuffer[4*j+t] = (BYTE) block[t][j];
# }
# }
# break;
if ($cipher->{mode} == MODE_ECB) {
for $i (0..$numBlocks-1) {
for $j (0..$cipher->{blockLen}/32-1) {
for $t (0..3) {
$block[$t][$j] = $input->[4*$j+$t] & 0xFF;
}
}
rijndaelDecrypt(@block, $key->{keyLen}, $cipher->{blockLen}, $key->{keySched});
for $j (0..$cipher->{blockLen}/32-1) {
for $t (0..3) {
$outBuffer->[4*$j+$t] = $block[$t][$j];
}
}
}
}
#
# case MODE_CBC:
# /* first block */
# for (j = 0; j < cipher->blockLen/32; j++) {
# for(t = 0; t < 4; t++)
# /* parse input stream into rectangular array */
# block[t][j] = input[4*j+t] & 0xFF;
# }
elsif ($cipher->{mode} == MODE_CBC) {
for $j (0..$cipher->{blockLen}/32-1) {
for $t (0..3) {
$block[$t][$j] = $input->[$t+4*$j] & 0xFF
}
}
# rijndaelDecrypt (block, key->keyLen, cipher->blockLen, key->keySched);
rijndaelDecrypt(@block, $key->{keyLen}, $cipher->{blockLen}, $key->{keySched});
#
# for (j = 0; j < cipher->blockLen/32; j++) {
# /* exor the IV and parse rectangular array into output ciphertext bytes */
# for(t = 0; t < 4; t++)
# outBuffer[4*j+t] = (BYTE) (block[t][j] ^ cipher->IV[t+4*j]);
# }
for $j (0.. $cipher->{blockLen}/32-1) {
for $t (0..3) {
$outBuffer->[4*$j+$t] = $block[$t][$j] ^ $cipher->{IV}[$t+4*$j]
}
}
#
# /* next blocks */
# for (i = 1; i < numBlocks; i++) {
# for (j = 0; j < cipher->blockLen/32; j++) {
# for(t = 0; t < 4; t++)
# /* parse input stream into rectangular array */
# block[t][j] = input[cipher->blockLen/8+4*j+t] & 0xFF;
# }
# rijndaelDecrypt (block, key->keyLen, cipher->blockLen, key->keySched);
#
# for (j = 0; j < cipher->blockLen/32; j++) {
# /* exor previous ciphertext block and parse rectangular array
# into output ciphertext bytes */
# for(t = 0; t < 4; t++)
# outBuffer[cipher->blockLen/8+4*j+t] = (BYTE) (block[t][j] ^
# input[4*j+t-4*cipher->blockLen/32]);
# }
# }
# break;
for $i (1..$numBlocks-1) {
for $j (0..$cipher->{blockLen}/32-1) {
for $t (0..3) {
$block[$t][$j] ^= $input->[$cipher->{blockLen}/8+4*$j+$t] & 0xFF;
}
}
rijndaelDecrypt(@block,$key->{keyLen},$cipher->{blockLen}, $key->{keySched});
for $j (0..$cipher->{blockLen}/32-1) {
for $t (0..3) {
$outBuffer->[$cipher->{blockLen}/8+4*$j+$t] =
$block[$t][$j] ^ $input->[4*$j+$t-4*$cipher->{blockLen}/32];
}
}
}
}
#
# default: return BAD_CIPHER_STATE;
else { die "BAD_CIPHER_STATE" }
# }
#
# return numBlocks*cipher->blockLen;
#}
$_[4] = $outBuffer;
return $numBlocks * $cipher->{blockLen};
}
#/**
# * cipherUpdateRounds:
# *
# * Encrypts/Decrypts exactly one full block a specified number of rounds.
# * Only used in the Intermediate Value Known Answer Test.
# *
# * Returns:
# * TRUE - on success
# * BAD_CIPHER_STATE - cipher in bad state (e.g., not initialized)
# */
#int cipherUpdateRounds(cipherInstance *cipher,
# keyInstance *key, BYTE *input, int inputLen, BYTE *outBuffer, int rounds)
#{
sub cipherUpdateRounds($$$$$$) {
my ($cipher, $key, $input, $inputLen, $outBuffer, $rounds) = @_;
# int j, t;
# word8 block[4][MAXBC];
my ($j,$t,@block);
#
# if (cipher == NULL ||
# key == NULL ||
# cipher->blockLen != key->blockLen) {
# return BAD_CIPHER_STATE;
# }
if (not defined $cipher or not defined $key or $key->{direction} == DIR_ENCRYPT or $cipher->{blockLen} != $key->{blockLen}) {
die "BAD_CIPHER_STATE";
}
#
# for (j = 0; j < cipher->blockLen/32; j++) {
# for(t = 0; t < 4; t++)
# /* parse input stream into rectangular array */
# block[t][j] = input[4*j+t] & 0xFF;
# }
for $j (0..$cipher->{blockLen}/32-1) {
for $t (0..3) {
$block[$t][$j] = $input->[4*$j+$t] & 0xFF
}
}
# switch (key->direction) {
# case DIR_ENCRYPT:
# rijndaelEncryptRound (block, key->keyLen, cipher->blockLen,
# key->keySched, rounds);
# break;
if ($key->{direction} == DIR_ENCRYPT) {
rijndaelEncryptRound(@block, $key->{keyLen}, $cipher->{blockLen}, $key->{keySched}, $rounds);
}
#
# case DIR_DECRYPT:
# rijndaelDecryptRound (block, key->keyLen, cipher->blockLen,
# key->keySched, rounds);
# break;
elsif ($key->{direction} == DIR_DECRYPT) {
rijndaelDecryptRound(@block, $key->{keyLen}, $cipher->{blockLen}, $key->{keySched}, $rounds);
}
#
# default: return BAD_KEY_DIR;
# }
else {
die "BAD_KEY_DIR"
}
# for (j = 0; j < cipher->blockLen/32; j++) {
# /* parse rectangular array into output ciphertext bytes */
# for(t = 0; t < 4; t++)
# outBuffer[4*j+t] = (BYTE) block[t][j];
# }
for $j (0..$cipher->{blockLen}/32-1) {
for $t (0..3) {
$outBuffer->[4*$j+$t] = $block[$t][$j];
}
}
#
# return TRUE;
return TRUE;
#}
#
}
#####################################################################################
# my code
#####################################################################################
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
# objektinterface
#
use vars qw'$DEFAULT_BLOCKSIZE $DEFAULT_KEYSIZE';
# sub DEFAULT_BLOCKSIZE() { 128 }
# sub DEFAULT_KEYSIZE() { 256 }
$DEFAULT_BLOCKSIZE = 128;
$DEFAULT_KEYSIZE = 256;
sub new {
my ($class,$key,$mode) = @_;
my $blocksize = $DEFAULT_BLOCKSIZE;
my $keysize = $DEFAULT_KEYSIZE;
my $ENkeyInst = { blockLen => $blocksize };
my $DEkeyInst = { blockLen => $blocksize };
$mode = MODE_ECB unless defined $mode;
# compatibility mode for Crypt::Rijndael
$key = join '', unpack 'H*', $key;
if (length($key) * 4 != $keysize) {
warn __PACKAGE__, ": set keysize to ", length($key)*4, ".\n";
$keysize = length($key) * 4;
}
eval { makeKey($ENkeyInst, DIR_ENCRYPT, $keysize, $key) };
die $@ if $@;
eval { makeKey($DEkeyInst, DIR_DECRYPT, $keysize, $key) };
die $@ if $@;
my $cipherInst = { blockLen => $blocksize };
my $IV = "\0" x ($blocksize/8);
eval { cipherInit($cipherInst, $mode, $IV) };
die $@ if $@;
my $self = {
cipherInst => $cipherInst,
ENkeyInst => $ENkeyInst,
DEkeyInst => $DEkeyInst,
IV => $IV,
keysize => $keysize,
blocksize => $blocksize
};
bless $self, ref($class) || $class;
}
sub encrypt {
my ($self,$data) = @_;
my $out;
for (my $i=0; $i < length($data) / ($self->{blocksize}/8); $i++) {
my $tmp = [];
my @block = unpack 'C'x($self->{blocksize}/8),
substr($data,$i*$self->{blocksize}/8,$self->{blocksize}/8);
eval {
my $res = blockEncrypt($self->{cipherInst}, $self->{ENkeyInst}, \@block, $self->{blocksize}, $tmp);
};
die $@ if $@;
$out .= pack 'C'x($self->{blocksize}/8), @$tmp;
}
return unless defined $out;
$out;
}
sub decrypt {
my ($self,$data) = @_;
my $out;
for (my $i=0; $i < length($data) / ($self->{blocksize}/8); $i++) {
my $tmp = [];
my @block = unpack 'C'x($self->{blocksize}/8),
substr($data,$i*$self->{blocksize}/8,$self->{blocksize}/8);
eval {
my $res = blockDecrypt($self->{cipherInst}, $self->{DEkeyInst}, \@block, $self->{blocksize}, $tmp);
};
die $@ if $@;
$out .= pack 'C'x($self->{blocksize}/8), @$tmp;
}
return unless defined $out;
$out;
}
sub rijndael_encrypt($$$;$$) {
my ($key, $mode, $data, $keysize, $blocksize) = @_;
$keysize = 128 unless defined $keysize;
$blocksize = 128 unless defined $blocksize;
my $keyInst = { blockLen => $blocksize };
if (length $key < $keysize/4) {
$key .= "0" x ($keysize/4 - length $key);
warn "rijndael_encrypt: padded key to keysize ($keysize)\n";
} elsif (length $key > $keysize/4) {
$key = substr $key, 0, $keysize/4;
warn "rijndael_encrypt: truncated key to keysize ($keysize)\n";
}
if (length($data) % ($blocksize/8)) {
$data .= "0" x ($blocksize/8 - (length($data) % ($blocksize/8)));
warn "rijndael_encrypt: padded data to multiple of blocksize ($blocksize)\n";
}
my $res;
eval { makeKey($keyInst, DIR_ENCRYPT, $keysize, $key) };
die $@ if $@;
my $cipherInst = { blockLen => $blocksize };
my $IV = "\0" x ($blocksize/8);
eval { cipherInit($cipherInst, $mode, $IV) };
die $@ if $@;
my $out;
my $i;
for ($i=0; $i < length($data) / ($blocksize/8); $i++) {
my $tmp = [];
my @block = unpack 'C'x($blocksize/8), substr($data,$i*$blocksize/8,$blocksize/8);
eval {
my $res = blockEncrypt($cipherInst, $keyInst, \@block, $blocksize, $tmp);
};
die $@ if $@;
$out .= pack 'C'x($blocksize/8), @$tmp;
}
return unless defined $out;
$out;
}
sub rijndael_decrypt($$$;$$) {
my ($key, $mode, $data, $keysize, $blocksize) = @_;
$keysize = 128 unless defined $keysize;
$blocksize = 128 unless defined $blocksize;
my $keyInst = { blockLen => $blocksize };
if (length $key < ($keysize/4)) {
$key .= "0" x ($keysize/4 - length $key);
warn "rijndael_decrypt: padded key to keysize ($keysize)\n";
} elsif (length $key > $keysize/4) {
$key = substr $key, 0, $keysize/4;
warn "rijndael_decrypt: truncate key to keysize ($keysize)\n";
}
my $res;
eval { makeKey($keyInst, DIR_DECRYPT, $keysize, $key) };
die $@ if $@;
my $cipherInst = { blockLen => $blocksize };
my $IV = "\0" x ($blocksize/8);
eval { cipherInit($cipherInst, $mode, $IV) };
die $@ if $@;
my $out;
my $i;
for ($i=0; $i < length($data) / ($blocksize/8); $i++) {
my $tmp = [];
my @block = unpack 'C'x($blocksize/8), substr($data,$i*$blocksize/8,$blocksize/8);
eval {
blockDecrypt($cipherInst, $keyInst, \@block, $blocksize, $tmp)
};
die $@ if $@;
$out .= pack 'C'x($blocksize/8), @$tmp;
}
return unless defined $out;
$out;
}
####################################################
#
# Interface for Crypt::CBC
#
####################################################
# return keysize in bytes
sub keysize {
my $self = shift;
if (defined $self and ref $self and defined $self->{keysize}) {
return $self->{keysize}/8
}
return $DEFAULT_KEYSIZE/8
}
# return blocksize in bytes
sub blocksize {
my $self = shift;
if (defined $self and ref $self and defined $self->{blocksize}) {
return $self->{blocksize}/8
}
return $DEFAULT_BLOCKSIZE/8
}
1; # make require happy :-)
__END__
=head1 NAME
Crypt::Rijndael_PP - Perl implementation of Rijndael
=head1 DISCLAIMER
This is a pure perl implementation of the new AES Rijndael.
You want to use C<Crypt::Rijndael> where available. This implementation
is really slow, but I am working on it.
=head1 SYNOPSIS
# Functional style
use Crypt::Rijndael_PP ':all';
$key = '1234567890ABCDEF' x 4; # 256bit hex number
# keysize = 256bit, blocksize = 128bit
$c_txt = rijndael_encrypt($key, MODE_CBC, $data, 256, 128);
$p_txt = rijndael_decrypt($key, MODE_CBC, $c_txt, 256, 128);
# OO style
# same interface as Crypt::Rijndael
use Crypt::Rijndael_PP;
$cipher = Crypt::Rijndael_PP->new( pack('H*', $key), MODE_CBC );
$c_txt = $cipher->encrypt($data);
$p_txt = $cipher->decrypt($c_txt);
=head1 DESCRIPTION
This modules shares the OO style interface with C<Crypt::Rijndael>
from Rafael R. Sevilla.
=over 4
=item
Supported modes: Electronic CodeBook (MODE_ECB) and Cipher Block Chaining
(MODE_CBC). Please use C<Crypt::CBC> for CBC-Mode, as my CBC is not compatible
with neither C<Crypt::CBC> nor C<Crypt::Rijndael> and it is subject to change
in the near future. When using C<Crypt::CBC> this module is 100% compatible to
C<Crypt::Rijndael> and you can decrypt and encrypt your data with both modules!
=item
Supported keysizes: 128, 192 and 256 (default)
=item
Supported blocksizes: 128 (default), 192 and 256
=back
If the size of the key does not match the given
keysize then the key is padded with "0" (hex) or
truncated to the right size.
The last data block is padded with "\0" if it does not match
a multiple of the blocksize.
Warnings a raised in both cases.
=head1 EXAMPLES
Using C<Crypt::CBC>
use Crypt::CBC;
my $key = 'my secret key';
my $input = 'The answer is 42.';
my $cipher = new Crypt::CBC($key,'Rijndael_PP');
my $ciphertext = $cipher->encrypt($input);
my $plaintext = $cipher->decrypt($ciphertext);
# - or -
#!/usr/local/bin/perl -w
#
# Usage: r.pl e "my secret key" < in > out
#
use strict;
use Crypt::CBC;
die "Usage: $0 mode([ed]) key\n" unless @ARGV == 2;
my $cipher = new Crypt::CBC($ARGV[1],'Rijndael_PP');
$cipher->start($ARGV[0]);
my $buffer;
while( read(STDIN, $buffer, 1024) ) {
print $cipher->crypt($buffer);
}
print $cipher->finish;
=head1 LIMITATIONS
This implementation is really slow. I'm trying to tweak the
performance in coming releases.
CBC-Mode is not yet compatible to C<Crypt::Rijndael>. But you are
advised to use C<Crypt::CBC> for this mode anyway.
=head1 SEE ALSO
L<Crypt::Rijndael>
L<Crypt::CBC>
L<http://csrc.nist.gov/encryption/aes/>
=head1 COPYRIGHT
This library is free software; you can redistribute it and/or
modify it under the same terms as Perl itself.
Copyright 2001 Christian Lackas
Copyright 2000 Vincent Rijmen and Joan Daemen
=head1 AUTHORS
The original algorithm was developed by Vincent Rijmen and Joan Daemen.
This release was made by Christian Lackas <delta@lackas.net>.
http://www.lackas.net/. It is based on the reference implementation
for the AES contest. At present I am working on a faster version.
=cut