1 /* public domain code from http://www.efgh.com/software/rijndael.htm */
2 #define FULL_UNROLL
3 
4 #include "rijndael.h"
5 
6 typedef unsigned long u32;
7 typedef unsigned char u8;
8 
9 static const u32 Te0[256] =
10 {
11   0xc66363a5U, 0xf87c7c84U, 0xee777799U, 0xf67b7b8dU,
12   0xfff2f20dU, 0xd66b6bbdU, 0xde6f6fb1U, 0x91c5c554U,
13   0x60303050U, 0x02010103U, 0xce6767a9U, 0x562b2b7dU,
14   0xe7fefe19U, 0xb5d7d762U, 0x4dababe6U, 0xec76769aU,
15   0x8fcaca45U, 0x1f82829dU, 0x89c9c940U, 0xfa7d7d87U,
16   0xeffafa15U, 0xb25959ebU, 0x8e4747c9U, 0xfbf0f00bU,
17   0x41adadecU, 0xb3d4d467U, 0x5fa2a2fdU, 0x45afafeaU,
18   0x239c9cbfU, 0x53a4a4f7U, 0xe4727296U, 0x9bc0c05bU,
19   0x75b7b7c2U, 0xe1fdfd1cU, 0x3d9393aeU, 0x4c26266aU,
20   0x6c36365aU, 0x7e3f3f41U, 0xf5f7f702U, 0x83cccc4fU,
21   0x6834345cU, 0x51a5a5f4U, 0xd1e5e534U, 0xf9f1f108U,
22   0xe2717193U, 0xabd8d873U, 0x62313153U, 0x2a15153fU,
23   0x0804040cU, 0x95c7c752U, 0x46232365U, 0x9dc3c35eU,
24   0x30181828U, 0x379696a1U, 0x0a05050fU, 0x2f9a9ab5U,
25   0x0e070709U, 0x24121236U, 0x1b80809bU, 0xdfe2e23dU,
26   0xcdebeb26U, 0x4e272769U, 0x7fb2b2cdU, 0xea75759fU,
27   0x1209091bU, 0x1d83839eU, 0x582c2c74U, 0x341a1a2eU,
28   0x361b1b2dU, 0xdc6e6eb2U, 0xb45a5aeeU, 0x5ba0a0fbU,
29   0xa45252f6U, 0x763b3b4dU, 0xb7d6d661U, 0x7db3b3ceU,
30   0x5229297bU, 0xdde3e33eU, 0x5e2f2f71U, 0x13848497U,
31   0xa65353f5U, 0xb9d1d168U, 0x00000000U, 0xc1eded2cU,
32   0x40202060U, 0xe3fcfc1fU, 0x79b1b1c8U, 0xb65b5bedU,
33   0xd46a6abeU, 0x8dcbcb46U, 0x67bebed9U, 0x7239394bU,
34   0x944a4adeU, 0x984c4cd4U, 0xb05858e8U, 0x85cfcf4aU,
35   0xbbd0d06bU, 0xc5efef2aU, 0x4faaaae5U, 0xedfbfb16U,
36   0x864343c5U, 0x9a4d4dd7U, 0x66333355U, 0x11858594U,
37   0x8a4545cfU, 0xe9f9f910U, 0x04020206U, 0xfe7f7f81U,
38   0xa05050f0U, 0x783c3c44U, 0x259f9fbaU, 0x4ba8a8e3U,
39   0xa25151f3U, 0x5da3a3feU, 0x804040c0U, 0x058f8f8aU,
40   0x3f9292adU, 0x219d9dbcU, 0x70383848U, 0xf1f5f504U,
41   0x63bcbcdfU, 0x77b6b6c1U, 0xafdada75U, 0x42212163U,
42   0x20101030U, 0xe5ffff1aU, 0xfdf3f30eU, 0xbfd2d26dU,
43   0x81cdcd4cU, 0x180c0c14U, 0x26131335U, 0xc3ecec2fU,
44   0xbe5f5fe1U, 0x359797a2U, 0x884444ccU, 0x2e171739U,
45   0x93c4c457U, 0x55a7a7f2U, 0xfc7e7e82U, 0x7a3d3d47U,
46   0xc86464acU, 0xba5d5de7U, 0x3219192bU, 0xe6737395U,
47   0xc06060a0U, 0x19818198U, 0x9e4f4fd1U, 0xa3dcdc7fU,
48   0x44222266U, 0x542a2a7eU, 0x3b9090abU, 0x0b888883U,
49   0x8c4646caU, 0xc7eeee29U, 0x6bb8b8d3U, 0x2814143cU,
50   0xa7dede79U, 0xbc5e5ee2U, 0x160b0b1dU, 0xaddbdb76U,
51   0xdbe0e03bU, 0x64323256U, 0x743a3a4eU, 0x140a0a1eU,
52   0x924949dbU, 0x0c06060aU, 0x4824246cU, 0xb85c5ce4U,
53   0x9fc2c25dU, 0xbdd3d36eU, 0x43acacefU, 0xc46262a6U,
54   0x399191a8U, 0x319595a4U, 0xd3e4e437U, 0xf279798bU,
55   0xd5e7e732U, 0x8bc8c843U, 0x6e373759U, 0xda6d6db7U,
56   0x018d8d8cU, 0xb1d5d564U, 0x9c4e4ed2U, 0x49a9a9e0U,
57   0xd86c6cb4U, 0xac5656faU, 0xf3f4f407U, 0xcfeaea25U,
58   0xca6565afU, 0xf47a7a8eU, 0x47aeaee9U, 0x10080818U,
59   0x6fbabad5U, 0xf0787888U, 0x4a25256fU, 0x5c2e2e72U,
60   0x381c1c24U, 0x57a6a6f1U, 0x73b4b4c7U, 0x97c6c651U,
61   0xcbe8e823U, 0xa1dddd7cU, 0xe874749cU, 0x3e1f1f21U,
62   0x964b4bddU, 0x61bdbddcU, 0x0d8b8b86U, 0x0f8a8a85U,
63   0xe0707090U, 0x7c3e3e42U, 0x71b5b5c4U, 0xcc6666aaU,
64   0x904848d8U, 0x06030305U, 0xf7f6f601U, 0x1c0e0e12U,
65   0xc26161a3U, 0x6a35355fU, 0xae5757f9U, 0x69b9b9d0U,
66   0x17868691U, 0x99c1c158U, 0x3a1d1d27U, 0x279e9eb9U,
67   0xd9e1e138U, 0xebf8f813U, 0x2b9898b3U, 0x22111133U,
68   0xd26969bbU, 0xa9d9d970U, 0x078e8e89U, 0x339494a7U,
69   0x2d9b9bb6U, 0x3c1e1e22U, 0x15878792U, 0xc9e9e920U,
70   0x87cece49U, 0xaa5555ffU, 0x50282878U, 0xa5dfdf7aU,
71   0x038c8c8fU, 0x59a1a1f8U, 0x09898980U, 0x1a0d0d17U,
72   0x65bfbfdaU, 0xd7e6e631U, 0x844242c6U, 0xd06868b8U,
73   0x824141c3U, 0x299999b0U, 0x5a2d2d77U, 0x1e0f0f11U,
74   0x7bb0b0cbU, 0xa85454fcU, 0x6dbbbbd6U, 0x2c16163aU,
75 };
76 
77 static const u32 Te1[256] =
78 {
79   0xa5c66363U, 0x84f87c7cU, 0x99ee7777U, 0x8df67b7bU,
80   0x0dfff2f2U, 0xbdd66b6bU, 0xb1de6f6fU, 0x5491c5c5U,
81   0x50603030U, 0x03020101U, 0xa9ce6767U, 0x7d562b2bU,
82   0x19e7fefeU, 0x62b5d7d7U, 0xe64dababU, 0x9aec7676U,
83   0x458fcacaU, 0x9d1f8282U, 0x4089c9c9U, 0x87fa7d7dU,
84   0x15effafaU, 0xebb25959U, 0xc98e4747U, 0x0bfbf0f0U,
85   0xec41adadU, 0x67b3d4d4U, 0xfd5fa2a2U, 0xea45afafU,
86   0xbf239c9cU, 0xf753a4a4U, 0x96e47272U, 0x5b9bc0c0U,
87   0xc275b7b7U, 0x1ce1fdfdU, 0xae3d9393U, 0x6a4c2626U,
88   0x5a6c3636U, 0x417e3f3fU, 0x02f5f7f7U, 0x4f83ccccU,
89   0x5c683434U, 0xf451a5a5U, 0x34d1e5e5U, 0x08f9f1f1U,
90   0x93e27171U, 0x73abd8d8U, 0x53623131U, 0x3f2a1515U,
91   0x0c080404U, 0x5295c7c7U, 0x65462323U, 0x5e9dc3c3U,
92   0x28301818U, 0xa1379696U, 0x0f0a0505U, 0xb52f9a9aU,
93   0x090e0707U, 0x36241212U, 0x9b1b8080U, 0x3ddfe2e2U,
94   0x26cdebebU, 0x694e2727U, 0xcd7fb2b2U, 0x9fea7575U,
95   0x1b120909U, 0x9e1d8383U, 0x74582c2cU, 0x2e341a1aU,
96   0x2d361b1bU, 0xb2dc6e6eU, 0xeeb45a5aU, 0xfb5ba0a0U,
97   0xf6a45252U, 0x4d763b3bU, 0x61b7d6d6U, 0xce7db3b3U,
98   0x7b522929U, 0x3edde3e3U, 0x715e2f2fU, 0x97138484U,
99   0xf5a65353U, 0x68b9d1d1U, 0x00000000U, 0x2cc1ededU,
100   0x60402020U, 0x1fe3fcfcU, 0xc879b1b1U, 0xedb65b5bU,
101   0xbed46a6aU, 0x468dcbcbU, 0xd967bebeU, 0x4b723939U,
102   0xde944a4aU, 0xd4984c4cU, 0xe8b05858U, 0x4a85cfcfU,
103   0x6bbbd0d0U, 0x2ac5efefU, 0xe54faaaaU, 0x16edfbfbU,
104   0xc5864343U, 0xd79a4d4dU, 0x55663333U, 0x94118585U,
105   0xcf8a4545U, 0x10e9f9f9U, 0x06040202U, 0x81fe7f7fU,
106   0xf0a05050U, 0x44783c3cU, 0xba259f9fU, 0xe34ba8a8U,
107   0xf3a25151U, 0xfe5da3a3U, 0xc0804040U, 0x8a058f8fU,
108   0xad3f9292U, 0xbc219d9dU, 0x48703838U, 0x04f1f5f5U,
109   0xdf63bcbcU, 0xc177b6b6U, 0x75afdadaU, 0x63422121U,
110   0x30201010U, 0x1ae5ffffU, 0x0efdf3f3U, 0x6dbfd2d2U,
111   0x4c81cdcdU, 0x14180c0cU, 0x35261313U, 0x2fc3ececU,
112   0xe1be5f5fU, 0xa2359797U, 0xcc884444U, 0x392e1717U,
113   0x5793c4c4U, 0xf255a7a7U, 0x82fc7e7eU, 0x477a3d3dU,
114   0xacc86464U, 0xe7ba5d5dU, 0x2b321919U, 0x95e67373U,
115   0xa0c06060U, 0x98198181U, 0xd19e4f4fU, 0x7fa3dcdcU,
116   0x66442222U, 0x7e542a2aU, 0xab3b9090U, 0x830b8888U,
117   0xca8c4646U, 0x29c7eeeeU, 0xd36bb8b8U, 0x3c281414U,
118   0x79a7dedeU, 0xe2bc5e5eU, 0x1d160b0bU, 0x76addbdbU,
119   0x3bdbe0e0U, 0x56643232U, 0x4e743a3aU, 0x1e140a0aU,
120   0xdb924949U, 0x0a0c0606U, 0x6c482424U, 0xe4b85c5cU,
121   0x5d9fc2c2U, 0x6ebdd3d3U, 0xef43acacU, 0xa6c46262U,
122   0xa8399191U, 0xa4319595U, 0x37d3e4e4U, 0x8bf27979U,
123   0x32d5e7e7U, 0x438bc8c8U, 0x596e3737U, 0xb7da6d6dU,
124   0x8c018d8dU, 0x64b1d5d5U, 0xd29c4e4eU, 0xe049a9a9U,
125   0xb4d86c6cU, 0xfaac5656U, 0x07f3f4f4U, 0x25cfeaeaU,
126   0xafca6565U, 0x8ef47a7aU, 0xe947aeaeU, 0x18100808U,
127   0xd56fbabaU, 0x88f07878U, 0x6f4a2525U, 0x725c2e2eU,
128   0x24381c1cU, 0xf157a6a6U, 0xc773b4b4U, 0x5197c6c6U,
129   0x23cbe8e8U, 0x7ca1ddddU, 0x9ce87474U, 0x213e1f1fU,
130   0xdd964b4bU, 0xdc61bdbdU, 0x860d8b8bU, 0x850f8a8aU,
131   0x90e07070U, 0x427c3e3eU, 0xc471b5b5U, 0xaacc6666U,
132   0xd8904848U, 0x05060303U, 0x01f7f6f6U, 0x121c0e0eU,
133   0xa3c26161U, 0x5f6a3535U, 0xf9ae5757U, 0xd069b9b9U,
134   0x91178686U, 0x5899c1c1U, 0x273a1d1dU, 0xb9279e9eU,
135   0x38d9e1e1U, 0x13ebf8f8U, 0xb32b9898U, 0x33221111U,
136   0xbbd26969U, 0x70a9d9d9U, 0x89078e8eU, 0xa7339494U,
137   0xb62d9b9bU, 0x223c1e1eU, 0x92158787U, 0x20c9e9e9U,
138   0x4987ceceU, 0xffaa5555U, 0x78502828U, 0x7aa5dfdfU,
139   0x8f038c8cU, 0xf859a1a1U, 0x80098989U, 0x171a0d0dU,
140   0xda65bfbfU, 0x31d7e6e6U, 0xc6844242U, 0xb8d06868U,
141   0xc3824141U, 0xb0299999U, 0x775a2d2dU, 0x111e0f0fU,
142   0xcb7bb0b0U, 0xfca85454U, 0xd66dbbbbU, 0x3a2c1616U,
143 };
144 
145 static const u32 Te2[256] =
146 {
147   0x63a5c663U, 0x7c84f87cU, 0x7799ee77U, 0x7b8df67bU,
148   0xf20dfff2U, 0x6bbdd66bU, 0x6fb1de6fU, 0xc55491c5U,
149   0x30506030U, 0x01030201U, 0x67a9ce67U, 0x2b7d562bU,
150   0xfe19e7feU, 0xd762b5d7U, 0xabe64dabU, 0x769aec76U,
151   0xca458fcaU, 0x829d1f82U, 0xc94089c9U, 0x7d87fa7dU,
152   0xfa15effaU, 0x59ebb259U, 0x47c98e47U, 0xf00bfbf0U,
153   0xadec41adU, 0xd467b3d4U, 0xa2fd5fa2U, 0xafea45afU,
154   0x9cbf239cU, 0xa4f753a4U, 0x7296e472U, 0xc05b9bc0U,
155   0xb7c275b7U, 0xfd1ce1fdU, 0x93ae3d93U, 0x266a4c26U,
156   0x365a6c36U, 0x3f417e3fU, 0xf702f5f7U, 0xcc4f83ccU,
157   0x345c6834U, 0xa5f451a5U, 0xe534d1e5U, 0xf108f9f1U,
158   0x7193e271U, 0xd873abd8U, 0x31536231U, 0x153f2a15U,
159   0x040c0804U, 0xc75295c7U, 0x23654623U, 0xc35e9dc3U,
160   0x18283018U, 0x96a13796U, 0x050f0a05U, 0x9ab52f9aU,
161   0x07090e07U, 0x12362412U, 0x809b1b80U, 0xe23ddfe2U,
162   0xeb26cdebU, 0x27694e27U, 0xb2cd7fb2U, 0x759fea75U,
163   0x091b1209U, 0x839e1d83U, 0x2c74582cU, 0x1a2e341aU,
164   0x1b2d361bU, 0x6eb2dc6eU, 0x5aeeb45aU, 0xa0fb5ba0U,
165   0x52f6a452U, 0x3b4d763bU, 0xd661b7d6U, 0xb3ce7db3U,
166   0x297b5229U, 0xe33edde3U, 0x2f715e2fU, 0x84971384U,
167   0x53f5a653U, 0xd168b9d1U, 0x00000000U, 0xed2cc1edU,
168   0x20604020U, 0xfc1fe3fcU, 0xb1c879b1U, 0x5bedb65bU,
169   0x6abed46aU, 0xcb468dcbU, 0xbed967beU, 0x394b7239U,
170   0x4ade944aU, 0x4cd4984cU, 0x58e8b058U, 0xcf4a85cfU,
171   0xd06bbbd0U, 0xef2ac5efU, 0xaae54faaU, 0xfb16edfbU,
172   0x43c58643U, 0x4dd79a4dU, 0x33556633U, 0x85941185U,
173   0x45cf8a45U, 0xf910e9f9U, 0x02060402U, 0x7f81fe7fU,
174   0x50f0a050U, 0x3c44783cU, 0x9fba259fU, 0xa8e34ba8U,
175   0x51f3a251U, 0xa3fe5da3U, 0x40c08040U, 0x8f8a058fU,
176   0x92ad3f92U, 0x9dbc219dU, 0x38487038U, 0xf504f1f5U,
177   0xbcdf63bcU, 0xb6c177b6U, 0xda75afdaU, 0x21634221U,
178   0x10302010U, 0xff1ae5ffU, 0xf30efdf3U, 0xd26dbfd2U,
179   0xcd4c81cdU, 0x0c14180cU, 0x13352613U, 0xec2fc3ecU,
180   0x5fe1be5fU, 0x97a23597U, 0x44cc8844U, 0x17392e17U,
181   0xc45793c4U, 0xa7f255a7U, 0x7e82fc7eU, 0x3d477a3dU,
182   0x64acc864U, 0x5de7ba5dU, 0x192b3219U, 0x7395e673U,
183   0x60a0c060U, 0x81981981U, 0x4fd19e4fU, 0xdc7fa3dcU,
184   0x22664422U, 0x2a7e542aU, 0x90ab3b90U, 0x88830b88U,
185   0x46ca8c46U, 0xee29c7eeU, 0xb8d36bb8U, 0x143c2814U,
186   0xde79a7deU, 0x5ee2bc5eU, 0x0b1d160bU, 0xdb76addbU,
187   0xe03bdbe0U, 0x32566432U, 0x3a4e743aU, 0x0a1e140aU,
188   0x49db9249U, 0x060a0c06U, 0x246c4824U, 0x5ce4b85cU,
189   0xc25d9fc2U, 0xd36ebdd3U, 0xacef43acU, 0x62a6c462U,
190   0x91a83991U, 0x95a43195U, 0xe437d3e4U, 0x798bf279U,
191   0xe732d5e7U, 0xc8438bc8U, 0x37596e37U, 0x6db7da6dU,
192   0x8d8c018dU, 0xd564b1d5U, 0x4ed29c4eU, 0xa9e049a9U,
193   0x6cb4d86cU, 0x56faac56U, 0xf407f3f4U, 0xea25cfeaU,
194   0x65afca65U, 0x7a8ef47aU, 0xaee947aeU, 0x08181008U,
195   0xbad56fbaU, 0x7888f078U, 0x256f4a25U, 0x2e725c2eU,
196   0x1c24381cU, 0xa6f157a6U, 0xb4c773b4U, 0xc65197c6U,
197   0xe823cbe8U, 0xdd7ca1ddU, 0x749ce874U, 0x1f213e1fU,
198   0x4bdd964bU, 0xbddc61bdU, 0x8b860d8bU, 0x8a850f8aU,
199   0x7090e070U, 0x3e427c3eU, 0xb5c471b5U, 0x66aacc66U,
200   0x48d89048U, 0x03050603U, 0xf601f7f6U, 0x0e121c0eU,
201   0x61a3c261U, 0x355f6a35U, 0x57f9ae57U, 0xb9d069b9U,
202   0x86911786U, 0xc15899c1U, 0x1d273a1dU, 0x9eb9279eU,
203   0xe138d9e1U, 0xf813ebf8U, 0x98b32b98U, 0x11332211U,
204   0x69bbd269U, 0xd970a9d9U, 0x8e89078eU, 0x94a73394U,
205   0x9bb62d9bU, 0x1e223c1eU, 0x87921587U, 0xe920c9e9U,
206   0xce4987ceU, 0x55ffaa55U, 0x28785028U, 0xdf7aa5dfU,
207   0x8c8f038cU, 0xa1f859a1U, 0x89800989U, 0x0d171a0dU,
208   0xbfda65bfU, 0xe631d7e6U, 0x42c68442U, 0x68b8d068U,
209   0x41c38241U, 0x99b02999U, 0x2d775a2dU, 0x0f111e0fU,
210   0xb0cb7bb0U, 0x54fca854U, 0xbbd66dbbU, 0x163a2c16U,
211 };
212 
213 static const u32 Te3[256] =
214 {
215   0x6363a5c6U, 0x7c7c84f8U, 0x777799eeU, 0x7b7b8df6U,
216   0xf2f20dffU, 0x6b6bbdd6U, 0x6f6fb1deU, 0xc5c55491U,
217   0x30305060U, 0x01010302U, 0x6767a9ceU, 0x2b2b7d56U,
218   0xfefe19e7U, 0xd7d762b5U, 0xababe64dU, 0x76769aecU,
219   0xcaca458fU, 0x82829d1fU, 0xc9c94089U, 0x7d7d87faU,
220   0xfafa15efU, 0x5959ebb2U, 0x4747c98eU, 0xf0f00bfbU,
221   0xadadec41U, 0xd4d467b3U, 0xa2a2fd5fU, 0xafafea45U,
222   0x9c9cbf23U, 0xa4a4f753U, 0x727296e4U, 0xc0c05b9bU,
223   0xb7b7c275U, 0xfdfd1ce1U, 0x9393ae3dU, 0x26266a4cU,
224   0x36365a6cU, 0x3f3f417eU, 0xf7f702f5U, 0xcccc4f83U,
225   0x34345c68U, 0xa5a5f451U, 0xe5e534d1U, 0xf1f108f9U,
226   0x717193e2U, 0xd8d873abU, 0x31315362U, 0x15153f2aU,
227   0x04040c08U, 0xc7c75295U, 0x23236546U, 0xc3c35e9dU,
228   0x18182830U, 0x9696a137U, 0x05050f0aU, 0x9a9ab52fU,
229   0x0707090eU, 0x12123624U, 0x80809b1bU, 0xe2e23ddfU,
230   0xebeb26cdU, 0x2727694eU, 0xb2b2cd7fU, 0x75759feaU,
231   0x09091b12U, 0x83839e1dU, 0x2c2c7458U, 0x1a1a2e34U,
232   0x1b1b2d36U, 0x6e6eb2dcU, 0x5a5aeeb4U, 0xa0a0fb5bU,
233   0x5252f6a4U, 0x3b3b4d76U, 0xd6d661b7U, 0xb3b3ce7dU,
234   0x29297b52U, 0xe3e33eddU, 0x2f2f715eU, 0x84849713U,
235   0x5353f5a6U, 0xd1d168b9U, 0x00000000U, 0xeded2cc1U,
236   0x20206040U, 0xfcfc1fe3U, 0xb1b1c879U, 0x5b5bedb6U,
237   0x6a6abed4U, 0xcbcb468dU, 0xbebed967U, 0x39394b72U,
238   0x4a4ade94U, 0x4c4cd498U, 0x5858e8b0U, 0xcfcf4a85U,
239   0xd0d06bbbU, 0xefef2ac5U, 0xaaaae54fU, 0xfbfb16edU,
240   0x4343c586U, 0x4d4dd79aU, 0x33335566U, 0x85859411U,
241   0x4545cf8aU, 0xf9f910e9U, 0x02020604U, 0x7f7f81feU,
242   0x5050f0a0U, 0x3c3c4478U, 0x9f9fba25U, 0xa8a8e34bU,
243   0x5151f3a2U, 0xa3a3fe5dU, 0x4040c080U, 0x8f8f8a05U,
244   0x9292ad3fU, 0x9d9dbc21U, 0x38384870U, 0xf5f504f1U,
245   0xbcbcdf63U, 0xb6b6c177U, 0xdada75afU, 0x21216342U,
246   0x10103020U, 0xffff1ae5U, 0xf3f30efdU, 0xd2d26dbfU,
247   0xcdcd4c81U, 0x0c0c1418U, 0x13133526U, 0xecec2fc3U,
248   0x5f5fe1beU, 0x9797a235U, 0x4444cc88U, 0x1717392eU,
249   0xc4c45793U, 0xa7a7f255U, 0x7e7e82fcU, 0x3d3d477aU,
250   0x6464acc8U, 0x5d5de7baU, 0x19192b32U, 0x737395e6U,
251   0x6060a0c0U, 0x81819819U, 0x4f4fd19eU, 0xdcdc7fa3U,
252   0x22226644U, 0x2a2a7e54U, 0x9090ab3bU, 0x8888830bU,
253   0x4646ca8cU, 0xeeee29c7U, 0xb8b8d36bU, 0x14143c28U,
254   0xdede79a7U, 0x5e5ee2bcU, 0x0b0b1d16U, 0xdbdb76adU,
255   0xe0e03bdbU, 0x32325664U, 0x3a3a4e74U, 0x0a0a1e14U,
256   0x4949db92U, 0x06060a0cU, 0x24246c48U, 0x5c5ce4b8U,
257   0xc2c25d9fU, 0xd3d36ebdU, 0xacacef43U, 0x6262a6c4U,
258   0x9191a839U, 0x9595a431U, 0xe4e437d3U, 0x79798bf2U,
259   0xe7e732d5U, 0xc8c8438bU, 0x3737596eU, 0x6d6db7daU,
260   0x8d8d8c01U, 0xd5d564b1U, 0x4e4ed29cU, 0xa9a9e049U,
261   0x6c6cb4d8U, 0x5656faacU, 0xf4f407f3U, 0xeaea25cfU,
262   0x6565afcaU, 0x7a7a8ef4U, 0xaeaee947U, 0x08081810U,
263   0xbabad56fU, 0x787888f0U, 0x25256f4aU, 0x2e2e725cU,
264   0x1c1c2438U, 0xa6a6f157U, 0xb4b4c773U, 0xc6c65197U,
265   0xe8e823cbU, 0xdddd7ca1U, 0x74749ce8U, 0x1f1f213eU,
266   0x4b4bdd96U, 0xbdbddc61U, 0x8b8b860dU, 0x8a8a850fU,
267   0x707090e0U, 0x3e3e427cU, 0xb5b5c471U, 0x6666aaccU,
268   0x4848d890U, 0x03030506U, 0xf6f601f7U, 0x0e0e121cU,
269   0x6161a3c2U, 0x35355f6aU, 0x5757f9aeU, 0xb9b9d069U,
270   0x86869117U, 0xc1c15899U, 0x1d1d273aU, 0x9e9eb927U,
271   0xe1e138d9U, 0xf8f813ebU, 0x9898b32bU, 0x11113322U,
272   0x6969bbd2U, 0xd9d970a9U, 0x8e8e8907U, 0x9494a733U,
273   0x9b9bb62dU, 0x1e1e223cU, 0x87879215U, 0xe9e920c9U,
274   0xcece4987U, 0x5555ffaaU, 0x28287850U, 0xdfdf7aa5U,
275   0x8c8c8f03U, 0xa1a1f859U, 0x89898009U, 0x0d0d171aU,
276   0xbfbfda65U, 0xe6e631d7U, 0x4242c684U, 0x6868b8d0U,
277   0x4141c382U, 0x9999b029U, 0x2d2d775aU, 0x0f0f111eU,
278   0xb0b0cb7bU, 0x5454fca8U, 0xbbbbd66dU, 0x16163a2cU,
279 };
280 
281 static const u32 Te4[256] =
282 {
283   0x63636363U, 0x7c7c7c7cU, 0x77777777U, 0x7b7b7b7bU,
284   0xf2f2f2f2U, 0x6b6b6b6bU, 0x6f6f6f6fU, 0xc5c5c5c5U,
285   0x30303030U, 0x01010101U, 0x67676767U, 0x2b2b2b2bU,
286   0xfefefefeU, 0xd7d7d7d7U, 0xababababU, 0x76767676U,
287   0xcacacacaU, 0x82828282U, 0xc9c9c9c9U, 0x7d7d7d7dU,
288   0xfafafafaU, 0x59595959U, 0x47474747U, 0xf0f0f0f0U,
289   0xadadadadU, 0xd4d4d4d4U, 0xa2a2a2a2U, 0xafafafafU,
290   0x9c9c9c9cU, 0xa4a4a4a4U, 0x72727272U, 0xc0c0c0c0U,
291   0xb7b7b7b7U, 0xfdfdfdfdU, 0x93939393U, 0x26262626U,
292   0x36363636U, 0x3f3f3f3fU, 0xf7f7f7f7U, 0xccccccccU,
293   0x34343434U, 0xa5a5a5a5U, 0xe5e5e5e5U, 0xf1f1f1f1U,
294   0x71717171U, 0xd8d8d8d8U, 0x31313131U, 0x15151515U,
295   0x04040404U, 0xc7c7c7c7U, 0x23232323U, 0xc3c3c3c3U,
296   0x18181818U, 0x96969696U, 0x05050505U, 0x9a9a9a9aU,
297   0x07070707U, 0x12121212U, 0x80808080U, 0xe2e2e2e2U,
298   0xebebebebU, 0x27272727U, 0xb2b2b2b2U, 0x75757575U,
299   0x09090909U, 0x83838383U, 0x2c2c2c2cU, 0x1a1a1a1aU,
300   0x1b1b1b1bU, 0x6e6e6e6eU, 0x5a5a5a5aU, 0xa0a0a0a0U,
301   0x52525252U, 0x3b3b3b3bU, 0xd6d6d6d6U, 0xb3b3b3b3U,
302   0x29292929U, 0xe3e3e3e3U, 0x2f2f2f2fU, 0x84848484U,
303   0x53535353U, 0xd1d1d1d1U, 0x00000000U, 0xededededU,
304   0x20202020U, 0xfcfcfcfcU, 0xb1b1b1b1U, 0x5b5b5b5bU,
305   0x6a6a6a6aU, 0xcbcbcbcbU, 0xbebebebeU, 0x39393939U,
306   0x4a4a4a4aU, 0x4c4c4c4cU, 0x58585858U, 0xcfcfcfcfU,
307   0xd0d0d0d0U, 0xefefefefU, 0xaaaaaaaaU, 0xfbfbfbfbU,
308   0x43434343U, 0x4d4d4d4dU, 0x33333333U, 0x85858585U,
309   0x45454545U, 0xf9f9f9f9U, 0x02020202U, 0x7f7f7f7fU,
310   0x50505050U, 0x3c3c3c3cU, 0x9f9f9f9fU, 0xa8a8a8a8U,
311   0x51515151U, 0xa3a3a3a3U, 0x40404040U, 0x8f8f8f8fU,
312   0x92929292U, 0x9d9d9d9dU, 0x38383838U, 0xf5f5f5f5U,
313   0xbcbcbcbcU, 0xb6b6b6b6U, 0xdadadadaU, 0x21212121U,
314   0x10101010U, 0xffffffffU, 0xf3f3f3f3U, 0xd2d2d2d2U,
315   0xcdcdcdcdU, 0x0c0c0c0cU, 0x13131313U, 0xececececU,
316   0x5f5f5f5fU, 0x97979797U, 0x44444444U, 0x17171717U,
317   0xc4c4c4c4U, 0xa7a7a7a7U, 0x7e7e7e7eU, 0x3d3d3d3dU,
318   0x64646464U, 0x5d5d5d5dU, 0x19191919U, 0x73737373U,
319   0x60606060U, 0x81818181U, 0x4f4f4f4fU, 0xdcdcdcdcU,
320   0x22222222U, 0x2a2a2a2aU, 0x90909090U, 0x88888888U,
321   0x46464646U, 0xeeeeeeeeU, 0xb8b8b8b8U, 0x14141414U,
322   0xdedededeU, 0x5e5e5e5eU, 0x0b0b0b0bU, 0xdbdbdbdbU,
323   0xe0e0e0e0U, 0x32323232U, 0x3a3a3a3aU, 0x0a0a0a0aU,
324   0x49494949U, 0x06060606U, 0x24242424U, 0x5c5c5c5cU,
325   0xc2c2c2c2U, 0xd3d3d3d3U, 0xacacacacU, 0x62626262U,
326   0x91919191U, 0x95959595U, 0xe4e4e4e4U, 0x79797979U,
327   0xe7e7e7e7U, 0xc8c8c8c8U, 0x37373737U, 0x6d6d6d6dU,
328   0x8d8d8d8dU, 0xd5d5d5d5U, 0x4e4e4e4eU, 0xa9a9a9a9U,
329   0x6c6c6c6cU, 0x56565656U, 0xf4f4f4f4U, 0xeaeaeaeaU,
330   0x65656565U, 0x7a7a7a7aU, 0xaeaeaeaeU, 0x08080808U,
331   0xbabababaU, 0x78787878U, 0x25252525U, 0x2e2e2e2eU,
332   0x1c1c1c1cU, 0xa6a6a6a6U, 0xb4b4b4b4U, 0xc6c6c6c6U,
333   0xe8e8e8e8U, 0xddddddddU, 0x74747474U, 0x1f1f1f1fU,
334   0x4b4b4b4bU, 0xbdbdbdbdU, 0x8b8b8b8bU, 0x8a8a8a8aU,
335   0x70707070U, 0x3e3e3e3eU, 0xb5b5b5b5U, 0x66666666U,
336   0x48484848U, 0x03030303U, 0xf6f6f6f6U, 0x0e0e0e0eU,
337   0x61616161U, 0x35353535U, 0x57575757U, 0xb9b9b9b9U,
338   0x86868686U, 0xc1c1c1c1U, 0x1d1d1d1dU, 0x9e9e9e9eU,
339   0xe1e1e1e1U, 0xf8f8f8f8U, 0x98989898U, 0x11111111U,
340   0x69696969U, 0xd9d9d9d9U, 0x8e8e8e8eU, 0x94949494U,
341   0x9b9b9b9bU, 0x1e1e1e1eU, 0x87878787U, 0xe9e9e9e9U,
342   0xcecececeU, 0x55555555U, 0x28282828U, 0xdfdfdfdfU,
343   0x8c8c8c8cU, 0xa1a1a1a1U, 0x89898989U, 0x0d0d0d0dU,
344   0xbfbfbfbfU, 0xe6e6e6e6U, 0x42424242U, 0x68686868U,
345   0x41414141U, 0x99999999U, 0x2d2d2d2dU, 0x0f0f0f0fU,
346   0xb0b0b0b0U, 0x54545454U, 0xbbbbbbbbU, 0x16161616U,
347 };
348 
349 static const u32 Td0[256] =
350 {
351   0x51f4a750U, 0x7e416553U, 0x1a17a4c3U, 0x3a275e96U,
352   0x3bab6bcbU, 0x1f9d45f1U, 0xacfa58abU, 0x4be30393U,
353   0x2030fa55U, 0xad766df6U, 0x88cc7691U, 0xf5024c25U,
354   0x4fe5d7fcU, 0xc52acbd7U, 0x26354480U, 0xb562a38fU,
355   0xdeb15a49U, 0x25ba1b67U, 0x45ea0e98U, 0x5dfec0e1U,
356   0xc32f7502U, 0x814cf012U, 0x8d4697a3U, 0x6bd3f9c6U,
357   0x038f5fe7U, 0x15929c95U, 0xbf6d7aebU, 0x955259daU,
358   0xd4be832dU, 0x587421d3U, 0x49e06929U, 0x8ec9c844U,
359   0x75c2896aU, 0xf48e7978U, 0x99583e6bU, 0x27b971ddU,
360   0xbee14fb6U, 0xf088ad17U, 0xc920ac66U, 0x7dce3ab4U,
361   0x63df4a18U, 0xe51a3182U, 0x97513360U, 0x62537f45U,
362   0xb16477e0U, 0xbb6bae84U, 0xfe81a01cU, 0xf9082b94U,
363   0x70486858U, 0x8f45fd19U, 0x94de6c87U, 0x527bf8b7U,
364   0xab73d323U, 0x724b02e2U, 0xe31f8f57U, 0x6655ab2aU,
365   0xb2eb2807U, 0x2fb5c203U, 0x86c57b9aU, 0xd33708a5U,
366   0x302887f2U, 0x23bfa5b2U, 0x02036abaU, 0xed16825cU,
367   0x8acf1c2bU, 0xa779b492U, 0xf307f2f0U, 0x4e69e2a1U,
368   0x65daf4cdU, 0x0605bed5U, 0xd134621fU, 0xc4a6fe8aU,
369   0x342e539dU, 0xa2f355a0U, 0x058ae132U, 0xa4f6eb75U,
370   0x0b83ec39U, 0x4060efaaU, 0x5e719f06U, 0xbd6e1051U,
371   0x3e218af9U, 0x96dd063dU, 0xdd3e05aeU, 0x4de6bd46U,
372   0x91548db5U, 0x71c45d05U, 0x0406d46fU, 0x605015ffU,
373   0x1998fb24U, 0xd6bde997U, 0x894043ccU, 0x67d99e77U,
374   0xb0e842bdU, 0x07898b88U, 0xe7195b38U, 0x79c8eedbU,
375   0xa17c0a47U, 0x7c420fe9U, 0xf8841ec9U, 0x00000000U,
376   0x09808683U, 0x322bed48U, 0x1e1170acU, 0x6c5a724eU,
377   0xfd0efffbU, 0x0f853856U, 0x3daed51eU, 0x362d3927U,
378   0x0a0fd964U, 0x685ca621U, 0x9b5b54d1U, 0x24362e3aU,
379   0x0c0a67b1U, 0x9357e70fU, 0xb4ee96d2U, 0x1b9b919eU,
380   0x80c0c54fU, 0x61dc20a2U, 0x5a774b69U, 0x1c121a16U,
381   0xe293ba0aU, 0xc0a02ae5U, 0x3c22e043U, 0x121b171dU,
382   0x0e090d0bU, 0xf28bc7adU, 0x2db6a8b9U, 0x141ea9c8U,
383   0x57f11985U, 0xaf75074cU, 0xee99ddbbU, 0xa37f60fdU,
384   0xf701269fU, 0x5c72f5bcU, 0x44663bc5U, 0x5bfb7e34U,
385   0x8b432976U, 0xcb23c6dcU, 0xb6edfc68U, 0xb8e4f163U,
386   0xd731dccaU, 0x42638510U, 0x13972240U, 0x84c61120U,
387   0x854a247dU, 0xd2bb3df8U, 0xaef93211U, 0xc729a16dU,
388   0x1d9e2f4bU, 0xdcb230f3U, 0x0d8652ecU, 0x77c1e3d0U,
389   0x2bb3166cU, 0xa970b999U, 0x119448faU, 0x47e96422U,
390   0xa8fc8cc4U, 0xa0f03f1aU, 0x567d2cd8U, 0x223390efU,
391   0x87494ec7U, 0xd938d1c1U, 0x8ccaa2feU, 0x98d40b36U,
392   0xa6f581cfU, 0xa57ade28U, 0xdab78e26U, 0x3fadbfa4U,
393   0x2c3a9de4U, 0x5078920dU, 0x6a5fcc9bU, 0x547e4662U,
394   0xf68d13c2U, 0x90d8b8e8U, 0x2e39f75eU, 0x82c3aff5U,
395   0x9f5d80beU, 0x69d0937cU, 0x6fd52da9U, 0xcf2512b3U,
396   0xc8ac993bU, 0x10187da7U, 0xe89c636eU, 0xdb3bbb7bU,
397   0xcd267809U, 0x6e5918f4U, 0xec9ab701U, 0x834f9aa8U,
398   0xe6956e65U, 0xaaffe67eU, 0x21bccf08U, 0xef15e8e6U,
399   0xbae79bd9U, 0x4a6f36ceU, 0xea9f09d4U, 0x29b07cd6U,
400   0x31a4b2afU, 0x2a3f2331U, 0xc6a59430U, 0x35a266c0U,
401   0x744ebc37U, 0xfc82caa6U, 0xe090d0b0U, 0x33a7d815U,
402   0xf104984aU, 0x41ecdaf7U, 0x7fcd500eU, 0x1791f62fU,
403   0x764dd68dU, 0x43efb04dU, 0xccaa4d54U, 0xe49604dfU,
404   0x9ed1b5e3U, 0x4c6a881bU, 0xc12c1fb8U, 0x4665517fU,
405   0x9d5eea04U, 0x018c355dU, 0xfa877473U, 0xfb0b412eU,
406   0xb3671d5aU, 0x92dbd252U, 0xe9105633U, 0x6dd64713U,
407   0x9ad7618cU, 0x37a10c7aU, 0x59f8148eU, 0xeb133c89U,
408   0xcea927eeU, 0xb761c935U, 0xe11ce5edU, 0x7a47b13cU,
409   0x9cd2df59U, 0x55f2733fU, 0x1814ce79U, 0x73c737bfU,
410   0x53f7cdeaU, 0x5ffdaa5bU, 0xdf3d6f14U, 0x7844db86U,
411   0xcaaff381U, 0xb968c43eU, 0x3824342cU, 0xc2a3405fU,
412   0x161dc372U, 0xbce2250cU, 0x283c498bU, 0xff0d9541U,
413   0x39a80171U, 0x080cb3deU, 0xd8b4e49cU, 0x6456c190U,
414   0x7bcb8461U, 0xd532b670U, 0x486c5c74U, 0xd0b85742U,
415 };
416 
417 static const u32 Td1[256] =
418 {
419   0x5051f4a7U, 0x537e4165U, 0xc31a17a4U, 0x963a275eU,
420   0xcb3bab6bU, 0xf11f9d45U, 0xabacfa58U, 0x934be303U,
421   0x552030faU, 0xf6ad766dU, 0x9188cc76U, 0x25f5024cU,
422   0xfc4fe5d7U, 0xd7c52acbU, 0x80263544U, 0x8fb562a3U,
423   0x49deb15aU, 0x6725ba1bU, 0x9845ea0eU, 0xe15dfec0U,
424   0x02c32f75U, 0x12814cf0U, 0xa38d4697U, 0xc66bd3f9U,
425   0xe7038f5fU, 0x9515929cU, 0xebbf6d7aU, 0xda955259U,
426   0x2dd4be83U, 0xd3587421U, 0x2949e069U, 0x448ec9c8U,
427   0x6a75c289U, 0x78f48e79U, 0x6b99583eU, 0xdd27b971U,
428   0xb6bee14fU, 0x17f088adU, 0x66c920acU, 0xb47dce3aU,
429   0x1863df4aU, 0x82e51a31U, 0x60975133U, 0x4562537fU,
430   0xe0b16477U, 0x84bb6baeU, 0x1cfe81a0U, 0x94f9082bU,
431   0x58704868U, 0x198f45fdU, 0x8794de6cU, 0xb7527bf8U,
432   0x23ab73d3U, 0xe2724b02U, 0x57e31f8fU, 0x2a6655abU,
433   0x07b2eb28U, 0x032fb5c2U, 0x9a86c57bU, 0xa5d33708U,
434   0xf2302887U, 0xb223bfa5U, 0xba02036aU, 0x5ced1682U,
435   0x2b8acf1cU, 0x92a779b4U, 0xf0f307f2U, 0xa14e69e2U,
436   0xcd65daf4U, 0xd50605beU, 0x1fd13462U, 0x8ac4a6feU,
437   0x9d342e53U, 0xa0a2f355U, 0x32058ae1U, 0x75a4f6ebU,
438   0x390b83ecU, 0xaa4060efU, 0x065e719fU, 0x51bd6e10U,
439   0xf93e218aU, 0x3d96dd06U, 0xaedd3e05U, 0x464de6bdU,
440   0xb591548dU, 0x0571c45dU, 0x6f0406d4U, 0xff605015U,
441   0x241998fbU, 0x97d6bde9U, 0xcc894043U, 0x7767d99eU,
442   0xbdb0e842U, 0x8807898bU, 0x38e7195bU, 0xdb79c8eeU,
443   0x47a17c0aU, 0xe97c420fU, 0xc9f8841eU, 0x00000000U,
444   0x83098086U, 0x48322bedU, 0xac1e1170U, 0x4e6c5a72U,
445   0xfbfd0effU, 0x560f8538U, 0x1e3daed5U, 0x27362d39U,
446   0x640a0fd9U, 0x21685ca6U, 0xd19b5b54U, 0x3a24362eU,
447   0xb10c0a67U, 0x0f9357e7U, 0xd2b4ee96U, 0x9e1b9b91U,
448   0x4f80c0c5U, 0xa261dc20U, 0x695a774bU, 0x161c121aU,
449   0x0ae293baU, 0xe5c0a02aU, 0x433c22e0U, 0x1d121b17U,
450   0x0b0e090dU, 0xadf28bc7U, 0xb92db6a8U, 0xc8141ea9U,
451   0x8557f119U, 0x4caf7507U, 0xbbee99ddU, 0xfda37f60U,
452   0x9ff70126U, 0xbc5c72f5U, 0xc544663bU, 0x345bfb7eU,
453   0x768b4329U, 0xdccb23c6U, 0x68b6edfcU, 0x63b8e4f1U,
454   0xcad731dcU, 0x10426385U, 0x40139722U, 0x2084c611U,
455   0x7d854a24U, 0xf8d2bb3dU, 0x11aef932U, 0x6dc729a1U,
456   0x4b1d9e2fU, 0xf3dcb230U, 0xec0d8652U, 0xd077c1e3U,
457   0x6c2bb316U, 0x99a970b9U, 0xfa119448U, 0x2247e964U,
458   0xc4a8fc8cU, 0x1aa0f03fU, 0xd8567d2cU, 0xef223390U,
459   0xc787494eU, 0xc1d938d1U, 0xfe8ccaa2U, 0x3698d40bU,
460   0xcfa6f581U, 0x28a57adeU, 0x26dab78eU, 0xa43fadbfU,
461   0xe42c3a9dU, 0x0d507892U, 0x9b6a5fccU, 0x62547e46U,
462   0xc2f68d13U, 0xe890d8b8U, 0x5e2e39f7U, 0xf582c3afU,
463   0xbe9f5d80U, 0x7c69d093U, 0xa96fd52dU, 0xb3cf2512U,
464   0x3bc8ac99U, 0xa710187dU, 0x6ee89c63U, 0x7bdb3bbbU,
465   0x09cd2678U, 0xf46e5918U, 0x01ec9ab7U, 0xa8834f9aU,
466   0x65e6956eU, 0x7eaaffe6U, 0x0821bccfU, 0xe6ef15e8U,
467   0xd9bae79bU, 0xce4a6f36U, 0xd4ea9f09U, 0xd629b07cU,
468   0xaf31a4b2U, 0x312a3f23U, 0x30c6a594U, 0xc035a266U,
469   0x37744ebcU, 0xa6fc82caU, 0xb0e090d0U, 0x1533a7d8U,
470   0x4af10498U, 0xf741ecdaU, 0x0e7fcd50U, 0x2f1791f6U,
471   0x8d764dd6U, 0x4d43efb0U, 0x54ccaa4dU, 0xdfe49604U,
472   0xe39ed1b5U, 0x1b4c6a88U, 0xb8c12c1fU, 0x7f466551U,
473   0x049d5eeaU, 0x5d018c35U, 0x73fa8774U, 0x2efb0b41U,
474   0x5ab3671dU, 0x5292dbd2U, 0x33e91056U, 0x136dd647U,
475   0x8c9ad761U, 0x7a37a10cU, 0x8e59f814U, 0x89eb133cU,
476   0xeecea927U, 0x35b761c9U, 0xede11ce5U, 0x3c7a47b1U,
477   0x599cd2dfU, 0x3f55f273U, 0x791814ceU, 0xbf73c737U,
478   0xea53f7cdU, 0x5b5ffdaaU, 0x14df3d6fU, 0x867844dbU,
479   0x81caaff3U, 0x3eb968c4U, 0x2c382434U, 0x5fc2a340U,
480   0x72161dc3U, 0x0cbce225U, 0x8b283c49U, 0x41ff0d95U,
481   0x7139a801U, 0xde080cb3U, 0x9cd8b4e4U, 0x906456c1U,
482   0x617bcb84U, 0x70d532b6U, 0x74486c5cU, 0x42d0b857U,
483 };
484 
485 static const u32 Td2[256] =
486 {
487   0xa75051f4U, 0x65537e41U, 0xa4c31a17U, 0x5e963a27U,
488   0x6bcb3babU, 0x45f11f9dU, 0x58abacfaU, 0x03934be3U,
489   0xfa552030U, 0x6df6ad76U, 0x769188ccU, 0x4c25f502U,
490   0xd7fc4fe5U, 0xcbd7c52aU, 0x44802635U, 0xa38fb562U,
491   0x5a49deb1U, 0x1b6725baU, 0x0e9845eaU, 0xc0e15dfeU,
492   0x7502c32fU, 0xf012814cU, 0x97a38d46U, 0xf9c66bd3U,
493   0x5fe7038fU, 0x9c951592U, 0x7aebbf6dU, 0x59da9552U,
494   0x832dd4beU, 0x21d35874U, 0x692949e0U, 0xc8448ec9U,
495   0x896a75c2U, 0x7978f48eU, 0x3e6b9958U, 0x71dd27b9U,
496   0x4fb6bee1U, 0xad17f088U, 0xac66c920U, 0x3ab47dceU,
497   0x4a1863dfU, 0x3182e51aU, 0x33609751U, 0x7f456253U,
498   0x77e0b164U, 0xae84bb6bU, 0xa01cfe81U, 0x2b94f908U,
499   0x68587048U, 0xfd198f45U, 0x6c8794deU, 0xf8b7527bU,
500   0xd323ab73U, 0x02e2724bU, 0x8f57e31fU, 0xab2a6655U,
501   0x2807b2ebU, 0xc2032fb5U, 0x7b9a86c5U, 0x08a5d337U,
502   0x87f23028U, 0xa5b223bfU, 0x6aba0203U, 0x825ced16U,
503   0x1c2b8acfU, 0xb492a779U, 0xf2f0f307U, 0xe2a14e69U,
504   0xf4cd65daU, 0xbed50605U, 0x621fd134U, 0xfe8ac4a6U,
505   0x539d342eU, 0x55a0a2f3U, 0xe132058aU, 0xeb75a4f6U,
506   0xec390b83U, 0xefaa4060U, 0x9f065e71U, 0x1051bd6eU,
507   0x8af93e21U, 0x063d96ddU, 0x05aedd3eU, 0xbd464de6U,
508   0x8db59154U, 0x5d0571c4U, 0xd46f0406U, 0x15ff6050U,
509   0xfb241998U, 0xe997d6bdU, 0x43cc8940U, 0x9e7767d9U,
510   0x42bdb0e8U, 0x8b880789U, 0x5b38e719U, 0xeedb79c8U,
511   0x0a47a17cU, 0x0fe97c42U, 0x1ec9f884U, 0x00000000U,
512   0x86830980U, 0xed48322bU, 0x70ac1e11U, 0x724e6c5aU,
513   0xfffbfd0eU, 0x38560f85U, 0xd51e3daeU, 0x3927362dU,
514   0xd9640a0fU, 0xa621685cU, 0x54d19b5bU, 0x2e3a2436U,
515   0x67b10c0aU, 0xe70f9357U, 0x96d2b4eeU, 0x919e1b9bU,
516   0xc54f80c0U, 0x20a261dcU, 0x4b695a77U, 0x1a161c12U,
517   0xba0ae293U, 0x2ae5c0a0U, 0xe0433c22U, 0x171d121bU,
518   0x0d0b0e09U, 0xc7adf28bU, 0xa8b92db6U, 0xa9c8141eU,
519   0x198557f1U, 0x074caf75U, 0xddbbee99U, 0x60fda37fU,
520   0x269ff701U, 0xf5bc5c72U, 0x3bc54466U, 0x7e345bfbU,
521   0x29768b43U, 0xc6dccb23U, 0xfc68b6edU, 0xf163b8e4U,
522   0xdccad731U, 0x85104263U, 0x22401397U, 0x112084c6U,
523   0x247d854aU, 0x3df8d2bbU, 0x3211aef9U, 0xa16dc729U,
524   0x2f4b1d9eU, 0x30f3dcb2U, 0x52ec0d86U, 0xe3d077c1U,
525   0x166c2bb3U, 0xb999a970U, 0x48fa1194U, 0x642247e9U,
526   0x8cc4a8fcU, 0x3f1aa0f0U, 0x2cd8567dU, 0x90ef2233U,
527   0x4ec78749U, 0xd1c1d938U, 0xa2fe8ccaU, 0x0b3698d4U,
528   0x81cfa6f5U, 0xde28a57aU, 0x8e26dab7U, 0xbfa43fadU,
529   0x9de42c3aU, 0x920d5078U, 0xcc9b6a5fU, 0x4662547eU,
530   0x13c2f68dU, 0xb8e890d8U, 0xf75e2e39U, 0xaff582c3U,
531   0x80be9f5dU, 0x937c69d0U, 0x2da96fd5U, 0x12b3cf25U,
532   0x993bc8acU, 0x7da71018U, 0x636ee89cU, 0xbb7bdb3bU,
533   0x7809cd26U, 0x18f46e59U, 0xb701ec9aU, 0x9aa8834fU,
534   0x6e65e695U, 0xe67eaaffU, 0xcf0821bcU, 0xe8e6ef15U,
535   0x9bd9bae7U, 0x36ce4a6fU, 0x09d4ea9fU, 0x7cd629b0U,
536   0xb2af31a4U, 0x23312a3fU, 0x9430c6a5U, 0x66c035a2U,
537   0xbc37744eU, 0xcaa6fc82U, 0xd0b0e090U, 0xd81533a7U,
538   0x984af104U, 0xdaf741ecU, 0x500e7fcdU, 0xf62f1791U,
539   0xd68d764dU, 0xb04d43efU, 0x4d54ccaaU, 0x04dfe496U,
540   0xb5e39ed1U, 0x881b4c6aU, 0x1fb8c12cU, 0x517f4665U,
541   0xea049d5eU, 0x355d018cU, 0x7473fa87U, 0x412efb0bU,
542   0x1d5ab367U, 0xd25292dbU, 0x5633e910U, 0x47136dd6U,
543   0x618c9ad7U, 0x0c7a37a1U, 0x148e59f8U, 0x3c89eb13U,
544   0x27eecea9U, 0xc935b761U, 0xe5ede11cU, 0xb13c7a47U,
545   0xdf599cd2U, 0x733f55f2U, 0xce791814U, 0x37bf73c7U,
546   0xcdea53f7U, 0xaa5b5ffdU, 0x6f14df3dU, 0xdb867844U,
547   0xf381caafU, 0xc43eb968U, 0x342c3824U, 0x405fc2a3U,
548   0xc372161dU, 0x250cbce2U, 0x498b283cU, 0x9541ff0dU,
549   0x017139a8U, 0xb3de080cU, 0xe49cd8b4U, 0xc1906456U,
550   0x84617bcbU, 0xb670d532U, 0x5c74486cU, 0x5742d0b8U,
551 };
552 
553 static const u32 Td3[256] =
554 {
555   0xf4a75051U, 0x4165537eU, 0x17a4c31aU, 0x275e963aU,
556   0xab6bcb3bU, 0x9d45f11fU, 0xfa58abacU, 0xe303934bU,
557   0x30fa5520U, 0x766df6adU, 0xcc769188U, 0x024c25f5U,
558   0xe5d7fc4fU, 0x2acbd7c5U, 0x35448026U, 0x62a38fb5U,
559   0xb15a49deU, 0xba1b6725U, 0xea0e9845U, 0xfec0e15dU,
560   0x2f7502c3U, 0x4cf01281U, 0x4697a38dU, 0xd3f9c66bU,
561   0x8f5fe703U, 0x929c9515U, 0x6d7aebbfU, 0x5259da95U,
562   0xbe832dd4U, 0x7421d358U, 0xe0692949U, 0xc9c8448eU,
563   0xc2896a75U, 0x8e7978f4U, 0x583e6b99U, 0xb971dd27U,
564   0xe14fb6beU, 0x88ad17f0U, 0x20ac66c9U, 0xce3ab47dU,
565   0xdf4a1863U, 0x1a3182e5U, 0x51336097U, 0x537f4562U,
566   0x6477e0b1U, 0x6bae84bbU, 0x81a01cfeU, 0x082b94f9U,
567   0x48685870U, 0x45fd198fU, 0xde6c8794U, 0x7bf8b752U,
568   0x73d323abU, 0x4b02e272U, 0x1f8f57e3U, 0x55ab2a66U,
569   0xeb2807b2U, 0xb5c2032fU, 0xc57b9a86U, 0x3708a5d3U,
570   0x2887f230U, 0xbfa5b223U, 0x036aba02U, 0x16825cedU,
571   0xcf1c2b8aU, 0x79b492a7U, 0x07f2f0f3U, 0x69e2a14eU,
572   0xdaf4cd65U, 0x05bed506U, 0x34621fd1U, 0xa6fe8ac4U,
573   0x2e539d34U, 0xf355a0a2U, 0x8ae13205U, 0xf6eb75a4U,
574   0x83ec390bU, 0x60efaa40U, 0x719f065eU, 0x6e1051bdU,
575   0x218af93eU, 0xdd063d96U, 0x3e05aeddU, 0xe6bd464dU,
576   0x548db591U, 0xc45d0571U, 0x06d46f04U, 0x5015ff60U,
577   0x98fb2419U, 0xbde997d6U, 0x4043cc89U, 0xd99e7767U,
578   0xe842bdb0U, 0x898b8807U, 0x195b38e7U, 0xc8eedb79U,
579   0x7c0a47a1U, 0x420fe97cU, 0x841ec9f8U, 0x00000000U,
580   0x80868309U, 0x2bed4832U, 0x1170ac1eU, 0x5a724e6cU,
581   0x0efffbfdU, 0x8538560fU, 0xaed51e3dU, 0x2d392736U,
582   0x0fd9640aU, 0x5ca62168U, 0x5b54d19bU, 0x362e3a24U,
583   0x0a67b10cU, 0x57e70f93U, 0xee96d2b4U, 0x9b919e1bU,
584   0xc0c54f80U, 0xdc20a261U, 0x774b695aU, 0x121a161cU,
585   0x93ba0ae2U, 0xa02ae5c0U, 0x22e0433cU, 0x1b171d12U,
586   0x090d0b0eU, 0x8bc7adf2U, 0xb6a8b92dU, 0x1ea9c814U,
587   0xf1198557U, 0x75074cafU, 0x99ddbbeeU, 0x7f60fda3U,
588   0x01269ff7U, 0x72f5bc5cU, 0x663bc544U, 0xfb7e345bU,
589   0x4329768bU, 0x23c6dccbU, 0xedfc68b6U, 0xe4f163b8U,
590   0x31dccad7U, 0x63851042U, 0x97224013U, 0xc6112084U,
591   0x4a247d85U, 0xbb3df8d2U, 0xf93211aeU, 0x29a16dc7U,
592   0x9e2f4b1dU, 0xb230f3dcU, 0x8652ec0dU, 0xc1e3d077U,
593   0xb3166c2bU, 0x70b999a9U, 0x9448fa11U, 0xe9642247U,
594   0xfc8cc4a8U, 0xf03f1aa0U, 0x7d2cd856U, 0x3390ef22U,
595   0x494ec787U, 0x38d1c1d9U, 0xcaa2fe8cU, 0xd40b3698U,
596   0xf581cfa6U, 0x7ade28a5U, 0xb78e26daU, 0xadbfa43fU,
597   0x3a9de42cU, 0x78920d50U, 0x5fcc9b6aU, 0x7e466254U,
598   0x8d13c2f6U, 0xd8b8e890U, 0x39f75e2eU, 0xc3aff582U,
599   0x5d80be9fU, 0xd0937c69U, 0xd52da96fU, 0x2512b3cfU,
600   0xac993bc8U, 0x187da710U, 0x9c636ee8U, 0x3bbb7bdbU,
601   0x267809cdU, 0x5918f46eU, 0x9ab701ecU, 0x4f9aa883U,
602   0x956e65e6U, 0xffe67eaaU, 0xbccf0821U, 0x15e8e6efU,
603   0xe79bd9baU, 0x6f36ce4aU, 0x9f09d4eaU, 0xb07cd629U,
604   0xa4b2af31U, 0x3f23312aU, 0xa59430c6U, 0xa266c035U,
605   0x4ebc3774U, 0x82caa6fcU, 0x90d0b0e0U, 0xa7d81533U,
606   0x04984af1U, 0xecdaf741U, 0xcd500e7fU, 0x91f62f17U,
607   0x4dd68d76U, 0xefb04d43U, 0xaa4d54ccU, 0x9604dfe4U,
608   0xd1b5e39eU, 0x6a881b4cU, 0x2c1fb8c1U, 0x65517f46U,
609   0x5eea049dU, 0x8c355d01U, 0x877473faU, 0x0b412efbU,
610   0x671d5ab3U, 0xdbd25292U, 0x105633e9U, 0xd647136dU,
611   0xd7618c9aU, 0xa10c7a37U, 0xf8148e59U, 0x133c89ebU,
612   0xa927eeceU, 0x61c935b7U, 0x1ce5ede1U, 0x47b13c7aU,
613   0xd2df599cU, 0xf2733f55U, 0x14ce7918U, 0xc737bf73U,
614   0xf7cdea53U, 0xfdaa5b5fU, 0x3d6f14dfU, 0x44db8678U,
615   0xaff381caU, 0x68c43eb9U, 0x24342c38U, 0xa3405fc2U,
616   0x1dc37216U, 0xe2250cbcU, 0x3c498b28U, 0x0d9541ffU,
617   0xa8017139U, 0x0cb3de08U, 0xb4e49cd8U, 0x56c19064U,
618   0xcb84617bU, 0x32b670d5U, 0x6c5c7448U, 0xb85742d0U,
619 };
620 
621 static const u32 Td4[256] =
622 {
623   0x52525252U, 0x09090909U, 0x6a6a6a6aU, 0xd5d5d5d5U,
624   0x30303030U, 0x36363636U, 0xa5a5a5a5U, 0x38383838U,
625   0xbfbfbfbfU, 0x40404040U, 0xa3a3a3a3U, 0x9e9e9e9eU,
626   0x81818181U, 0xf3f3f3f3U, 0xd7d7d7d7U, 0xfbfbfbfbU,
627   0x7c7c7c7cU, 0xe3e3e3e3U, 0x39393939U, 0x82828282U,
628   0x9b9b9b9bU, 0x2f2f2f2fU, 0xffffffffU, 0x87878787U,
629   0x34343434U, 0x8e8e8e8eU, 0x43434343U, 0x44444444U,
630   0xc4c4c4c4U, 0xdedededeU, 0xe9e9e9e9U, 0xcbcbcbcbU,
631   0x54545454U, 0x7b7b7b7bU, 0x94949494U, 0x32323232U,
632   0xa6a6a6a6U, 0xc2c2c2c2U, 0x23232323U, 0x3d3d3d3dU,
633   0xeeeeeeeeU, 0x4c4c4c4cU, 0x95959595U, 0x0b0b0b0bU,
634   0x42424242U, 0xfafafafaU, 0xc3c3c3c3U, 0x4e4e4e4eU,
635   0x08080808U, 0x2e2e2e2eU, 0xa1a1a1a1U, 0x66666666U,
636   0x28282828U, 0xd9d9d9d9U, 0x24242424U, 0xb2b2b2b2U,
637   0x76767676U, 0x5b5b5b5bU, 0xa2a2a2a2U, 0x49494949U,
638   0x6d6d6d6dU, 0x8b8b8b8bU, 0xd1d1d1d1U, 0x25252525U,
639   0x72727272U, 0xf8f8f8f8U, 0xf6f6f6f6U, 0x64646464U,
640   0x86868686U, 0x68686868U, 0x98989898U, 0x16161616U,
641   0xd4d4d4d4U, 0xa4a4a4a4U, 0x5c5c5c5cU, 0xccccccccU,
642   0x5d5d5d5dU, 0x65656565U, 0xb6b6b6b6U, 0x92929292U,
643   0x6c6c6c6cU, 0x70707070U, 0x48484848U, 0x50505050U,
644   0xfdfdfdfdU, 0xededededU, 0xb9b9b9b9U, 0xdadadadaU,
645   0x5e5e5e5eU, 0x15151515U, 0x46464646U, 0x57575757U,
646   0xa7a7a7a7U, 0x8d8d8d8dU, 0x9d9d9d9dU, 0x84848484U,
647   0x90909090U, 0xd8d8d8d8U, 0xababababU, 0x00000000U,
648   0x8c8c8c8cU, 0xbcbcbcbcU, 0xd3d3d3d3U, 0x0a0a0a0aU,
649   0xf7f7f7f7U, 0xe4e4e4e4U, 0x58585858U, 0x05050505U,
650   0xb8b8b8b8U, 0xb3b3b3b3U, 0x45454545U, 0x06060606U,
651   0xd0d0d0d0U, 0x2c2c2c2cU, 0x1e1e1e1eU, 0x8f8f8f8fU,
652   0xcacacacaU, 0x3f3f3f3fU, 0x0f0f0f0fU, 0x02020202U,
653   0xc1c1c1c1U, 0xafafafafU, 0xbdbdbdbdU, 0x03030303U,
654   0x01010101U, 0x13131313U, 0x8a8a8a8aU, 0x6b6b6b6bU,
655   0x3a3a3a3aU, 0x91919191U, 0x11111111U, 0x41414141U,
656   0x4f4f4f4fU, 0x67676767U, 0xdcdcdcdcU, 0xeaeaeaeaU,
657   0x97979797U, 0xf2f2f2f2U, 0xcfcfcfcfU, 0xcecececeU,
658   0xf0f0f0f0U, 0xb4b4b4b4U, 0xe6e6e6e6U, 0x73737373U,
659   0x96969696U, 0xacacacacU, 0x74747474U, 0x22222222U,
660   0xe7e7e7e7U, 0xadadadadU, 0x35353535U, 0x85858585U,
661   0xe2e2e2e2U, 0xf9f9f9f9U, 0x37373737U, 0xe8e8e8e8U,
662   0x1c1c1c1cU, 0x75757575U, 0xdfdfdfdfU, 0x6e6e6e6eU,
663   0x47474747U, 0xf1f1f1f1U, 0x1a1a1a1aU, 0x71717171U,
664   0x1d1d1d1dU, 0x29292929U, 0xc5c5c5c5U, 0x89898989U,
665   0x6f6f6f6fU, 0xb7b7b7b7U, 0x62626262U, 0x0e0e0e0eU,
666   0xaaaaaaaaU, 0x18181818U, 0xbebebebeU, 0x1b1b1b1bU,
667   0xfcfcfcfcU, 0x56565656U, 0x3e3e3e3eU, 0x4b4b4b4bU,
668   0xc6c6c6c6U, 0xd2d2d2d2U, 0x79797979U, 0x20202020U,
669   0x9a9a9a9aU, 0xdbdbdbdbU, 0xc0c0c0c0U, 0xfefefefeU,
670   0x78787878U, 0xcdcdcdcdU, 0x5a5a5a5aU, 0xf4f4f4f4U,
671   0x1f1f1f1fU, 0xddddddddU, 0xa8a8a8a8U, 0x33333333U,
672   0x88888888U, 0x07070707U, 0xc7c7c7c7U, 0x31313131U,
673   0xb1b1b1b1U, 0x12121212U, 0x10101010U, 0x59595959U,
674   0x27272727U, 0x80808080U, 0xececececU, 0x5f5f5f5fU,
675   0x60606060U, 0x51515151U, 0x7f7f7f7fU, 0xa9a9a9a9U,
676   0x19191919U, 0xb5b5b5b5U, 0x4a4a4a4aU, 0x0d0d0d0dU,
677   0x2d2d2d2dU, 0xe5e5e5e5U, 0x7a7a7a7aU, 0x9f9f9f9fU,
678   0x93939393U, 0xc9c9c9c9U, 0x9c9c9c9cU, 0xefefefefU,
679   0xa0a0a0a0U, 0xe0e0e0e0U, 0x3b3b3b3bU, 0x4d4d4d4dU,
680   0xaeaeaeaeU, 0x2a2a2a2aU, 0xf5f5f5f5U, 0xb0b0b0b0U,
681   0xc8c8c8c8U, 0xebebebebU, 0xbbbbbbbbU, 0x3c3c3c3cU,
682   0x83838383U, 0x53535353U, 0x99999999U, 0x61616161U,
683   0x17171717U, 0x2b2b2b2bU, 0x04040404U, 0x7e7e7e7eU,
684   0xbabababaU, 0x77777777U, 0xd6d6d6d6U, 0x26262626U,
685   0xe1e1e1e1U, 0x69696969U, 0x14141414U, 0x63636363U,
686   0x55555555U, 0x21212121U, 0x0c0c0c0cU, 0x7d7d7d7dU,
687 };
688 
689 static const u32 rcon[] =
690 {
691   0x01000000, 0x02000000, 0x04000000, 0x08000000,
692   0x10000000, 0x20000000, 0x40000000, 0x80000000,
693   0x1B000000, 0x36000000,
694   /* for 128-bit blocks, Rijndael never uses more than 10 rcon values */
695 };
696 
697 #define GETU32(plaintext) (((u32)(plaintext)[0] << 24) ^ \
698                     ((u32)(plaintext)[1] << 16) ^ \
699                     ((u32)(plaintext)[2] <<  8) ^ \
700                     ((u32)(plaintext)[3]))
701 
702 #define PUTU32(ciphertext, st) { (ciphertext)[0] = (u8)((st) >> 24); \
703                          (ciphertext)[1] = (u8)((st) >> 16); \
704                          (ciphertext)[2] = (u8)((st) >>  8); \
705                          (ciphertext)[3] = (u8)(st); }
706 
707 int rijndaelSetupEncrypt(u32 *rk, const u8 *key, int keybits);
708 void rijndaelEncrypt(const u32 *rk, int nrounds, const u8 plaintext[16], u8 ciphertext[16]);
709 
710 /**
711  * Expand the cipher key into the encryption key schedule.
712  *
713  * @return the number of rounds for the given cipher key size.
714  */
rijndaelSetupEncrypt(u32 * rk,const u8 * key,int keybits)715 int rijndaelSetupEncrypt(u32 *rk, const u8 *key, int keybits)
716 {
717   int i = 0;
718   u32 temp;
719 
720   rk[0] = GETU32(key     );
721   rk[1] = GETU32(key +  4);
722   rk[2] = GETU32(key +  8);
723   rk[3] = GETU32(key + 12);
724   if (keybits == 128)
725   {
726     for (;;)
727     {
728       temp  = rk[3];
729       rk[4] = rk[0] ^
730         (Te4[(temp >> 16) & 0xff] & 0xff000000) ^
731         (Te4[(temp >>  8) & 0xff] & 0x00ff0000) ^
732         (Te4[(temp      ) & 0xff] & 0x0000ff00) ^
733         (Te4[(temp >> 24)       ] & 0x000000ff) ^
734         rcon[i];
735       rk[5] = rk[1] ^ rk[4];
736       rk[6] = rk[2] ^ rk[5];
737       rk[7] = rk[3] ^ rk[6];
738       if (++i == 10)
739         return 10;
740       rk += 4;
741     }
742   }
743   rk[4] = GETU32(key + 16);
744   rk[5] = GETU32(key + 20);
745   if (keybits == 192)
746   {
747     for (;;)
748     {
749       temp = rk[ 5];
750       rk[ 6] = rk[ 0] ^
751         (Te4[(temp >> 16) & 0xff] & 0xff000000) ^
752         (Te4[(temp >>  8) & 0xff] & 0x00ff0000) ^
753         (Te4[(temp      ) & 0xff] & 0x0000ff00) ^
754         (Te4[(temp >> 24)       ] & 0x000000ff) ^
755         rcon[i];
756       rk[ 7] = rk[ 1] ^ rk[ 6];
757       rk[ 8] = rk[ 2] ^ rk[ 7];
758       rk[ 9] = rk[ 3] ^ rk[ 8];
759       if (++i == 8)
760         return 12;
761       rk[10] = rk[ 4] ^ rk[ 9];
762       rk[11] = rk[ 5] ^ rk[10];
763       rk += 6;
764     }
765   }
766   rk[6] = GETU32(key + 24);
767   rk[7] = GETU32(key + 28);
768   if (keybits == 256)
769   {
770     for (;;)
771     {
772       temp = rk[ 7];
773       rk[ 8] = rk[ 0] ^
774         (Te4[(temp >> 16) & 0xff] & 0xff000000) ^
775         (Te4[(temp >>  8) & 0xff] & 0x00ff0000) ^
776         (Te4[(temp      ) & 0xff] & 0x0000ff00) ^
777         (Te4[(temp >> 24)       ] & 0x000000ff) ^
778         rcon[i];
779       rk[ 9] = rk[ 1] ^ rk[ 8];
780       rk[10] = rk[ 2] ^ rk[ 9];
781       rk[11] = rk[ 3] ^ rk[10];
782       if (++i == 7)
783         return 14;
784       temp = rk[11];
785       rk[12] = rk[ 4] ^
786         (Te4[(temp >> 24)       ] & 0xff000000) ^
787         (Te4[(temp >> 16) & 0xff] & 0x00ff0000) ^
788         (Te4[(temp >>  8) & 0xff] & 0x0000ff00) ^
789         (Te4[(temp      ) & 0xff] & 0x000000ff);
790       rk[13] = rk[ 5] ^ rk[12];
791       rk[14] = rk[ 6] ^ rk[13];
792       rk[15] = rk[ 7] ^ rk[14];
793       rk += 8;
794     }
795   }
796   return 0;
797 }
798 
799 /**
800  * Expand the cipher key into the decryption key schedule.
801  *
802  * @return the number of rounds for the given cipher key size.
803  */
rijndaelSetupDecrypt(u32 * rk,const u8 * key,int keybits)804 int rijndaelSetupDecrypt(u32 *rk, const u8 *key, int keybits)
805 {
806   int nrounds, i, j;
807   u32 temp;
808 
809   /* expand the cipher key: */
810   nrounds = rijndaelSetupEncrypt(rk, key, keybits);
811   /* invert the order of the round keys: */
812   for (i = 0, j = 4*nrounds; i < j; i += 4, j -= 4)
813   {
814     temp = rk[i    ]; rk[i    ] = rk[j    ]; rk[j    ] = temp;
815     temp = rk[i + 1]; rk[i + 1] = rk[j + 1]; rk[j + 1] = temp;
816     temp = rk[i + 2]; rk[i + 2] = rk[j + 2]; rk[j + 2] = temp;
817     temp = rk[i + 3]; rk[i + 3] = rk[j + 3]; rk[j + 3] = temp;
818   }
819   /* apply the inverse MixColumn transform to all round keys but the first and the last: */
820   for (i = 1; i < nrounds; i++)
821   {
822     rk += 4;
823     rk[0] =
824       Td0[Te4[(rk[0] >> 24)       ] & 0xff] ^
825       Td1[Te4[(rk[0] >> 16) & 0xff] & 0xff] ^
826       Td2[Te4[(rk[0] >>  8) & 0xff] & 0xff] ^
827       Td3[Te4[(rk[0]      ) & 0xff] & 0xff];
828     rk[1] =
829       Td0[Te4[(rk[1] >> 24)       ] & 0xff] ^
830       Td1[Te4[(rk[1] >> 16) & 0xff] & 0xff] ^
831       Td2[Te4[(rk[1] >>  8) & 0xff] & 0xff] ^
832       Td3[Te4[(rk[1]      ) & 0xff] & 0xff];
833     rk[2] =
834       Td0[Te4[(rk[2] >> 24)       ] & 0xff] ^
835       Td1[Te4[(rk[2] >> 16) & 0xff] & 0xff] ^
836       Td2[Te4[(rk[2] >>  8) & 0xff] & 0xff] ^
837       Td3[Te4[(rk[2]      ) & 0xff] & 0xff];
838     rk[3] =
839       Td0[Te4[(rk[3] >> 24)       ] & 0xff] ^
840       Td1[Te4[(rk[3] >> 16) & 0xff] & 0xff] ^
841       Td2[Te4[(rk[3] >>  8) & 0xff] & 0xff] ^
842       Td3[Te4[(rk[3]      ) & 0xff] & 0xff];
843   }
844   return nrounds;
845 }
846 
rijndaelEncrypt(const u32 * rk,int nrounds,const u8 plaintext[16],u8 ciphertext[16])847 void rijndaelEncrypt(const u32 *rk, int nrounds, const u8 plaintext[16],
848   u8 ciphertext[16])
849 {
850   u32 s0, s1, s2, s3, t0, t1, t2, t3;
851   #ifndef FULL_UNROLL
852     int r;
853   #endif /* ?FULL_UNROLL */
854   /*
855    * map byte array block to cipher state
856    * and add initial round key:
857   */
858   s0 = GETU32(plaintext     ) ^ rk[0];
859   s1 = GETU32(plaintext +  4) ^ rk[1];
860   s2 = GETU32(plaintext +  8) ^ rk[2];
861   s3 = GETU32(plaintext + 12) ^ rk[3];
862   #ifdef FULL_UNROLL
863     /* round 1: */
864     t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >>  8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[ 4];
865     t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >>  8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[ 5];
866     t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >>  8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[ 6];
867     t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >>  8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[ 7];
868     /* round 2: */
869     s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >>  8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[ 8];
870     s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >>  8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[ 9];
871     s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >>  8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[10];
872     s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >>  8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[11];
873     /* round 3: */
874     t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >>  8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[12];
875     t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >>  8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[13];
876     t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >>  8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[14];
877     t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >>  8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[15];
878     /* round 4: */
879     s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >>  8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[16];
880     s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >>  8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[17];
881     s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >>  8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[18];
882     s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >>  8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[19];
883     /* round 5: */
884     t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >>  8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[20];
885     t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >>  8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[21];
886     t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >>  8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[22];
887     t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >>  8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[23];
888     /* round 6: */
889     s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >>  8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[24];
890     s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >>  8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[25];
891     s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >>  8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[26];
892     s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >>  8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[27];
893     /* round 7: */
894     t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >>  8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[28];
895     t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >>  8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[29];
896     t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >>  8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[30];
897     t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >>  8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[31];
898     /* round 8: */
899     s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >>  8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[32];
900     s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >>  8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[33];
901     s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >>  8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[34];
902     s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >>  8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[35];
903     /* round 9: */
904     t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >>  8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[36];
905     t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >>  8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[37];
906     t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >>  8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[38];
907     t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >>  8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[39];
908     if (nrounds > 10)
909     {
910       /* round 10: */
911       s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >>  8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[40];
912       s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >>  8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[41];
913       s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >>  8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[42];
914       s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >>  8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[43];
915       /* round 11: */
916       t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >>  8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[44];
917       t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >>  8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[45];
918       t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >>  8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[46];
919       t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >>  8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[47];
920       if (nrounds > 12)
921       {
922         /* round 12: */
923         s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >>  8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[48];
924         s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >>  8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[49];
925         s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >>  8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[50];
926         s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >>  8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[51];
927         /* round 13: */
928         t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >>  8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[52];
929         t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >>  8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[53];
930         t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >>  8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[54];
931         t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >>  8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[55];
932       }
933     }
934     rk += nrounds << 2;
935   #else  /* !FULL_UNROLL */
936     /*
937     * nrounds - 1 full rounds:
938     */
939     r = nrounds >> 1;
940     for (;;)
941     {
942       t0 =
943         Te0[(s0 >> 24)       ] ^
944         Te1[(s1 >> 16) & 0xff] ^
945         Te2[(s2 >>  8) & 0xff] ^
946         Te3[(s3      ) & 0xff] ^
947         rk[4];
948       t1 =
949         Te0[(s1 >> 24)       ] ^
950         Te1[(s2 >> 16) & 0xff] ^
951         Te2[(s3 >>  8) & 0xff] ^
952         Te3[(s0      ) & 0xff] ^
953         rk[5];
954       t2 =
955         Te0[(s2 >> 24)       ] ^
956         Te1[(s3 >> 16) & 0xff] ^
957         Te2[(s0 >>  8) & 0xff] ^
958         Te3[(s1      ) & 0xff] ^
959         rk[6];
960       t3 =
961         Te0[(s3 >> 24)       ] ^
962         Te1[(s0 >> 16) & 0xff] ^
963         Te2[(s1 >>  8) & 0xff] ^
964         Te3[(s2      ) & 0xff] ^
965         rk[7];
966         rk += 8;
967         if (--r == 0)
968             break;
969       s0 =
970         Te0[(t0 >> 24)       ] ^
971         Te1[(t1 >> 16) & 0xff] ^
972         Te2[(t2 >>  8) & 0xff] ^
973         Te3[(t3      ) & 0xff] ^
974         rk[0];
975       s1 =
976         Te0[(t1 >> 24)       ] ^
977         Te1[(t2 >> 16) & 0xff] ^
978         Te2[(t3 >>  8) & 0xff] ^
979         Te3[(t0      ) & 0xff] ^
980         rk[1];
981       s2 =
982         Te0[(t2 >> 24)       ] ^
983         Te1[(t3 >> 16) & 0xff] ^
984         Te2[(t0 >>  8) & 0xff] ^
985         Te3[(t1      ) & 0xff] ^
986         rk[2];
987       s3 =
988         Te0[(t3 >> 24)       ] ^
989         Te1[(t0 >> 16) & 0xff] ^
990         Te2[(t1 >>  8) & 0xff] ^
991         Te3[(t2      ) & 0xff] ^
992         rk[3];
993      }
994  #endif /* ?FULL_UNROLL */
995   /*
996   * apply last round and
997   * map cipher state to byte array block:
998   */
999   s0 =
1000     (Te4[(t0 >> 24)       ] & 0xff000000) ^
1001     (Te4[(t1 >> 16) & 0xff] & 0x00ff0000) ^
1002     (Te4[(t2 >>  8) & 0xff] & 0x0000ff00) ^
1003     (Te4[(t3      ) & 0xff] & 0x000000ff) ^
1004     rk[0];
1005   PUTU32(ciphertext     , s0);
1006   s1 =
1007     (Te4[(t1 >> 24)       ] & 0xff000000) ^
1008     (Te4[(t2 >> 16) & 0xff] & 0x00ff0000) ^
1009     (Te4[(t3 >>  8) & 0xff] & 0x0000ff00) ^
1010     (Te4[(t0      ) & 0xff] & 0x000000ff) ^
1011     rk[1];
1012   PUTU32(ciphertext +  4, s1);
1013   s2 =
1014     (Te4[(t2 >> 24)       ] & 0xff000000) ^
1015     (Te4[(t3 >> 16) & 0xff] & 0x00ff0000) ^
1016     (Te4[(t0 >>  8) & 0xff] & 0x0000ff00) ^
1017     (Te4[(t1      ) & 0xff] & 0x000000ff) ^
1018     rk[2];
1019   PUTU32(ciphertext +  8, s2);
1020   s3 =
1021     (Te4[(t3 >> 24)       ] & 0xff000000) ^
1022     (Te4[(t0 >> 16) & 0xff] & 0x00ff0000) ^
1023     (Te4[(t1 >>  8) & 0xff] & 0x0000ff00) ^
1024     (Te4[(t2      ) & 0xff] & 0x000000ff) ^
1025     rk[3];
1026   PUTU32(ciphertext + 12, s3);
1027 }
1028 
rijndaelDecrypt(const u32 * rk,int nrounds,const u8 ciphertext[16],u8 plaintext[16])1029 void rijndaelDecrypt(const u32 *rk, int nrounds, const u8 ciphertext[16],
1030   u8 plaintext[16])
1031 {
1032   u32 s0, s1, s2, s3, t0, t1, t2, t3;
1033   #ifndef FULL_UNROLL
1034     int r;
1035   #endif /* ?FULL_UNROLL */
1036 
1037   /*
1038   * map byte array block to cipher state
1039   * and add initial round key:
1040   */
1041     s0 = GETU32(ciphertext     ) ^ rk[0];
1042     s1 = GETU32(ciphertext +  4) ^ rk[1];
1043     s2 = GETU32(ciphertext +  8) ^ rk[2];
1044     s3 = GETU32(ciphertext + 12) ^ rk[3];
1045   #ifdef FULL_UNROLL
1046     /* round 1: */
1047     t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >>  8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[ 4];
1048     t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >>  8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[ 5];
1049     t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >>  8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[ 6];
1050     t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >>  8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[ 7];
1051     /* round 2: */
1052     s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >>  8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[ 8];
1053     s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >>  8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[ 9];
1054     s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >>  8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[10];
1055     s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >>  8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[11];
1056     /* round 3: */
1057     t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >>  8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[12];
1058     t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >>  8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[13];
1059     t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >>  8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[14];
1060     t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >>  8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[15];
1061     /* round 4: */
1062     s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >>  8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[16];
1063     s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >>  8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[17];
1064     s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >>  8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[18];
1065     s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >>  8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[19];
1066     /* round 5: */
1067     t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >>  8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[20];
1068     t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >>  8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[21];
1069     t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >>  8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[22];
1070     t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >>  8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[23];
1071     /* round 6: */
1072     s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >>  8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[24];
1073     s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >>  8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[25];
1074     s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >>  8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[26];
1075     s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >>  8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[27];
1076     /* round 7: */
1077     t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >>  8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[28];
1078     t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >>  8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[29];
1079     t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >>  8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[30];
1080     t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >>  8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[31];
1081     /* round 8: */
1082     s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >>  8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[32];
1083     s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >>  8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[33];
1084     s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >>  8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[34];
1085     s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >>  8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[35];
1086     /* round 9: */
1087     t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >>  8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[36];
1088     t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >>  8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[37];
1089     t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >>  8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[38];
1090     t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >>  8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[39];
1091     if (nrounds > 10)
1092     {
1093       /* round 10: */
1094       s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >>  8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[40];
1095       s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >>  8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[41];
1096       s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >>  8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[42];
1097       s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >>  8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[43];
1098       /* round 11: */
1099       t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >>  8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[44];
1100       t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >>  8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[45];
1101       t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >>  8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[46];
1102       t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >>  8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[47];
1103       if (nrounds > 12)
1104       {
1105         /* round 12: */
1106         s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >>  8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[48];
1107         s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >>  8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[49];
1108         s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >>  8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[50];
1109         s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >>  8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[51];
1110         /* round 13: */
1111         t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >>  8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[52];
1112         t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >>  8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[53];
1113         t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >>  8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[54];
1114         t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >>  8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[55];
1115       }
1116     }
1117     rk += nrounds << 2;
1118   #else  /* !FULL_UNROLL */
1119     /*
1120     * nrounds - 1 full rounds:
1121     */
1122     r = nrounds >> 1;
1123     for (;;)
1124     {
1125       t0 =
1126         Td0[(s0 >> 24)       ] ^
1127         Td1[(s3 >> 16) & 0xff] ^
1128         Td2[(s2 >>  8) & 0xff] ^
1129         Td3[(s1      ) & 0xff] ^
1130         rk[4];
1131       t1 =
1132         Td0[(s1 >> 24)       ] ^
1133         Td1[(s0 >> 16) & 0xff] ^
1134         Td2[(s3 >>  8) & 0xff] ^
1135         Td3[(s2      ) & 0xff] ^
1136         rk[5];
1137       t2 =
1138         Td0[(s2 >> 24)       ] ^
1139         Td1[(s1 >> 16) & 0xff] ^
1140         Td2[(s0 >>  8) & 0xff] ^
1141         Td3[(s3      ) & 0xff] ^
1142         rk[6];
1143       t3 =
1144         Td0[(s3 >> 24)       ] ^
1145         Td1[(s2 >> 16) & 0xff] ^
1146         Td2[(s1 >>  8) & 0xff] ^
1147         Td3[(s0      ) & 0xff] ^
1148         rk[7];
1149       rk += 8;
1150       if (--r == 0)
1151           break;
1152       s0 =
1153         Td0[(t0 >> 24)       ] ^
1154         Td1[(t3 >> 16) & 0xff] ^
1155         Td2[(t2 >>  8) & 0xff] ^
1156         Td3[(t1      ) & 0xff] ^
1157         rk[0];
1158       s1 =
1159         Td0[(t1 >> 24)       ] ^
1160         Td1[(t0 >> 16) & 0xff] ^
1161         Td2[(t3 >>  8) & 0xff] ^
1162         Td3[(t2      ) & 0xff] ^
1163         rk[1];
1164       s2 =
1165         Td0[(t2 >> 24)       ] ^
1166         Td1[(t1 >> 16) & 0xff] ^
1167         Td2[(t0 >>  8) & 0xff] ^
1168         Td3[(t3      ) & 0xff] ^
1169         rk[2];
1170       s3 =
1171         Td0[(t3 >> 24)       ] ^
1172         Td1[(t2 >> 16) & 0xff] ^
1173         Td2[(t1 >>  8) & 0xff] ^
1174         Td3[(t0      ) & 0xff] ^
1175         rk[3];
1176     }
1177   #endif /* ?FULL_UNROLL */
1178   /*
1179   * apply last round and
1180   * map cipher state to byte array block:
1181   */
1182   s0 =
1183     (Td4[(t0 >> 24)       ] & 0xff000000) ^
1184     (Td4[(t3 >> 16) & 0xff] & 0x00ff0000) ^
1185     (Td4[(t2 >>  8) & 0xff] & 0x0000ff00) ^
1186     (Td4[(t1      ) & 0xff] & 0x000000ff) ^
1187     rk[0];
1188   PUTU32(plaintext     , s0);
1189   s1 =
1190     (Td4[(t1 >> 24)       ] & 0xff000000) ^
1191     (Td4[(t0 >> 16) & 0xff] & 0x00ff0000) ^
1192     (Td4[(t3 >>  8) & 0xff] & 0x0000ff00) ^
1193     (Td4[(t2      ) & 0xff] & 0x000000ff) ^
1194     rk[1];
1195   PUTU32(plaintext +  4, s1);
1196   s2 =
1197     (Td4[(t2 >> 24)       ] & 0xff000000) ^
1198     (Td4[(t1 >> 16) & 0xff] & 0x00ff0000) ^
1199     (Td4[(t0 >>  8) & 0xff] & 0x0000ff00) ^
1200     (Td4[(t3      ) & 0xff] & 0x000000ff) ^
1201     rk[2];
1202   PUTU32(plaintext +  8, s2);
1203   s3 =
1204     (Td4[(t3 >> 24)       ] & 0xff000000) ^
1205     (Td4[(t2 >> 16) & 0xff] & 0x00ff0000) ^
1206     (Td4[(t1 >>  8) & 0xff] & 0x0000ff00) ^
1207     (Td4[(t0      ) & 0xff] & 0x000000ff) ^
1208     rk[3];
1209   PUTU32(plaintext + 12, s3);
1210 }
1211 
1212