1ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Copyright 2014 PDFium Authors. All rights reserved.
2ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Use of this source code is governed by a BSD-style license that can be
3ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// found in the LICENSE file.
4ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
5ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
7ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "../../../include/fxcrt/fx_basic.h"
8ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "../../../include/fdrm/fx_crypt.h"
9ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifdef __cplusplus
10ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovextern "C" {
11ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif
12ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define MAX_NR 14
13ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define MAX_NK 8
14ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define MAX_NB 8
15ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define mulby2(x) ( ((x&0x7F) << 1) ^ (x & 0x80 ? 0x1B : 0) )
16ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define GET_32BIT_MSB_FIRST(cp) \
17ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    (((unsigned long)(unsigned char)(cp)[3]) | \
18ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov     ((unsigned long)(unsigned char)(cp)[2] << 8) | \
19ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov     ((unsigned long)(unsigned char)(cp)[1] << 16) | \
20ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov     ((unsigned long)(unsigned char)(cp)[0] << 24))
21ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define PUT_32BIT_MSB_FIRST(cp, value) do { \
22ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        (cp)[3] = (value); \
23ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        (cp)[2] = (value) >> 8; \
24ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        (cp)[1] = (value) >> 16; \
25ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        (cp)[0] = (value) >> 24; } while (0)
26ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstruct AESContext {
27ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    unsigned int keysched[(MAX_NR + 1) * MAX_NB];
28ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    unsigned int invkeysched[(MAX_NR + 1) * MAX_NB];
29ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    void (*encrypt) (AESContext * ctx, unsigned int * block);
30ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    void (*decrypt) (AESContext * ctx, unsigned int * block);
31ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    unsigned int iv[MAX_NB];
32ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int Nb, Nr;
33ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov};
34ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic const unsigned char Sbox[256] = {
35ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5,
36ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
37ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0,
38ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
39ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc,
40ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
41ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a,
42ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
43ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0,
44ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
45ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b,
46ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
47ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85,
48ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
49ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5,
50ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
51ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17,
52ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
53ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88,
54ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
55ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c,
56ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
57ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9,
58ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
59ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6,
60ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
61ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e,
62ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
63ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94,
64ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
65ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68,
66ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
67ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov};
68ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic const unsigned char Sboxinv[256] = {
69ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38,
70ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb,
71ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87,
72ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb,
73ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d,
74ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e,
75ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2,
76ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25,
77ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16,
78ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92,
79ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda,
80ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84,
81ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a,
82ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06,
83ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02,
84ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b,
85ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea,
86ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73,
87ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85,
88ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e,
89ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89,
90ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b,
91ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20,
92ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4,
93ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31,
94ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f,
95ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d,
96ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef,
97ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0,
98ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61,
99ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26,
100ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d
101ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov};
102ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic const unsigned int E0[256] = {
103ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xc66363a5, 0xf87c7c84, 0xee777799, 0xf67b7b8d,
104ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xfff2f20d, 0xd66b6bbd, 0xde6f6fb1, 0x91c5c554,
105ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x60303050, 0x02010103, 0xce6767a9, 0x562b2b7d,
106ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xe7fefe19, 0xb5d7d762, 0x4dababe6, 0xec76769a,
107ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x8fcaca45, 0x1f82829d, 0x89c9c940, 0xfa7d7d87,
108ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xeffafa15, 0xb25959eb, 0x8e4747c9, 0xfbf0f00b,
109ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x41adadec, 0xb3d4d467, 0x5fa2a2fd, 0x45afafea,
110ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x239c9cbf, 0x53a4a4f7, 0xe4727296, 0x9bc0c05b,
111ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x75b7b7c2, 0xe1fdfd1c, 0x3d9393ae, 0x4c26266a,
112ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x6c36365a, 0x7e3f3f41, 0xf5f7f702, 0x83cccc4f,
113ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x6834345c, 0x51a5a5f4, 0xd1e5e534, 0xf9f1f108,
114ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xe2717193, 0xabd8d873, 0x62313153, 0x2a15153f,
115ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x0804040c, 0x95c7c752, 0x46232365, 0x9dc3c35e,
116ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x30181828, 0x379696a1, 0x0a05050f, 0x2f9a9ab5,
117ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x0e070709, 0x24121236, 0x1b80809b, 0xdfe2e23d,
118ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xcdebeb26, 0x4e272769, 0x7fb2b2cd, 0xea75759f,
119ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x1209091b, 0x1d83839e, 0x582c2c74, 0x341a1a2e,
120ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x361b1b2d, 0xdc6e6eb2, 0xb45a5aee, 0x5ba0a0fb,
121ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xa45252f6, 0x763b3b4d, 0xb7d6d661, 0x7db3b3ce,
122ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x5229297b, 0xdde3e33e, 0x5e2f2f71, 0x13848497,
123ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xa65353f5, 0xb9d1d168, 0x00000000, 0xc1eded2c,
124ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x40202060, 0xe3fcfc1f, 0x79b1b1c8, 0xb65b5bed,
125ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xd46a6abe, 0x8dcbcb46, 0x67bebed9, 0x7239394b,
126ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x944a4ade, 0x984c4cd4, 0xb05858e8, 0x85cfcf4a,
127ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xbbd0d06b, 0xc5efef2a, 0x4faaaae5, 0xedfbfb16,
128ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x864343c5, 0x9a4d4dd7, 0x66333355, 0x11858594,
129ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x8a4545cf, 0xe9f9f910, 0x04020206, 0xfe7f7f81,
130ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xa05050f0, 0x783c3c44, 0x259f9fba, 0x4ba8a8e3,
131ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xa25151f3, 0x5da3a3fe, 0x804040c0, 0x058f8f8a,
132ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x3f9292ad, 0x219d9dbc, 0x70383848, 0xf1f5f504,
133ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x63bcbcdf, 0x77b6b6c1, 0xafdada75, 0x42212163,
134ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x20101030, 0xe5ffff1a, 0xfdf3f30e, 0xbfd2d26d,
135ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x81cdcd4c, 0x180c0c14, 0x26131335, 0xc3ecec2f,
136ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xbe5f5fe1, 0x359797a2, 0x884444cc, 0x2e171739,
137ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x93c4c457, 0x55a7a7f2, 0xfc7e7e82, 0x7a3d3d47,
138ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xc86464ac, 0xba5d5de7, 0x3219192b, 0xe6737395,
139ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xc06060a0, 0x19818198, 0x9e4f4fd1, 0xa3dcdc7f,
140ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x44222266, 0x542a2a7e, 0x3b9090ab, 0x0b888883,
141ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x8c4646ca, 0xc7eeee29, 0x6bb8b8d3, 0x2814143c,
142ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xa7dede79, 0xbc5e5ee2, 0x160b0b1d, 0xaddbdb76,
143ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xdbe0e03b, 0x64323256, 0x743a3a4e, 0x140a0a1e,
144ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x924949db, 0x0c06060a, 0x4824246c, 0xb85c5ce4,
145ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x9fc2c25d, 0xbdd3d36e, 0x43acacef, 0xc46262a6,
146ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x399191a8, 0x319595a4, 0xd3e4e437, 0xf279798b,
147ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xd5e7e732, 0x8bc8c843, 0x6e373759, 0xda6d6db7,
148ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x018d8d8c, 0xb1d5d564, 0x9c4e4ed2, 0x49a9a9e0,
149ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xd86c6cb4, 0xac5656fa, 0xf3f4f407, 0xcfeaea25,
150ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xca6565af, 0xf47a7a8e, 0x47aeaee9, 0x10080818,
151ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x6fbabad5, 0xf0787888, 0x4a25256f, 0x5c2e2e72,
152ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x381c1c24, 0x57a6a6f1, 0x73b4b4c7, 0x97c6c651,
153ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xcbe8e823, 0xa1dddd7c, 0xe874749c, 0x3e1f1f21,
154ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x964b4bdd, 0x61bdbddc, 0x0d8b8b86, 0x0f8a8a85,
155ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xe0707090, 0x7c3e3e42, 0x71b5b5c4, 0xcc6666aa,
156ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x904848d8, 0x06030305, 0xf7f6f601, 0x1c0e0e12,
157ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xc26161a3, 0x6a35355f, 0xae5757f9, 0x69b9b9d0,
158ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x17868691, 0x99c1c158, 0x3a1d1d27, 0x279e9eb9,
159ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xd9e1e138, 0xebf8f813, 0x2b9898b3, 0x22111133,
160ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xd26969bb, 0xa9d9d970, 0x078e8e89, 0x339494a7,
161ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x2d9b9bb6, 0x3c1e1e22, 0x15878792, 0xc9e9e920,
162ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x87cece49, 0xaa5555ff, 0x50282878, 0xa5dfdf7a,
163ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x038c8c8f, 0x59a1a1f8, 0x09898980, 0x1a0d0d17,
164ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x65bfbfda, 0xd7e6e631, 0x844242c6, 0xd06868b8,
165ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x824141c3, 0x299999b0, 0x5a2d2d77, 0x1e0f0f11,
166ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x7bb0b0cb, 0xa85454fc, 0x6dbbbbd6, 0x2c16163a,
167ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov};
168ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic const unsigned int E1[256] = {
169ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xa5c66363, 0x84f87c7c, 0x99ee7777, 0x8df67b7b,
170ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x0dfff2f2, 0xbdd66b6b, 0xb1de6f6f, 0x5491c5c5,
171ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x50603030, 0x03020101, 0xa9ce6767, 0x7d562b2b,
172ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x19e7fefe, 0x62b5d7d7, 0xe64dabab, 0x9aec7676,
173ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x458fcaca, 0x9d1f8282, 0x4089c9c9, 0x87fa7d7d,
174ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x15effafa, 0xebb25959, 0xc98e4747, 0x0bfbf0f0,
175ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xec41adad, 0x67b3d4d4, 0xfd5fa2a2, 0xea45afaf,
176ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xbf239c9c, 0xf753a4a4, 0x96e47272, 0x5b9bc0c0,
177ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xc275b7b7, 0x1ce1fdfd, 0xae3d9393, 0x6a4c2626,
178ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x5a6c3636, 0x417e3f3f, 0x02f5f7f7, 0x4f83cccc,
179ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x5c683434, 0xf451a5a5, 0x34d1e5e5, 0x08f9f1f1,
180ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x93e27171, 0x73abd8d8, 0x53623131, 0x3f2a1515,
181ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x0c080404, 0x5295c7c7, 0x65462323, 0x5e9dc3c3,
182ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x28301818, 0xa1379696, 0x0f0a0505, 0xb52f9a9a,
183ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x090e0707, 0x36241212, 0x9b1b8080, 0x3ddfe2e2,
184ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x26cdebeb, 0x694e2727, 0xcd7fb2b2, 0x9fea7575,
185ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x1b120909, 0x9e1d8383, 0x74582c2c, 0x2e341a1a,
186ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x2d361b1b, 0xb2dc6e6e, 0xeeb45a5a, 0xfb5ba0a0,
187ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xf6a45252, 0x4d763b3b, 0x61b7d6d6, 0xce7db3b3,
188ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x7b522929, 0x3edde3e3, 0x715e2f2f, 0x97138484,
189ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xf5a65353, 0x68b9d1d1, 0x00000000, 0x2cc1eded,
190ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x60402020, 0x1fe3fcfc, 0xc879b1b1, 0xedb65b5b,
191ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xbed46a6a, 0x468dcbcb, 0xd967bebe, 0x4b723939,
192ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xde944a4a, 0xd4984c4c, 0xe8b05858, 0x4a85cfcf,
193ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x6bbbd0d0, 0x2ac5efef, 0xe54faaaa, 0x16edfbfb,
194ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xc5864343, 0xd79a4d4d, 0x55663333, 0x94118585,
195ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xcf8a4545, 0x10e9f9f9, 0x06040202, 0x81fe7f7f,
196ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xf0a05050, 0x44783c3c, 0xba259f9f, 0xe34ba8a8,
197ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xf3a25151, 0xfe5da3a3, 0xc0804040, 0x8a058f8f,
198ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xad3f9292, 0xbc219d9d, 0x48703838, 0x04f1f5f5,
199ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xdf63bcbc, 0xc177b6b6, 0x75afdada, 0x63422121,
200ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x30201010, 0x1ae5ffff, 0x0efdf3f3, 0x6dbfd2d2,
201ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x4c81cdcd, 0x14180c0c, 0x35261313, 0x2fc3ecec,
202ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xe1be5f5f, 0xa2359797, 0xcc884444, 0x392e1717,
203ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x5793c4c4, 0xf255a7a7, 0x82fc7e7e, 0x477a3d3d,
204ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xacc86464, 0xe7ba5d5d, 0x2b321919, 0x95e67373,
205ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xa0c06060, 0x98198181, 0xd19e4f4f, 0x7fa3dcdc,
206ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x66442222, 0x7e542a2a, 0xab3b9090, 0x830b8888,
207ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xca8c4646, 0x29c7eeee, 0xd36bb8b8, 0x3c281414,
208ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x79a7dede, 0xe2bc5e5e, 0x1d160b0b, 0x76addbdb,
209ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x3bdbe0e0, 0x56643232, 0x4e743a3a, 0x1e140a0a,
210ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xdb924949, 0x0a0c0606, 0x6c482424, 0xe4b85c5c,
211ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x5d9fc2c2, 0x6ebdd3d3, 0xef43acac, 0xa6c46262,
212ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xa8399191, 0xa4319595, 0x37d3e4e4, 0x8bf27979,
213ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x32d5e7e7, 0x438bc8c8, 0x596e3737, 0xb7da6d6d,
214ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x8c018d8d, 0x64b1d5d5, 0xd29c4e4e, 0xe049a9a9,
215ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xb4d86c6c, 0xfaac5656, 0x07f3f4f4, 0x25cfeaea,
216ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xafca6565, 0x8ef47a7a, 0xe947aeae, 0x18100808,
217ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xd56fbaba, 0x88f07878, 0x6f4a2525, 0x725c2e2e,
218ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x24381c1c, 0xf157a6a6, 0xc773b4b4, 0x5197c6c6,
219ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x23cbe8e8, 0x7ca1dddd, 0x9ce87474, 0x213e1f1f,
220ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xdd964b4b, 0xdc61bdbd, 0x860d8b8b, 0x850f8a8a,
221ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x90e07070, 0x427c3e3e, 0xc471b5b5, 0xaacc6666,
222ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xd8904848, 0x05060303, 0x01f7f6f6, 0x121c0e0e,
223ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xa3c26161, 0x5f6a3535, 0xf9ae5757, 0xd069b9b9,
224ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x91178686, 0x5899c1c1, 0x273a1d1d, 0xb9279e9e,
225ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x38d9e1e1, 0x13ebf8f8, 0xb32b9898, 0x33221111,
226ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xbbd26969, 0x70a9d9d9, 0x89078e8e, 0xa7339494,
227ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xb62d9b9b, 0x223c1e1e, 0x92158787, 0x20c9e9e9,
228ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x4987cece, 0xffaa5555, 0x78502828, 0x7aa5dfdf,
229ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x8f038c8c, 0xf859a1a1, 0x80098989, 0x171a0d0d,
230ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xda65bfbf, 0x31d7e6e6, 0xc6844242, 0xb8d06868,
231ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xc3824141, 0xb0299999, 0x775a2d2d, 0x111e0f0f,
232ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xcb7bb0b0, 0xfca85454, 0xd66dbbbb, 0x3a2c1616,
233ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov};
234ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic const unsigned int E2[256] = {
235ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x63a5c663, 0x7c84f87c, 0x7799ee77, 0x7b8df67b,
236ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xf20dfff2, 0x6bbdd66b, 0x6fb1de6f, 0xc55491c5,
237ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x30506030, 0x01030201, 0x67a9ce67, 0x2b7d562b,
238ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xfe19e7fe, 0xd762b5d7, 0xabe64dab, 0x769aec76,
239ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xca458fca, 0x829d1f82, 0xc94089c9, 0x7d87fa7d,
240ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xfa15effa, 0x59ebb259, 0x47c98e47, 0xf00bfbf0,
241ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xadec41ad, 0xd467b3d4, 0xa2fd5fa2, 0xafea45af,
242ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x9cbf239c, 0xa4f753a4, 0x7296e472, 0xc05b9bc0,
243ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xb7c275b7, 0xfd1ce1fd, 0x93ae3d93, 0x266a4c26,
244ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x365a6c36, 0x3f417e3f, 0xf702f5f7, 0xcc4f83cc,
245ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x345c6834, 0xa5f451a5, 0xe534d1e5, 0xf108f9f1,
246ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x7193e271, 0xd873abd8, 0x31536231, 0x153f2a15,
247ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x040c0804, 0xc75295c7, 0x23654623, 0xc35e9dc3,
248ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x18283018, 0x96a13796, 0x050f0a05, 0x9ab52f9a,
249ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x07090e07, 0x12362412, 0x809b1b80, 0xe23ddfe2,
250ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xeb26cdeb, 0x27694e27, 0xb2cd7fb2, 0x759fea75,
251ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x091b1209, 0x839e1d83, 0x2c74582c, 0x1a2e341a,
252ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x1b2d361b, 0x6eb2dc6e, 0x5aeeb45a, 0xa0fb5ba0,
253ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x52f6a452, 0x3b4d763b, 0xd661b7d6, 0xb3ce7db3,
254ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x297b5229, 0xe33edde3, 0x2f715e2f, 0x84971384,
255ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x53f5a653, 0xd168b9d1, 0x00000000, 0xed2cc1ed,
256ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x20604020, 0xfc1fe3fc, 0xb1c879b1, 0x5bedb65b,
257ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x6abed46a, 0xcb468dcb, 0xbed967be, 0x394b7239,
258ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x4ade944a, 0x4cd4984c, 0x58e8b058, 0xcf4a85cf,
259ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xd06bbbd0, 0xef2ac5ef, 0xaae54faa, 0xfb16edfb,
260ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x43c58643, 0x4dd79a4d, 0x33556633, 0x85941185,
261ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x45cf8a45, 0xf910e9f9, 0x02060402, 0x7f81fe7f,
262ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x50f0a050, 0x3c44783c, 0x9fba259f, 0xa8e34ba8,
263ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x51f3a251, 0xa3fe5da3, 0x40c08040, 0x8f8a058f,
264ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x92ad3f92, 0x9dbc219d, 0x38487038, 0xf504f1f5,
265ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xbcdf63bc, 0xb6c177b6, 0xda75afda, 0x21634221,
266ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x10302010, 0xff1ae5ff, 0xf30efdf3, 0xd26dbfd2,
267ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xcd4c81cd, 0x0c14180c, 0x13352613, 0xec2fc3ec,
268ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x5fe1be5f, 0x97a23597, 0x44cc8844, 0x17392e17,
269ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xc45793c4, 0xa7f255a7, 0x7e82fc7e, 0x3d477a3d,
270ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x64acc864, 0x5de7ba5d, 0x192b3219, 0x7395e673,
271ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x60a0c060, 0x81981981, 0x4fd19e4f, 0xdc7fa3dc,
272ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x22664422, 0x2a7e542a, 0x90ab3b90, 0x88830b88,
273ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x46ca8c46, 0xee29c7ee, 0xb8d36bb8, 0x143c2814,
274ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xde79a7de, 0x5ee2bc5e, 0x0b1d160b, 0xdb76addb,
275ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xe03bdbe0, 0x32566432, 0x3a4e743a, 0x0a1e140a,
276ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x49db9249, 0x060a0c06, 0x246c4824, 0x5ce4b85c,
277ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xc25d9fc2, 0xd36ebdd3, 0xacef43ac, 0x62a6c462,
278ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x91a83991, 0x95a43195, 0xe437d3e4, 0x798bf279,
279ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xe732d5e7, 0xc8438bc8, 0x37596e37, 0x6db7da6d,
280ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x8d8c018d, 0xd564b1d5, 0x4ed29c4e, 0xa9e049a9,
281ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x6cb4d86c, 0x56faac56, 0xf407f3f4, 0xea25cfea,
282ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x65afca65, 0x7a8ef47a, 0xaee947ae, 0x08181008,
283ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xbad56fba, 0x7888f078, 0x256f4a25, 0x2e725c2e,
284ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x1c24381c, 0xa6f157a6, 0xb4c773b4, 0xc65197c6,
285ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xe823cbe8, 0xdd7ca1dd, 0x749ce874, 0x1f213e1f,
286ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x4bdd964b, 0xbddc61bd, 0x8b860d8b, 0x8a850f8a,
287ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x7090e070, 0x3e427c3e, 0xb5c471b5, 0x66aacc66,
288ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x48d89048, 0x03050603, 0xf601f7f6, 0x0e121c0e,
289ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x61a3c261, 0x355f6a35, 0x57f9ae57, 0xb9d069b9,
290ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x86911786, 0xc15899c1, 0x1d273a1d, 0x9eb9279e,
291ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xe138d9e1, 0xf813ebf8, 0x98b32b98, 0x11332211,
292ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x69bbd269, 0xd970a9d9, 0x8e89078e, 0x94a73394,
293ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x9bb62d9b, 0x1e223c1e, 0x87921587, 0xe920c9e9,
294ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xce4987ce, 0x55ffaa55, 0x28785028, 0xdf7aa5df,
295ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x8c8f038c, 0xa1f859a1, 0x89800989, 0x0d171a0d,
296ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xbfda65bf, 0xe631d7e6, 0x42c68442, 0x68b8d068,
297ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x41c38241, 0x99b02999, 0x2d775a2d, 0x0f111e0f,
298ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xb0cb7bb0, 0x54fca854, 0xbbd66dbb, 0x163a2c16,
299ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov};
300ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic const unsigned int E3[256] = {
301ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x6363a5c6, 0x7c7c84f8, 0x777799ee, 0x7b7b8df6,
302ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xf2f20dff, 0x6b6bbdd6, 0x6f6fb1de, 0xc5c55491,
303ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x30305060, 0x01010302, 0x6767a9ce, 0x2b2b7d56,
304ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xfefe19e7, 0xd7d762b5, 0xababe64d, 0x76769aec,
305ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xcaca458f, 0x82829d1f, 0xc9c94089, 0x7d7d87fa,
306ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xfafa15ef, 0x5959ebb2, 0x4747c98e, 0xf0f00bfb,
307ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xadadec41, 0xd4d467b3, 0xa2a2fd5f, 0xafafea45,
308ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x9c9cbf23, 0xa4a4f753, 0x727296e4, 0xc0c05b9b,
309ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xb7b7c275, 0xfdfd1ce1, 0x9393ae3d, 0x26266a4c,
310ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x36365a6c, 0x3f3f417e, 0xf7f702f5, 0xcccc4f83,
311ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x34345c68, 0xa5a5f451, 0xe5e534d1, 0xf1f108f9,
312ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x717193e2, 0xd8d873ab, 0x31315362, 0x15153f2a,
313ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x04040c08, 0xc7c75295, 0x23236546, 0xc3c35e9d,
314ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x18182830, 0x9696a137, 0x05050f0a, 0x9a9ab52f,
315ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x0707090e, 0x12123624, 0x80809b1b, 0xe2e23ddf,
316ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xebeb26cd, 0x2727694e, 0xb2b2cd7f, 0x75759fea,
317ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x09091b12, 0x83839e1d, 0x2c2c7458, 0x1a1a2e34,
318ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x1b1b2d36, 0x6e6eb2dc, 0x5a5aeeb4, 0xa0a0fb5b,
319ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x5252f6a4, 0x3b3b4d76, 0xd6d661b7, 0xb3b3ce7d,
320ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x29297b52, 0xe3e33edd, 0x2f2f715e, 0x84849713,
321ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x5353f5a6, 0xd1d168b9, 0x00000000, 0xeded2cc1,
322ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x20206040, 0xfcfc1fe3, 0xb1b1c879, 0x5b5bedb6,
323ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x6a6abed4, 0xcbcb468d, 0xbebed967, 0x39394b72,
324ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x4a4ade94, 0x4c4cd498, 0x5858e8b0, 0xcfcf4a85,
325ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xd0d06bbb, 0xefef2ac5, 0xaaaae54f, 0xfbfb16ed,
326ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x4343c586, 0x4d4dd79a, 0x33335566, 0x85859411,
327ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x4545cf8a, 0xf9f910e9, 0x02020604, 0x7f7f81fe,
328ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x5050f0a0, 0x3c3c4478, 0x9f9fba25, 0xa8a8e34b,
329ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x5151f3a2, 0xa3a3fe5d, 0x4040c080, 0x8f8f8a05,
330ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x9292ad3f, 0x9d9dbc21, 0x38384870, 0xf5f504f1,
331ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xbcbcdf63, 0xb6b6c177, 0xdada75af, 0x21216342,
332ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x10103020, 0xffff1ae5, 0xf3f30efd, 0xd2d26dbf,
333ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xcdcd4c81, 0x0c0c1418, 0x13133526, 0xecec2fc3,
334ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x5f5fe1be, 0x9797a235, 0x4444cc88, 0x1717392e,
335ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xc4c45793, 0xa7a7f255, 0x7e7e82fc, 0x3d3d477a,
336ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x6464acc8, 0x5d5de7ba, 0x19192b32, 0x737395e6,
337ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x6060a0c0, 0x81819819, 0x4f4fd19e, 0xdcdc7fa3,
338ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x22226644, 0x2a2a7e54, 0x9090ab3b, 0x8888830b,
339ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x4646ca8c, 0xeeee29c7, 0xb8b8d36b, 0x14143c28,
340ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xdede79a7, 0x5e5ee2bc, 0x0b0b1d16, 0xdbdb76ad,
341ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xe0e03bdb, 0x32325664, 0x3a3a4e74, 0x0a0a1e14,
342ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x4949db92, 0x06060a0c, 0x24246c48, 0x5c5ce4b8,
343ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xc2c25d9f, 0xd3d36ebd, 0xacacef43, 0x6262a6c4,
344ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x9191a839, 0x9595a431, 0xe4e437d3, 0x79798bf2,
345ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xe7e732d5, 0xc8c8438b, 0x3737596e, 0x6d6db7da,
346ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x8d8d8c01, 0xd5d564b1, 0x4e4ed29c, 0xa9a9e049,
347ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x6c6cb4d8, 0x5656faac, 0xf4f407f3, 0xeaea25cf,
348ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x6565afca, 0x7a7a8ef4, 0xaeaee947, 0x08081810,
349ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xbabad56f, 0x787888f0, 0x25256f4a, 0x2e2e725c,
350ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x1c1c2438, 0xa6a6f157, 0xb4b4c773, 0xc6c65197,
351ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xe8e823cb, 0xdddd7ca1, 0x74749ce8, 0x1f1f213e,
352ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x4b4bdd96, 0xbdbddc61, 0x8b8b860d, 0x8a8a850f,
353ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x707090e0, 0x3e3e427c, 0xb5b5c471, 0x6666aacc,
354ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x4848d890, 0x03030506, 0xf6f601f7, 0x0e0e121c,
355ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x6161a3c2, 0x35355f6a, 0x5757f9ae, 0xb9b9d069,
356ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x86869117, 0xc1c15899, 0x1d1d273a, 0x9e9eb927,
357ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xe1e138d9, 0xf8f813eb, 0x9898b32b, 0x11113322,
358ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x6969bbd2, 0xd9d970a9, 0x8e8e8907, 0x9494a733,
359ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x9b9bb62d, 0x1e1e223c, 0x87879215, 0xe9e920c9,
360ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xcece4987, 0x5555ffaa, 0x28287850, 0xdfdf7aa5,
361ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x8c8c8f03, 0xa1a1f859, 0x89898009, 0x0d0d171a,
362ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xbfbfda65, 0xe6e631d7, 0x4242c684, 0x6868b8d0,
363ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x4141c382, 0x9999b029, 0x2d2d775a, 0x0f0f111e,
364ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xb0b0cb7b, 0x5454fca8, 0xbbbbd66d, 0x16163a2c,
365ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov};
366ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic const unsigned int D0[256] = {
367ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x51f4a750, 0x7e416553, 0x1a17a4c3, 0x3a275e96,
368ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x3bab6bcb, 0x1f9d45f1, 0xacfa58ab, 0x4be30393,
369ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x2030fa55, 0xad766df6, 0x88cc7691, 0xf5024c25,
370ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x4fe5d7fc, 0xc52acbd7, 0x26354480, 0xb562a38f,
371ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xdeb15a49, 0x25ba1b67, 0x45ea0e98, 0x5dfec0e1,
372ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xc32f7502, 0x814cf012, 0x8d4697a3, 0x6bd3f9c6,
373ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x038f5fe7, 0x15929c95, 0xbf6d7aeb, 0x955259da,
374ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xd4be832d, 0x587421d3, 0x49e06929, 0x8ec9c844,
375ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x75c2896a, 0xf48e7978, 0x99583e6b, 0x27b971dd,
376ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xbee14fb6, 0xf088ad17, 0xc920ac66, 0x7dce3ab4,
377ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x63df4a18, 0xe51a3182, 0x97513360, 0x62537f45,
378ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xb16477e0, 0xbb6bae84, 0xfe81a01c, 0xf9082b94,
379ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x70486858, 0x8f45fd19, 0x94de6c87, 0x527bf8b7,
380ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xab73d323, 0x724b02e2, 0xe31f8f57, 0x6655ab2a,
381ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xb2eb2807, 0x2fb5c203, 0x86c57b9a, 0xd33708a5,
382ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x302887f2, 0x23bfa5b2, 0x02036aba, 0xed16825c,
383ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x8acf1c2b, 0xa779b492, 0xf307f2f0, 0x4e69e2a1,
384ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x65daf4cd, 0x0605bed5, 0xd134621f, 0xc4a6fe8a,
385ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x342e539d, 0xa2f355a0, 0x058ae132, 0xa4f6eb75,
386ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x0b83ec39, 0x4060efaa, 0x5e719f06, 0xbd6e1051,
387ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x3e218af9, 0x96dd063d, 0xdd3e05ae, 0x4de6bd46,
388ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x91548db5, 0x71c45d05, 0x0406d46f, 0x605015ff,
389ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x1998fb24, 0xd6bde997, 0x894043cc, 0x67d99e77,
390ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xb0e842bd, 0x07898b88, 0xe7195b38, 0x79c8eedb,
391ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xa17c0a47, 0x7c420fe9, 0xf8841ec9, 0x00000000,
392ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x09808683, 0x322bed48, 0x1e1170ac, 0x6c5a724e,
393ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xfd0efffb, 0x0f853856, 0x3daed51e, 0x362d3927,
394ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x0a0fd964, 0x685ca621, 0x9b5b54d1, 0x24362e3a,
395ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x0c0a67b1, 0x9357e70f, 0xb4ee96d2, 0x1b9b919e,
396ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x80c0c54f, 0x61dc20a2, 0x5a774b69, 0x1c121a16,
397ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xe293ba0a, 0xc0a02ae5, 0x3c22e043, 0x121b171d,
398ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x0e090d0b, 0xf28bc7ad, 0x2db6a8b9, 0x141ea9c8,
399ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x57f11985, 0xaf75074c, 0xee99ddbb, 0xa37f60fd,
400ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xf701269f, 0x5c72f5bc, 0x44663bc5, 0x5bfb7e34,
401ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x8b432976, 0xcb23c6dc, 0xb6edfc68, 0xb8e4f163,
402ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xd731dcca, 0x42638510, 0x13972240, 0x84c61120,
403ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x854a247d, 0xd2bb3df8, 0xaef93211, 0xc729a16d,
404ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x1d9e2f4b, 0xdcb230f3, 0x0d8652ec, 0x77c1e3d0,
405ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x2bb3166c, 0xa970b999, 0x119448fa, 0x47e96422,
406ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xa8fc8cc4, 0xa0f03f1a, 0x567d2cd8, 0x223390ef,
407ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x87494ec7, 0xd938d1c1, 0x8ccaa2fe, 0x98d40b36,
408ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xa6f581cf, 0xa57ade28, 0xdab78e26, 0x3fadbfa4,
409ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x2c3a9de4, 0x5078920d, 0x6a5fcc9b, 0x547e4662,
410ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xf68d13c2, 0x90d8b8e8, 0x2e39f75e, 0x82c3aff5,
411ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x9f5d80be, 0x69d0937c, 0x6fd52da9, 0xcf2512b3,
412ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xc8ac993b, 0x10187da7, 0xe89c636e, 0xdb3bbb7b,
413ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xcd267809, 0x6e5918f4, 0xec9ab701, 0x834f9aa8,
414ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xe6956e65, 0xaaffe67e, 0x21bccf08, 0xef15e8e6,
415ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xbae79bd9, 0x4a6f36ce, 0xea9f09d4, 0x29b07cd6,
416ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x31a4b2af, 0x2a3f2331, 0xc6a59430, 0x35a266c0,
417ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x744ebc37, 0xfc82caa6, 0xe090d0b0, 0x33a7d815,
418ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xf104984a, 0x41ecdaf7, 0x7fcd500e, 0x1791f62f,
419ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x764dd68d, 0x43efb04d, 0xccaa4d54, 0xe49604df,
420ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x9ed1b5e3, 0x4c6a881b, 0xc12c1fb8, 0x4665517f,
421ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x9d5eea04, 0x018c355d, 0xfa877473, 0xfb0b412e,
422ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xb3671d5a, 0x92dbd252, 0xe9105633, 0x6dd64713,
423ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x9ad7618c, 0x37a10c7a, 0x59f8148e, 0xeb133c89,
424ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xcea927ee, 0xb761c935, 0xe11ce5ed, 0x7a47b13c,
425ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x9cd2df59, 0x55f2733f, 0x1814ce79, 0x73c737bf,
426ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x53f7cdea, 0x5ffdaa5b, 0xdf3d6f14, 0x7844db86,
427ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xcaaff381, 0xb968c43e, 0x3824342c, 0xc2a3405f,
428ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x161dc372, 0xbce2250c, 0x283c498b, 0xff0d9541,
429ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x39a80171, 0x080cb3de, 0xd8b4e49c, 0x6456c190,
430ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x7bcb8461, 0xd532b670, 0x486c5c74, 0xd0b85742,
431ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov};
432ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic const unsigned int D1[256] = {
433ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x5051f4a7, 0x537e4165, 0xc31a17a4, 0x963a275e,
434ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xcb3bab6b, 0xf11f9d45, 0xabacfa58, 0x934be303,
435ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x552030fa, 0xf6ad766d, 0x9188cc76, 0x25f5024c,
436ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xfc4fe5d7, 0xd7c52acb, 0x80263544, 0x8fb562a3,
437ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x49deb15a, 0x6725ba1b, 0x9845ea0e, 0xe15dfec0,
438ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x02c32f75, 0x12814cf0, 0xa38d4697, 0xc66bd3f9,
439ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xe7038f5f, 0x9515929c, 0xebbf6d7a, 0xda955259,
440ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x2dd4be83, 0xd3587421, 0x2949e069, 0x448ec9c8,
441ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x6a75c289, 0x78f48e79, 0x6b99583e, 0xdd27b971,
442ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xb6bee14f, 0x17f088ad, 0x66c920ac, 0xb47dce3a,
443ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x1863df4a, 0x82e51a31, 0x60975133, 0x4562537f,
444ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xe0b16477, 0x84bb6bae, 0x1cfe81a0, 0x94f9082b,
445ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x58704868, 0x198f45fd, 0x8794de6c, 0xb7527bf8,
446ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x23ab73d3, 0xe2724b02, 0x57e31f8f, 0x2a6655ab,
447ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x07b2eb28, 0x032fb5c2, 0x9a86c57b, 0xa5d33708,
448ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xf2302887, 0xb223bfa5, 0xba02036a, 0x5ced1682,
449ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x2b8acf1c, 0x92a779b4, 0xf0f307f2, 0xa14e69e2,
450ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xcd65daf4, 0xd50605be, 0x1fd13462, 0x8ac4a6fe,
451ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x9d342e53, 0xa0a2f355, 0x32058ae1, 0x75a4f6eb,
452ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x390b83ec, 0xaa4060ef, 0x065e719f, 0x51bd6e10,
453ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xf93e218a, 0x3d96dd06, 0xaedd3e05, 0x464de6bd,
454ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xb591548d, 0x0571c45d, 0x6f0406d4, 0xff605015,
455ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x241998fb, 0x97d6bde9, 0xcc894043, 0x7767d99e,
456ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xbdb0e842, 0x8807898b, 0x38e7195b, 0xdb79c8ee,
457ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x47a17c0a, 0xe97c420f, 0xc9f8841e, 0x00000000,
458ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x83098086, 0x48322bed, 0xac1e1170, 0x4e6c5a72,
459ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xfbfd0eff, 0x560f8538, 0x1e3daed5, 0x27362d39,
460ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x640a0fd9, 0x21685ca6, 0xd19b5b54, 0x3a24362e,
461ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xb10c0a67, 0x0f9357e7, 0xd2b4ee96, 0x9e1b9b91,
462ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x4f80c0c5, 0xa261dc20, 0x695a774b, 0x161c121a,
463ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x0ae293ba, 0xe5c0a02a, 0x433c22e0, 0x1d121b17,
464ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x0b0e090d, 0xadf28bc7, 0xb92db6a8, 0xc8141ea9,
465ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x8557f119, 0x4caf7507, 0xbbee99dd, 0xfda37f60,
466ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x9ff70126, 0xbc5c72f5, 0xc544663b, 0x345bfb7e,
467ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x768b4329, 0xdccb23c6, 0x68b6edfc, 0x63b8e4f1,
468ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xcad731dc, 0x10426385, 0x40139722, 0x2084c611,
469ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x7d854a24, 0xf8d2bb3d, 0x11aef932, 0x6dc729a1,
470ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x4b1d9e2f, 0xf3dcb230, 0xec0d8652, 0xd077c1e3,
471ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x6c2bb316, 0x99a970b9, 0xfa119448, 0x2247e964,
472ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xc4a8fc8c, 0x1aa0f03f, 0xd8567d2c, 0xef223390,
473ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xc787494e, 0xc1d938d1, 0xfe8ccaa2, 0x3698d40b,
474ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xcfa6f581, 0x28a57ade, 0x26dab78e, 0xa43fadbf,
475ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xe42c3a9d, 0x0d507892, 0x9b6a5fcc, 0x62547e46,
476ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xc2f68d13, 0xe890d8b8, 0x5e2e39f7, 0xf582c3af,
477ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xbe9f5d80, 0x7c69d093, 0xa96fd52d, 0xb3cf2512,
478ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x3bc8ac99, 0xa710187d, 0x6ee89c63, 0x7bdb3bbb,
479ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x09cd2678, 0xf46e5918, 0x01ec9ab7, 0xa8834f9a,
480ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x65e6956e, 0x7eaaffe6, 0x0821bccf, 0xe6ef15e8,
481ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xd9bae79b, 0xce4a6f36, 0xd4ea9f09, 0xd629b07c,
482ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xaf31a4b2, 0x312a3f23, 0x30c6a594, 0xc035a266,
483ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x37744ebc, 0xa6fc82ca, 0xb0e090d0, 0x1533a7d8,
484ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x4af10498, 0xf741ecda, 0x0e7fcd50, 0x2f1791f6,
485ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x8d764dd6, 0x4d43efb0, 0x54ccaa4d, 0xdfe49604,
486ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xe39ed1b5, 0x1b4c6a88, 0xb8c12c1f, 0x7f466551,
487ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x049d5eea, 0x5d018c35, 0x73fa8774, 0x2efb0b41,
488ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x5ab3671d, 0x5292dbd2, 0x33e91056, 0x136dd647,
489ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x8c9ad761, 0x7a37a10c, 0x8e59f814, 0x89eb133c,
490ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xeecea927, 0x35b761c9, 0xede11ce5, 0x3c7a47b1,
491ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x599cd2df, 0x3f55f273, 0x791814ce, 0xbf73c737,
492ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xea53f7cd, 0x5b5ffdaa, 0x14df3d6f, 0x867844db,
493ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x81caaff3, 0x3eb968c4, 0x2c382434, 0x5fc2a340,
494ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x72161dc3, 0x0cbce225, 0x8b283c49, 0x41ff0d95,
495ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x7139a801, 0xde080cb3, 0x9cd8b4e4, 0x906456c1,
496ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x617bcb84, 0x70d532b6, 0x74486c5c, 0x42d0b857,
497ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov};
498ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic const unsigned int D2[256] = {
499ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xa75051f4, 0x65537e41, 0xa4c31a17, 0x5e963a27,
500ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x6bcb3bab, 0x45f11f9d, 0x58abacfa, 0x03934be3,
501ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xfa552030, 0x6df6ad76, 0x769188cc, 0x4c25f502,
502ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xd7fc4fe5, 0xcbd7c52a, 0x44802635, 0xa38fb562,
503ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x5a49deb1, 0x1b6725ba, 0x0e9845ea, 0xc0e15dfe,
504ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x7502c32f, 0xf012814c, 0x97a38d46, 0xf9c66bd3,
505ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x5fe7038f, 0x9c951592, 0x7aebbf6d, 0x59da9552,
506ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x832dd4be, 0x21d35874, 0x692949e0, 0xc8448ec9,
507ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x896a75c2, 0x7978f48e, 0x3e6b9958, 0x71dd27b9,
508ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x4fb6bee1, 0xad17f088, 0xac66c920, 0x3ab47dce,
509ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x4a1863df, 0x3182e51a, 0x33609751, 0x7f456253,
510ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x77e0b164, 0xae84bb6b, 0xa01cfe81, 0x2b94f908,
511ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x68587048, 0xfd198f45, 0x6c8794de, 0xf8b7527b,
512ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xd323ab73, 0x02e2724b, 0x8f57e31f, 0xab2a6655,
513ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x2807b2eb, 0xc2032fb5, 0x7b9a86c5, 0x08a5d337,
514ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x87f23028, 0xa5b223bf, 0x6aba0203, 0x825ced16,
515ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x1c2b8acf, 0xb492a779, 0xf2f0f307, 0xe2a14e69,
516ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xf4cd65da, 0xbed50605, 0x621fd134, 0xfe8ac4a6,
517ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x539d342e, 0x55a0a2f3, 0xe132058a, 0xeb75a4f6,
518ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xec390b83, 0xefaa4060, 0x9f065e71, 0x1051bd6e,
519ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x8af93e21, 0x063d96dd, 0x05aedd3e, 0xbd464de6,
520ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x8db59154, 0x5d0571c4, 0xd46f0406, 0x15ff6050,
521ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xfb241998, 0xe997d6bd, 0x43cc8940, 0x9e7767d9,
522ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x42bdb0e8, 0x8b880789, 0x5b38e719, 0xeedb79c8,
523ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x0a47a17c, 0x0fe97c42, 0x1ec9f884, 0x00000000,
524ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x86830980, 0xed48322b, 0x70ac1e11, 0x724e6c5a,
525ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xfffbfd0e, 0x38560f85, 0xd51e3dae, 0x3927362d,
526ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xd9640a0f, 0xa621685c, 0x54d19b5b, 0x2e3a2436,
527ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x67b10c0a, 0xe70f9357, 0x96d2b4ee, 0x919e1b9b,
528ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xc54f80c0, 0x20a261dc, 0x4b695a77, 0x1a161c12,
529ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xba0ae293, 0x2ae5c0a0, 0xe0433c22, 0x171d121b,
530ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x0d0b0e09, 0xc7adf28b, 0xa8b92db6, 0xa9c8141e,
531ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x198557f1, 0x074caf75, 0xddbbee99, 0x60fda37f,
532ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x269ff701, 0xf5bc5c72, 0x3bc54466, 0x7e345bfb,
533ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x29768b43, 0xc6dccb23, 0xfc68b6ed, 0xf163b8e4,
534ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xdccad731, 0x85104263, 0x22401397, 0x112084c6,
535ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x247d854a, 0x3df8d2bb, 0x3211aef9, 0xa16dc729,
536ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x2f4b1d9e, 0x30f3dcb2, 0x52ec0d86, 0xe3d077c1,
537ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x166c2bb3, 0xb999a970, 0x48fa1194, 0x642247e9,
538ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x8cc4a8fc, 0x3f1aa0f0, 0x2cd8567d, 0x90ef2233,
539ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x4ec78749, 0xd1c1d938, 0xa2fe8cca, 0x0b3698d4,
540ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x81cfa6f5, 0xde28a57a, 0x8e26dab7, 0xbfa43fad,
541ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x9de42c3a, 0x920d5078, 0xcc9b6a5f, 0x4662547e,
542ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x13c2f68d, 0xb8e890d8, 0xf75e2e39, 0xaff582c3,
543ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x80be9f5d, 0x937c69d0, 0x2da96fd5, 0x12b3cf25,
544ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x993bc8ac, 0x7da71018, 0x636ee89c, 0xbb7bdb3b,
545ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x7809cd26, 0x18f46e59, 0xb701ec9a, 0x9aa8834f,
546ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x6e65e695, 0xe67eaaff, 0xcf0821bc, 0xe8e6ef15,
547ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x9bd9bae7, 0x36ce4a6f, 0x09d4ea9f, 0x7cd629b0,
548ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xb2af31a4, 0x23312a3f, 0x9430c6a5, 0x66c035a2,
549ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xbc37744e, 0xcaa6fc82, 0xd0b0e090, 0xd81533a7,
550ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x984af104, 0xdaf741ec, 0x500e7fcd, 0xf62f1791,
551ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xd68d764d, 0xb04d43ef, 0x4d54ccaa, 0x04dfe496,
552ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xb5e39ed1, 0x881b4c6a, 0x1fb8c12c, 0x517f4665,
553ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xea049d5e, 0x355d018c, 0x7473fa87, 0x412efb0b,
554ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x1d5ab367, 0xd25292db, 0x5633e910, 0x47136dd6,
555ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x618c9ad7, 0x0c7a37a1, 0x148e59f8, 0x3c89eb13,
556ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x27eecea9, 0xc935b761, 0xe5ede11c, 0xb13c7a47,
557ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xdf599cd2, 0x733f55f2, 0xce791814, 0x37bf73c7,
558ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xcdea53f7, 0xaa5b5ffd, 0x6f14df3d, 0xdb867844,
559ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xf381caaf, 0xc43eb968, 0x342c3824, 0x405fc2a3,
560ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xc372161d, 0x250cbce2, 0x498b283c, 0x9541ff0d,
561ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x017139a8, 0xb3de080c, 0xe49cd8b4, 0xc1906456,
562ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x84617bcb, 0xb670d532, 0x5c74486c, 0x5742d0b8,
563ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov};
564ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic const unsigned int D3[256] = {
565ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xf4a75051, 0x4165537e, 0x17a4c31a, 0x275e963a,
566ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xab6bcb3b, 0x9d45f11f, 0xfa58abac, 0xe303934b,
567ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x30fa5520, 0x766df6ad, 0xcc769188, 0x024c25f5,
568ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xe5d7fc4f, 0x2acbd7c5, 0x35448026, 0x62a38fb5,
569ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xb15a49de, 0xba1b6725, 0xea0e9845, 0xfec0e15d,
570ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x2f7502c3, 0x4cf01281, 0x4697a38d, 0xd3f9c66b,
571ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x8f5fe703, 0x929c9515, 0x6d7aebbf, 0x5259da95,
572ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xbe832dd4, 0x7421d358, 0xe0692949, 0xc9c8448e,
573ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xc2896a75, 0x8e7978f4, 0x583e6b99, 0xb971dd27,
574ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xe14fb6be, 0x88ad17f0, 0x20ac66c9, 0xce3ab47d,
575ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xdf4a1863, 0x1a3182e5, 0x51336097, 0x537f4562,
576ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x6477e0b1, 0x6bae84bb, 0x81a01cfe, 0x082b94f9,
577ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x48685870, 0x45fd198f, 0xde6c8794, 0x7bf8b752,
578ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x73d323ab, 0x4b02e272, 0x1f8f57e3, 0x55ab2a66,
579ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xeb2807b2, 0xb5c2032f, 0xc57b9a86, 0x3708a5d3,
580ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x2887f230, 0xbfa5b223, 0x036aba02, 0x16825ced,
581ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xcf1c2b8a, 0x79b492a7, 0x07f2f0f3, 0x69e2a14e,
582ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xdaf4cd65, 0x05bed506, 0x34621fd1, 0xa6fe8ac4,
583ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x2e539d34, 0xf355a0a2, 0x8ae13205, 0xf6eb75a4,
584ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x83ec390b, 0x60efaa40, 0x719f065e, 0x6e1051bd,
585ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x218af93e, 0xdd063d96, 0x3e05aedd, 0xe6bd464d,
586ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x548db591, 0xc45d0571, 0x06d46f04, 0x5015ff60,
587ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x98fb2419, 0xbde997d6, 0x4043cc89, 0xd99e7767,
588ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xe842bdb0, 0x898b8807, 0x195b38e7, 0xc8eedb79,
589ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x7c0a47a1, 0x420fe97c, 0x841ec9f8, 0x00000000,
590ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x80868309, 0x2bed4832, 0x1170ac1e, 0x5a724e6c,
591ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x0efffbfd, 0x8538560f, 0xaed51e3d, 0x2d392736,
592ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x0fd9640a, 0x5ca62168, 0x5b54d19b, 0x362e3a24,
593ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x0a67b10c, 0x57e70f93, 0xee96d2b4, 0x9b919e1b,
594ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xc0c54f80, 0xdc20a261, 0x774b695a, 0x121a161c,
595ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x93ba0ae2, 0xa02ae5c0, 0x22e0433c, 0x1b171d12,
596ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x090d0b0e, 0x8bc7adf2, 0xb6a8b92d, 0x1ea9c814,
597ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xf1198557, 0x75074caf, 0x99ddbbee, 0x7f60fda3,
598ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x01269ff7, 0x72f5bc5c, 0x663bc544, 0xfb7e345b,
599ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x4329768b, 0x23c6dccb, 0xedfc68b6, 0xe4f163b8,
600ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x31dccad7, 0x63851042, 0x97224013, 0xc6112084,
601ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x4a247d85, 0xbb3df8d2, 0xf93211ae, 0x29a16dc7,
602ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x9e2f4b1d, 0xb230f3dc, 0x8652ec0d, 0xc1e3d077,
603ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xb3166c2b, 0x70b999a9, 0x9448fa11, 0xe9642247,
604ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xfc8cc4a8, 0xf03f1aa0, 0x7d2cd856, 0x3390ef22,
605ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x494ec787, 0x38d1c1d9, 0xcaa2fe8c, 0xd40b3698,
606ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xf581cfa6, 0x7ade28a5, 0xb78e26da, 0xadbfa43f,
607ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x3a9de42c, 0x78920d50, 0x5fcc9b6a, 0x7e466254,
608ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x8d13c2f6, 0xd8b8e890, 0x39f75e2e, 0xc3aff582,
609ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x5d80be9f, 0xd0937c69, 0xd52da96f, 0x2512b3cf,
610ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xac993bc8, 0x187da710, 0x9c636ee8, 0x3bbb7bdb,
611ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x267809cd, 0x5918f46e, 0x9ab701ec, 0x4f9aa883,
612ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x956e65e6, 0xffe67eaa, 0xbccf0821, 0x15e8e6ef,
613ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xe79bd9ba, 0x6f36ce4a, 0x9f09d4ea, 0xb07cd629,
614ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xa4b2af31, 0x3f23312a, 0xa59430c6, 0xa266c035,
615ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x4ebc3774, 0x82caa6fc, 0x90d0b0e0, 0xa7d81533,
616ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x04984af1, 0xecdaf741, 0xcd500e7f, 0x91f62f17,
617ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x4dd68d76, 0xefb04d43, 0xaa4d54cc, 0x9604dfe4,
618ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xd1b5e39e, 0x6a881b4c, 0x2c1fb8c1, 0x65517f46,
619ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x5eea049d, 0x8c355d01, 0x877473fa, 0x0b412efb,
620ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x671d5ab3, 0xdbd25292, 0x105633e9, 0xd647136d,
621ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xd7618c9a, 0xa10c7a37, 0xf8148e59, 0x133c89eb,
622ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xa927eece, 0x61c935b7, 0x1ce5ede1, 0x47b13c7a,
623ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xd2df599c, 0xf2733f55, 0x14ce7918, 0xc737bf73,
624ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xf7cdea53, 0xfdaa5b5f, 0x3d6f14df, 0x44db8678,
625ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xaff381ca, 0x68c43eb9, 0x24342c38, 0xa3405fc2,
626ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x1dc37216, 0xe2250cbc, 0x3c498b28, 0x0d9541ff,
627ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xa8017139, 0x0cb3de08, 0xb4e49cd8, 0x56c19064,
628ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0xcb84617b, 0x32b670d5, 0x6c5c7448, 0xb85742d0,
629ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov};
630ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define ADD_ROUND_KEY_4 (block[0]^=*keysched++, block[1]^=*keysched++, \
631ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                         block[2]^=*keysched++, block[3]^=*keysched++)
632ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define ADD_ROUND_KEY_6 (block[0]^=*keysched++, block[1]^=*keysched++, \
633ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                         block[2]^=*keysched++, block[3]^=*keysched++, \
634ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                         block[4]^=*keysched++, block[5]^=*keysched++)
635ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define ADD_ROUND_KEY_8 (block[0]^=*keysched++, block[1]^=*keysched++, \
636ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                         block[2]^=*keysched++, block[3]^=*keysched++, \
637ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                         block[4]^=*keysched++, block[5]^=*keysched++, \
638ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                         block[6]^=*keysched++, block[7]^=*keysched++)
639ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define MOVEWORD(i) ( block[i] = newstate[i] )
640ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#undef MAKEWORD
641ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define MAKEWORD(i) ( newstate[i] = (E0[(block[i] >> 24) & 0xFF] ^ \
642ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                     E1[(block[(i+C1)%Nb] >> 16) & 0xFF] ^ \
643ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                     E2[(block[(i+C2)%Nb] >> 8) & 0xFF] ^ \
644ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                     E3[block[(i+C3)%Nb] & 0xFF]) )
645ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define LASTWORD(i) ( newstate[i] = (Sbox[(block[i] >> 24) & 0xFF] << 24) | \
646ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                    (Sbox[(block[(i+C1)%Nb] >> 16) & 0xFF] << 16) | \
647ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                    (Sbox[(block[(i+C2)%Nb] >>  8) & 0xFF] <<  8) | \
648ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                    (Sbox[(block[(i+C3)%Nb]      ) & 0xFF]      ) )
649ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic void aes_encrypt_nb_4(AESContext * ctx, unsigned int * block)
650ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
651ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int i;
652ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    static const int C1 = 1, C2 = 2, C3 = 3, Nb = 4;
653ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    unsigned int *keysched = ctx->keysched;
654ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    unsigned int newstate[4];
655ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    for (i = 0; i < ctx->Nr - 1; i++) {
656ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        ADD_ROUND_KEY_4;
657ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        MAKEWORD(0);
658ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        MAKEWORD(1);
659ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        MAKEWORD(2);
660ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        MAKEWORD(3);
661ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        MOVEWORD(0);
662ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        MOVEWORD(1);
663ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        MOVEWORD(2);
664ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        MOVEWORD(3);
665ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
666ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    ADD_ROUND_KEY_4;
667ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    LASTWORD(0);
668ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    LASTWORD(1);
669ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    LASTWORD(2);
670ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    LASTWORD(3);
671ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    MOVEWORD(0);
672ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    MOVEWORD(1);
673ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    MOVEWORD(2);
674ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    MOVEWORD(3);
675ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    ADD_ROUND_KEY_4;
676ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
677ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic void aes_encrypt_nb_6(AESContext * ctx, unsigned int * block)
678ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
679ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int i;
680ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    static const int C1 = 1, C2 = 2, C3 = 3, Nb = 6;
681ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    unsigned int *keysched = ctx->keysched;
682ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    unsigned int newstate[6];
683ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    for (i = 0; i < ctx->Nr - 1; i++) {
684ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        ADD_ROUND_KEY_6;
685ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        MAKEWORD(0);
686ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        MAKEWORD(1);
687ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        MAKEWORD(2);
688ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        MAKEWORD(3);
689ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        MAKEWORD(4);
690ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        MAKEWORD(5);
691ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        MOVEWORD(0);
692ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        MOVEWORD(1);
693ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        MOVEWORD(2);
694ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        MOVEWORD(3);
695ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        MOVEWORD(4);
696ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        MOVEWORD(5);
697ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
698ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    ADD_ROUND_KEY_6;
699ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    LASTWORD(0);
700ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    LASTWORD(1);
701ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    LASTWORD(2);
702ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    LASTWORD(3);
703ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    LASTWORD(4);
704ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    LASTWORD(5);
705ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    MOVEWORD(0);
706ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    MOVEWORD(1);
707ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    MOVEWORD(2);
708ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    MOVEWORD(3);
709ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    MOVEWORD(4);
710ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    MOVEWORD(5);
711ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    ADD_ROUND_KEY_6;
712ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
713ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic void aes_encrypt_nb_8(AESContext * ctx, unsigned int * block)
714ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
715ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int i;
716ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    static const int C1 = 1, C2 = 3, C3 = 4, Nb = 8;
717ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    unsigned int *keysched = ctx->keysched;
718ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    unsigned int newstate[8];
719ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    for (i = 0; i < ctx->Nr - 1; i++) {
720ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        ADD_ROUND_KEY_8;
721ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        MAKEWORD(0);
722ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        MAKEWORD(1);
723ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        MAKEWORD(2);
724ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        MAKEWORD(3);
725ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        MAKEWORD(4);
726ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        MAKEWORD(5);
727ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        MAKEWORD(6);
728ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        MAKEWORD(7);
729ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        MOVEWORD(0);
730ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        MOVEWORD(1);
731ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        MOVEWORD(2);
732ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        MOVEWORD(3);
733ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        MOVEWORD(4);
734ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        MOVEWORD(5);
735ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        MOVEWORD(6);
736ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        MOVEWORD(7);
737ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
738ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    ADD_ROUND_KEY_8;
739ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    LASTWORD(0);
740ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    LASTWORD(1);
741ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    LASTWORD(2);
742ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    LASTWORD(3);
743ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    LASTWORD(4);
744ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    LASTWORD(5);
745ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    LASTWORD(6);
746ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    LASTWORD(7);
747ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    MOVEWORD(0);
748ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    MOVEWORD(1);
749ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    MOVEWORD(2);
750ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    MOVEWORD(3);
751ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    MOVEWORD(4);
752ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    MOVEWORD(5);
753ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    MOVEWORD(6);
754ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    MOVEWORD(7);
755ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    ADD_ROUND_KEY_8;
756ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
757ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#undef MAKEWORD
758ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#undef LASTWORD
759ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define MAKEWORD(i) ( newstate[i] = (D0[(block[i] >> 24) & 0xFF] ^ \
760ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                     D1[(block[(i+C1)%Nb] >> 16) & 0xFF] ^ \
761ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                     D2[(block[(i+C2)%Nb] >> 8) & 0xFF] ^ \
762ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                     D3[block[(i+C3)%Nb] & 0xFF]) )
763ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define LASTWORD(i) (newstate[i] = (Sboxinv[(block[i] >> 24) & 0xFF] << 24) | \
764ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                   (Sboxinv[(block[(i+C1)%Nb] >> 16) & 0xFF] << 16) | \
765ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                   (Sboxinv[(block[(i+C2)%Nb] >>  8) & 0xFF] <<  8) | \
766ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                   (Sboxinv[(block[(i+C3)%Nb]      ) & 0xFF]      ) )
767ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic void aes_decrypt_nb_4(AESContext * ctx, unsigned int * block)
768ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
769ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int i;
770ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    static const int C1 = 4 - 1, C2 = 4 - 2, C3 = 4 - 3, Nb = 4;
771ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    unsigned int *keysched = ctx->invkeysched;
772ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    unsigned int newstate[4];
773ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    for (i = 0; i < ctx->Nr - 1; i++) {
774ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        ADD_ROUND_KEY_4;
775ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        MAKEWORD(0);
776ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        MAKEWORD(1);
777ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        MAKEWORD(2);
778ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        MAKEWORD(3);
779ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        MOVEWORD(0);
780ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        MOVEWORD(1);
781ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        MOVEWORD(2);
782ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        MOVEWORD(3);
783ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
784ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    ADD_ROUND_KEY_4;
785ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    LASTWORD(0);
786ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    LASTWORD(1);
787ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    LASTWORD(2);
788ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    LASTWORD(3);
789ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    MOVEWORD(0);
790ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    MOVEWORD(1);
791ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    MOVEWORD(2);
792ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    MOVEWORD(3);
793ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    ADD_ROUND_KEY_4;
794ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
795ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic void aes_decrypt_nb_6(AESContext * ctx, unsigned int * block)
796ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
797ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int i;
798ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    static const int C1 = 6 - 1, C2 = 6 - 2, C3 = 6 - 3, Nb = 6;
799ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    unsigned int *keysched = ctx->invkeysched;
800ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    unsigned int newstate[6];
801ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    for (i = 0; i < ctx->Nr - 1; i++) {
802ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        ADD_ROUND_KEY_6;
803ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        MAKEWORD(0);
804ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        MAKEWORD(1);
805ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        MAKEWORD(2);
806ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        MAKEWORD(3);
807ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        MAKEWORD(4);
808ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        MAKEWORD(5);
809ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        MOVEWORD(0);
810ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        MOVEWORD(1);
811ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        MOVEWORD(2);
812ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        MOVEWORD(3);
813ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        MOVEWORD(4);
814ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        MOVEWORD(5);
815ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
816ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    ADD_ROUND_KEY_6;
817ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    LASTWORD(0);
818ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    LASTWORD(1);
819ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    LASTWORD(2);
820ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    LASTWORD(3);
821ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    LASTWORD(4);
822ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    LASTWORD(5);
823ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    MOVEWORD(0);
824ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    MOVEWORD(1);
825ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    MOVEWORD(2);
826ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    MOVEWORD(3);
827ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    MOVEWORD(4);
828ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    MOVEWORD(5);
829ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    ADD_ROUND_KEY_6;
830ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
831ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic void aes_decrypt_nb_8(AESContext * ctx, unsigned int * block)
832ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
833ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int i;
834ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    static const int C1 = 8 - 1, C2 = 8 - 3, C3 = 8 - 4, Nb = 8;
835ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    unsigned int *keysched = ctx->invkeysched;
836ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    unsigned int newstate[8];
837ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    for (i = 0; i < ctx->Nr - 1; i++) {
838ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        ADD_ROUND_KEY_8;
839ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        MAKEWORD(0);
840ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        MAKEWORD(1);
841ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        MAKEWORD(2);
842ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        MAKEWORD(3);
843ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        MAKEWORD(4);
844ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        MAKEWORD(5);
845ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        MAKEWORD(6);
846ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        MAKEWORD(7);
847ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        MOVEWORD(0);
848ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        MOVEWORD(1);
849ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        MOVEWORD(2);
850ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        MOVEWORD(3);
851ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        MOVEWORD(4);
852ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        MOVEWORD(5);
853ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        MOVEWORD(6);
854ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        MOVEWORD(7);
855ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
856ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    ADD_ROUND_KEY_8;
857ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    LASTWORD(0);
858ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    LASTWORD(1);
859ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    LASTWORD(2);
860ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    LASTWORD(3);
861ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    LASTWORD(4);
862ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    LASTWORD(5);
863ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    LASTWORD(6);
864ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    LASTWORD(7);
865ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    MOVEWORD(0);
866ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    MOVEWORD(1);
867ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    MOVEWORD(2);
868ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    MOVEWORD(3);
869ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    MOVEWORD(4);
870ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    MOVEWORD(5);
871ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    MOVEWORD(6);
872ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    MOVEWORD(7);
873ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    ADD_ROUND_KEY_8;
874ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
875ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#undef MAKEWORD
876ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#undef LASTWORD
877ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic void aes_setup(AESContext * ctx, int blocklen,
878ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                      const unsigned char *key, int keylen)
879ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
880ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int i, j, Nk, rconst;
881ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    ASSERT(blocklen == 16 || blocklen == 24 || blocklen == 32);
882ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    ASSERT(keylen == 16 || keylen == 24 || keylen == 32);
883ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    Nk = keylen / 4;
884ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    ctx->Nb = blocklen / 4;
885ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    ctx->Nr = 6 + (ctx->Nb > Nk ? ctx->Nb : Nk);
886ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (ctx->Nb == 8) {
887ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        ctx->encrypt = aes_encrypt_nb_8, ctx->decrypt = aes_decrypt_nb_8;
888ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } else if (ctx->Nb == 6) {
889ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        ctx->encrypt = aes_encrypt_nb_6, ctx->decrypt = aes_decrypt_nb_6;
890ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } else if (ctx->Nb == 4) {
891ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        ctx->encrypt = aes_encrypt_nb_4, ctx->decrypt = aes_decrypt_nb_4;
892ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
893ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    rconst = 1;
894ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    for (i = 0; i < (ctx->Nr + 1) * ctx->Nb; i++) {
895ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (i < Nk) {
896ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            ctx->keysched[i] = GET_32BIT_MSB_FIRST(key + 4 * i);
897ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        } else {
898ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            unsigned int temp = ctx->keysched[i - 1];
899ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (i % Nk == 0) {
900ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                int a, b, c, d;
901ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                a = (temp >> 16) & 0xFF;
902ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                b = (temp >> 8) & 0xFF;
903ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                c = (temp >> 0) & 0xFF;
904ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                d = (temp >> 24) & 0xFF;
905ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                temp = Sbox[a] ^ rconst;
906ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                temp = (temp << 8) | Sbox[b];
907ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                temp = (temp << 8) | Sbox[c];
908ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                temp = (temp << 8) | Sbox[d];
909ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                rconst = mulby2(rconst);
910ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            } else if (i % Nk == 4 && Nk > 6) {
911ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                int a, b, c, d;
912ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                a = (temp >> 24) & 0xFF;
913ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                b = (temp >> 16) & 0xFF;
914ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                c = (temp >> 8) & 0xFF;
915ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                d = (temp >> 0) & 0xFF;
916ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                temp = Sbox[a];
917ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                temp = (temp << 8) | Sbox[b];
918ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                temp = (temp << 8) | Sbox[c];
919ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                temp = (temp << 8) | Sbox[d];
920ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
921ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            ctx->keysched[i] = ctx->keysched[i - Nk] ^ temp;
922ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
923ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
924ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    for (i = 0; i <= ctx->Nr; i++) {
925ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        for (j = 0; j < ctx->Nb; j++) {
926ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            unsigned int temp;
927ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            temp = ctx->keysched[(ctx->Nr - i) * ctx->Nb + j];
928ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (i != 0 && i != ctx->Nr) {
929ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                int a, b, c, d;
930ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                a = (temp >> 24) & 0xFF;
931ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                b = (temp >> 16) & 0xFF;
932ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                c = (temp >> 8) & 0xFF;
933ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                d = (temp >> 0) & 0xFF;
934ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                temp = D0[Sbox[a]];
935ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                temp ^= D1[Sbox[b]];
936ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                temp ^= D2[Sbox[c]];
937ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                temp ^= D3[Sbox[d]];
938ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
939ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            ctx->invkeysched[i * ctx->Nb + j] = temp;
940ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
941ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
942ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
943ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic void aes_decrypt(AESContext * ctx, unsigned int * block)
944ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
945ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    ctx->decrypt(ctx, block);
946ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
947ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic void aes_decrypt_cbc(unsigned char *dest, const unsigned char *src, int len, AESContext * ctx)
948ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
949ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    unsigned int iv[4], x[4], ct[4];
950ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int i;
951ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    ASSERT((len & 15) == 0);
952ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FXSYS_memcpy32(iv, ctx->iv, sizeof(iv));
953ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    while (len > 0) {
954ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        for (i = 0; i < 4; i++) {
955ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            x[i] = ct[i] = GET_32BIT_MSB_FIRST(src + 4 * i);
956ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
957ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        aes_decrypt(ctx, x);
958ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        for (i = 0; i < 4; i++) {
959ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            PUT_32BIT_MSB_FIRST(dest + 4 * i, iv[i] ^ x[i]);
960ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            iv[i] = ct[i];
961ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
962ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        dest += 16;
963ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        src += 16;
964ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        len -= 16;
965ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
966ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FXSYS_memcpy32(ctx->iv, iv, sizeof(iv));
967ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
968ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic void aes_encrypt(AESContext * ctx, unsigned int * block)
969ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
970ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    ctx->encrypt(ctx, block);
971ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
972ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic void aes_encrypt_cbc(unsigned char *dest, const unsigned char *src, int len, AESContext * ctx)
973ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
974ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    unsigned int iv[4];
975ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int i;
976ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    ASSERT((len & 15) == 0);
977ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FXSYS_memcpy32(iv, ctx->iv, sizeof(iv));
978ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    while (len > 0) {
979ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        for (i = 0; i < 4; i++) {
980ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            iv[i] ^= GET_32BIT_MSB_FIRST(src + 4 * i);
981ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
982ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        aes_encrypt(ctx, iv);
983ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        for (i = 0; i < 4; i++) {
984ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            PUT_32BIT_MSB_FIRST(dest + 4 * i, iv[i]);
985ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
986ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        dest += 16;
987ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        src += 16;
988ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        len -= 16;
989ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
990ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FXSYS_memcpy32(ctx->iv, iv, sizeof(iv));
991ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
992ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid CRYPT_AESSetKey(FX_LPVOID context, FX_DWORD blocklen, FX_LPCBYTE key, FX_DWORD keylen, FX_BOOL bEncrypt)
993ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
994ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    aes_setup((AESContext*)context, blocklen, key, keylen);
995ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
996ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid CRYPT_AESSetIV(FX_LPVOID context, FX_LPCBYTE iv)
997ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
998ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int i;
999ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    for (i = 0; i < ((AESContext*)context)->Nb; i++) {
1000ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        ((AESContext*)context)->iv[i] = GET_32BIT_MSB_FIRST(iv + 4 * i);
1001ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1002ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
1003ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid CRYPT_AESDecrypt(FX_LPVOID context, FX_LPBYTE dest, FX_LPCBYTE src, FX_DWORD len)
1004ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
1005ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    aes_decrypt_cbc(dest, src, len, (AESContext*)context);
1006ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
1007ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid CRYPT_AESEncrypt(FX_LPVOID context, FX_LPBYTE dest, FX_LPCBYTE src, FX_DWORD len)
1008ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
1009ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    aes_encrypt_cbc(dest, src, len, (AESContext*)context);
1010ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
1011ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifdef __cplusplus
1012ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov};
1013ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif
1014