SHA-1: Add SSSE3 implementation
[libgcrypt.git] / cipher / tiger.c
1 /* tiger.c  -  The TIGER hash function
2  * Copyright (C) 1998, 2001, 2002, 2003, 2010 Free Software Foundation, Inc.
3  *
4  * This file is part of Libgcrypt.
5  *
6  * Libgcrypt is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU Lesser General Public License as
8  * published by the Free Software Foundation; either version 2.1 of
9  * the License, or (at your option) any later version.
10  *
11  * Libgcrypt is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
19  */
20
21 /* See http://www.cs.technion.ac.il/~biham/Reports/Tiger/  */
22
23 #include <config.h>
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <string.h>
27
28 #include "g10lib.h"
29 #include "cipher.h"
30 #include "hash-common.h"
31 #include "bithelp.h"
32 #include "bufhelp.h"
33
34 /* We really need a 64 bit type for this code.  */
35 #ifdef HAVE_U64_TYPEDEF
36
37 typedef struct
38 {
39   gcry_md_block_ctx_t bctx;
40   u64  a, b, c;
41   int  variant;  /* 0 = old code, 1 = fixed code, 2 - TIGER2.  */
42 } TIGER_CONTEXT;
43
44
45 /*********************************
46  * Okay, okay, this is not the fastest code - improvements are welcome.
47  *
48  */
49
50 /* Some test vectors:
51  * ""                   24F0130C63AC9332 16166E76B1BB925F F373DE2D49584E7A
52  * "abc"                F258C1E88414AB2A 527AB541FFC5B8BF 935F7B951C132951
53  * "Tiger"              9F00F599072300DD 276ABB38C8EB6DEC 37790C116F9D2BDF
54  * "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-"
55  *                      87FB2A9083851CF7 470D2CF810E6DF9E B586445034A5A386
56  * "ABCDEFGHIJKLMNOPQRSTUVWXYZ=abcdefghijklmnopqrstuvwxyz+0123456789"
57  *                      467DB80863EBCE48 8DF1CD1261655DE9 57896565975F9197
58  * "Tiger - A Fast New Hash Function, by Ross Anderson and Eli Biham"
59  *                      0C410A042968868A 1671DA5A3FD29A72 5EC1E457D3CDB303
60  * "Tiger - A Fast New Hash Function, by Ross Anderson and Eli Biham, proc"
61  * "eedings of Fast Software Encryption 3, Cambridge."
62  *                      EBF591D5AFA655CE 7F22894FF87F54AC 89C811B6B0DA3193
63  * "Tiger - A Fast New Hash Function, by Ross Anderson and Eli Biham, proc"
64  * "eedings of Fast Software Encryption 3, Cambridge, 1996."
65  *                      3D9AEB03D1BD1A63 57B2774DFD6D5B24 DD68151D503974FC
66  * "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-ABCDEF"
67  * "GHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-"
68  *                      00B83EB4E53440C5 76AC6AAEE0A74858 25FD15E70A59FFE4
69  */
70
71 static u64 sbox1[256] = {
72   U64_C(0x02aab17cf7e90c5e) /*    0 */, U64_C(0xac424b03e243a8ec) /*    1 */,
73   U64_C(0x72cd5be30dd5fcd3) /*    2 */, U64_C(0x6d019b93f6f97f3a) /*    3 */,
74   U64_C(0xcd9978ffd21f9193) /*    4 */, U64_C(0x7573a1c9708029e2) /*    5 */,
75   U64_C(0xb164326b922a83c3) /*    6 */, U64_C(0x46883eee04915870) /*    7 */,
76   U64_C(0xeaace3057103ece6) /*    8 */, U64_C(0xc54169b808a3535c) /*    9 */,
77   U64_C(0x4ce754918ddec47c) /*   10 */, U64_C(0x0aa2f4dfdc0df40c) /*   11 */,
78   U64_C(0x10b76f18a74dbefa) /*   12 */, U64_C(0xc6ccb6235ad1ab6a) /*   13 */,
79   U64_C(0x13726121572fe2ff) /*   14 */, U64_C(0x1a488c6f199d921e) /*   15 */,
80   U64_C(0x4bc9f9f4da0007ca) /*   16 */, U64_C(0x26f5e6f6e85241c7) /*   17 */,
81   U64_C(0x859079dbea5947b6) /*   18 */, U64_C(0x4f1885c5c99e8c92) /*   19 */,
82   U64_C(0xd78e761ea96f864b) /*   20 */, U64_C(0x8e36428c52b5c17d) /*   21 */,
83   U64_C(0x69cf6827373063c1) /*   22 */, U64_C(0xb607c93d9bb4c56e) /*   23 */,
84   U64_C(0x7d820e760e76b5ea) /*   24 */, U64_C(0x645c9cc6f07fdc42) /*   25 */,
85   U64_C(0xbf38a078243342e0) /*   26 */, U64_C(0x5f6b343c9d2e7d04) /*   27 */,
86   U64_C(0xf2c28aeb600b0ec6) /*   28 */, U64_C(0x6c0ed85f7254bcac) /*   29 */,
87   U64_C(0x71592281a4db4fe5) /*   30 */, U64_C(0x1967fa69ce0fed9f) /*   31 */,
88   U64_C(0xfd5293f8b96545db) /*   32 */, U64_C(0xc879e9d7f2a7600b) /*   33 */,
89   U64_C(0x860248920193194e) /*   34 */, U64_C(0xa4f9533b2d9cc0b3) /*   35 */,
90   U64_C(0x9053836c15957613) /*   36 */, U64_C(0xdb6dcf8afc357bf1) /*   37 */,
91   U64_C(0x18beea7a7a370f57) /*   38 */, U64_C(0x037117ca50b99066) /*   39 */,
92   U64_C(0x6ab30a9774424a35) /*   40 */, U64_C(0xf4e92f02e325249b) /*   41 */,
93   U64_C(0x7739db07061ccae1) /*   42 */, U64_C(0xd8f3b49ceca42a05) /*   43 */,
94   U64_C(0xbd56be3f51382f73) /*   44 */, U64_C(0x45faed5843b0bb28) /*   45 */,
95   U64_C(0x1c813d5c11bf1f83) /*   46 */, U64_C(0x8af0e4b6d75fa169) /*   47 */,
96   U64_C(0x33ee18a487ad9999) /*   48 */, U64_C(0x3c26e8eab1c94410) /*   49 */,
97   U64_C(0xb510102bc0a822f9) /*   50 */, U64_C(0x141eef310ce6123b) /*   51 */,
98   U64_C(0xfc65b90059ddb154) /*   52 */, U64_C(0xe0158640c5e0e607) /*   53 */,
99   U64_C(0x884e079826c3a3cf) /*   54 */, U64_C(0x930d0d9523c535fd) /*   55 */,
100   U64_C(0x35638d754e9a2b00) /*   56 */, U64_C(0x4085fccf40469dd5) /*   57 */,
101   U64_C(0xc4b17ad28be23a4c) /*   58 */, U64_C(0xcab2f0fc6a3e6a2e) /*   59 */,
102   U64_C(0x2860971a6b943fcd) /*   60 */, U64_C(0x3dde6ee212e30446) /*   61 */,
103   U64_C(0x6222f32ae01765ae) /*   62 */, U64_C(0x5d550bb5478308fe) /*   63 */,
104   U64_C(0xa9efa98da0eda22a) /*   64 */, U64_C(0xc351a71686c40da7) /*   65 */,
105   U64_C(0x1105586d9c867c84) /*   66 */, U64_C(0xdcffee85fda22853) /*   67 */,
106   U64_C(0xccfbd0262c5eef76) /*   68 */, U64_C(0xbaf294cb8990d201) /*   69 */,
107   U64_C(0xe69464f52afad975) /*   70 */, U64_C(0x94b013afdf133e14) /*   71 */,
108   U64_C(0x06a7d1a32823c958) /*   72 */, U64_C(0x6f95fe5130f61119) /*   73 */,
109   U64_C(0xd92ab34e462c06c0) /*   74 */, U64_C(0xed7bde33887c71d2) /*   75 */,
110   U64_C(0x79746d6e6518393e) /*   76 */, U64_C(0x5ba419385d713329) /*   77 */,
111   U64_C(0x7c1ba6b948a97564) /*   78 */, U64_C(0x31987c197bfdac67) /*   79 */,
112   U64_C(0xde6c23c44b053d02) /*   80 */, U64_C(0x581c49fed002d64d) /*   81 */,
113   U64_C(0xdd474d6338261571) /*   82 */, U64_C(0xaa4546c3e473d062) /*   83 */,
114   U64_C(0x928fce349455f860) /*   84 */, U64_C(0x48161bbacaab94d9) /*   85 */,
115   U64_C(0x63912430770e6f68) /*   86 */, U64_C(0x6ec8a5e602c6641c) /*   87 */,
116   U64_C(0x87282515337ddd2b) /*   88 */, U64_C(0x2cda6b42034b701b) /*   89 */,
117   U64_C(0xb03d37c181cb096d) /*   90 */, U64_C(0xe108438266c71c6f) /*   91 */,
118   U64_C(0x2b3180c7eb51b255) /*   92 */, U64_C(0xdf92b82f96c08bbc) /*   93 */,
119   U64_C(0x5c68c8c0a632f3ba) /*   94 */, U64_C(0x5504cc861c3d0556) /*   95 */,
120   U64_C(0xabbfa4e55fb26b8f) /*   96 */, U64_C(0x41848b0ab3baceb4) /*   97 */,
121   U64_C(0xb334a273aa445d32) /*   98 */, U64_C(0xbca696f0a85ad881) /*   99 */,
122   U64_C(0x24f6ec65b528d56c) /*  100 */, U64_C(0x0ce1512e90f4524a) /*  101 */,
123   U64_C(0x4e9dd79d5506d35a) /*  102 */, U64_C(0x258905fac6ce9779) /*  103 */,
124   U64_C(0x2019295b3e109b33) /*  104 */, U64_C(0xf8a9478b73a054cc) /*  105 */,
125   U64_C(0x2924f2f934417eb0) /*  106 */, U64_C(0x3993357d536d1bc4) /*  107 */,
126   U64_C(0x38a81ac21db6ff8b) /*  108 */, U64_C(0x47c4fbf17d6016bf) /*  109 */,
127   U64_C(0x1e0faadd7667e3f5) /*  110 */, U64_C(0x7abcff62938beb96) /*  111 */,
128   U64_C(0xa78dad948fc179c9) /*  112 */, U64_C(0x8f1f98b72911e50d) /*  113 */,
129   U64_C(0x61e48eae27121a91) /*  114 */, U64_C(0x4d62f7ad31859808) /*  115 */,
130   U64_C(0xeceba345ef5ceaeb) /*  116 */, U64_C(0xf5ceb25ebc9684ce) /*  117 */,
131   U64_C(0xf633e20cb7f76221) /*  118 */, U64_C(0xa32cdf06ab8293e4) /*  119 */,
132   U64_C(0x985a202ca5ee2ca4) /*  120 */, U64_C(0xcf0b8447cc8a8fb1) /*  121 */,
133   U64_C(0x9f765244979859a3) /*  122 */, U64_C(0xa8d516b1a1240017) /*  123 */,
134   U64_C(0x0bd7ba3ebb5dc726) /*  124 */, U64_C(0xe54bca55b86adb39) /*  125 */,
135   U64_C(0x1d7a3afd6c478063) /*  126 */, U64_C(0x519ec608e7669edd) /*  127 */,
136   U64_C(0x0e5715a2d149aa23) /*  128 */, U64_C(0x177d4571848ff194) /*  129 */,
137   U64_C(0xeeb55f3241014c22) /*  130 */, U64_C(0x0f5e5ca13a6e2ec2) /*  131 */,
138   U64_C(0x8029927b75f5c361) /*  132 */, U64_C(0xad139fabc3d6e436) /*  133 */,
139   U64_C(0x0d5df1a94ccf402f) /*  134 */, U64_C(0x3e8bd948bea5dfc8) /*  135 */,
140   U64_C(0xa5a0d357bd3ff77e) /*  136 */, U64_C(0xa2d12e251f74f645) /*  137 */,
141   U64_C(0x66fd9e525e81a082) /*  138 */, U64_C(0x2e0c90ce7f687a49) /*  139 */,
142   U64_C(0xc2e8bcbeba973bc5) /*  140 */, U64_C(0x000001bce509745f) /*  141 */,
143   U64_C(0x423777bbe6dab3d6) /*  142 */, U64_C(0xd1661c7eaef06eb5) /*  143 */,
144   U64_C(0xa1781f354daacfd8) /*  144 */, U64_C(0x2d11284a2b16affc) /*  145 */,
145   U64_C(0xf1fc4f67fa891d1f) /*  146 */, U64_C(0x73ecc25dcb920ada) /*  147 */,
146   U64_C(0xae610c22c2a12651) /*  148 */, U64_C(0x96e0a810d356b78a) /*  149 */,
147   U64_C(0x5a9a381f2fe7870f) /*  150 */, U64_C(0xd5ad62ede94e5530) /*  151 */,
148   U64_C(0xd225e5e8368d1427) /*  152 */, U64_C(0x65977b70c7af4631) /*  153 */,
149   U64_C(0x99f889b2de39d74f) /*  154 */, U64_C(0x233f30bf54e1d143) /*  155 */,
150   U64_C(0x9a9675d3d9a63c97) /*  156 */, U64_C(0x5470554ff334f9a8) /*  157 */,
151   U64_C(0x166acb744a4f5688) /*  158 */, U64_C(0x70c74caab2e4aead) /*  159 */,
152   U64_C(0xf0d091646f294d12) /*  160 */, U64_C(0x57b82a89684031d1) /*  161 */,
153   U64_C(0xefd95a5a61be0b6b) /*  162 */, U64_C(0x2fbd12e969f2f29a) /*  163 */,
154   U64_C(0x9bd37013feff9fe8) /*  164 */, U64_C(0x3f9b0404d6085a06) /*  165 */,
155   U64_C(0x4940c1f3166cfe15) /*  166 */, U64_C(0x09542c4dcdf3defb) /*  167 */,
156   U64_C(0xb4c5218385cd5ce3) /*  168 */, U64_C(0xc935b7dc4462a641) /*  169 */,
157   U64_C(0x3417f8a68ed3b63f) /*  170 */, U64_C(0xb80959295b215b40) /*  171 */,
158   U64_C(0xf99cdaef3b8c8572) /*  172 */, U64_C(0x018c0614f8fcb95d) /*  173 */,
159   U64_C(0x1b14accd1a3acdf3) /*  174 */, U64_C(0x84d471f200bb732d) /*  175 */,
160   U64_C(0xc1a3110e95e8da16) /*  176 */, U64_C(0x430a7220bf1a82b8) /*  177 */,
161   U64_C(0xb77e090d39df210e) /*  178 */, U64_C(0x5ef4bd9f3cd05e9d) /*  179 */,
162   U64_C(0x9d4ff6da7e57a444) /*  180 */, U64_C(0xda1d60e183d4a5f8) /*  181 */,
163   U64_C(0xb287c38417998e47) /*  182 */, U64_C(0xfe3edc121bb31886) /*  183 */,
164   U64_C(0xc7fe3ccc980ccbef) /*  184 */, U64_C(0xe46fb590189bfd03) /*  185 */,
165   U64_C(0x3732fd469a4c57dc) /*  186 */, U64_C(0x7ef700a07cf1ad65) /*  187 */,
166   U64_C(0x59c64468a31d8859) /*  188 */, U64_C(0x762fb0b4d45b61f6) /*  189 */,
167   U64_C(0x155baed099047718) /*  190 */, U64_C(0x68755e4c3d50baa6) /*  191 */,
168   U64_C(0xe9214e7f22d8b4df) /*  192 */, U64_C(0x2addbf532eac95f4) /*  193 */,
169   U64_C(0x32ae3909b4bd0109) /*  194 */, U64_C(0x834df537b08e3450) /*  195 */,
170   U64_C(0xfa209da84220728d) /*  196 */, U64_C(0x9e691d9b9efe23f7) /*  197 */,
171   U64_C(0x0446d288c4ae8d7f) /*  198 */, U64_C(0x7b4cc524e169785b) /*  199 */,
172   U64_C(0x21d87f0135ca1385) /*  200 */, U64_C(0xcebb400f137b8aa5) /*  201 */,
173   U64_C(0x272e2b66580796be) /*  202 */, U64_C(0x3612264125c2b0de) /*  203 */,
174   U64_C(0x057702bdad1efbb2) /*  204 */, U64_C(0xd4babb8eacf84be9) /*  205 */,
175   U64_C(0x91583139641bc67b) /*  206 */, U64_C(0x8bdc2de08036e024) /*  207 */,
176   U64_C(0x603c8156f49f68ed) /*  208 */, U64_C(0xf7d236f7dbef5111) /*  209 */,
177   U64_C(0x9727c4598ad21e80) /*  210 */, U64_C(0xa08a0896670a5fd7) /*  211 */,
178   U64_C(0xcb4a8f4309eba9cb) /*  212 */, U64_C(0x81af564b0f7036a1) /*  213 */,
179   U64_C(0xc0b99aa778199abd) /*  214 */, U64_C(0x959f1ec83fc8e952) /*  215 */,
180   U64_C(0x8c505077794a81b9) /*  216 */, U64_C(0x3acaaf8f056338f0) /*  217 */,
181   U64_C(0x07b43f50627a6778) /*  218 */, U64_C(0x4a44ab49f5eccc77) /*  219 */,
182   U64_C(0x3bc3d6e4b679ee98) /*  220 */, U64_C(0x9cc0d4d1cf14108c) /*  221 */,
183   U64_C(0x4406c00b206bc8a0) /*  222 */, U64_C(0x82a18854c8d72d89) /*  223 */,
184   U64_C(0x67e366b35c3c432c) /*  224 */, U64_C(0xb923dd61102b37f2) /*  225 */,
185   U64_C(0x56ab2779d884271d) /*  226 */, U64_C(0xbe83e1b0ff1525af) /*  227 */,
186   U64_C(0xfb7c65d4217e49a9) /*  228 */, U64_C(0x6bdbe0e76d48e7d4) /*  229 */,
187   U64_C(0x08df828745d9179e) /*  230 */, U64_C(0x22ea6a9add53bd34) /*  231 */,
188   U64_C(0xe36e141c5622200a) /*  232 */, U64_C(0x7f805d1b8cb750ee) /*  233 */,
189   U64_C(0xafe5c7a59f58e837) /*  234 */, U64_C(0xe27f996a4fb1c23c) /*  235 */,
190   U64_C(0xd3867dfb0775f0d0) /*  236 */, U64_C(0xd0e673de6e88891a) /*  237 */,
191   U64_C(0x123aeb9eafb86c25) /*  238 */, U64_C(0x30f1d5d5c145b895) /*  239 */,
192   U64_C(0xbb434a2dee7269e7) /*  240 */, U64_C(0x78cb67ecf931fa38) /*  241 */,
193   U64_C(0xf33b0372323bbf9c) /*  242 */, U64_C(0x52d66336fb279c74) /*  243 */,
194   U64_C(0x505f33ac0afb4eaa) /*  244 */, U64_C(0xe8a5cd99a2cce187) /*  245 */,
195   U64_C(0x534974801e2d30bb) /*  246 */, U64_C(0x8d2d5711d5876d90) /*  247 */,
196   U64_C(0x1f1a412891bc038e) /*  248 */, U64_C(0xd6e2e71d82e56648) /*  249 */,
197   U64_C(0x74036c3a497732b7) /*  250 */, U64_C(0x89b67ed96361f5ab) /*  251 */,
198   U64_C(0xffed95d8f1ea02a2) /*  252 */, U64_C(0xe72b3bd61464d43d) /*  253 */,
199   U64_C(0xa6300f170bdc4820) /*  254 */, U64_C(0xebc18760ed78a77a) /*  255 */
200 };
201 static u64 sbox2[256] = {
202   U64_C(0xe6a6be5a05a12138) /*  256 */, U64_C(0xb5a122a5b4f87c98) /*  257 */,
203   U64_C(0x563c6089140b6990) /*  258 */, U64_C(0x4c46cb2e391f5dd5) /*  259 */,
204   U64_C(0xd932addbc9b79434) /*  260 */, U64_C(0x08ea70e42015aff5) /*  261 */,
205   U64_C(0xd765a6673e478cf1) /*  262 */, U64_C(0xc4fb757eab278d99) /*  263 */,
206   U64_C(0xdf11c6862d6e0692) /*  264 */, U64_C(0xddeb84f10d7f3b16) /*  265 */,
207   U64_C(0x6f2ef604a665ea04) /*  266 */, U64_C(0x4a8e0f0ff0e0dfb3) /*  267 */,
208   U64_C(0xa5edeef83dbcba51) /*  268 */, U64_C(0xfc4f0a2a0ea4371e) /*  269 */,
209   U64_C(0xe83e1da85cb38429) /*  270 */, U64_C(0xdc8ff882ba1b1ce2) /*  271 */,
210   U64_C(0xcd45505e8353e80d) /*  272 */, U64_C(0x18d19a00d4db0717) /*  273 */,
211   U64_C(0x34a0cfeda5f38101) /*  274 */, U64_C(0x0be77e518887caf2) /*  275 */,
212   U64_C(0x1e341438b3c45136) /*  276 */, U64_C(0xe05797f49089ccf9) /*  277 */,
213   U64_C(0xffd23f9df2591d14) /*  278 */, U64_C(0x543dda228595c5cd) /*  279 */,
214   U64_C(0x661f81fd99052a33) /*  280 */, U64_C(0x8736e641db0f7b76) /*  281 */,
215   U64_C(0x15227725418e5307) /*  282 */, U64_C(0xe25f7f46162eb2fa) /*  283 */,
216   U64_C(0x48a8b2126c13d9fe) /*  284 */, U64_C(0xafdc541792e76eea) /*  285 */,
217   U64_C(0x03d912bfc6d1898f) /*  286 */, U64_C(0x31b1aafa1b83f51b) /*  287 */,
218   U64_C(0xf1ac2796e42ab7d9) /*  288 */, U64_C(0x40a3a7d7fcd2ebac) /*  289 */,
219   U64_C(0x1056136d0afbbcc5) /*  290 */, U64_C(0x7889e1dd9a6d0c85) /*  291 */,
220   U64_C(0xd33525782a7974aa) /*  292 */, U64_C(0xa7e25d09078ac09b) /*  293 */,
221   U64_C(0xbd4138b3eac6edd0) /*  294 */, U64_C(0x920abfbe71eb9e70) /*  295 */,
222   U64_C(0xa2a5d0f54fc2625c) /*  296 */, U64_C(0xc054e36b0b1290a3) /*  297 */,
223   U64_C(0xf6dd59ff62fe932b) /*  298 */, U64_C(0x3537354511a8ac7d) /*  299 */,
224   U64_C(0xca845e9172fadcd4) /*  300 */, U64_C(0x84f82b60329d20dc) /*  301 */,
225   U64_C(0x79c62ce1cd672f18) /*  302 */, U64_C(0x8b09a2add124642c) /*  303 */,
226   U64_C(0xd0c1e96a19d9e726) /*  304 */, U64_C(0x5a786a9b4ba9500c) /*  305 */,
227   U64_C(0x0e020336634c43f3) /*  306 */, U64_C(0xc17b474aeb66d822) /*  307 */,
228   U64_C(0x6a731ae3ec9baac2) /*  308 */, U64_C(0x8226667ae0840258) /*  309 */,
229   U64_C(0x67d4567691caeca5) /*  310 */, U64_C(0x1d94155c4875adb5) /*  311 */,
230   U64_C(0x6d00fd985b813fdf) /*  312 */, U64_C(0x51286efcb774cd06) /*  313 */,
231   U64_C(0x5e8834471fa744af) /*  314 */, U64_C(0xf72ca0aee761ae2e) /*  315 */,
232   U64_C(0xbe40e4cdaee8e09a) /*  316 */, U64_C(0xe9970bbb5118f665) /*  317 */,
233   U64_C(0x726e4beb33df1964) /*  318 */, U64_C(0x703b000729199762) /*  319 */,
234   U64_C(0x4631d816f5ef30a7) /*  320 */, U64_C(0xb880b5b51504a6be) /*  321 */,
235   U64_C(0x641793c37ed84b6c) /*  322 */, U64_C(0x7b21ed77f6e97d96) /*  323 */,
236   U64_C(0x776306312ef96b73) /*  324 */, U64_C(0xae528948e86ff3f4) /*  325 */,
237   U64_C(0x53dbd7f286a3f8f8) /*  326 */, U64_C(0x16cadce74cfc1063) /*  327 */,
238   U64_C(0x005c19bdfa52c6dd) /*  328 */, U64_C(0x68868f5d64d46ad3) /*  329 */,
239   U64_C(0x3a9d512ccf1e186a) /*  330 */, U64_C(0x367e62c2385660ae) /*  331 */,
240   U64_C(0xe359e7ea77dcb1d7) /*  332 */, U64_C(0x526c0773749abe6e) /*  333 */,
241   U64_C(0x735ae5f9d09f734b) /*  334 */, U64_C(0x493fc7cc8a558ba8) /*  335 */,
242   U64_C(0xb0b9c1533041ab45) /*  336 */, U64_C(0x321958ba470a59bd) /*  337 */,
243   U64_C(0x852db00b5f46c393) /*  338 */, U64_C(0x91209b2bd336b0e5) /*  339 */,
244   U64_C(0x6e604f7d659ef19f) /*  340 */, U64_C(0xb99a8ae2782ccb24) /*  341 */,
245   U64_C(0xccf52ab6c814c4c7) /*  342 */, U64_C(0x4727d9afbe11727b) /*  343 */,
246   U64_C(0x7e950d0c0121b34d) /*  344 */, U64_C(0x756f435670ad471f) /*  345 */,
247   U64_C(0xf5add442615a6849) /*  346 */, U64_C(0x4e87e09980b9957a) /*  347 */,
248   U64_C(0x2acfa1df50aee355) /*  348 */, U64_C(0xd898263afd2fd556) /*  349 */,
249   U64_C(0xc8f4924dd80c8fd6) /*  350 */, U64_C(0xcf99ca3d754a173a) /*  351 */,
250   U64_C(0xfe477bacaf91bf3c) /*  352 */, U64_C(0xed5371f6d690c12d) /*  353 */,
251   U64_C(0x831a5c285e687094) /*  354 */, U64_C(0xc5d3c90a3708a0a4) /*  355 */,
252   U64_C(0x0f7f903717d06580) /*  356 */, U64_C(0x19f9bb13b8fdf27f) /*  357 */,
253   U64_C(0xb1bd6f1b4d502843) /*  358 */, U64_C(0x1c761ba38fff4012) /*  359 */,
254   U64_C(0x0d1530c4e2e21f3b) /*  360 */, U64_C(0x8943ce69a7372c8a) /*  361 */,
255   U64_C(0xe5184e11feb5ce66) /*  362 */, U64_C(0x618bdb80bd736621) /*  363 */,
256   U64_C(0x7d29bad68b574d0b) /*  364 */, U64_C(0x81bb613e25e6fe5b) /*  365 */,
257   U64_C(0x071c9c10bc07913f) /*  366 */, U64_C(0xc7beeb7909ac2d97) /*  367 */,
258   U64_C(0xc3e58d353bc5d757) /*  368 */, U64_C(0xeb017892f38f61e8) /*  369 */,
259   U64_C(0xd4effb9c9b1cc21a) /*  370 */, U64_C(0x99727d26f494f7ab) /*  371 */,
260   U64_C(0xa3e063a2956b3e03) /*  372 */, U64_C(0x9d4a8b9a4aa09c30) /*  373 */,
261   U64_C(0x3f6ab7d500090fb4) /*  374 */, U64_C(0x9cc0f2a057268ac0) /*  375 */,
262   U64_C(0x3dee9d2dedbf42d1) /*  376 */, U64_C(0x330f49c87960a972) /*  377 */,
263   U64_C(0xc6b2720287421b41) /*  378 */, U64_C(0x0ac59ec07c00369c) /*  379 */,
264   U64_C(0xef4eac49cb353425) /*  380 */, U64_C(0xf450244eef0129d8) /*  381 */,
265   U64_C(0x8acc46e5caf4deb6) /*  382 */, U64_C(0x2ffeab63989263f7) /*  383 */,
266   U64_C(0x8f7cb9fe5d7a4578) /*  384 */, U64_C(0x5bd8f7644e634635) /*  385 */,
267   U64_C(0x427a7315bf2dc900) /*  386 */, U64_C(0x17d0c4aa2125261c) /*  387 */,
268   U64_C(0x3992486c93518e50) /*  388 */, U64_C(0xb4cbfee0a2d7d4c3) /*  389 */,
269   U64_C(0x7c75d6202c5ddd8d) /*  390 */, U64_C(0xdbc295d8e35b6c61) /*  391 */,
270   U64_C(0x60b369d302032b19) /*  392 */, U64_C(0xce42685fdce44132) /*  393 */,
271   U64_C(0x06f3ddb9ddf65610) /*  394 */, U64_C(0x8ea4d21db5e148f0) /*  395 */,
272   U64_C(0x20b0fce62fcd496f) /*  396 */, U64_C(0x2c1b912358b0ee31) /*  397 */,
273   U64_C(0xb28317b818f5a308) /*  398 */, U64_C(0xa89c1e189ca6d2cf) /*  399 */,
274   U64_C(0x0c6b18576aaadbc8) /*  400 */, U64_C(0xb65deaa91299fae3) /*  401 */,
275   U64_C(0xfb2b794b7f1027e7) /*  402 */, U64_C(0x04e4317f443b5beb) /*  403 */,
276   U64_C(0x4b852d325939d0a6) /*  404 */, U64_C(0xd5ae6beefb207ffc) /*  405 */,
277   U64_C(0x309682b281c7d374) /*  406 */, U64_C(0xbae309a194c3b475) /*  407 */,
278   U64_C(0x8cc3f97b13b49f05) /*  408 */, U64_C(0x98a9422ff8293967) /*  409 */,
279   U64_C(0x244b16b01076ff7c) /*  410 */, U64_C(0xf8bf571c663d67ee) /*  411 */,
280   U64_C(0x1f0d6758eee30da1) /*  412 */, U64_C(0xc9b611d97adeb9b7) /*  413 */,
281   U64_C(0xb7afd5887b6c57a2) /*  414 */, U64_C(0x6290ae846b984fe1) /*  415 */,
282   U64_C(0x94df4cdeacc1a5fd) /*  416 */, U64_C(0x058a5bd1c5483aff) /*  417 */,
283   U64_C(0x63166cc142ba3c37) /*  418 */, U64_C(0x8db8526eb2f76f40) /*  419 */,
284   U64_C(0xe10880036f0d6d4e) /*  420 */, U64_C(0x9e0523c9971d311d) /*  421 */,
285   U64_C(0x45ec2824cc7cd691) /*  422 */, U64_C(0x575b8359e62382c9) /*  423 */,
286   U64_C(0xfa9e400dc4889995) /*  424 */, U64_C(0xd1823ecb45721568) /*  425 */,
287   U64_C(0xdafd983b8206082f) /*  426 */, U64_C(0xaa7d29082386a8cb) /*  427 */,
288   U64_C(0x269fcd4403b87588) /*  428 */, U64_C(0x1b91f5f728bdd1e0) /*  429 */,
289   U64_C(0xe4669f39040201f6) /*  430 */, U64_C(0x7a1d7c218cf04ade) /*  431 */,
290   U64_C(0x65623c29d79ce5ce) /*  432 */, U64_C(0x2368449096c00bb1) /*  433 */,
291   U64_C(0xab9bf1879da503ba) /*  434 */, U64_C(0xbc23ecb1a458058e) /*  435 */,
292   U64_C(0x9a58df01bb401ecc) /*  436 */, U64_C(0xa070e868a85f143d) /*  437 */,
293   U64_C(0x4ff188307df2239e) /*  438 */, U64_C(0x14d565b41a641183) /*  439 */,
294   U64_C(0xee13337452701602) /*  440 */, U64_C(0x950e3dcf3f285e09) /*  441 */,
295   U64_C(0x59930254b9c80953) /*  442 */, U64_C(0x3bf299408930da6d) /*  443 */,
296   U64_C(0xa955943f53691387) /*  444 */, U64_C(0xa15edecaa9cb8784) /*  445 */,
297   U64_C(0x29142127352be9a0) /*  446 */, U64_C(0x76f0371fff4e7afb) /*  447 */,
298   U64_C(0x0239f450274f2228) /*  448 */, U64_C(0xbb073af01d5e868b) /*  449 */,
299   U64_C(0xbfc80571c10e96c1) /*  450 */, U64_C(0xd267088568222e23) /*  451 */,
300   U64_C(0x9671a3d48e80b5b0) /*  452 */, U64_C(0x55b5d38ae193bb81) /*  453 */,
301   U64_C(0x693ae2d0a18b04b8) /*  454 */, U64_C(0x5c48b4ecadd5335f) /*  455 */,
302   U64_C(0xfd743b194916a1ca) /*  456 */, U64_C(0x2577018134be98c4) /*  457 */,
303   U64_C(0xe77987e83c54a4ad) /*  458 */, U64_C(0x28e11014da33e1b9) /*  459 */,
304   U64_C(0x270cc59e226aa213) /*  460 */, U64_C(0x71495f756d1a5f60) /*  461 */,
305   U64_C(0x9be853fb60afef77) /*  462 */, U64_C(0xadc786a7f7443dbf) /*  463 */,
306   U64_C(0x0904456173b29a82) /*  464 */, U64_C(0x58bc7a66c232bd5e) /*  465 */,
307   U64_C(0xf306558c673ac8b2) /*  466 */, U64_C(0x41f639c6b6c9772a) /*  467 */,
308   U64_C(0x216defe99fda35da) /*  468 */, U64_C(0x11640cc71c7be615) /*  469 */,
309   U64_C(0x93c43694565c5527) /*  470 */, U64_C(0xea038e6246777839) /*  471 */,
310   U64_C(0xf9abf3ce5a3e2469) /*  472 */, U64_C(0x741e768d0fd312d2) /*  473 */,
311   U64_C(0x0144b883ced652c6) /*  474 */, U64_C(0xc20b5a5ba33f8552) /*  475 */,
312   U64_C(0x1ae69633c3435a9d) /*  476 */, U64_C(0x97a28ca4088cfdec) /*  477 */,
313   U64_C(0x8824a43c1e96f420) /*  478 */, U64_C(0x37612fa66eeea746) /*  479 */,
314   U64_C(0x6b4cb165f9cf0e5a) /*  480 */, U64_C(0x43aa1c06a0abfb4a) /*  481 */,
315   U64_C(0x7f4dc26ff162796b) /*  482 */, U64_C(0x6cbacc8e54ed9b0f) /*  483 */,
316   U64_C(0xa6b7ffefd2bb253e) /*  484 */, U64_C(0x2e25bc95b0a29d4f) /*  485 */,
317   U64_C(0x86d6a58bdef1388c) /*  486 */, U64_C(0xded74ac576b6f054) /*  487 */,
318   U64_C(0x8030bdbc2b45805d) /*  488 */, U64_C(0x3c81af70e94d9289) /*  489 */,
319   U64_C(0x3eff6dda9e3100db) /*  490 */, U64_C(0xb38dc39fdfcc8847) /*  491 */,
320   U64_C(0x123885528d17b87e) /*  492 */, U64_C(0xf2da0ed240b1b642) /*  493 */,
321   U64_C(0x44cefadcd54bf9a9) /*  494 */, U64_C(0x1312200e433c7ee6) /*  495 */,
322   U64_C(0x9ffcc84f3a78c748) /*  496 */, U64_C(0xf0cd1f72248576bb) /*  497 */,
323   U64_C(0xec6974053638cfe4) /*  498 */, U64_C(0x2ba7b67c0cec4e4c) /*  499 */,
324   U64_C(0xac2f4df3e5ce32ed) /*  500 */, U64_C(0xcb33d14326ea4c11) /*  501 */,
325   U64_C(0xa4e9044cc77e58bc) /*  502 */, U64_C(0x5f513293d934fcef) /*  503 */,
326   U64_C(0x5dc9645506e55444) /*  504 */, U64_C(0x50de418f317de40a) /*  505 */,
327   U64_C(0x388cb31a69dde259) /*  506 */, U64_C(0x2db4a83455820a86) /*  507 */,
328   U64_C(0x9010a91e84711ae9) /*  508 */, U64_C(0x4df7f0b7b1498371) /*  509 */,
329   U64_C(0xd62a2eabc0977179) /*  510 */, U64_C(0x22fac097aa8d5c0e) /*  511 */
330 };
331 static u64 sbox3[256] = {
332   U64_C(0xf49fcc2ff1daf39b) /*  512 */, U64_C(0x487fd5c66ff29281) /*  513 */,
333   U64_C(0xe8a30667fcdca83f) /*  514 */, U64_C(0x2c9b4be3d2fcce63) /*  515 */,
334   U64_C(0xda3ff74b93fbbbc2) /*  516 */, U64_C(0x2fa165d2fe70ba66) /*  517 */,
335   U64_C(0xa103e279970e93d4) /*  518 */, U64_C(0xbecdec77b0e45e71) /*  519 */,
336   U64_C(0xcfb41e723985e497) /*  520 */, U64_C(0xb70aaa025ef75017) /*  521 */,
337   U64_C(0xd42309f03840b8e0) /*  522 */, U64_C(0x8efc1ad035898579) /*  523 */,
338   U64_C(0x96c6920be2b2abc5) /*  524 */, U64_C(0x66af4163375a9172) /*  525 */,
339   U64_C(0x2174abdcca7127fb) /*  526 */, U64_C(0xb33ccea64a72ff41) /*  527 */,
340   U64_C(0xf04a4933083066a5) /*  528 */, U64_C(0x8d970acdd7289af5) /*  529 */,
341   U64_C(0x8f96e8e031c8c25e) /*  530 */, U64_C(0xf3fec02276875d47) /*  531 */,
342   U64_C(0xec7bf310056190dd) /*  532 */, U64_C(0xf5adb0aebb0f1491) /*  533 */,
343   U64_C(0x9b50f8850fd58892) /*  534 */, U64_C(0x4975488358b74de8) /*  535 */,
344   U64_C(0xa3354ff691531c61) /*  536 */, U64_C(0x0702bbe481d2c6ee) /*  537 */,
345   U64_C(0x89fb24057deded98) /*  538 */, U64_C(0xac3075138596e902) /*  539 */,
346   U64_C(0x1d2d3580172772ed) /*  540 */, U64_C(0xeb738fc28e6bc30d) /*  541 */,
347   U64_C(0x5854ef8f63044326) /*  542 */, U64_C(0x9e5c52325add3bbe) /*  543 */,
348   U64_C(0x90aa53cf325c4623) /*  544 */, U64_C(0xc1d24d51349dd067) /*  545 */,
349   U64_C(0x2051cfeea69ea624) /*  546 */, U64_C(0x13220f0a862e7e4f) /*  547 */,
350   U64_C(0xce39399404e04864) /*  548 */, U64_C(0xd9c42ca47086fcb7) /*  549 */,
351   U64_C(0x685ad2238a03e7cc) /*  550 */, U64_C(0x066484b2ab2ff1db) /*  551 */,
352   U64_C(0xfe9d5d70efbf79ec) /*  552 */, U64_C(0x5b13b9dd9c481854) /*  553 */,
353   U64_C(0x15f0d475ed1509ad) /*  554 */, U64_C(0x0bebcd060ec79851) /*  555 */,
354   U64_C(0xd58c6791183ab7f8) /*  556 */, U64_C(0xd1187c5052f3eee4) /*  557 */,
355   U64_C(0xc95d1192e54e82ff) /*  558 */, U64_C(0x86eea14cb9ac6ca2) /*  559 */,
356   U64_C(0x3485beb153677d5d) /*  560 */, U64_C(0xdd191d781f8c492a) /*  561 */,
357   U64_C(0xf60866baa784ebf9) /*  562 */, U64_C(0x518f643ba2d08c74) /*  563 */,
358   U64_C(0x8852e956e1087c22) /*  564 */, U64_C(0xa768cb8dc410ae8d) /*  565 */,
359   U64_C(0x38047726bfec8e1a) /*  566 */, U64_C(0xa67738b4cd3b45aa) /*  567 */,
360   U64_C(0xad16691cec0dde19) /*  568 */, U64_C(0xc6d4319380462e07) /*  569 */,
361   U64_C(0xc5a5876d0ba61938) /*  570 */, U64_C(0x16b9fa1fa58fd840) /*  571 */,
362   U64_C(0x188ab1173ca74f18) /*  572 */, U64_C(0xabda2f98c99c021f) /*  573 */,
363   U64_C(0x3e0580ab134ae816) /*  574 */, U64_C(0x5f3b05b773645abb) /*  575 */,
364   U64_C(0x2501a2be5575f2f6) /*  576 */, U64_C(0x1b2f74004e7e8ba9) /*  577 */,
365   U64_C(0x1cd7580371e8d953) /*  578 */, U64_C(0x7f6ed89562764e30) /*  579 */,
366   U64_C(0xb15926ff596f003d) /*  580 */, U64_C(0x9f65293da8c5d6b9) /*  581 */,
367   U64_C(0x6ecef04dd690f84c) /*  582 */, U64_C(0x4782275fff33af88) /*  583 */,
368   U64_C(0xe41433083f820801) /*  584 */, U64_C(0xfd0dfe409a1af9b5) /*  585 */,
369   U64_C(0x4325a3342cdb396b) /*  586 */, U64_C(0x8ae77e62b301b252) /*  587 */,
370   U64_C(0xc36f9e9f6655615a) /*  588 */, U64_C(0x85455a2d92d32c09) /*  589 */,
371   U64_C(0xf2c7dea949477485) /*  590 */, U64_C(0x63cfb4c133a39eba) /*  591 */,
372   U64_C(0x83b040cc6ebc5462) /*  592 */, U64_C(0x3b9454c8fdb326b0) /*  593 */,
373   U64_C(0x56f56a9e87ffd78c) /*  594 */, U64_C(0x2dc2940d99f42bc6) /*  595 */,
374   U64_C(0x98f7df096b096e2d) /*  596 */, U64_C(0x19a6e01e3ad852bf) /*  597 */,
375   U64_C(0x42a99ccbdbd4b40b) /*  598 */, U64_C(0xa59998af45e9c559) /*  599 */,
376   U64_C(0x366295e807d93186) /*  600 */, U64_C(0x6b48181bfaa1f773) /*  601 */,
377   U64_C(0x1fec57e2157a0a1d) /*  602 */, U64_C(0x4667446af6201ad5) /*  603 */,
378   U64_C(0xe615ebcacfb0f075) /*  604 */, U64_C(0xb8f31f4f68290778) /*  605 */,
379   U64_C(0x22713ed6ce22d11e) /*  606 */, U64_C(0x3057c1a72ec3c93b) /*  607 */,
380   U64_C(0xcb46acc37c3f1f2f) /*  608 */, U64_C(0xdbb893fd02aaf50e) /*  609 */,
381   U64_C(0x331fd92e600b9fcf) /*  610 */, U64_C(0xa498f96148ea3ad6) /*  611 */,
382   U64_C(0xa8d8426e8b6a83ea) /*  612 */, U64_C(0xa089b274b7735cdc) /*  613 */,
383   U64_C(0x87f6b3731e524a11) /*  614 */, U64_C(0x118808e5cbc96749) /*  615 */,
384   U64_C(0x9906e4c7b19bd394) /*  616 */, U64_C(0xafed7f7e9b24a20c) /*  617 */,
385   U64_C(0x6509eadeeb3644a7) /*  618 */, U64_C(0x6c1ef1d3e8ef0ede) /*  619 */,
386   U64_C(0xb9c97d43e9798fb4) /*  620 */, U64_C(0xa2f2d784740c28a3) /*  621 */,
387   U64_C(0x7b8496476197566f) /*  622 */, U64_C(0x7a5be3e6b65f069d) /*  623 */,
388   U64_C(0xf96330ed78be6f10) /*  624 */, U64_C(0xeee60de77a076a15) /*  625 */,
389   U64_C(0x2b4bee4aa08b9bd0) /*  626 */, U64_C(0x6a56a63ec7b8894e) /*  627 */,
390   U64_C(0x02121359ba34fef4) /*  628 */, U64_C(0x4cbf99f8283703fc) /*  629 */,
391   U64_C(0x398071350caf30c8) /*  630 */, U64_C(0xd0a77a89f017687a) /*  631 */,
392   U64_C(0xf1c1a9eb9e423569) /*  632 */, U64_C(0x8c7976282dee8199) /*  633 */,
393   U64_C(0x5d1737a5dd1f7abd) /*  634 */, U64_C(0x4f53433c09a9fa80) /*  635 */,
394   U64_C(0xfa8b0c53df7ca1d9) /*  636 */, U64_C(0x3fd9dcbc886ccb77) /*  637 */,
395   U64_C(0xc040917ca91b4720) /*  638 */, U64_C(0x7dd00142f9d1dcdf) /*  639 */,
396   U64_C(0x8476fc1d4f387b58) /*  640 */, U64_C(0x23f8e7c5f3316503) /*  641 */,
397   U64_C(0x032a2244e7e37339) /*  642 */, U64_C(0x5c87a5d750f5a74b) /*  643 */,
398   U64_C(0x082b4cc43698992e) /*  644 */, U64_C(0xdf917becb858f63c) /*  645 */,
399   U64_C(0x3270b8fc5bf86dda) /*  646 */, U64_C(0x10ae72bb29b5dd76) /*  647 */,
400   U64_C(0x576ac94e7700362b) /*  648 */, U64_C(0x1ad112dac61efb8f) /*  649 */,
401   U64_C(0x691bc30ec5faa427) /*  650 */, U64_C(0xff246311cc327143) /*  651 */,
402   U64_C(0x3142368e30e53206) /*  652 */, U64_C(0x71380e31e02ca396) /*  653 */,
403   U64_C(0x958d5c960aad76f1) /*  654 */, U64_C(0xf8d6f430c16da536) /*  655 */,
404   U64_C(0xc8ffd13f1be7e1d2) /*  656 */, U64_C(0x7578ae66004ddbe1) /*  657 */,
405   U64_C(0x05833f01067be646) /*  658 */, U64_C(0xbb34b5ad3bfe586d) /*  659 */,
406   U64_C(0x095f34c9a12b97f0) /*  660 */, U64_C(0x247ab64525d60ca8) /*  661 */,
407   U64_C(0xdcdbc6f3017477d1) /*  662 */, U64_C(0x4a2e14d4decad24d) /*  663 */,
408   U64_C(0xbdb5e6d9be0a1eeb) /*  664 */, U64_C(0x2a7e70f7794301ab) /*  665 */,
409   U64_C(0xdef42d8a270540fd) /*  666 */, U64_C(0x01078ec0a34c22c1) /*  667 */,
410   U64_C(0xe5de511af4c16387) /*  668 */, U64_C(0x7ebb3a52bd9a330a) /*  669 */,
411   U64_C(0x77697857aa7d6435) /*  670 */, U64_C(0x004e831603ae4c32) /*  671 */,
412   U64_C(0xe7a21020ad78e312) /*  672 */, U64_C(0x9d41a70c6ab420f2) /*  673 */,
413   U64_C(0x28e06c18ea1141e6) /*  674 */, U64_C(0xd2b28cbd984f6b28) /*  675 */,
414   U64_C(0x26b75f6c446e9d83) /*  676 */, U64_C(0xba47568c4d418d7f) /*  677 */,
415   U64_C(0xd80badbfe6183d8e) /*  678 */, U64_C(0x0e206d7f5f166044) /*  679 */,
416   U64_C(0xe258a43911cbca3e) /*  680 */, U64_C(0x723a1746b21dc0bc) /*  681 */,
417   U64_C(0xc7caa854f5d7cdd3) /*  682 */, U64_C(0x7cac32883d261d9c) /*  683 */,
418   U64_C(0x7690c26423ba942c) /*  684 */, U64_C(0x17e55524478042b8) /*  685 */,
419   U64_C(0xe0be477656a2389f) /*  686 */, U64_C(0x4d289b5e67ab2da0) /*  687 */,
420   U64_C(0x44862b9c8fbbfd31) /*  688 */, U64_C(0xb47cc8049d141365) /*  689 */,
421   U64_C(0x822c1b362b91c793) /*  690 */, U64_C(0x4eb14655fb13dfd8) /*  691 */,
422   U64_C(0x1ecbba0714e2a97b) /*  692 */, U64_C(0x6143459d5cde5f14) /*  693 */,
423   U64_C(0x53a8fbf1d5f0ac89) /*  694 */, U64_C(0x97ea04d81c5e5b00) /*  695 */,
424   U64_C(0x622181a8d4fdb3f3) /*  696 */, U64_C(0xe9bcd341572a1208) /*  697 */,
425   U64_C(0x1411258643cce58a) /*  698 */, U64_C(0x9144c5fea4c6e0a4) /*  699 */,
426   U64_C(0x0d33d06565cf620f) /*  700 */, U64_C(0x54a48d489f219ca1) /*  701 */,
427   U64_C(0xc43e5eac6d63c821) /*  702 */, U64_C(0xa9728b3a72770daf) /*  703 */,
428   U64_C(0xd7934e7b20df87ef) /*  704 */, U64_C(0xe35503b61a3e86e5) /*  705 */,
429   U64_C(0xcae321fbc819d504) /*  706 */, U64_C(0x129a50b3ac60bfa6) /*  707 */,
430   U64_C(0xcd5e68ea7e9fb6c3) /*  708 */, U64_C(0xb01c90199483b1c7) /*  709 */,
431   U64_C(0x3de93cd5c295376c) /*  710 */, U64_C(0xaed52edf2ab9ad13) /*  711 */,
432   U64_C(0x2e60f512c0a07884) /*  712 */, U64_C(0xbc3d86a3e36210c9) /*  713 */,
433   U64_C(0x35269d9b163951ce) /*  714 */, U64_C(0x0c7d6e2ad0cdb5fa) /*  715 */,
434   U64_C(0x59e86297d87f5733) /*  716 */, U64_C(0x298ef221898db0e7) /*  717 */,
435   U64_C(0x55000029d1a5aa7e) /*  718 */, U64_C(0x8bc08ae1b5061b45) /*  719 */,
436   U64_C(0xc2c31c2b6c92703a) /*  720 */, U64_C(0x94cc596baf25ef42) /*  721 */,
437   U64_C(0x0a1d73db22540456) /*  722 */, U64_C(0x04b6a0f9d9c4179a) /*  723 */,
438   U64_C(0xeffdafa2ae3d3c60) /*  724 */, U64_C(0xf7c8075bb49496c4) /*  725 */,
439   U64_C(0x9cc5c7141d1cd4e3) /*  726 */, U64_C(0x78bd1638218e5534) /*  727 */,
440   U64_C(0xb2f11568f850246a) /*  728 */, U64_C(0xedfabcfa9502bc29) /*  729 */,
441   U64_C(0x796ce5f2da23051b) /*  730 */, U64_C(0xaae128b0dc93537c) /*  731 */,
442   U64_C(0x3a493da0ee4b29ae) /*  732 */, U64_C(0xb5df6b2c416895d7) /*  733 */,
443   U64_C(0xfcabbd25122d7f37) /*  734 */, U64_C(0x70810b58105dc4b1) /*  735 */,
444   U64_C(0xe10fdd37f7882a90) /*  736 */, U64_C(0x524dcab5518a3f5c) /*  737 */,
445   U64_C(0x3c9e85878451255b) /*  738 */, U64_C(0x4029828119bd34e2) /*  739 */,
446   U64_C(0x74a05b6f5d3ceccb) /*  740 */, U64_C(0xb610021542e13eca) /*  741 */,
447   U64_C(0x0ff979d12f59e2ac) /*  742 */, U64_C(0x6037da27e4f9cc50) /*  743 */,
448   U64_C(0x5e92975a0df1847d) /*  744 */, U64_C(0xd66de190d3e623fe) /*  745 */,
449   U64_C(0x5032d6b87b568048) /*  746 */, U64_C(0x9a36b7ce8235216e) /*  747 */,
450   U64_C(0x80272a7a24f64b4a) /*  748 */, U64_C(0x93efed8b8c6916f7) /*  749 */,
451   U64_C(0x37ddbff44cce1555) /*  750 */, U64_C(0x4b95db5d4b99bd25) /*  751 */,
452   U64_C(0x92d3fda169812fc0) /*  752 */, U64_C(0xfb1a4a9a90660bb6) /*  753 */,
453   U64_C(0x730c196946a4b9b2) /*  754 */, U64_C(0x81e289aa7f49da68) /*  755 */,
454   U64_C(0x64669a0f83b1a05f) /*  756 */, U64_C(0x27b3ff7d9644f48b) /*  757 */,
455   U64_C(0xcc6b615c8db675b3) /*  758 */, U64_C(0x674f20b9bcebbe95) /*  759 */,
456   U64_C(0x6f31238275655982) /*  760 */, U64_C(0x5ae488713e45cf05) /*  761 */,
457   U64_C(0xbf619f9954c21157) /*  762 */, U64_C(0xeabac46040a8eae9) /*  763 */,
458   U64_C(0x454c6fe9f2c0c1cd) /*  764 */, U64_C(0x419cf6496412691c) /*  765 */,
459   U64_C(0xd3dc3bef265b0f70) /*  766 */, U64_C(0x6d0e60f5c3578a9e) /*  767 */
460 };
461 static u64 sbox4[256] = {
462   U64_C(0x5b0e608526323c55) /*  768 */, U64_C(0x1a46c1a9fa1b59f5) /*  769 */,
463   U64_C(0xa9e245a17c4c8ffa) /*  770 */, U64_C(0x65ca5159db2955d7) /*  771 */,
464   U64_C(0x05db0a76ce35afc2) /*  772 */, U64_C(0x81eac77ea9113d45) /*  773 */,
465   U64_C(0x528ef88ab6ac0a0d) /*  774 */, U64_C(0xa09ea253597be3ff) /*  775 */,
466   U64_C(0x430ddfb3ac48cd56) /*  776 */, U64_C(0xc4b3a67af45ce46f) /*  777 */,
467   U64_C(0x4ececfd8fbe2d05e) /*  778 */, U64_C(0x3ef56f10b39935f0) /*  779 */,
468   U64_C(0x0b22d6829cd619c6) /*  780 */, U64_C(0x17fd460a74df2069) /*  781 */,
469   U64_C(0x6cf8cc8e8510ed40) /*  782 */, U64_C(0xd6c824bf3a6ecaa7) /*  783 */,
470   U64_C(0x61243d581a817049) /*  784 */, U64_C(0x048bacb6bbc163a2) /*  785 */,
471   U64_C(0xd9a38ac27d44cc32) /*  786 */, U64_C(0x7fddff5baaf410ab) /*  787 */,
472   U64_C(0xad6d495aa804824b) /*  788 */, U64_C(0xe1a6a74f2d8c9f94) /*  789 */,
473   U64_C(0xd4f7851235dee8e3) /*  790 */, U64_C(0xfd4b7f886540d893) /*  791 */,
474   U64_C(0x247c20042aa4bfda) /*  792 */, U64_C(0x096ea1c517d1327c) /*  793 */,
475   U64_C(0xd56966b4361a6685) /*  794 */, U64_C(0x277da5c31221057d) /*  795 */,
476   U64_C(0x94d59893a43acff7) /*  796 */, U64_C(0x64f0c51ccdc02281) /*  797 */,
477   U64_C(0x3d33bcc4ff6189db) /*  798 */, U64_C(0xe005cb184ce66af1) /*  799 */,
478   U64_C(0xff5ccd1d1db99bea) /*  800 */, U64_C(0xb0b854a7fe42980f) /*  801 */,
479   U64_C(0x7bd46a6a718d4b9f) /*  802 */, U64_C(0xd10fa8cc22a5fd8c) /*  803 */,
480   U64_C(0xd31484952be4bd31) /*  804 */, U64_C(0xc7fa975fcb243847) /*  805 */,
481   U64_C(0x4886ed1e5846c407) /*  806 */, U64_C(0x28cddb791eb70b04) /*  807 */,
482   U64_C(0xc2b00be2f573417f) /*  808 */, U64_C(0x5c9590452180f877) /*  809 */,
483   U64_C(0x7a6bddfff370eb00) /*  810 */, U64_C(0xce509e38d6d9d6a4) /*  811 */,
484   U64_C(0xebeb0f00647fa702) /*  812 */, U64_C(0x1dcc06cf76606f06) /*  813 */,
485   U64_C(0xe4d9f28ba286ff0a) /*  814 */, U64_C(0xd85a305dc918c262) /*  815 */,
486   U64_C(0x475b1d8732225f54) /*  816 */, U64_C(0x2d4fb51668ccb5fe) /*  817 */,
487   U64_C(0xa679b9d9d72bba20) /*  818 */, U64_C(0x53841c0d912d43a5) /*  819 */,
488   U64_C(0x3b7eaa48bf12a4e8) /*  820 */, U64_C(0x781e0e47f22f1ddf) /*  821 */,
489   U64_C(0xeff20ce60ab50973) /*  822 */, U64_C(0x20d261d19dffb742) /*  823 */,
490   U64_C(0x16a12b03062a2e39) /*  824 */, U64_C(0x1960eb2239650495) /*  825 */,
491   U64_C(0x251c16fed50eb8b8) /*  826 */, U64_C(0x9ac0c330f826016e) /*  827 */,
492   U64_C(0xed152665953e7671) /*  828 */, U64_C(0x02d63194a6369570) /*  829 */,
493   U64_C(0x5074f08394b1c987) /*  830 */, U64_C(0x70ba598c90b25ce1) /*  831 */,
494   U64_C(0x794a15810b9742f6) /*  832 */, U64_C(0x0d5925e9fcaf8c6c) /*  833 */,
495   U64_C(0x3067716cd868744e) /*  834 */, U64_C(0x910ab077e8d7731b) /*  835 */,
496   U64_C(0x6a61bbdb5ac42f61) /*  836 */, U64_C(0x93513efbf0851567) /*  837 */,
497   U64_C(0xf494724b9e83e9d5) /*  838 */, U64_C(0xe887e1985c09648d) /*  839 */,
498   U64_C(0x34b1d3c675370cfd) /*  840 */, U64_C(0xdc35e433bc0d255d) /*  841 */,
499   U64_C(0xd0aab84234131be0) /*  842 */, U64_C(0x08042a50b48b7eaf) /*  843 */,
500   U64_C(0x9997c4ee44a3ab35) /*  844 */, U64_C(0x829a7b49201799d0) /*  845 */,
501   U64_C(0x263b8307b7c54441) /*  846 */, U64_C(0x752f95f4fd6a6ca6) /*  847 */,
502   U64_C(0x927217402c08c6e5) /*  848 */, U64_C(0x2a8ab754a795d9ee) /*  849 */,
503   U64_C(0xa442f7552f72943d) /*  850 */, U64_C(0x2c31334e19781208) /*  851 */,
504   U64_C(0x4fa98d7ceaee6291) /*  852 */, U64_C(0x55c3862f665db309) /*  853 */,
505   U64_C(0xbd0610175d53b1f3) /*  854 */, U64_C(0x46fe6cb840413f27) /*  855 */,
506   U64_C(0x3fe03792df0cfa59) /*  856 */, U64_C(0xcfe700372eb85e8f) /*  857 */,
507   U64_C(0xa7be29e7adbce118) /*  858 */, U64_C(0xe544ee5cde8431dd) /*  859 */,
508   U64_C(0x8a781b1b41f1873e) /*  860 */, U64_C(0xa5c94c78a0d2f0e7) /*  861 */,
509   U64_C(0x39412e2877b60728) /*  862 */, U64_C(0xa1265ef3afc9a62c) /*  863 */,
510   U64_C(0xbcc2770c6a2506c5) /*  864 */, U64_C(0x3ab66dd5dce1ce12) /*  865 */,
511   U64_C(0xe65499d04a675b37) /*  866 */, U64_C(0x7d8f523481bfd216) /*  867 */,
512   U64_C(0x0f6f64fcec15f389) /*  868 */, U64_C(0x74efbe618b5b13c8) /*  869 */,
513   U64_C(0xacdc82b714273e1d) /*  870 */, U64_C(0xdd40bfe003199d17) /*  871 */,
514   U64_C(0x37e99257e7e061f8) /*  872 */, U64_C(0xfa52626904775aaa) /*  873 */,
515   U64_C(0x8bbbf63a463d56f9) /*  874 */, U64_C(0xf0013f1543a26e64) /*  875 */,
516   U64_C(0xa8307e9f879ec898) /*  876 */, U64_C(0xcc4c27a4150177cc) /*  877 */,
517   U64_C(0x1b432f2cca1d3348) /*  878 */, U64_C(0xde1d1f8f9f6fa013) /*  879 */,
518   U64_C(0x606602a047a7ddd6) /*  880 */, U64_C(0xd237ab64cc1cb2c7) /*  881 */,
519   U64_C(0x9b938e7225fcd1d3) /*  882 */, U64_C(0xec4e03708e0ff476) /*  883 */,
520   U64_C(0xfeb2fbda3d03c12d) /*  884 */, U64_C(0xae0bced2ee43889a) /*  885 */,
521   U64_C(0x22cb8923ebfb4f43) /*  886 */, U64_C(0x69360d013cf7396d) /*  887 */,
522   U64_C(0x855e3602d2d4e022) /*  888 */, U64_C(0x073805bad01f784c) /*  889 */,
523   U64_C(0x33e17a133852f546) /*  890 */, U64_C(0xdf4874058ac7b638) /*  891 */,
524   U64_C(0xba92b29c678aa14a) /*  892 */, U64_C(0x0ce89fc76cfaadcd) /*  893 */,
525   U64_C(0x5f9d4e0908339e34) /*  894 */, U64_C(0xf1afe9291f5923b9) /*  895 */,
526   U64_C(0x6e3480f60f4a265f) /*  896 */, U64_C(0xeebf3a2ab29b841c) /*  897 */,
527   U64_C(0xe21938a88f91b4ad) /*  898 */, U64_C(0x57dfeff845c6d3c3) /*  899 */,
528   U64_C(0x2f006b0bf62caaf2) /*  900 */, U64_C(0x62f479ef6f75ee78) /*  901 */,
529   U64_C(0x11a55ad41c8916a9) /*  902 */, U64_C(0xf229d29084fed453) /*  903 */,
530   U64_C(0x42f1c27b16b000e6) /*  904 */, U64_C(0x2b1f76749823c074) /*  905 */,
531   U64_C(0x4b76eca3c2745360) /*  906 */, U64_C(0x8c98f463b91691bd) /*  907 */,
532   U64_C(0x14bcc93cf1ade66a) /*  908 */, U64_C(0x8885213e6d458397) /*  909 */,
533   U64_C(0x8e177df0274d4711) /*  910 */, U64_C(0xb49b73b5503f2951) /*  911 */,
534   U64_C(0x10168168c3f96b6b) /*  912 */, U64_C(0x0e3d963b63cab0ae) /*  913 */,
535   U64_C(0x8dfc4b5655a1db14) /*  914 */, U64_C(0xf789f1356e14de5c) /*  915 */,
536   U64_C(0x683e68af4e51dac1) /*  916 */, U64_C(0xc9a84f9d8d4b0fd9) /*  917 */,
537   U64_C(0x3691e03f52a0f9d1) /*  918 */, U64_C(0x5ed86e46e1878e80) /*  919 */,
538   U64_C(0x3c711a0e99d07150) /*  920 */, U64_C(0x5a0865b20c4e9310) /*  921 */,
539   U64_C(0x56fbfc1fe4f0682e) /*  922 */, U64_C(0xea8d5de3105edf9b) /*  923 */,
540   U64_C(0x71abfdb12379187a) /*  924 */, U64_C(0x2eb99de1bee77b9c) /*  925 */,
541   U64_C(0x21ecc0ea33cf4523) /*  926 */, U64_C(0x59a4d7521805c7a1) /*  927 */,
542   U64_C(0x3896f5eb56ae7c72) /*  928 */, U64_C(0xaa638f3db18f75dc) /*  929 */,
543   U64_C(0x9f39358dabe9808e) /*  930 */, U64_C(0xb7defa91c00b72ac) /*  931 */,
544   U64_C(0x6b5541fd62492d92) /*  932 */, U64_C(0x6dc6dee8f92e4d5b) /*  933 */,
545   U64_C(0x353f57abc4beea7e) /*  934 */, U64_C(0x735769d6da5690ce) /*  935 */,
546   U64_C(0x0a234aa642391484) /*  936 */, U64_C(0xf6f9508028f80d9d) /*  937 */,
547   U64_C(0xb8e319a27ab3f215) /*  938 */, U64_C(0x31ad9c1151341a4d) /*  939 */,
548   U64_C(0x773c22a57bef5805) /*  940 */, U64_C(0x45c7561a07968633) /*  941 */,
549   U64_C(0xf913da9e249dbe36) /*  942 */, U64_C(0xda652d9b78a64c68) /*  943 */,
550   U64_C(0x4c27a97f3bc334ef) /*  944 */, U64_C(0x76621220e66b17f4) /*  945 */,
551   U64_C(0x967743899acd7d0b) /*  946 */, U64_C(0xf3ee5bcae0ed6782) /*  947 */,
552   U64_C(0x409f753600c879fc) /*  948 */, U64_C(0x06d09a39b5926db6) /*  949 */,
553   U64_C(0x6f83aeb0317ac588) /*  950 */, U64_C(0x01e6ca4a86381f21) /*  951 */,
554   U64_C(0x66ff3462d19f3025) /*  952 */, U64_C(0x72207c24ddfd3bfb) /*  953 */,
555   U64_C(0x4af6b6d3e2ece2eb) /*  954 */, U64_C(0x9c994dbec7ea08de) /*  955 */,
556   U64_C(0x49ace597b09a8bc4) /*  956 */, U64_C(0xb38c4766cf0797ba) /*  957 */,
557   U64_C(0x131b9373c57c2a75) /*  958 */, U64_C(0xb1822cce61931e58) /*  959 */,
558   U64_C(0x9d7555b909ba1c0c) /*  960 */, U64_C(0x127fafdd937d11d2) /*  961 */,
559   U64_C(0x29da3badc66d92e4) /*  962 */, U64_C(0xa2c1d57154c2ecbc) /*  963 */,
560   U64_C(0x58c5134d82f6fe24) /*  964 */, U64_C(0x1c3ae3515b62274f) /*  965 */,
561   U64_C(0xe907c82e01cb8126) /*  966 */, U64_C(0xf8ed091913e37fcb) /*  967 */,
562   U64_C(0x3249d8f9c80046c9) /*  968 */, U64_C(0x80cf9bede388fb63) /*  969 */,
563   U64_C(0x1881539a116cf19e) /*  970 */, U64_C(0x5103f3f76bd52457) /*  971 */,
564   U64_C(0x15b7e6f5ae47f7a8) /*  972 */, U64_C(0xdbd7c6ded47e9ccf) /*  973 */,
565   U64_C(0x44e55c410228bb1a) /*  974 */, U64_C(0xb647d4255edb4e99) /*  975 */,
566   U64_C(0x5d11882bb8aafc30) /*  976 */, U64_C(0xf5098bbb29d3212a) /*  977 */,
567   U64_C(0x8fb5ea14e90296b3) /*  978 */, U64_C(0x677b942157dd025a) /*  979 */,
568   U64_C(0xfb58e7c0a390acb5) /*  980 */, U64_C(0x89d3674c83bd4a01) /*  981 */,
569   U64_C(0x9e2da4df4bf3b93b) /*  982 */, U64_C(0xfcc41e328cab4829) /*  983 */,
570   U64_C(0x03f38c96ba582c52) /*  984 */, U64_C(0xcad1bdbd7fd85db2) /*  985 */,
571   U64_C(0xbbb442c16082ae83) /*  986 */, U64_C(0xb95fe86ba5da9ab0) /*  987 */,
572   U64_C(0xb22e04673771a93f) /*  988 */, U64_C(0x845358c9493152d8) /*  989 */,
573   U64_C(0xbe2a488697b4541e) /*  990 */, U64_C(0x95a2dc2dd38e6966) /*  991 */,
574   U64_C(0xc02c11ac923c852b) /*  992 */, U64_C(0x2388b1990df2a87b) /*  993 */,
575   U64_C(0x7c8008fa1b4f37be) /*  994 */, U64_C(0x1f70d0c84d54e503) /*  995 */,
576   U64_C(0x5490adec7ece57d4) /*  996 */, U64_C(0x002b3c27d9063a3a) /*  997 */,
577   U64_C(0x7eaea3848030a2bf) /*  998 */, U64_C(0xc602326ded2003c0) /*  999 */,
578   U64_C(0x83a7287d69a94086) /* 1000 */, U64_C(0xc57a5fcb30f57a8a) /* 1001 */,
579   U64_C(0xb56844e479ebe779) /* 1002 */, U64_C(0xa373b40f05dcbce9) /* 1003 */,
580   U64_C(0xd71a786e88570ee2) /* 1004 */, U64_C(0x879cbacdbde8f6a0) /* 1005 */,
581   U64_C(0x976ad1bcc164a32f) /* 1006 */, U64_C(0xab21e25e9666d78b) /* 1007 */,
582   U64_C(0x901063aae5e5c33c) /* 1008 */, U64_C(0x9818b34448698d90) /* 1009 */,
583   U64_C(0xe36487ae3e1e8abb) /* 1010 */, U64_C(0xafbdf931893bdcb4) /* 1011 */,
584   U64_C(0x6345a0dc5fbbd519) /* 1012 */, U64_C(0x8628fe269b9465ca) /* 1013 */,
585   U64_C(0x1e5d01603f9c51ec) /* 1014 */, U64_C(0x4de44006a15049b7) /* 1015 */,
586   U64_C(0xbf6c70e5f776cbb1) /* 1016 */, U64_C(0x411218f2ef552bed) /* 1017 */,
587   U64_C(0xcb0c0708705a36a3) /* 1018 */, U64_C(0xe74d14754f986044) /* 1019 */,
588   U64_C(0xcd56d9430ea8280e) /* 1020 */, U64_C(0xc12591d7535f5065) /* 1021 */,
589   U64_C(0xc83223f1720aef96) /* 1022 */, U64_C(0xc3a0396f7363a51f) /* 1023 */
590 };
591
592 static unsigned int
593 transform ( void *ctx, const unsigned char *data );
594
595 static void
596 do_init (void *context, int variant)
597 {
598   TIGER_CONTEXT *hd = context;
599
600   hd->a = 0x0123456789abcdefLL;
601   hd->b = 0xfedcba9876543210LL;
602   hd->c = 0xf096a5b4c3b2e187LL;
603
604   hd->bctx.nblocks = 0;
605   hd->bctx.nblocks_high = 0;
606   hd->bctx.count = 0;
607   hd->bctx.blocksize = 64;
608   hd->bctx.bwrite = transform;
609   hd->variant = variant;
610 }
611
612 static void
613 tiger_init (void *context)
614 {
615   do_init (context, 0);
616 }
617
618 static void
619 tiger1_init (void *context)
620 {
621   do_init (context, 1);
622 }
623
624 static void
625 tiger2_init (void *context)
626 {
627   do_init (context, 2);
628 }
629
630 static void
631 tiger_round( u64 *ra, u64 *rb, u64 *rc, u64 x, int mul )
632 {
633   u64 a = *ra;
634   u64 b = *rb;
635   u64 c = *rc;
636
637   c ^= x;
638   a -= (  sbox1[  c        & 0xff ] ^ sbox2[ (c >> 16) & 0xff ]
639         ^ sbox3[ (c >> 32) & 0xff ] ^ sbox4[ (c >> 48) & 0xff ]);
640   b += (  sbox4[ (c >>  8) & 0xff ] ^ sbox3[ (c >> 24) & 0xff ]
641         ^ sbox2[ (c >> 40) & 0xff ] ^ sbox1[ (c >> 56) & 0xff ]);
642   b *= mul;
643
644   *ra = a;
645   *rb = b;
646   *rc = c;
647 }
648
649
650 static void
651 pass( u64 *ra, u64 *rb, u64 *rc, u64 *x, int mul )
652 {
653   u64 a = *ra;
654   u64 b = *rb;
655   u64 c = *rc;
656
657   tiger_round( &a, &b, &c, x[0], mul );
658   tiger_round( &b, &c, &a, x[1], mul );
659   tiger_round( &c, &a, &b, x[2], mul );
660   tiger_round( &a, &b, &c, x[3], mul );
661   tiger_round( &b, &c, &a, x[4], mul );
662   tiger_round( &c, &a, &b, x[5], mul );
663   tiger_round( &a, &b, &c, x[6], mul );
664   tiger_round( &b, &c, &a, x[7], mul );
665
666   *ra = a;
667   *rb = b;
668   *rc = c;
669 }
670
671
672 static void
673 key_schedule( u64 *x )
674 {
675   x[0] -= x[7] ^ 0xa5a5a5a5a5a5a5a5LL;
676   x[1] ^= x[0];
677   x[2] += x[1];
678   x[3] -= x[2] ^ ((~x[1]) << 19 );
679   x[4] ^= x[3];
680   x[5] += x[4];
681   x[6] -= x[5] ^ ((~x[4]) >> 23 );
682   x[7] ^= x[6];
683   x[0] += x[7];
684   x[1] -= x[0] ^ ((~x[7]) << 19 );
685   x[2] ^= x[1];
686   x[3] += x[2];
687   x[4] -= x[3] ^ ((~x[2]) >> 23 );
688   x[5] ^= x[4];
689   x[6] += x[5];
690   x[7] -= x[6] ^ 0x0123456789abcdefLL;
691 }
692
693
694 /****************
695  * Transform the message DATA which consists of 512 bytes (8 words)
696  */
697 static unsigned int
698 transform ( void *ctx, const unsigned char *data )
699 {
700   TIGER_CONTEXT *hd = ctx;
701   u64 a,b,c,aa,bb,cc;
702   u64 x[8];
703   int i;
704
705   for ( i = 0; i < 8; i++ )
706     x[i] = buf_get_le64(data + i * 8);
707
708   /* save */
709   a = aa = hd->a;
710   b = bb = hd->b;
711   c = cc = hd->c;
712
713   pass( &a, &b, &c, x, 5);
714   key_schedule( x );
715   pass( &c, &a, &b, x, 7);
716   key_schedule( x );
717   pass( &b, &c, &a, x, 9);
718
719   /* feedforward */
720   a ^= aa;
721   b -= bb;
722   c += cc;
723   /* store */
724   hd->a = a;
725   hd->b = b;
726   hd->c = c;
727
728   return /*burn_stack*/ 21*8+11*sizeof(void*);
729 }
730
731
732
733 /* The routine terminates the computation
734  */
735 static void
736 tiger_final( void *context )
737 {
738   TIGER_CONTEXT *hd = context;
739   u32 t, th, msb, lsb;
740   byte *p;
741   unsigned int burn;
742   byte pad = hd->variant == 2? 0x80 : 0x01;
743
744   _gcry_md_block_write(hd, NULL, 0); /* flush */;
745
746   t = hd->bctx.nblocks;
747   if (sizeof t == sizeof hd->bctx.nblocks)
748     th = hd->bctx.nblocks_high;
749   else
750     th = hd->bctx.nblocks >> 32;
751
752   /* multiply by 64 to make a byte count */
753   lsb = t << 6;
754   msb = (th << 6) | (t >> 26);
755   /* add the count */
756   t = lsb;
757   if( (lsb += hd->bctx.count) < t )
758     msb++;
759   /* multiply by 8 to make a bit count */
760   t = lsb;
761   lsb <<= 3;
762   msb <<= 3;
763   msb |= t >> 29;
764
765   if( hd->bctx.count < 56 )  /* enough room */
766     {
767       hd->bctx.buf[hd->bctx.count++] = pad;
768       while( hd->bctx.count < 56 )
769         hd->bctx.buf[hd->bctx.count++] = 0;  /* pad */
770     }
771   else  /* need one extra block */
772     {
773       hd->bctx.buf[hd->bctx.count++] = pad; /* pad character */
774       while( hd->bctx.count < 64 )
775         hd->bctx.buf[hd->bctx.count++] = 0;
776       _gcry_md_block_write(hd, NULL, 0);  /* flush */;
777       memset(hd->bctx.buf, 0, 56 ); /* fill next block with zeroes */
778     }
779   /* append the 64 bit count */
780   buf_put_le32(hd->bctx.buf + 56, lsb);
781   buf_put_le32(hd->bctx.buf + 60, msb);
782   burn = transform( hd, hd->bctx.buf );
783   _gcry_burn_stack (burn);
784
785   p = hd->bctx.buf;
786 #define X(a) do { *(u64*)p = be_bswap64(hd->a); p += 8; } while(0)
787 #define Y(a) do { *(u64*)p = le_bswap64(hd->a); p += 8; } while(0)
788   if (hd->variant == 0)
789     {
790       X(a);
791       X(b);
792       X(c);
793     }
794   else
795     {
796       Y(a);
797       Y(b);
798       Y(c);
799     }
800 #undef X
801 #undef Y
802 }
803
804 static byte *
805 tiger_read( void *context )
806 {
807   TIGER_CONTEXT *hd = context;
808
809   return hd->bctx.buf;
810 }
811
812
813 \f
814 /* This is the old TIGER variant based on the unfixed reference
815    implementation.  IT was used in GnupG up to 1.3.2.  We don't provide
816    an OID anymore because that would not be correct.  */
817 gcry_md_spec_t _gcry_digest_spec_tiger =
818   {
819     GCRY_MD_TIGER, {0, 0},
820     "TIGER192", NULL, 0, NULL, 24,
821     tiger_init, _gcry_md_block_write, tiger_final, tiger_read,
822     sizeof (TIGER_CONTEXT)
823   };
824
825
826 \f
827 /* This is the fixed TIGER implementation.  */
828 static byte asn1[19] = /* Object ID is 1.3.6.1.4.1.11591.12.2 */
829   { 0x30, 0x29, 0x30, 0x0d, 0x06, 0x09, 0x2b, 0x06,
830     0x01, 0x04, 0x01, 0xda, 0x47, 0x0c, 0x02,
831     0x05, 0x00, 0x04, 0x18 };
832
833 static gcry_md_oid_spec_t oid_spec_tiger1[] =
834   {
835     /* GNU.digestAlgorithm TIGER */
836     { "1.3.6.1.4.1.11591.12.2" },
837     { NULL }
838   };
839
840 gcry_md_spec_t _gcry_digest_spec_tiger1 =
841   {
842     GCRY_MD_TIGER1, {0, 0},
843     "TIGER", asn1, DIM (asn1), oid_spec_tiger1, 24,
844     tiger1_init, _gcry_md_block_write, tiger_final, tiger_read,
845     sizeof (TIGER_CONTEXT)
846   };
847
848
849 \f
850 /* This is TIGER2 which usues a changed padding algorithm.  */
851 gcry_md_spec_t _gcry_digest_spec_tiger2 =
852   {
853     GCRY_MD_TIGER2, {0, 0},
854     "TIGER2", NULL, 0, NULL, 24,
855     tiger2_init, _gcry_md_block_write, tiger_final, tiger_read,
856     sizeof (TIGER_CONTEXT)
857   };
858
859 #endif /* HAVE_U64_TYPEDEF */