do-release-commit-and-tag: add option to specify branch
[gnulib.git] / lib / rijndael-alg-fst.c
1 /* rijndael-alg-fst.c --- Rijndael cipher implementation.
2  * Copyright (C) 2005-2006, 2009-2011 Free Software Foundation, Inc.
3  *
4  * This file is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published
6  * by the Free Software Foundation; either version 2, or (at your
7  * option) any later version.
8  *
9  * This file is distributed in the hope that it will be useful, but
10  * WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this file; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17  * 02110-1301, USA.
18  *
19  */
20
21 /* Adapted for gnulib by Simon Josefsson.
22  *
23  * Based on public domain "Optimised C code" retrieved from (SHA1
24  * 7c8e4b00d06685d1dbc6724a9e0d502353de339e):
25  * http://www.iaik.tu-graz.ac.at/research/krypto/AES/old/~rijmen/rijndael/rijndael-fst-3.0.zip
26  */
27
28 #include <config.h>
29
30 /**
31  * rijndael-alg-fst.c
32  *
33  * @version 3.0 (December 2000)
34  *
35  * Optimised ANSI C code for the Rijndael cipher (now AES)
36  *
37  * @author Vincent Rijmen <vincent.rijmen@esat.kuleuven.ac.be>
38  * @author Antoon Bosselaers <antoon.bosselaers@esat.kuleuven.ac.be>
39  * @author Paulo Barreto <paulo.barreto@terra.com.br>
40  *
41  * This code is hereby placed in the public domain.
42  *
43  * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS
44  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
45  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
46  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE
47  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
48  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
49  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
50  * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
51  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
52  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
53  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
54  */
55
56 #include "rijndael-alg-fst.h"
57
58 /*
59 Te0[x] = S [x].[02, 01, 01, 03];
60 Te1[x] = S [x].[03, 02, 01, 01];
61 Te2[x] = S [x].[01, 03, 02, 01];
62 Te3[x] = S [x].[01, 01, 03, 02];
63 Te4[x] = S [x].[01, 01, 01, 01];
64
65 Td0[x] = Si[x].[0e, 09, 0d, 0b];
66 Td1[x] = Si[x].[0b, 0e, 09, 0d];
67 Td2[x] = Si[x].[0d, 0b, 0e, 09];
68 Td3[x] = Si[x].[09, 0d, 0b, 0e];
69 Td4[x] = Si[x].[01, 01, 01, 01];
70 */
71
72 static const uint32_t Te0[256] = {
73   0xc66363a5, 0xf87c7c84, 0xee777799, 0xf67b7b8d,
74   0xfff2f20d, 0xd66b6bbd, 0xde6f6fb1, 0x91c5c554,
75   0x60303050, 0x02010103, 0xce6767a9, 0x562b2b7d,
76   0xe7fefe19, 0xb5d7d762, 0x4dababe6, 0xec76769a,
77   0x8fcaca45, 0x1f82829d, 0x89c9c940, 0xfa7d7d87,
78   0xeffafa15, 0xb25959eb, 0x8e4747c9, 0xfbf0f00b,
79   0x41adadec, 0xb3d4d467, 0x5fa2a2fd, 0x45afafea,
80   0x239c9cbf, 0x53a4a4f7, 0xe4727296, 0x9bc0c05b,
81   0x75b7b7c2, 0xe1fdfd1c, 0x3d9393ae, 0x4c26266a,
82   0x6c36365a, 0x7e3f3f41, 0xf5f7f702, 0x83cccc4f,
83   0x6834345c, 0x51a5a5f4, 0xd1e5e534, 0xf9f1f108,
84   0xe2717193, 0xabd8d873, 0x62313153, 0x2a15153f,
85   0x0804040c, 0x95c7c752, 0x46232365, 0x9dc3c35e,
86   0x30181828, 0x379696a1, 0x0a05050f, 0x2f9a9ab5,
87   0x0e070709, 0x24121236, 0x1b80809b, 0xdfe2e23d,
88   0xcdebeb26, 0x4e272769, 0x7fb2b2cd, 0xea75759f,
89   0x1209091b, 0x1d83839e, 0x582c2c74, 0x341a1a2e,
90   0x361b1b2d, 0xdc6e6eb2, 0xb45a5aee, 0x5ba0a0fb,
91   0xa45252f6, 0x763b3b4d, 0xb7d6d661, 0x7db3b3ce,
92   0x5229297b, 0xdde3e33e, 0x5e2f2f71, 0x13848497,
93   0xa65353f5, 0xb9d1d168, 0x00000000, 0xc1eded2c,
94   0x40202060, 0xe3fcfc1f, 0x79b1b1c8, 0xb65b5bed,
95   0xd46a6abe, 0x8dcbcb46, 0x67bebed9, 0x7239394b,
96   0x944a4ade, 0x984c4cd4, 0xb05858e8, 0x85cfcf4a,
97   0xbbd0d06b, 0xc5efef2a, 0x4faaaae5, 0xedfbfb16,
98   0x864343c5, 0x9a4d4dd7, 0x66333355, 0x11858594,
99   0x8a4545cf, 0xe9f9f910, 0x04020206, 0xfe7f7f81,
100   0xa05050f0, 0x783c3c44, 0x259f9fba, 0x4ba8a8e3,
101   0xa25151f3, 0x5da3a3fe, 0x804040c0, 0x058f8f8a,
102   0x3f9292ad, 0x219d9dbc, 0x70383848, 0xf1f5f504,
103   0x63bcbcdf, 0x77b6b6c1, 0xafdada75, 0x42212163,
104   0x20101030, 0xe5ffff1a, 0xfdf3f30e, 0xbfd2d26d,
105   0x81cdcd4c, 0x180c0c14, 0x26131335, 0xc3ecec2f,
106   0xbe5f5fe1, 0x359797a2, 0x884444cc, 0x2e171739,
107   0x93c4c457, 0x55a7a7f2, 0xfc7e7e82, 0x7a3d3d47,
108   0xc86464ac, 0xba5d5de7, 0x3219192b, 0xe6737395,
109   0xc06060a0, 0x19818198, 0x9e4f4fd1, 0xa3dcdc7f,
110   0x44222266, 0x542a2a7e, 0x3b9090ab, 0x0b888883,
111   0x8c4646ca, 0xc7eeee29, 0x6bb8b8d3, 0x2814143c,
112   0xa7dede79, 0xbc5e5ee2, 0x160b0b1d, 0xaddbdb76,
113   0xdbe0e03b, 0x64323256, 0x743a3a4e, 0x140a0a1e,
114   0x924949db, 0x0c06060a, 0x4824246c, 0xb85c5ce4,
115   0x9fc2c25d, 0xbdd3d36e, 0x43acacef, 0xc46262a6,
116   0x399191a8, 0x319595a4, 0xd3e4e437, 0xf279798b,
117   0xd5e7e732, 0x8bc8c843, 0x6e373759, 0xda6d6db7,
118   0x018d8d8c, 0xb1d5d564, 0x9c4e4ed2, 0x49a9a9e0,
119   0xd86c6cb4, 0xac5656fa, 0xf3f4f407, 0xcfeaea25,
120   0xca6565af, 0xf47a7a8e, 0x47aeaee9, 0x10080818,
121   0x6fbabad5, 0xf0787888, 0x4a25256f, 0x5c2e2e72,
122   0x381c1c24, 0x57a6a6f1, 0x73b4b4c7, 0x97c6c651,
123   0xcbe8e823, 0xa1dddd7c, 0xe874749c, 0x3e1f1f21,
124   0x964b4bdd, 0x61bdbddc, 0x0d8b8b86, 0x0f8a8a85,
125   0xe0707090, 0x7c3e3e42, 0x71b5b5c4, 0xcc6666aa,
126   0x904848d8, 0x06030305, 0xf7f6f601, 0x1c0e0e12,
127   0xc26161a3, 0x6a35355f, 0xae5757f9, 0x69b9b9d0,
128   0x17868691, 0x99c1c158, 0x3a1d1d27, 0x279e9eb9,
129   0xd9e1e138, 0xebf8f813, 0x2b9898b3, 0x22111133,
130   0xd26969bb, 0xa9d9d970, 0x078e8e89, 0x339494a7,
131   0x2d9b9bb6, 0x3c1e1e22, 0x15878792, 0xc9e9e920,
132   0x87cece49, 0xaa5555ff, 0x50282878, 0xa5dfdf7a,
133   0x038c8c8f, 0x59a1a1f8, 0x09898980, 0x1a0d0d17,
134   0x65bfbfda, 0xd7e6e631, 0x844242c6, 0xd06868b8,
135   0x824141c3, 0x299999b0, 0x5a2d2d77, 0x1e0f0f11,
136   0x7bb0b0cb, 0xa85454fc, 0x6dbbbbd6, 0x2c16163a,
137 };
138 static const uint32_t Te1[256] = {
139   0xa5c66363, 0x84f87c7c, 0x99ee7777, 0x8df67b7b,
140   0x0dfff2f2, 0xbdd66b6b, 0xb1de6f6f, 0x5491c5c5,
141   0x50603030, 0x03020101, 0xa9ce6767, 0x7d562b2b,
142   0x19e7fefe, 0x62b5d7d7, 0xe64dabab, 0x9aec7676,
143   0x458fcaca, 0x9d1f8282, 0x4089c9c9, 0x87fa7d7d,
144   0x15effafa, 0xebb25959, 0xc98e4747, 0x0bfbf0f0,
145   0xec41adad, 0x67b3d4d4, 0xfd5fa2a2, 0xea45afaf,
146   0xbf239c9c, 0xf753a4a4, 0x96e47272, 0x5b9bc0c0,
147   0xc275b7b7, 0x1ce1fdfd, 0xae3d9393, 0x6a4c2626,
148   0x5a6c3636, 0x417e3f3f, 0x02f5f7f7, 0x4f83cccc,
149   0x5c683434, 0xf451a5a5, 0x34d1e5e5, 0x08f9f1f1,
150   0x93e27171, 0x73abd8d8, 0x53623131, 0x3f2a1515,
151   0x0c080404, 0x5295c7c7, 0x65462323, 0x5e9dc3c3,
152   0x28301818, 0xa1379696, 0x0f0a0505, 0xb52f9a9a,
153   0x090e0707, 0x36241212, 0x9b1b8080, 0x3ddfe2e2,
154   0x26cdebeb, 0x694e2727, 0xcd7fb2b2, 0x9fea7575,
155   0x1b120909, 0x9e1d8383, 0x74582c2c, 0x2e341a1a,
156   0x2d361b1b, 0xb2dc6e6e, 0xeeb45a5a, 0xfb5ba0a0,
157   0xf6a45252, 0x4d763b3b, 0x61b7d6d6, 0xce7db3b3,
158   0x7b522929, 0x3edde3e3, 0x715e2f2f, 0x97138484,
159   0xf5a65353, 0x68b9d1d1, 0x00000000, 0x2cc1eded,
160   0x60402020, 0x1fe3fcfc, 0xc879b1b1, 0xedb65b5b,
161   0xbed46a6a, 0x468dcbcb, 0xd967bebe, 0x4b723939,
162   0xde944a4a, 0xd4984c4c, 0xe8b05858, 0x4a85cfcf,
163   0x6bbbd0d0, 0x2ac5efef, 0xe54faaaa, 0x16edfbfb,
164   0xc5864343, 0xd79a4d4d, 0x55663333, 0x94118585,
165   0xcf8a4545, 0x10e9f9f9, 0x06040202, 0x81fe7f7f,
166   0xf0a05050, 0x44783c3c, 0xba259f9f, 0xe34ba8a8,
167   0xf3a25151, 0xfe5da3a3, 0xc0804040, 0x8a058f8f,
168   0xad3f9292, 0xbc219d9d, 0x48703838, 0x04f1f5f5,
169   0xdf63bcbc, 0xc177b6b6, 0x75afdada, 0x63422121,
170   0x30201010, 0x1ae5ffff, 0x0efdf3f3, 0x6dbfd2d2,
171   0x4c81cdcd, 0x14180c0c, 0x35261313, 0x2fc3ecec,
172   0xe1be5f5f, 0xa2359797, 0xcc884444, 0x392e1717,
173   0x5793c4c4, 0xf255a7a7, 0x82fc7e7e, 0x477a3d3d,
174   0xacc86464, 0xe7ba5d5d, 0x2b321919, 0x95e67373,
175   0xa0c06060, 0x98198181, 0xd19e4f4f, 0x7fa3dcdc,
176   0x66442222, 0x7e542a2a, 0xab3b9090, 0x830b8888,
177   0xca8c4646, 0x29c7eeee, 0xd36bb8b8, 0x3c281414,
178   0x79a7dede, 0xe2bc5e5e, 0x1d160b0b, 0x76addbdb,
179   0x3bdbe0e0, 0x56643232, 0x4e743a3a, 0x1e140a0a,
180   0xdb924949, 0x0a0c0606, 0x6c482424, 0xe4b85c5c,
181   0x5d9fc2c2, 0x6ebdd3d3, 0xef43acac, 0xa6c46262,
182   0xa8399191, 0xa4319595, 0x37d3e4e4, 0x8bf27979,
183   0x32d5e7e7, 0x438bc8c8, 0x596e3737, 0xb7da6d6d,
184   0x8c018d8d, 0x64b1d5d5, 0xd29c4e4e, 0xe049a9a9,
185   0xb4d86c6c, 0xfaac5656, 0x07f3f4f4, 0x25cfeaea,
186   0xafca6565, 0x8ef47a7a, 0xe947aeae, 0x18100808,
187   0xd56fbaba, 0x88f07878, 0x6f4a2525, 0x725c2e2e,
188   0x24381c1c, 0xf157a6a6, 0xc773b4b4, 0x5197c6c6,
189   0x23cbe8e8, 0x7ca1dddd, 0x9ce87474, 0x213e1f1f,
190   0xdd964b4b, 0xdc61bdbd, 0x860d8b8b, 0x850f8a8a,
191   0x90e07070, 0x427c3e3e, 0xc471b5b5, 0xaacc6666,
192   0xd8904848, 0x05060303, 0x01f7f6f6, 0x121c0e0e,
193   0xa3c26161, 0x5f6a3535, 0xf9ae5757, 0xd069b9b9,
194   0x91178686, 0x5899c1c1, 0x273a1d1d, 0xb9279e9e,
195   0x38d9e1e1, 0x13ebf8f8, 0xb32b9898, 0x33221111,
196   0xbbd26969, 0x70a9d9d9, 0x89078e8e, 0xa7339494,
197   0xb62d9b9b, 0x223c1e1e, 0x92158787, 0x20c9e9e9,
198   0x4987cece, 0xffaa5555, 0x78502828, 0x7aa5dfdf,
199   0x8f038c8c, 0xf859a1a1, 0x80098989, 0x171a0d0d,
200   0xda65bfbf, 0x31d7e6e6, 0xc6844242, 0xb8d06868,
201   0xc3824141, 0xb0299999, 0x775a2d2d, 0x111e0f0f,
202   0xcb7bb0b0, 0xfca85454, 0xd66dbbbb, 0x3a2c1616,
203 };
204 static const uint32_t Te2[256] = {
205   0x63a5c663, 0x7c84f87c, 0x7799ee77, 0x7b8df67b,
206   0xf20dfff2, 0x6bbdd66b, 0x6fb1de6f, 0xc55491c5,
207   0x30506030, 0x01030201, 0x67a9ce67, 0x2b7d562b,
208   0xfe19e7fe, 0xd762b5d7, 0xabe64dab, 0x769aec76,
209   0xca458fca, 0x829d1f82, 0xc94089c9, 0x7d87fa7d,
210   0xfa15effa, 0x59ebb259, 0x47c98e47, 0xf00bfbf0,
211   0xadec41ad, 0xd467b3d4, 0xa2fd5fa2, 0xafea45af,
212   0x9cbf239c, 0xa4f753a4, 0x7296e472, 0xc05b9bc0,
213   0xb7c275b7, 0xfd1ce1fd, 0x93ae3d93, 0x266a4c26,
214   0x365a6c36, 0x3f417e3f, 0xf702f5f7, 0xcc4f83cc,
215   0x345c6834, 0xa5f451a5, 0xe534d1e5, 0xf108f9f1,
216   0x7193e271, 0xd873abd8, 0x31536231, 0x153f2a15,
217   0x040c0804, 0xc75295c7, 0x23654623, 0xc35e9dc3,
218   0x18283018, 0x96a13796, 0x050f0a05, 0x9ab52f9a,
219   0x07090e07, 0x12362412, 0x809b1b80, 0xe23ddfe2,
220   0xeb26cdeb, 0x27694e27, 0xb2cd7fb2, 0x759fea75,
221   0x091b1209, 0x839e1d83, 0x2c74582c, 0x1a2e341a,
222   0x1b2d361b, 0x6eb2dc6e, 0x5aeeb45a, 0xa0fb5ba0,
223   0x52f6a452, 0x3b4d763b, 0xd661b7d6, 0xb3ce7db3,
224   0x297b5229, 0xe33edde3, 0x2f715e2f, 0x84971384,
225   0x53f5a653, 0xd168b9d1, 0x00000000, 0xed2cc1ed,
226   0x20604020, 0xfc1fe3fc, 0xb1c879b1, 0x5bedb65b,
227   0x6abed46a, 0xcb468dcb, 0xbed967be, 0x394b7239,
228   0x4ade944a, 0x4cd4984c, 0x58e8b058, 0xcf4a85cf,
229   0xd06bbbd0, 0xef2ac5ef, 0xaae54faa, 0xfb16edfb,
230   0x43c58643, 0x4dd79a4d, 0x33556633, 0x85941185,
231   0x45cf8a45, 0xf910e9f9, 0x02060402, 0x7f81fe7f,
232   0x50f0a050, 0x3c44783c, 0x9fba259f, 0xa8e34ba8,
233   0x51f3a251, 0xa3fe5da3, 0x40c08040, 0x8f8a058f,
234   0x92ad3f92, 0x9dbc219d, 0x38487038, 0xf504f1f5,
235   0xbcdf63bc, 0xb6c177b6, 0xda75afda, 0x21634221,
236   0x10302010, 0xff1ae5ff, 0xf30efdf3, 0xd26dbfd2,
237   0xcd4c81cd, 0x0c14180c, 0x13352613, 0xec2fc3ec,
238   0x5fe1be5f, 0x97a23597, 0x44cc8844, 0x17392e17,
239   0xc45793c4, 0xa7f255a7, 0x7e82fc7e, 0x3d477a3d,
240   0x64acc864, 0x5de7ba5d, 0x192b3219, 0x7395e673,
241   0x60a0c060, 0x81981981, 0x4fd19e4f, 0xdc7fa3dc,
242   0x22664422, 0x2a7e542a, 0x90ab3b90, 0x88830b88,
243   0x46ca8c46, 0xee29c7ee, 0xb8d36bb8, 0x143c2814,
244   0xde79a7de, 0x5ee2bc5e, 0x0b1d160b, 0xdb76addb,
245   0xe03bdbe0, 0x32566432, 0x3a4e743a, 0x0a1e140a,
246   0x49db9249, 0x060a0c06, 0x246c4824, 0x5ce4b85c,
247   0xc25d9fc2, 0xd36ebdd3, 0xacef43ac, 0x62a6c462,
248   0x91a83991, 0x95a43195, 0xe437d3e4, 0x798bf279,
249   0xe732d5e7, 0xc8438bc8, 0x37596e37, 0x6db7da6d,
250   0x8d8c018d, 0xd564b1d5, 0x4ed29c4e, 0xa9e049a9,
251   0x6cb4d86c, 0x56faac56, 0xf407f3f4, 0xea25cfea,
252   0x65afca65, 0x7a8ef47a, 0xaee947ae, 0x08181008,
253   0xbad56fba, 0x7888f078, 0x256f4a25, 0x2e725c2e,
254   0x1c24381c, 0xa6f157a6, 0xb4c773b4, 0xc65197c6,
255   0xe823cbe8, 0xdd7ca1dd, 0x749ce874, 0x1f213e1f,
256   0x4bdd964b, 0xbddc61bd, 0x8b860d8b, 0x8a850f8a,
257   0x7090e070, 0x3e427c3e, 0xb5c471b5, 0x66aacc66,
258   0x48d89048, 0x03050603, 0xf601f7f6, 0x0e121c0e,
259   0x61a3c261, 0x355f6a35, 0x57f9ae57, 0xb9d069b9,
260   0x86911786, 0xc15899c1, 0x1d273a1d, 0x9eb9279e,
261   0xe138d9e1, 0xf813ebf8, 0x98b32b98, 0x11332211,
262   0x69bbd269, 0xd970a9d9, 0x8e89078e, 0x94a73394,
263   0x9bb62d9b, 0x1e223c1e, 0x87921587, 0xe920c9e9,
264   0xce4987ce, 0x55ffaa55, 0x28785028, 0xdf7aa5df,
265   0x8c8f038c, 0xa1f859a1, 0x89800989, 0x0d171a0d,
266   0xbfda65bf, 0xe631d7e6, 0x42c68442, 0x68b8d068,
267   0x41c38241, 0x99b02999, 0x2d775a2d, 0x0f111e0f,
268   0xb0cb7bb0, 0x54fca854, 0xbbd66dbb, 0x163a2c16,
269 };
270 static const uint32_t Te3[256] = {
271   0x6363a5c6, 0x7c7c84f8, 0x777799ee, 0x7b7b8df6,
272   0xf2f20dff, 0x6b6bbdd6, 0x6f6fb1de, 0xc5c55491,
273   0x30305060, 0x01010302, 0x6767a9ce, 0x2b2b7d56,
274   0xfefe19e7, 0xd7d762b5, 0xababe64d, 0x76769aec,
275   0xcaca458f, 0x82829d1f, 0xc9c94089, 0x7d7d87fa,
276   0xfafa15ef, 0x5959ebb2, 0x4747c98e, 0xf0f00bfb,
277   0xadadec41, 0xd4d467b3, 0xa2a2fd5f, 0xafafea45,
278   0x9c9cbf23, 0xa4a4f753, 0x727296e4, 0xc0c05b9b,
279   0xb7b7c275, 0xfdfd1ce1, 0x9393ae3d, 0x26266a4c,
280   0x36365a6c, 0x3f3f417e, 0xf7f702f5, 0xcccc4f83,
281   0x34345c68, 0xa5a5f451, 0xe5e534d1, 0xf1f108f9,
282   0x717193e2, 0xd8d873ab, 0x31315362, 0x15153f2a,
283   0x04040c08, 0xc7c75295, 0x23236546, 0xc3c35e9d,
284   0x18182830, 0x9696a137, 0x05050f0a, 0x9a9ab52f,
285   0x0707090e, 0x12123624, 0x80809b1b, 0xe2e23ddf,
286   0xebeb26cd, 0x2727694e, 0xb2b2cd7f, 0x75759fea,
287   0x09091b12, 0x83839e1d, 0x2c2c7458, 0x1a1a2e34,
288   0x1b1b2d36, 0x6e6eb2dc, 0x5a5aeeb4, 0xa0a0fb5b,
289   0x5252f6a4, 0x3b3b4d76, 0xd6d661b7, 0xb3b3ce7d,
290   0x29297b52, 0xe3e33edd, 0x2f2f715e, 0x84849713,
291   0x5353f5a6, 0xd1d168b9, 0x00000000, 0xeded2cc1,
292   0x20206040, 0xfcfc1fe3, 0xb1b1c879, 0x5b5bedb6,
293   0x6a6abed4, 0xcbcb468d, 0xbebed967, 0x39394b72,
294   0x4a4ade94, 0x4c4cd498, 0x5858e8b0, 0xcfcf4a85,
295   0xd0d06bbb, 0xefef2ac5, 0xaaaae54f, 0xfbfb16ed,
296   0x4343c586, 0x4d4dd79a, 0x33335566, 0x85859411,
297   0x4545cf8a, 0xf9f910e9, 0x02020604, 0x7f7f81fe,
298   0x5050f0a0, 0x3c3c4478, 0x9f9fba25, 0xa8a8e34b,
299   0x5151f3a2, 0xa3a3fe5d, 0x4040c080, 0x8f8f8a05,
300   0x9292ad3f, 0x9d9dbc21, 0x38384870, 0xf5f504f1,
301   0xbcbcdf63, 0xb6b6c177, 0xdada75af, 0x21216342,
302   0x10103020, 0xffff1ae5, 0xf3f30efd, 0xd2d26dbf,
303   0xcdcd4c81, 0x0c0c1418, 0x13133526, 0xecec2fc3,
304   0x5f5fe1be, 0x9797a235, 0x4444cc88, 0x1717392e,
305   0xc4c45793, 0xa7a7f255, 0x7e7e82fc, 0x3d3d477a,
306   0x6464acc8, 0x5d5de7ba, 0x19192b32, 0x737395e6,
307   0x6060a0c0, 0x81819819, 0x4f4fd19e, 0xdcdc7fa3,
308   0x22226644, 0x2a2a7e54, 0x9090ab3b, 0x8888830b,
309   0x4646ca8c, 0xeeee29c7, 0xb8b8d36b, 0x14143c28,
310   0xdede79a7, 0x5e5ee2bc, 0x0b0b1d16, 0xdbdb76ad,
311   0xe0e03bdb, 0x32325664, 0x3a3a4e74, 0x0a0a1e14,
312   0x4949db92, 0x06060a0c, 0x24246c48, 0x5c5ce4b8,
313   0xc2c25d9f, 0xd3d36ebd, 0xacacef43, 0x6262a6c4,
314   0x9191a839, 0x9595a431, 0xe4e437d3, 0x79798bf2,
315   0xe7e732d5, 0xc8c8438b, 0x3737596e, 0x6d6db7da,
316   0x8d8d8c01, 0xd5d564b1, 0x4e4ed29c, 0xa9a9e049,
317   0x6c6cb4d8, 0x5656faac, 0xf4f407f3, 0xeaea25cf,
318   0x6565afca, 0x7a7a8ef4, 0xaeaee947, 0x08081810,
319   0xbabad56f, 0x787888f0, 0x25256f4a, 0x2e2e725c,
320   0x1c1c2438, 0xa6a6f157, 0xb4b4c773, 0xc6c65197,
321   0xe8e823cb, 0xdddd7ca1, 0x74749ce8, 0x1f1f213e,
322   0x4b4bdd96, 0xbdbddc61, 0x8b8b860d, 0x8a8a850f,
323   0x707090e0, 0x3e3e427c, 0xb5b5c471, 0x6666aacc,
324   0x4848d890, 0x03030506, 0xf6f601f7, 0x0e0e121c,
325   0x6161a3c2, 0x35355f6a, 0x5757f9ae, 0xb9b9d069,
326   0x86869117, 0xc1c15899, 0x1d1d273a, 0x9e9eb927,
327   0xe1e138d9, 0xf8f813eb, 0x9898b32b, 0x11113322,
328   0x6969bbd2, 0xd9d970a9, 0x8e8e8907, 0x9494a733,
329   0x9b9bb62d, 0x1e1e223c, 0x87879215, 0xe9e920c9,
330   0xcece4987, 0x5555ffaa, 0x28287850, 0xdfdf7aa5,
331   0x8c8c8f03, 0xa1a1f859, 0x89898009, 0x0d0d171a,
332   0xbfbfda65, 0xe6e631d7, 0x4242c684, 0x6868b8d0,
333   0x4141c382, 0x9999b029, 0x2d2d775a, 0x0f0f111e,
334   0xb0b0cb7b, 0x5454fca8, 0xbbbbd66d, 0x16163a2c,
335 };
336 static const uint32_t Te4[256] = {
337   0x63636363, 0x7c7c7c7c, 0x77777777, 0x7b7b7b7b,
338   0xf2f2f2f2, 0x6b6b6b6b, 0x6f6f6f6f, 0xc5c5c5c5,
339   0x30303030, 0x01010101, 0x67676767, 0x2b2b2b2b,
340   0xfefefefe, 0xd7d7d7d7, 0xabababab, 0x76767676,
341   0xcacacaca, 0x82828282, 0xc9c9c9c9, 0x7d7d7d7d,
342   0xfafafafa, 0x59595959, 0x47474747, 0xf0f0f0f0,
343   0xadadadad, 0xd4d4d4d4, 0xa2a2a2a2, 0xafafafaf,
344   0x9c9c9c9c, 0xa4a4a4a4, 0x72727272, 0xc0c0c0c0,
345   0xb7b7b7b7, 0xfdfdfdfd, 0x93939393, 0x26262626,
346   0x36363636, 0x3f3f3f3f, 0xf7f7f7f7, 0xcccccccc,
347   0x34343434, 0xa5a5a5a5, 0xe5e5e5e5, 0xf1f1f1f1,
348   0x71717171, 0xd8d8d8d8, 0x31313131, 0x15151515,
349   0x04040404, 0xc7c7c7c7, 0x23232323, 0xc3c3c3c3,
350   0x18181818, 0x96969696, 0x05050505, 0x9a9a9a9a,
351   0x07070707, 0x12121212, 0x80808080, 0xe2e2e2e2,
352   0xebebebeb, 0x27272727, 0xb2b2b2b2, 0x75757575,
353   0x09090909, 0x83838383, 0x2c2c2c2c, 0x1a1a1a1a,
354   0x1b1b1b1b, 0x6e6e6e6e, 0x5a5a5a5a, 0xa0a0a0a0,
355   0x52525252, 0x3b3b3b3b, 0xd6d6d6d6, 0xb3b3b3b3,
356   0x29292929, 0xe3e3e3e3, 0x2f2f2f2f, 0x84848484,
357   0x53535353, 0xd1d1d1d1, 0x00000000, 0xedededed,
358   0x20202020, 0xfcfcfcfc, 0xb1b1b1b1, 0x5b5b5b5b,
359   0x6a6a6a6a, 0xcbcbcbcb, 0xbebebebe, 0x39393939,
360   0x4a4a4a4a, 0x4c4c4c4c, 0x58585858, 0xcfcfcfcf,
361   0xd0d0d0d0, 0xefefefef, 0xaaaaaaaa, 0xfbfbfbfb,
362   0x43434343, 0x4d4d4d4d, 0x33333333, 0x85858585,
363   0x45454545, 0xf9f9f9f9, 0x02020202, 0x7f7f7f7f,
364   0x50505050, 0x3c3c3c3c, 0x9f9f9f9f, 0xa8a8a8a8,
365   0x51515151, 0xa3a3a3a3, 0x40404040, 0x8f8f8f8f,
366   0x92929292, 0x9d9d9d9d, 0x38383838, 0xf5f5f5f5,
367   0xbcbcbcbc, 0xb6b6b6b6, 0xdadadada, 0x21212121,
368   0x10101010, 0xffffffff, 0xf3f3f3f3, 0xd2d2d2d2,
369   0xcdcdcdcd, 0x0c0c0c0c, 0x13131313, 0xecececec,
370   0x5f5f5f5f, 0x97979797, 0x44444444, 0x17171717,
371   0xc4c4c4c4, 0xa7a7a7a7, 0x7e7e7e7e, 0x3d3d3d3d,
372   0x64646464, 0x5d5d5d5d, 0x19191919, 0x73737373,
373   0x60606060, 0x81818181, 0x4f4f4f4f, 0xdcdcdcdc,
374   0x22222222, 0x2a2a2a2a, 0x90909090, 0x88888888,
375   0x46464646, 0xeeeeeeee, 0xb8b8b8b8, 0x14141414,
376   0xdededede, 0x5e5e5e5e, 0x0b0b0b0b, 0xdbdbdbdb,
377   0xe0e0e0e0, 0x32323232, 0x3a3a3a3a, 0x0a0a0a0a,
378   0x49494949, 0x06060606, 0x24242424, 0x5c5c5c5c,
379   0xc2c2c2c2, 0xd3d3d3d3, 0xacacacac, 0x62626262,
380   0x91919191, 0x95959595, 0xe4e4e4e4, 0x79797979,
381   0xe7e7e7e7, 0xc8c8c8c8, 0x37373737, 0x6d6d6d6d,
382   0x8d8d8d8d, 0xd5d5d5d5, 0x4e4e4e4e, 0xa9a9a9a9,
383   0x6c6c6c6c, 0x56565656, 0xf4f4f4f4, 0xeaeaeaea,
384   0x65656565, 0x7a7a7a7a, 0xaeaeaeae, 0x08080808,
385   0xbabababa, 0x78787878, 0x25252525, 0x2e2e2e2e,
386   0x1c1c1c1c, 0xa6a6a6a6, 0xb4b4b4b4, 0xc6c6c6c6,
387   0xe8e8e8e8, 0xdddddddd, 0x74747474, 0x1f1f1f1f,
388   0x4b4b4b4b, 0xbdbdbdbd, 0x8b8b8b8b, 0x8a8a8a8a,
389   0x70707070, 0x3e3e3e3e, 0xb5b5b5b5, 0x66666666,
390   0x48484848, 0x03030303, 0xf6f6f6f6, 0x0e0e0e0e,
391   0x61616161, 0x35353535, 0x57575757, 0xb9b9b9b9,
392   0x86868686, 0xc1c1c1c1, 0x1d1d1d1d, 0x9e9e9e9e,
393   0xe1e1e1e1, 0xf8f8f8f8, 0x98989898, 0x11111111,
394   0x69696969, 0xd9d9d9d9, 0x8e8e8e8e, 0x94949494,
395   0x9b9b9b9b, 0x1e1e1e1e, 0x87878787, 0xe9e9e9e9,
396   0xcececece, 0x55555555, 0x28282828, 0xdfdfdfdf,
397   0x8c8c8c8c, 0xa1a1a1a1, 0x89898989, 0x0d0d0d0d,
398   0xbfbfbfbf, 0xe6e6e6e6, 0x42424242, 0x68686868,
399   0x41414141, 0x99999999, 0x2d2d2d2d, 0x0f0f0f0f,
400   0xb0b0b0b0, 0x54545454, 0xbbbbbbbb, 0x16161616,
401 };
402 static const uint32_t Td0[256] = {
403   0x51f4a750, 0x7e416553, 0x1a17a4c3, 0x3a275e96,
404   0x3bab6bcb, 0x1f9d45f1, 0xacfa58ab, 0x4be30393,
405   0x2030fa55, 0xad766df6, 0x88cc7691, 0xf5024c25,
406   0x4fe5d7fc, 0xc52acbd7, 0x26354480, 0xb562a38f,
407   0xdeb15a49, 0x25ba1b67, 0x45ea0e98, 0x5dfec0e1,
408   0xc32f7502, 0x814cf012, 0x8d4697a3, 0x6bd3f9c6,
409   0x038f5fe7, 0x15929c95, 0xbf6d7aeb, 0x955259da,
410   0xd4be832d, 0x587421d3, 0x49e06929, 0x8ec9c844,
411   0x75c2896a, 0xf48e7978, 0x99583e6b, 0x27b971dd,
412   0xbee14fb6, 0xf088ad17, 0xc920ac66, 0x7dce3ab4,
413   0x63df4a18, 0xe51a3182, 0x97513360, 0x62537f45,
414   0xb16477e0, 0xbb6bae84, 0xfe81a01c, 0xf9082b94,
415   0x70486858, 0x8f45fd19, 0x94de6c87, 0x527bf8b7,
416   0xab73d323, 0x724b02e2, 0xe31f8f57, 0x6655ab2a,
417   0xb2eb2807, 0x2fb5c203, 0x86c57b9a, 0xd33708a5,
418   0x302887f2, 0x23bfa5b2, 0x02036aba, 0xed16825c,
419   0x8acf1c2b, 0xa779b492, 0xf307f2f0, 0x4e69e2a1,
420   0x65daf4cd, 0x0605bed5, 0xd134621f, 0xc4a6fe8a,
421   0x342e539d, 0xa2f355a0, 0x058ae132, 0xa4f6eb75,
422   0x0b83ec39, 0x4060efaa, 0x5e719f06, 0xbd6e1051,
423   0x3e218af9, 0x96dd063d, 0xdd3e05ae, 0x4de6bd46,
424   0x91548db5, 0x71c45d05, 0x0406d46f, 0x605015ff,
425   0x1998fb24, 0xd6bde997, 0x894043cc, 0x67d99e77,
426   0xb0e842bd, 0x07898b88, 0xe7195b38, 0x79c8eedb,
427   0xa17c0a47, 0x7c420fe9, 0xf8841ec9, 0x00000000,
428   0x09808683, 0x322bed48, 0x1e1170ac, 0x6c5a724e,
429   0xfd0efffb, 0x0f853856, 0x3daed51e, 0x362d3927,
430   0x0a0fd964, 0x685ca621, 0x9b5b54d1, 0x24362e3a,
431   0x0c0a67b1, 0x9357e70f, 0xb4ee96d2, 0x1b9b919e,
432   0x80c0c54f, 0x61dc20a2, 0x5a774b69, 0x1c121a16,
433   0xe293ba0a, 0xc0a02ae5, 0x3c22e043, 0x121b171d,
434   0x0e090d0b, 0xf28bc7ad, 0x2db6a8b9, 0x141ea9c8,
435   0x57f11985, 0xaf75074c, 0xee99ddbb, 0xa37f60fd,
436   0xf701269f, 0x5c72f5bc, 0x44663bc5, 0x5bfb7e34,
437   0x8b432976, 0xcb23c6dc, 0xb6edfc68, 0xb8e4f163,
438   0xd731dcca, 0x42638510, 0x13972240, 0x84c61120,
439   0x854a247d, 0xd2bb3df8, 0xaef93211, 0xc729a16d,
440   0x1d9e2f4b, 0xdcb230f3, 0x0d8652ec, 0x77c1e3d0,
441   0x2bb3166c, 0xa970b999, 0x119448fa, 0x47e96422,
442   0xa8fc8cc4, 0xa0f03f1a, 0x567d2cd8, 0x223390ef,
443   0x87494ec7, 0xd938d1c1, 0x8ccaa2fe, 0x98d40b36,
444   0xa6f581cf, 0xa57ade28, 0xdab78e26, 0x3fadbfa4,
445   0x2c3a9de4, 0x5078920d, 0x6a5fcc9b, 0x547e4662,
446   0xf68d13c2, 0x90d8b8e8, 0x2e39f75e, 0x82c3aff5,
447   0x9f5d80be, 0x69d0937c, 0x6fd52da9, 0xcf2512b3,
448   0xc8ac993b, 0x10187da7, 0xe89c636e, 0xdb3bbb7b,
449   0xcd267809, 0x6e5918f4, 0xec9ab701, 0x834f9aa8,
450   0xe6956e65, 0xaaffe67e, 0x21bccf08, 0xef15e8e6,
451   0xbae79bd9, 0x4a6f36ce, 0xea9f09d4, 0x29b07cd6,
452   0x31a4b2af, 0x2a3f2331, 0xc6a59430, 0x35a266c0,
453   0x744ebc37, 0xfc82caa6, 0xe090d0b0, 0x33a7d815,
454   0xf104984a, 0x41ecdaf7, 0x7fcd500e, 0x1791f62f,
455   0x764dd68d, 0x43efb04d, 0xccaa4d54, 0xe49604df,
456   0x9ed1b5e3, 0x4c6a881b, 0xc12c1fb8, 0x4665517f,
457   0x9d5eea04, 0x018c355d, 0xfa877473, 0xfb0b412e,
458   0xb3671d5a, 0x92dbd252, 0xe9105633, 0x6dd64713,
459   0x9ad7618c, 0x37a10c7a, 0x59f8148e, 0xeb133c89,
460   0xcea927ee, 0xb761c935, 0xe11ce5ed, 0x7a47b13c,
461   0x9cd2df59, 0x55f2733f, 0x1814ce79, 0x73c737bf,
462   0x53f7cdea, 0x5ffdaa5b, 0xdf3d6f14, 0x7844db86,
463   0xcaaff381, 0xb968c43e, 0x3824342c, 0xc2a3405f,
464   0x161dc372, 0xbce2250c, 0x283c498b, 0xff0d9541,
465   0x39a80171, 0x080cb3de, 0xd8b4e49c, 0x6456c190,
466   0x7bcb8461, 0xd532b670, 0x486c5c74, 0xd0b85742,
467 };
468 static const uint32_t Td1[256] = {
469   0x5051f4a7, 0x537e4165, 0xc31a17a4, 0x963a275e,
470   0xcb3bab6b, 0xf11f9d45, 0xabacfa58, 0x934be303,
471   0x552030fa, 0xf6ad766d, 0x9188cc76, 0x25f5024c,
472   0xfc4fe5d7, 0xd7c52acb, 0x80263544, 0x8fb562a3,
473   0x49deb15a, 0x6725ba1b, 0x9845ea0e, 0xe15dfec0,
474   0x02c32f75, 0x12814cf0, 0xa38d4697, 0xc66bd3f9,
475   0xe7038f5f, 0x9515929c, 0xebbf6d7a, 0xda955259,
476   0x2dd4be83, 0xd3587421, 0x2949e069, 0x448ec9c8,
477   0x6a75c289, 0x78f48e79, 0x6b99583e, 0xdd27b971,
478   0xb6bee14f, 0x17f088ad, 0x66c920ac, 0xb47dce3a,
479   0x1863df4a, 0x82e51a31, 0x60975133, 0x4562537f,
480   0xe0b16477, 0x84bb6bae, 0x1cfe81a0, 0x94f9082b,
481   0x58704868, 0x198f45fd, 0x8794de6c, 0xb7527bf8,
482   0x23ab73d3, 0xe2724b02, 0x57e31f8f, 0x2a6655ab,
483   0x07b2eb28, 0x032fb5c2, 0x9a86c57b, 0xa5d33708,
484   0xf2302887, 0xb223bfa5, 0xba02036a, 0x5ced1682,
485   0x2b8acf1c, 0x92a779b4, 0xf0f307f2, 0xa14e69e2,
486   0xcd65daf4, 0xd50605be, 0x1fd13462, 0x8ac4a6fe,
487   0x9d342e53, 0xa0a2f355, 0x32058ae1, 0x75a4f6eb,
488   0x390b83ec, 0xaa4060ef, 0x065e719f, 0x51bd6e10,
489   0xf93e218a, 0x3d96dd06, 0xaedd3e05, 0x464de6bd,
490   0xb591548d, 0x0571c45d, 0x6f0406d4, 0xff605015,
491   0x241998fb, 0x97d6bde9, 0xcc894043, 0x7767d99e,
492   0xbdb0e842, 0x8807898b, 0x38e7195b, 0xdb79c8ee,
493   0x47a17c0a, 0xe97c420f, 0xc9f8841e, 0x00000000,
494   0x83098086, 0x48322bed, 0xac1e1170, 0x4e6c5a72,
495   0xfbfd0eff, 0x560f8538, 0x1e3daed5, 0x27362d39,
496   0x640a0fd9, 0x21685ca6, 0xd19b5b54, 0x3a24362e,
497   0xb10c0a67, 0x0f9357e7, 0xd2b4ee96, 0x9e1b9b91,
498   0x4f80c0c5, 0xa261dc20, 0x695a774b, 0x161c121a,
499   0x0ae293ba, 0xe5c0a02a, 0x433c22e0, 0x1d121b17,
500   0x0b0e090d, 0xadf28bc7, 0xb92db6a8, 0xc8141ea9,
501   0x8557f119, 0x4caf7507, 0xbbee99dd, 0xfda37f60,
502   0x9ff70126, 0xbc5c72f5, 0xc544663b, 0x345bfb7e,
503   0x768b4329, 0xdccb23c6, 0x68b6edfc, 0x63b8e4f1,
504   0xcad731dc, 0x10426385, 0x40139722, 0x2084c611,
505   0x7d854a24, 0xf8d2bb3d, 0x11aef932, 0x6dc729a1,
506   0x4b1d9e2f, 0xf3dcb230, 0xec0d8652, 0xd077c1e3,
507   0x6c2bb316, 0x99a970b9, 0xfa119448, 0x2247e964,
508   0xc4a8fc8c, 0x1aa0f03f, 0xd8567d2c, 0xef223390,
509   0xc787494e, 0xc1d938d1, 0xfe8ccaa2, 0x3698d40b,
510   0xcfa6f581, 0x28a57ade, 0x26dab78e, 0xa43fadbf,
511   0xe42c3a9d, 0x0d507892, 0x9b6a5fcc, 0x62547e46,
512   0xc2f68d13, 0xe890d8b8, 0x5e2e39f7, 0xf582c3af,
513   0xbe9f5d80, 0x7c69d093, 0xa96fd52d, 0xb3cf2512,
514   0x3bc8ac99, 0xa710187d, 0x6ee89c63, 0x7bdb3bbb,
515   0x09cd2678, 0xf46e5918, 0x01ec9ab7, 0xa8834f9a,
516   0x65e6956e, 0x7eaaffe6, 0x0821bccf, 0xe6ef15e8,
517   0xd9bae79b, 0xce4a6f36, 0xd4ea9f09, 0xd629b07c,
518   0xaf31a4b2, 0x312a3f23, 0x30c6a594, 0xc035a266,
519   0x37744ebc, 0xa6fc82ca, 0xb0e090d0, 0x1533a7d8,
520   0x4af10498, 0xf741ecda, 0x0e7fcd50, 0x2f1791f6,
521   0x8d764dd6, 0x4d43efb0, 0x54ccaa4d, 0xdfe49604,
522   0xe39ed1b5, 0x1b4c6a88, 0xb8c12c1f, 0x7f466551,
523   0x049d5eea, 0x5d018c35, 0x73fa8774, 0x2efb0b41,
524   0x5ab3671d, 0x5292dbd2, 0x33e91056, 0x136dd647,
525   0x8c9ad761, 0x7a37a10c, 0x8e59f814, 0x89eb133c,
526   0xeecea927, 0x35b761c9, 0xede11ce5, 0x3c7a47b1,
527   0x599cd2df, 0x3f55f273, 0x791814ce, 0xbf73c737,
528   0xea53f7cd, 0x5b5ffdaa, 0x14df3d6f, 0x867844db,
529   0x81caaff3, 0x3eb968c4, 0x2c382434, 0x5fc2a340,
530   0x72161dc3, 0x0cbce225, 0x8b283c49, 0x41ff0d95,
531   0x7139a801, 0xde080cb3, 0x9cd8b4e4, 0x906456c1,
532   0x617bcb84, 0x70d532b6, 0x74486c5c, 0x42d0b857,
533 };
534 static const uint32_t Td2[256] = {
535   0xa75051f4, 0x65537e41, 0xa4c31a17, 0x5e963a27,
536   0x6bcb3bab, 0x45f11f9d, 0x58abacfa, 0x03934be3,
537   0xfa552030, 0x6df6ad76, 0x769188cc, 0x4c25f502,
538   0xd7fc4fe5, 0xcbd7c52a, 0x44802635, 0xa38fb562,
539   0x5a49deb1, 0x1b6725ba, 0x0e9845ea, 0xc0e15dfe,
540   0x7502c32f, 0xf012814c, 0x97a38d46, 0xf9c66bd3,
541   0x5fe7038f, 0x9c951592, 0x7aebbf6d, 0x59da9552,
542   0x832dd4be, 0x21d35874, 0x692949e0, 0xc8448ec9,
543   0x896a75c2, 0x7978f48e, 0x3e6b9958, 0x71dd27b9,
544   0x4fb6bee1, 0xad17f088, 0xac66c920, 0x3ab47dce,
545   0x4a1863df, 0x3182e51a, 0x33609751, 0x7f456253,
546   0x77e0b164, 0xae84bb6b, 0xa01cfe81, 0x2b94f908,
547   0x68587048, 0xfd198f45, 0x6c8794de, 0xf8b7527b,
548   0xd323ab73, 0x02e2724b, 0x8f57e31f, 0xab2a6655,
549   0x2807b2eb, 0xc2032fb5, 0x7b9a86c5, 0x08a5d337,
550   0x87f23028, 0xa5b223bf, 0x6aba0203, 0x825ced16,
551   0x1c2b8acf, 0xb492a779, 0xf2f0f307, 0xe2a14e69,
552   0xf4cd65da, 0xbed50605, 0x621fd134, 0xfe8ac4a6,
553   0x539d342e, 0x55a0a2f3, 0xe132058a, 0xeb75a4f6,
554   0xec390b83, 0xefaa4060, 0x9f065e71, 0x1051bd6e,
555   0x8af93e21, 0x063d96dd, 0x05aedd3e, 0xbd464de6,
556   0x8db59154, 0x5d0571c4, 0xd46f0406, 0x15ff6050,
557   0xfb241998, 0xe997d6bd, 0x43cc8940, 0x9e7767d9,
558   0x42bdb0e8, 0x8b880789, 0x5b38e719, 0xeedb79c8,
559   0x0a47a17c, 0x0fe97c42, 0x1ec9f884, 0x00000000,
560   0x86830980, 0xed48322b, 0x70ac1e11, 0x724e6c5a,
561   0xfffbfd0e, 0x38560f85, 0xd51e3dae, 0x3927362d,
562   0xd9640a0f, 0xa621685c, 0x54d19b5b, 0x2e3a2436,
563   0x67b10c0a, 0xe70f9357, 0x96d2b4ee, 0x919e1b9b,
564   0xc54f80c0, 0x20a261dc, 0x4b695a77, 0x1a161c12,
565   0xba0ae293, 0x2ae5c0a0, 0xe0433c22, 0x171d121b,
566   0x0d0b0e09, 0xc7adf28b, 0xa8b92db6, 0xa9c8141e,
567   0x198557f1, 0x074caf75, 0xddbbee99, 0x60fda37f,
568   0x269ff701, 0xf5bc5c72, 0x3bc54466, 0x7e345bfb,
569   0x29768b43, 0xc6dccb23, 0xfc68b6ed, 0xf163b8e4,
570   0xdccad731, 0x85104263, 0x22401397, 0x112084c6,
571   0x247d854a, 0x3df8d2bb, 0x3211aef9, 0xa16dc729,
572   0x2f4b1d9e, 0x30f3dcb2, 0x52ec0d86, 0xe3d077c1,
573   0x166c2bb3, 0xb999a970, 0x48fa1194, 0x642247e9,
574   0x8cc4a8fc, 0x3f1aa0f0, 0x2cd8567d, 0x90ef2233,
575   0x4ec78749, 0xd1c1d938, 0xa2fe8cca, 0x0b3698d4,
576   0x81cfa6f5, 0xde28a57a, 0x8e26dab7, 0xbfa43fad,
577   0x9de42c3a, 0x920d5078, 0xcc9b6a5f, 0x4662547e,
578   0x13c2f68d, 0xb8e890d8, 0xf75e2e39, 0xaff582c3,
579   0x80be9f5d, 0x937c69d0, 0x2da96fd5, 0x12b3cf25,
580   0x993bc8ac, 0x7da71018, 0x636ee89c, 0xbb7bdb3b,
581   0x7809cd26, 0x18f46e59, 0xb701ec9a, 0x9aa8834f,
582   0x6e65e695, 0xe67eaaff, 0xcf0821bc, 0xe8e6ef15,
583   0x9bd9bae7, 0x36ce4a6f, 0x09d4ea9f, 0x7cd629b0,
584   0xb2af31a4, 0x23312a3f, 0x9430c6a5, 0x66c035a2,
585   0xbc37744e, 0xcaa6fc82, 0xd0b0e090, 0xd81533a7,
586   0x984af104, 0xdaf741ec, 0x500e7fcd, 0xf62f1791,
587   0xd68d764d, 0xb04d43ef, 0x4d54ccaa, 0x04dfe496,
588   0xb5e39ed1, 0x881b4c6a, 0x1fb8c12c, 0x517f4665,
589   0xea049d5e, 0x355d018c, 0x7473fa87, 0x412efb0b,
590   0x1d5ab367, 0xd25292db, 0x5633e910, 0x47136dd6,
591   0x618c9ad7, 0x0c7a37a1, 0x148e59f8, 0x3c89eb13,
592   0x27eecea9, 0xc935b761, 0xe5ede11c, 0xb13c7a47,
593   0xdf599cd2, 0x733f55f2, 0xce791814, 0x37bf73c7,
594   0xcdea53f7, 0xaa5b5ffd, 0x6f14df3d, 0xdb867844,
595   0xf381caaf, 0xc43eb968, 0x342c3824, 0x405fc2a3,
596   0xc372161d, 0x250cbce2, 0x498b283c, 0x9541ff0d,
597   0x017139a8, 0xb3de080c, 0xe49cd8b4, 0xc1906456,
598   0x84617bcb, 0xb670d532, 0x5c74486c, 0x5742d0b8,
599 };
600 static const uint32_t Td3[256] = {
601   0xf4a75051, 0x4165537e, 0x17a4c31a, 0x275e963a,
602   0xab6bcb3b, 0x9d45f11f, 0xfa58abac, 0xe303934b,
603   0x30fa5520, 0x766df6ad, 0xcc769188, 0x024c25f5,
604   0xe5d7fc4f, 0x2acbd7c5, 0x35448026, 0x62a38fb5,
605   0xb15a49de, 0xba1b6725, 0xea0e9845, 0xfec0e15d,
606   0x2f7502c3, 0x4cf01281, 0x4697a38d, 0xd3f9c66b,
607   0x8f5fe703, 0x929c9515, 0x6d7aebbf, 0x5259da95,
608   0xbe832dd4, 0x7421d358, 0xe0692949, 0xc9c8448e,
609   0xc2896a75, 0x8e7978f4, 0x583e6b99, 0xb971dd27,
610   0xe14fb6be, 0x88ad17f0, 0x20ac66c9, 0xce3ab47d,
611   0xdf4a1863, 0x1a3182e5, 0x51336097, 0x537f4562,
612   0x6477e0b1, 0x6bae84bb, 0x81a01cfe, 0x082b94f9,
613   0x48685870, 0x45fd198f, 0xde6c8794, 0x7bf8b752,
614   0x73d323ab, 0x4b02e272, 0x1f8f57e3, 0x55ab2a66,
615   0xeb2807b2, 0xb5c2032f, 0xc57b9a86, 0x3708a5d3,
616   0x2887f230, 0xbfa5b223, 0x036aba02, 0x16825ced,
617   0xcf1c2b8a, 0x79b492a7, 0x07f2f0f3, 0x69e2a14e,
618   0xdaf4cd65, 0x05bed506, 0x34621fd1, 0xa6fe8ac4,
619   0x2e539d34, 0xf355a0a2, 0x8ae13205, 0xf6eb75a4,
620   0x83ec390b, 0x60efaa40, 0x719f065e, 0x6e1051bd,
621   0x218af93e, 0xdd063d96, 0x3e05aedd, 0xe6bd464d,
622   0x548db591, 0xc45d0571, 0x06d46f04, 0x5015ff60,
623   0x98fb2419, 0xbde997d6, 0x4043cc89, 0xd99e7767,
624   0xe842bdb0, 0x898b8807, 0x195b38e7, 0xc8eedb79,
625   0x7c0a47a1, 0x420fe97c, 0x841ec9f8, 0x00000000,
626   0x80868309, 0x2bed4832, 0x1170ac1e, 0x5a724e6c,
627   0x0efffbfd, 0x8538560f, 0xaed51e3d, 0x2d392736,
628   0x0fd9640a, 0x5ca62168, 0x5b54d19b, 0x362e3a24,
629   0x0a67b10c, 0x57e70f93, 0xee96d2b4, 0x9b919e1b,
630   0xc0c54f80, 0xdc20a261, 0x774b695a, 0x121a161c,
631   0x93ba0ae2, 0xa02ae5c0, 0x22e0433c, 0x1b171d12,
632   0x090d0b0e, 0x8bc7adf2, 0xb6a8b92d, 0x1ea9c814,
633   0xf1198557, 0x75074caf, 0x99ddbbee, 0x7f60fda3,
634   0x01269ff7, 0x72f5bc5c, 0x663bc544, 0xfb7e345b,
635   0x4329768b, 0x23c6dccb, 0xedfc68b6, 0xe4f163b8,
636   0x31dccad7, 0x63851042, 0x97224013, 0xc6112084,
637   0x4a247d85, 0xbb3df8d2, 0xf93211ae, 0x29a16dc7,
638   0x9e2f4b1d, 0xb230f3dc, 0x8652ec0d, 0xc1e3d077,
639   0xb3166c2b, 0x70b999a9, 0x9448fa11, 0xe9642247,
640   0xfc8cc4a8, 0xf03f1aa0, 0x7d2cd856, 0x3390ef22,
641   0x494ec787, 0x38d1c1d9, 0xcaa2fe8c, 0xd40b3698,
642   0xf581cfa6, 0x7ade28a5, 0xb78e26da, 0xadbfa43f,
643   0x3a9de42c, 0x78920d50, 0x5fcc9b6a, 0x7e466254,
644   0x8d13c2f6, 0xd8b8e890, 0x39f75e2e, 0xc3aff582,
645   0x5d80be9f, 0xd0937c69, 0xd52da96f, 0x2512b3cf,
646   0xac993bc8, 0x187da710, 0x9c636ee8, 0x3bbb7bdb,
647   0x267809cd, 0x5918f46e, 0x9ab701ec, 0x4f9aa883,
648   0x956e65e6, 0xffe67eaa, 0xbccf0821, 0x15e8e6ef,
649   0xe79bd9ba, 0x6f36ce4a, 0x9f09d4ea, 0xb07cd629,
650   0xa4b2af31, 0x3f23312a, 0xa59430c6, 0xa266c035,
651   0x4ebc3774, 0x82caa6fc, 0x90d0b0e0, 0xa7d81533,
652   0x04984af1, 0xecdaf741, 0xcd500e7f, 0x91f62f17,
653   0x4dd68d76, 0xefb04d43, 0xaa4d54cc, 0x9604dfe4,
654   0xd1b5e39e, 0x6a881b4c, 0x2c1fb8c1, 0x65517f46,
655   0x5eea049d, 0x8c355d01, 0x877473fa, 0x0b412efb,
656   0x671d5ab3, 0xdbd25292, 0x105633e9, 0xd647136d,
657   0xd7618c9a, 0xa10c7a37, 0xf8148e59, 0x133c89eb,
658   0xa927eece, 0x61c935b7, 0x1ce5ede1, 0x47b13c7a,
659   0xd2df599c, 0xf2733f55, 0x14ce7918, 0xc737bf73,
660   0xf7cdea53, 0xfdaa5b5f, 0x3d6f14df, 0x44db8678,
661   0xaff381ca, 0x68c43eb9, 0x24342c38, 0xa3405fc2,
662   0x1dc37216, 0xe2250cbc, 0x3c498b28, 0x0d9541ff,
663   0xa8017139, 0x0cb3de08, 0xb4e49cd8, 0x56c19064,
664   0xcb84617b, 0x32b670d5, 0x6c5c7448, 0xb85742d0,
665 };
666 static const uint32_t Td4[256] = {
667   0x52525252, 0x09090909, 0x6a6a6a6a, 0xd5d5d5d5,
668   0x30303030, 0x36363636, 0xa5a5a5a5, 0x38383838,
669   0xbfbfbfbf, 0x40404040, 0xa3a3a3a3, 0x9e9e9e9e,
670   0x81818181, 0xf3f3f3f3, 0xd7d7d7d7, 0xfbfbfbfb,
671   0x7c7c7c7c, 0xe3e3e3e3, 0x39393939, 0x82828282,
672   0x9b9b9b9b, 0x2f2f2f2f, 0xffffffff, 0x87878787,
673   0x34343434, 0x8e8e8e8e, 0x43434343, 0x44444444,
674   0xc4c4c4c4, 0xdededede, 0xe9e9e9e9, 0xcbcbcbcb,
675   0x54545454, 0x7b7b7b7b, 0x94949494, 0x32323232,
676   0xa6a6a6a6, 0xc2c2c2c2, 0x23232323, 0x3d3d3d3d,
677   0xeeeeeeee, 0x4c4c4c4c, 0x95959595, 0x0b0b0b0b,
678   0x42424242, 0xfafafafa, 0xc3c3c3c3, 0x4e4e4e4e,
679   0x08080808, 0x2e2e2e2e, 0xa1a1a1a1, 0x66666666,
680   0x28282828, 0xd9d9d9d9, 0x24242424, 0xb2b2b2b2,
681   0x76767676, 0x5b5b5b5b, 0xa2a2a2a2, 0x49494949,
682   0x6d6d6d6d, 0x8b8b8b8b, 0xd1d1d1d1, 0x25252525,
683   0x72727272, 0xf8f8f8f8, 0xf6f6f6f6, 0x64646464,
684   0x86868686, 0x68686868, 0x98989898, 0x16161616,
685   0xd4d4d4d4, 0xa4a4a4a4, 0x5c5c5c5c, 0xcccccccc,
686   0x5d5d5d5d, 0x65656565, 0xb6b6b6b6, 0x92929292,
687   0x6c6c6c6c, 0x70707070, 0x48484848, 0x50505050,
688   0xfdfdfdfd, 0xedededed, 0xb9b9b9b9, 0xdadadada,
689   0x5e5e5e5e, 0x15151515, 0x46464646, 0x57575757,
690   0xa7a7a7a7, 0x8d8d8d8d, 0x9d9d9d9d, 0x84848484,
691   0x90909090, 0xd8d8d8d8, 0xabababab, 0x00000000,
692   0x8c8c8c8c, 0xbcbcbcbc, 0xd3d3d3d3, 0x0a0a0a0a,
693   0xf7f7f7f7, 0xe4e4e4e4, 0x58585858, 0x05050505,
694   0xb8b8b8b8, 0xb3b3b3b3, 0x45454545, 0x06060606,
695   0xd0d0d0d0, 0x2c2c2c2c, 0x1e1e1e1e, 0x8f8f8f8f,
696   0xcacacaca, 0x3f3f3f3f, 0x0f0f0f0f, 0x02020202,
697   0xc1c1c1c1, 0xafafafaf, 0xbdbdbdbd, 0x03030303,
698   0x01010101, 0x13131313, 0x8a8a8a8a, 0x6b6b6b6b,
699   0x3a3a3a3a, 0x91919191, 0x11111111, 0x41414141,
700   0x4f4f4f4f, 0x67676767, 0xdcdcdcdc, 0xeaeaeaea,
701   0x97979797, 0xf2f2f2f2, 0xcfcfcfcf, 0xcececece,
702   0xf0f0f0f0, 0xb4b4b4b4, 0xe6e6e6e6, 0x73737373,
703   0x96969696, 0xacacacac, 0x74747474, 0x22222222,
704   0xe7e7e7e7, 0xadadadad, 0x35353535, 0x85858585,
705   0xe2e2e2e2, 0xf9f9f9f9, 0x37373737, 0xe8e8e8e8,
706   0x1c1c1c1c, 0x75757575, 0xdfdfdfdf, 0x6e6e6e6e,
707   0x47474747, 0xf1f1f1f1, 0x1a1a1a1a, 0x71717171,
708   0x1d1d1d1d, 0x29292929, 0xc5c5c5c5, 0x89898989,
709   0x6f6f6f6f, 0xb7b7b7b7, 0x62626262, 0x0e0e0e0e,
710   0xaaaaaaaa, 0x18181818, 0xbebebebe, 0x1b1b1b1b,
711   0xfcfcfcfc, 0x56565656, 0x3e3e3e3e, 0x4b4b4b4b,
712   0xc6c6c6c6, 0xd2d2d2d2, 0x79797979, 0x20202020,
713   0x9a9a9a9a, 0xdbdbdbdb, 0xc0c0c0c0, 0xfefefefe,
714   0x78787878, 0xcdcdcdcd, 0x5a5a5a5a, 0xf4f4f4f4,
715   0x1f1f1f1f, 0xdddddddd, 0xa8a8a8a8, 0x33333333,
716   0x88888888, 0x07070707, 0xc7c7c7c7, 0x31313131,
717   0xb1b1b1b1, 0x12121212, 0x10101010, 0x59595959,
718   0x27272727, 0x80808080, 0xecececec, 0x5f5f5f5f,
719   0x60606060, 0x51515151, 0x7f7f7f7f, 0xa9a9a9a9,
720   0x19191919, 0xb5b5b5b5, 0x4a4a4a4a, 0x0d0d0d0d,
721   0x2d2d2d2d, 0xe5e5e5e5, 0x7a7a7a7a, 0x9f9f9f9f,
722   0x93939393, 0xc9c9c9c9, 0x9c9c9c9c, 0xefefefef,
723   0xa0a0a0a0, 0xe0e0e0e0, 0x3b3b3b3b, 0x4d4d4d4d,
724   0xaeaeaeae, 0x2a2a2a2a, 0xf5f5f5f5, 0xb0b0b0b0,
725   0xc8c8c8c8, 0xebebebeb, 0xbbbbbbbb, 0x3c3c3c3c,
726   0x83838383, 0x53535353, 0x99999999, 0x61616161,
727   0x17171717, 0x2b2b2b2b, 0x04040404, 0x7e7e7e7e,
728   0xbabababa, 0x77777777, 0xd6d6d6d6, 0x26262626,
729   0xe1e1e1e1, 0x69696969, 0x14141414, 0x63636363,
730   0x55555555, 0x21212121, 0x0c0c0c0c, 0x7d7d7d7d,
731 };
732 static const uint32_t rcon[] = {
733   0x01000000, 0x02000000, 0x04000000, 0x08000000,
734   0x10000000, 0x20000000, 0x40000000, 0x80000000,
735   0x1B000000, 0x36000000
736     /* for 128-bit blocks, Rijndael never uses more than 10 rcon values */
737 };
738
739 #define GETU32(pt) (((uint32_t)((pt)[0] & 0xFF) << 24) ^ \
740                     ((uint32_t)((pt)[1] & 0xFF) << 16) ^ \
741                     ((uint32_t)((pt)[2] & 0xFF) <<  8) ^ \
742                     ((uint32_t)((pt)[3] & 0xFF)))
743 #define PUTU32(ct, st) {                                        \
744     (ct)[0] = (char)((st) >> 24);                               \
745     (ct)[1] = (char)((st) >> 16);                               \
746     (ct)[2] = (char)((st) >>  8);                               \
747     (ct)[3] = (char)(st); }
748
749 /**
750  * Expand the cipher key into the encryption key schedule.
751  *
752  * @return      the number of rounds for the given cipher key size.
753  */
754 int
755 rijndaelKeySetupEnc (uint32_t rk[ /*4*(Nr + 1) */ ],
756                      const char cipherKey[], size_t keyBits)
757 {
758   size_t i = 0;
759   uint32_t temp;
760
761   rk[0] = GETU32 (cipherKey);
762   rk[1] = GETU32 (cipherKey + 4);
763   rk[2] = GETU32 (cipherKey + 8);
764   rk[3] = GETU32 (cipherKey + 12);
765   if (keyBits == 128)
766     {
767       for (;;)
768         {
769           temp = rk[3];
770           rk[4] = rk[0] ^
771             (Te4[(temp >> 16) & 0xff] & 0xff000000) ^
772             (Te4[(temp >> 8) & 0xff] & 0x00ff0000) ^
773             (Te4[(temp) & 0xff] & 0x0000ff00) ^
774             (Te4[(temp >> 24)] & 0x000000ff) ^ rcon[i];
775           rk[5] = rk[1] ^ rk[4];
776           rk[6] = rk[2] ^ rk[5];
777           rk[7] = rk[3] ^ rk[6];
778           if (++i == 10)
779             {
780               return 10;
781             }
782           rk += 4;
783         }
784     }
785   rk[4] = GETU32 (cipherKey + 16);
786   rk[5] = GETU32 (cipherKey + 20);
787   if (keyBits == 192)
788     {
789       for (;;)
790         {
791           temp = rk[5];
792           rk[6] = rk[0] ^
793             (Te4[(temp >> 16) & 0xff] & 0xff000000) ^
794             (Te4[(temp >> 8) & 0xff] & 0x00ff0000) ^
795             (Te4[(temp) & 0xff] & 0x0000ff00) ^
796             (Te4[(temp >> 24)] & 0x000000ff) ^ rcon[i];
797           rk[7] = rk[1] ^ rk[6];
798           rk[8] = rk[2] ^ rk[7];
799           rk[9] = rk[3] ^ rk[8];
800           if (++i == 8)
801             {
802               return 12;
803             }
804           rk[10] = rk[4] ^ rk[9];
805           rk[11] = rk[5] ^ rk[10];
806           rk += 6;
807         }
808     }
809   rk[6] = GETU32 (cipherKey + 24);
810   rk[7] = GETU32 (cipherKey + 28);
811   if (keyBits == 256)
812     {
813       for (;;)
814         {
815           temp = rk[7];
816           rk[8] = rk[0] ^
817             (Te4[(temp >> 16) & 0xff] & 0xff000000) ^
818             (Te4[(temp >> 8) & 0xff] & 0x00ff0000) ^
819             (Te4[(temp) & 0xff] & 0x0000ff00) ^
820             (Te4[(temp >> 24)] & 0x000000ff) ^ rcon[i];
821           rk[9] = rk[1] ^ rk[8];
822           rk[10] = rk[2] ^ rk[9];
823           rk[11] = rk[3] ^ rk[10];
824           if (++i == 7)
825             {
826               return 14;
827             }
828           temp = rk[11];
829           rk[12] = rk[4] ^
830             (Te4[(temp >> 24)] & 0xff000000) ^
831             (Te4[(temp >> 16) & 0xff] & 0x00ff0000) ^
832             (Te4[(temp >> 8) & 0xff] & 0x0000ff00) ^
833             (Te4[(temp) & 0xff] & 0x000000ff);
834           rk[13] = rk[5] ^ rk[12];
835           rk[14] = rk[6] ^ rk[13];
836           rk[15] = rk[7] ^ rk[14];
837
838           rk += 8;
839         }
840     }
841   return 0;
842 }
843
844 /**
845  * Expand the cipher key into the decryption key schedule.
846  *
847  * @return      the number of rounds for the given cipher key size.
848  */
849 int
850 rijndaelKeySetupDec (uint32_t rk[ /*4*(Nr + 1) */ ],
851                      const char cipherKey[], size_t keyBits)
852 {
853   size_t Nr, i, j;
854   uint32_t temp;
855
856   /* expand the cipher key: */
857   Nr = rijndaelKeySetupEnc (rk, cipherKey, keyBits);
858   /* invert the order of the round keys: */
859   for (i = 0, j = 4 * Nr; i < j; i += 4, j -= 4)
860     {
861       temp = rk[i];
862       rk[i] = rk[j];
863       rk[j] = temp;
864       temp = rk[i + 1];
865       rk[i + 1] = rk[j + 1];
866       rk[j + 1] = temp;
867       temp = rk[i + 2];
868       rk[i + 2] = rk[j + 2];
869       rk[j + 2] = temp;
870       temp = rk[i + 3];
871       rk[i + 3] = rk[j + 3];
872       rk[j + 3] = temp;
873     }
874   /* apply the inverse MixColumn transform to all round keys but the
875      first and the last: */
876   for (i = 1; i < Nr; i++)
877     {
878       rk += 4;
879       rk[0] =
880         Td0[Te4[(rk[0] >> 24)] & 0xff] ^
881         Td1[Te4[(rk[0] >> 16) & 0xff] & 0xff] ^
882         Td2[Te4[(rk[0] >> 8) & 0xff] & 0xff] ^
883         Td3[Te4[(rk[0]) & 0xff] & 0xff];
884       rk[1] =
885         Td0[Te4[(rk[1] >> 24)] & 0xff] ^
886         Td1[Te4[(rk[1] >> 16) & 0xff] & 0xff] ^
887         Td2[Te4[(rk[1] >> 8) & 0xff] & 0xff] ^
888         Td3[Te4[(rk[1]) & 0xff] & 0xff];
889       rk[2] =
890         Td0[Te4[(rk[2] >> 24)] & 0xff] ^
891         Td1[Te4[(rk[2] >> 16) & 0xff] & 0xff] ^
892         Td2[Te4[(rk[2] >> 8) & 0xff] & 0xff] ^
893         Td3[Te4[(rk[2]) & 0xff] & 0xff];
894       rk[3] =
895         Td0[Te4[(rk[3] >> 24)] & 0xff] ^
896         Td1[Te4[(rk[3] >> 16) & 0xff] & 0xff] ^
897         Td2[Te4[(rk[3] >> 8) & 0xff] & 0xff] ^
898         Td3[Te4[(rk[3]) & 0xff] & 0xff];
899     }
900   return Nr;
901 }
902
903 void
904 rijndaelEncrypt (const uint32_t rk[ /*4*(Nr + 1) */ ], size_t Nr,
905                  const char pt[16], char ct[16])
906 {
907   uint32_t s0, s1, s2, s3, t0, t1, t2, t3;
908   size_t r;
909
910   /*
911    * map byte array block to cipher state
912    * and add initial round key:
913    */
914   s0 = GETU32 (pt) ^ rk[0];
915   s1 = GETU32 (pt + 4) ^ rk[1];
916   s2 = GETU32 (pt + 8) ^ rk[2];
917   s3 = GETU32 (pt + 12) ^ rk[3];
918   /*
919    * Nr - 1 full rounds:
920    */
921   r = Nr >> 1;
922   for (;;)
923     {
924       t0 =
925         Te0[(s0 >> 24)] ^
926         Te1[(s1 >> 16) & 0xff] ^
927         Te2[(s2 >> 8) & 0xff] ^ Te3[(s3) & 0xff] ^ rk[4];
928       t1 =
929         Te0[(s1 >> 24)] ^
930         Te1[(s2 >> 16) & 0xff] ^
931         Te2[(s3 >> 8) & 0xff] ^ Te3[(s0) & 0xff] ^ rk[5];
932       t2 =
933         Te0[(s2 >> 24)] ^
934         Te1[(s3 >> 16) & 0xff] ^
935         Te2[(s0 >> 8) & 0xff] ^ Te3[(s1) & 0xff] ^ rk[6];
936       t3 =
937         Te0[(s3 >> 24)] ^
938         Te1[(s0 >> 16) & 0xff] ^
939         Te2[(s1 >> 8) & 0xff] ^ Te3[(s2) & 0xff] ^ rk[7];
940
941       rk += 8;
942       if (--r == 0)
943         {
944           break;
945         }
946
947       s0 =
948         Te0[(t0 >> 24)] ^
949         Te1[(t1 >> 16) & 0xff] ^
950         Te2[(t2 >> 8) & 0xff] ^ Te3[(t3) & 0xff] ^ rk[0];
951       s1 =
952         Te0[(t1 >> 24)] ^
953         Te1[(t2 >> 16) & 0xff] ^
954         Te2[(t3 >> 8) & 0xff] ^ Te3[(t0) & 0xff] ^ rk[1];
955       s2 =
956         Te0[(t2 >> 24)] ^
957         Te1[(t3 >> 16) & 0xff] ^
958         Te2[(t0 >> 8) & 0xff] ^ Te3[(t1) & 0xff] ^ rk[2];
959       s3 =
960         Te0[(t3 >> 24)] ^
961         Te1[(t0 >> 16) & 0xff] ^
962         Te2[(t1 >> 8) & 0xff] ^ Te3[(t2) & 0xff] ^ rk[3];
963     }
964   /*
965    * apply last round and
966    * map cipher state to byte array block:
967    */
968   s0 =
969     (Te4[(t0 >> 24)] & 0xff000000) ^
970     (Te4[(t1 >> 16) & 0xff] & 0x00ff0000) ^
971     (Te4[(t2 >> 8) & 0xff] & 0x0000ff00) ^
972     (Te4[(t3) & 0xff] & 0x000000ff) ^ rk[0];
973   PUTU32 (ct, s0);
974   s1 =
975     (Te4[(t1 >> 24)] & 0xff000000) ^
976     (Te4[(t2 >> 16) & 0xff] & 0x00ff0000) ^
977     (Te4[(t3 >> 8) & 0xff] & 0x0000ff00) ^
978     (Te4[(t0) & 0xff] & 0x000000ff) ^ rk[1];
979   PUTU32 (ct + 4, s1);
980   s2 =
981     (Te4[(t2 >> 24)] & 0xff000000) ^
982     (Te4[(t3 >> 16) & 0xff] & 0x00ff0000) ^
983     (Te4[(t0 >> 8) & 0xff] & 0x0000ff00) ^
984     (Te4[(t1) & 0xff] & 0x000000ff) ^ rk[2];
985   PUTU32 (ct + 8, s2);
986   s3 =
987     (Te4[(t3 >> 24)] & 0xff000000) ^
988     (Te4[(t0 >> 16) & 0xff] & 0x00ff0000) ^
989     (Te4[(t1 >> 8) & 0xff] & 0x0000ff00) ^
990     (Te4[(t2) & 0xff] & 0x000000ff) ^ rk[3];
991   PUTU32 (ct + 12, s3);
992 }
993
994 void
995 rijndaelDecrypt (const uint32_t rk[ /*4*(Nr + 1) */ ], size_t Nr,
996                  const char ct[16], char pt[16])
997 {
998   uint32_t s0, s1, s2, s3, t0, t1, t2, t3;
999   size_t r;
1000
1001   /*
1002    * map byte array block to cipher state
1003    * and add initial round key:
1004    */
1005   s0 = GETU32 (ct) ^ rk[0];
1006   s1 = GETU32 (ct + 4) ^ rk[1];
1007   s2 = GETU32 (ct + 8) ^ rk[2];
1008   s3 = GETU32 (ct + 12) ^ rk[3];
1009   /*
1010    * Nr - 1 full rounds:
1011    */
1012   r = Nr >> 1;
1013   for (;;)
1014     {
1015       t0 =
1016         Td0[(s0 >> 24)] ^
1017         Td1[(s3 >> 16) & 0xff] ^
1018         Td2[(s2 >> 8) & 0xff] ^ Td3[(s1) & 0xff] ^ rk[4];
1019       t1 =
1020         Td0[(s1 >> 24)] ^
1021         Td1[(s0 >> 16) & 0xff] ^
1022         Td2[(s3 >> 8) & 0xff] ^ Td3[(s2) & 0xff] ^ rk[5];
1023       t2 =
1024         Td0[(s2 >> 24)] ^
1025         Td1[(s1 >> 16) & 0xff] ^
1026         Td2[(s0 >> 8) & 0xff] ^ Td3[(s3) & 0xff] ^ rk[6];
1027       t3 =
1028         Td0[(s3 >> 24)] ^
1029         Td1[(s2 >> 16) & 0xff] ^
1030         Td2[(s1 >> 8) & 0xff] ^ Td3[(s0) & 0xff] ^ rk[7];
1031
1032       rk += 8;
1033       if (--r == 0)
1034         {
1035           break;
1036         }
1037
1038       s0 =
1039         Td0[(t0 >> 24)] ^
1040         Td1[(t3 >> 16) & 0xff] ^
1041         Td2[(t2 >> 8) & 0xff] ^ Td3[(t1) & 0xff] ^ rk[0];
1042       s1 =
1043         Td0[(t1 >> 24)] ^
1044         Td1[(t0 >> 16) & 0xff] ^
1045         Td2[(t3 >> 8) & 0xff] ^ Td3[(t2) & 0xff] ^ rk[1];
1046       s2 =
1047         Td0[(t2 >> 24)] ^
1048         Td1[(t1 >> 16) & 0xff] ^
1049         Td2[(t0 >> 8) & 0xff] ^ Td3[(t3) & 0xff] ^ rk[2];
1050       s3 =
1051         Td0[(t3 >> 24)] ^
1052         Td1[(t2 >> 16) & 0xff] ^
1053         Td2[(t1 >> 8) & 0xff] ^ Td3[(t0) & 0xff] ^ rk[3];
1054     }
1055   /*
1056    * apply last round and
1057    * map cipher state to byte array block:
1058    */
1059   s0 =
1060     (Td4[(t0 >> 24)] & 0xff000000) ^
1061     (Td4[(t3 >> 16) & 0xff] & 0x00ff0000) ^
1062     (Td4[(t2 >> 8) & 0xff] & 0x0000ff00) ^
1063     (Td4[(t1) & 0xff] & 0x000000ff) ^ rk[0];
1064   PUTU32 (pt, s0);
1065   s1 =
1066     (Td4[(t1 >> 24)] & 0xff000000) ^
1067     (Td4[(t0 >> 16) & 0xff] & 0x00ff0000) ^
1068     (Td4[(t3 >> 8) & 0xff] & 0x0000ff00) ^
1069     (Td4[(t2) & 0xff] & 0x000000ff) ^ rk[1];
1070   PUTU32 (pt + 4, s1);
1071   s2 =
1072     (Td4[(t2 >> 24)] & 0xff000000) ^
1073     (Td4[(t1 >> 16) & 0xff] & 0x00ff0000) ^
1074     (Td4[(t0 >> 8) & 0xff] & 0x0000ff00) ^
1075     (Td4[(t3) & 0xff] & 0x000000ff) ^ rk[2];
1076   PUTU32 (pt + 8, s2);
1077   s3 =
1078     (Td4[(t3 >> 24)] & 0xff000000) ^
1079     (Td4[(t2 >> 16) & 0xff] & 0x00ff0000) ^
1080     (Td4[(t1 >> 8) & 0xff] & 0x0000ff00) ^
1081     (Td4[(t0) & 0xff] & 0x000000ff) ^ rk[3];
1082   PUTU32 (pt + 12, s3);
1083 }