1 /**
2 * DES
3 * 
4 * Copyright:
5 * (C) 1999-2007 Jack Lloyd
6 * (C) 2014-2015 Etienne Cimon
7 *
8 * License:
9 * Botan is released under the Simplified BSD License (see LICENSE.md)
10 */
11 module botan.block.des;
12 
13 import botan.constants;
14 static if (BOTAN_HAS_DES):
15 
16 import std.range : iota;
17 import botan.utils.loadstor;
18 import botan.utils.rotate;
19 public import botan.block.block_cipher;
20 import botan.utils.get_byte : get_byte;
21 import botan.utils.mem_ops;
22 
23 /**
24 * DES
25 */
26 class DES : BlockCipherFixedParams!(8, 8), BlockCipher, SymmetricAlgorithm
27 {
28 public:
29 
30     /*
31     * DES Encryption
32     */
33     override void encryptN(const(ubyte)* input, ubyte* output, size_t blocks)
34     {
35         foreach (size_t i; 0 .. blocks)
36         {
37             ulong T =   (DES_IPTAB1[input[0]]     ) | (DES_IPTAB1[input[1]] << 1) |
38                         (DES_IPTAB1[input[2]] << 2) | (DES_IPTAB1[input[3]] << 3) |
39                         (DES_IPTAB1[input[4]] << 4) | (DES_IPTAB1[input[5]] << 5) |
40                         (DES_IPTAB1[input[6]] << 6) | (DES_IPTAB2[input[7]]      );
41             
42             uint L = cast(uint)(T >> 32);
43             uint R = cast(uint)(T);
44             
45             des_encrypt(L, R, *cast(uint[32]*) m_round_key.ptr);
46             
47             T =     (DES_FPTAB1[get_byte(0, L)] << 5) | (DES_FPTAB1[get_byte(1, L)] << 3) |
48                     (DES_FPTAB1[get_byte(2, L)] << 1) | (DES_FPTAB2[get_byte(3, L)] << 1) |
49                     (DES_FPTAB1[get_byte(0, R)] << 4) | (DES_FPTAB1[get_byte(1, R)] << 2) |
50                     (DES_FPTAB1[get_byte(2, R)]     ) | (DES_FPTAB2[get_byte(3, R)]      );
51             T = rotateLeft(T, 32);
52             
53             storeBigEndian(T, output);
54             
55             input += BLOCK_SIZE;
56             output += BLOCK_SIZE;
57         }
58     }
59 
60 
61     /*
62     * DES Decryption
63     */
64     override void decryptN(const(ubyte)* input, ubyte* output, size_t blocks)
65     {
66         foreach (size_t i; 0 .. blocks)
67         {
68             ulong T =     (DES_IPTAB1[input[0]]   ) | (DES_IPTAB1[input[1]] << 1) |
69                         (DES_IPTAB1[input[2]] << 2) | (DES_IPTAB1[input[3]] << 3) |
70                         (DES_IPTAB1[input[4]] << 4) | (DES_IPTAB1[input[5]] << 5) |
71                         (DES_IPTAB1[input[6]] << 6) | (DES_IPTAB2[input[7]]      );
72             
73             uint L = cast(uint)(T >> 32);
74             uint R = cast(uint)(T);
75             
76             des_decrypt(L, R, *cast(uint[32]*) m_round_key.ptr);
77             
78             T =     (DES_FPTAB1[get_byte(0, L)] << 5) | (DES_FPTAB1[get_byte(1, L)] << 3) |
79                     (DES_FPTAB1[get_byte(2, L)] << 1) | (DES_FPTAB2[get_byte(3, L)] << 1) |
80                     (DES_FPTAB1[get_byte(0, R)] << 4) | (DES_FPTAB1[get_byte(1, R)] << 2) |
81                     (DES_FPTAB1[get_byte(2, R)]     ) | (DES_FPTAB2[get_byte(3, R)]      );
82             
83             T = rotateLeft(T, 32);
84             
85             storeBigEndian(T, output);
86             
87             input += BLOCK_SIZE;
88             output += BLOCK_SIZE;
89         }
90     }
91 
92     override void clear()
93     {
94         zap(m_round_key);
95     }
96 
97     @property string name() const { return "DES"; }
98     override @property size_t parallelism() const { return 1; }
99     override BlockCipher clone() const { return new DES; }
100     override size_t blockSize() const { return super.blockSize(); }
101     override KeyLengthSpecification keySpec() const { return super.keySpec(); }
102 protected:
103     /*
104     * DES Key Schedule
105     */
106     override void keySchedule(const(ubyte)* key, size_t)
107     {
108         m_round_key.resize(32);
109         des_key_schedule(*cast(uint[32]*) m_round_key.ptr, *cast(ubyte[8]*) key);
110     }
111 
112     SecureVector!uint m_round_key;
113 }
114 
115 /**
116 * Triple DES
117 */
118 class TripleDES : BlockCipherFixedParams!(8, 16, 24, 8), BlockCipher, SymmetricAlgorithm
119 {
120 public:
121     /*
122     * TripleDES Encryption
123     */
124     override void encryptN(const(ubyte)* input, ubyte* output, size_t blocks)
125     {
126         foreach (size_t i; 0 .. blocks)
127         {
128             ulong T =   (DES_IPTAB1[input[0]]     ) | (DES_IPTAB1[input[1]] << 1) |
129                         (DES_IPTAB1[input[2]] << 2) | (DES_IPTAB1[input[3]] << 3) |
130                         (DES_IPTAB1[input[4]] << 4) | (DES_IPTAB1[input[5]] << 5) |
131                         (DES_IPTAB1[input[6]] << 6) | (DES_IPTAB2[input[7]]      );
132             
133             uint L = cast(uint)(T >> 32);
134             uint R = cast(uint)(T);
135 
136             des_encrypt(L, R, *cast(uint[32]*) m_round_key.ptr);
137             des_decrypt(R, L, *cast(uint[32]*) &m_round_key[32]);
138             des_encrypt(L, R, *cast(uint[32]*) &m_round_key[64]);
139             
140             T =     (DES_FPTAB1[get_byte(0, L)] << 5) | (DES_FPTAB1[get_byte(1, L)] << 3) |
141                     (DES_FPTAB1[get_byte(2, L)] << 1) | (DES_FPTAB2[get_byte(3, L)] << 1) |
142                     (DES_FPTAB1[get_byte(0, R)] << 4) | (DES_FPTAB1[get_byte(1, R)] << 2) |
143                     (DES_FPTAB1[get_byte(2, R)]     ) | (DES_FPTAB2[get_byte(3, R)]     );
144             
145             T = rotateLeft(T, 32);
146             
147             storeBigEndian(T, output);
148             
149             input += BLOCK_SIZE;
150             output += BLOCK_SIZE;
151         }
152     }
153     /*
154     * TripleDES Decryption
155     */
156     override void decryptN(const(ubyte)* input, ubyte* output, size_t blocks)
157     {
158         foreach (size_t i; 0 .. blocks)
159         {
160             ulong T =   (DES_IPTAB1[input[0]]     ) | (DES_IPTAB1[input[1]] << 1) |
161                         (DES_IPTAB1[input[2]] << 2) | (DES_IPTAB1[input[3]] << 3) |
162                         (DES_IPTAB1[input[4]] << 4) | (DES_IPTAB1[input[5]] << 5) |
163                         (DES_IPTAB1[input[6]] << 6) | (DES_IPTAB2[input[7]]     );
164             
165             uint L = cast(uint)(T >> 32);
166             uint R = cast(uint)(T);
167 
168             des_decrypt(L, R, *cast(uint[32]*) &m_round_key[64]);
169             des_encrypt(R, L, *cast(uint[32]*) &m_round_key[32]);
170             des_decrypt(L, R, *cast(uint[32]*) m_round_key.ptr);
171             
172             T =     (DES_FPTAB1[get_byte(0, L)] << 5) | (DES_FPTAB1[get_byte(1, L)] << 3) |
173                     (DES_FPTAB1[get_byte(2, L)] << 1) | (DES_FPTAB2[get_byte(3, L)] << 1) |
174                     (DES_FPTAB1[get_byte(0, R)] << 4) | (DES_FPTAB1[get_byte(1, R)] << 2) |
175                     (DES_FPTAB1[get_byte(2, R)]     ) | (DES_FPTAB2[get_byte(3, R)]     );
176             
177             T = rotateLeft(T, 32);
178             
179             storeBigEndian(T, output);
180             
181             input += BLOCK_SIZE;
182             output += BLOCK_SIZE;
183         }
184     }
185 
186     override void clear()
187     {
188         zap(m_round_key);
189     }
190 
191     @property string name() const { return "TripleDES"; }
192     override @property size_t parallelism() const { return 1; }
193     override BlockCipher clone() const { return new TripleDES; }
194     override size_t blockSize() const { return super.blockSize(); }
195     override KeyLengthSpecification keySpec() const { return super.keySpec(); }
196 protected:
197     /*
198     * TripleDES Key Schedule
199     */
200     override void keySchedule(const(ubyte)* key, size_t length)
201     {
202         m_round_key.resize(3*32);
203         des_key_schedule(*cast(uint[32]*)m_round_key.ptr, key[0 .. 8]);
204         des_key_schedule(*cast(uint[32]*)&m_round_key[32], key[8 .. 16]);
205         
206         if (length == 24) {
207             des_key_schedule(*cast(uint[32]*)&m_round_key[64], key[16 .. 24]);
208         }
209         else {
210             copyMem(&m_round_key[64], m_round_key.ptr, 32);
211         }
212     }
213 
214     SecureVector!uint m_round_key;
215 }
216 
217 /*
218 * DES Tables
219 */
220 
221 __gshared immutable uint[256] DES_SPBOX1 = [
222     0x01010400, 0x00000000, 0x00010000, 0x01010404, 0x01010004, 0x00010404,
223     0x00000004, 0x00010000, 0x00000400, 0x01010400, 0x01010404, 0x00000400,
224     0x01000404, 0x01010004, 0x01000000, 0x00000004, 0x00000404, 0x01000400,
225     0x01000400, 0x00010400, 0x00010400, 0x01010000, 0x01010000, 0x01000404,
226     0x00010004, 0x01000004, 0x01000004, 0x00010004, 0x00000000, 0x00000404,
227     0x00010404, 0x01000000, 0x00010000, 0x01010404, 0x00000004, 0x01010000,
228     0x01010400, 0x01000000, 0x01000000, 0x00000400, 0x01010004, 0x00010000,
229     0x00010400, 0x01000004, 0x00000400, 0x00000004, 0x01000404, 0x00010404,
230     0x01010404, 0x00010004, 0x01010000, 0x01000404, 0x01000004, 0x00000404,
231     0x00010404, 0x01010400, 0x00000404, 0x01000400, 0x01000400, 0x00000000,
232     0x00010004, 0x00010400, 0x00000000, 0x01010004, 0x01010400, 0x00000000,
233     0x00010000, 0x01010404, 0x01010004, 0x00010404, 0x00000004, 0x00010000,
234     0x00000400, 0x01010400, 0x01010404, 0x00000400, 0x01000404, 0x01010004,
235     0x01000000, 0x00000004, 0x00000404, 0x01000400, 0x01000400, 0x00010400,
236     0x00010400, 0x01010000, 0x01010000, 0x01000404, 0x00010004, 0x01000004,
237     0x01000004, 0x00010004, 0x00000000, 0x00000404, 0x00010404, 0x01000000,
238     0x00010000, 0x01010404, 0x00000004, 0x01010000, 0x01010400, 0x01000000,
239     0x01000000, 0x00000400, 0x01010004, 0x00010000, 0x00010400, 0x01000004,
240     0x00000400, 0x00000004, 0x01000404, 0x00010404, 0x01010404, 0x00010004,
241     0x01010000, 0x01000404, 0x01000004, 0x00000404, 0x00010404, 0x01010400,
242     0x00000404, 0x01000400, 0x01000400, 0x00000000, 0x00010004, 0x00010400,
243     0x00000000, 0x01010004, 0x01010400, 0x00000000, 0x00010000, 0x01010404,
244     0x01010004, 0x00010404, 0x00000004, 0x00010000, 0x00000400, 0x01010400,
245     0x01010404, 0x00000400, 0x01000404, 0x01010004, 0x01000000, 0x00000004,
246     0x00000404, 0x01000400, 0x01000400, 0x00010400, 0x00010400, 0x01010000,
247     0x01010000, 0x01000404, 0x00010004, 0x01000004, 0x01000004, 0x00010004,
248     0x00000000, 0x00000404, 0x00010404, 0x01000000, 0x00010000, 0x01010404,
249     0x00000004, 0x01010000, 0x01010400, 0x01000000, 0x01000000, 0x00000400,
250     0x01010004, 0x00010000, 0x00010400, 0x01000004, 0x00000400, 0x00000004,
251     0x01000404, 0x00010404, 0x01010404, 0x00010004, 0x01010000, 0x01000404,
252     0x01000004, 0x00000404, 0x00010404, 0x01010400, 0x00000404, 0x01000400,
253     0x01000400, 0x00000000, 0x00010004, 0x00010400, 0x00000000, 0x01010004,
254     0x01010400, 0x00000000, 0x00010000, 0x01010404, 0x01010004, 0x00010404,
255     0x00000004, 0x00010000, 0x00000400, 0x01010400, 0x01010404, 0x00000400,
256     0x01000404, 0x01010004, 0x01000000, 0x00000004, 0x00000404, 0x01000400,
257     0x01000400, 0x00010400, 0x00010400, 0x01010000, 0x01010000, 0x01000404,
258     0x00010004, 0x01000004, 0x01000004, 0x00010004, 0x00000000, 0x00000404,
259     0x00010404, 0x01000000, 0x00010000, 0x01010404, 0x00000004, 0x01010000,
260     0x01010400, 0x01000000, 0x01000000, 0x00000400, 0x01010004, 0x00010000,
261     0x00010400, 0x01000004, 0x00000400, 0x00000004, 0x01000404, 0x00010404,
262     0x01010404, 0x00010004, 0x01010000, 0x01000404, 0x01000004, 0x00000404,
263     0x00010404, 0x01010400, 0x00000404, 0x01000400, 0x01000400, 0x00000000,
264     0x00010004, 0x00010400, 0x00000000, 0x01010004 ];
265 
266 __gshared immutable uint[256] DES_SPBOX2 = [
267     0x80108020, 0x80008000, 0x00008000, 0x00108020, 0x00100000, 0x00000020,
268     0x80100020, 0x80008020, 0x80000020, 0x80108020, 0x80108000, 0x80000000,
269     0x80008000, 0x00100000, 0x00000020, 0x80100020, 0x00108000, 0x00100020,
270     0x80008020, 0x00000000, 0x80000000, 0x00008000, 0x00108020, 0x80100000,
271     0x00100020, 0x80000020, 0x00000000, 0x00108000, 0x00008020, 0x80108000,
272     0x80100000, 0x00008020, 0x00000000, 0x00108020, 0x80100020, 0x00100000,
273     0x80008020, 0x80100000, 0x80108000, 0x00008000, 0x80100000, 0x80008000,
274     0x00000020, 0x80108020, 0x00108020, 0x00000020, 0x00008000, 0x80000000,
275     0x00008020, 0x80108000, 0x00100000, 0x80000020, 0x00100020, 0x80008020,
276     0x80000020, 0x00100020, 0x00108000, 0x00000000, 0x80008000, 0x00008020,
277     0x80000000, 0x80100020, 0x80108020, 0x00108000, 0x80108020, 0x80008000,
278     0x00008000, 0x00108020, 0x00100000, 0x00000020, 0x80100020, 0x80008020,
279     0x80000020, 0x80108020, 0x80108000, 0x80000000, 0x80008000, 0x00100000,
280     0x00000020, 0x80100020, 0x00108000, 0x00100020, 0x80008020, 0x00000000,
281     0x80000000, 0x00008000, 0x00108020, 0x80100000, 0x00100020, 0x80000020,
282     0x00000000, 0x00108000, 0x00008020, 0x80108000, 0x80100000, 0x00008020,
283     0x00000000, 0x00108020, 0x80100020, 0x00100000, 0x80008020, 0x80100000,
284     0x80108000, 0x00008000, 0x80100000, 0x80008000, 0x00000020, 0x80108020,
285     0x00108020, 0x00000020, 0x00008000, 0x80000000, 0x00008020, 0x80108000,
286     0x00100000, 0x80000020, 0x00100020, 0x80008020, 0x80000020, 0x00100020,
287     0x00108000, 0x00000000, 0x80008000, 0x00008020, 0x80000000, 0x80100020,
288     0x80108020, 0x00108000, 0x80108020, 0x80008000, 0x00008000, 0x00108020,
289     0x00100000, 0x00000020, 0x80100020, 0x80008020, 0x80000020, 0x80108020,
290     0x80108000, 0x80000000, 0x80008000, 0x00100000, 0x00000020, 0x80100020,
291     0x00108000, 0x00100020, 0x80008020, 0x00000000, 0x80000000, 0x00008000,
292     0x00108020, 0x80100000, 0x00100020, 0x80000020, 0x00000000, 0x00108000,
293     0x00008020, 0x80108000, 0x80100000, 0x00008020, 0x00000000, 0x00108020,
294     0x80100020, 0x00100000, 0x80008020, 0x80100000, 0x80108000, 0x00008000,
295     0x80100000, 0x80008000, 0x00000020, 0x80108020, 0x00108020, 0x00000020,
296     0x00008000, 0x80000000, 0x00008020, 0x80108000, 0x00100000, 0x80000020,
297     0x00100020, 0x80008020, 0x80000020, 0x00100020, 0x00108000, 0x00000000,
298     0x80008000, 0x00008020, 0x80000000, 0x80100020, 0x80108020, 0x00108000,
299     0x80108020, 0x80008000, 0x00008000, 0x00108020, 0x00100000, 0x00000020,
300     0x80100020, 0x80008020, 0x80000020, 0x80108020, 0x80108000, 0x80000000,
301     0x80008000, 0x00100000, 0x00000020, 0x80100020, 0x00108000, 0x00100020,
302     0x80008020, 0x00000000, 0x80000000, 0x00008000, 0x00108020, 0x80100000,
303     0x00100020, 0x80000020, 0x00000000, 0x00108000, 0x00008020, 0x80108000,
304     0x80100000, 0x00008020, 0x00000000, 0x00108020, 0x80100020, 0x00100000,
305     0x80008020, 0x80100000, 0x80108000, 0x00008000, 0x80100000, 0x80008000,
306     0x00000020, 0x80108020, 0x00108020, 0x00000020, 0x00008000, 0x80000000,
307     0x00008020, 0x80108000, 0x00100000, 0x80000020, 0x00100020, 0x80008020,
308     0x80000020, 0x00100020, 0x00108000, 0x00000000, 0x80008000, 0x00008020,
309     0x80000000, 0x80100020, 0x80108020, 0x00108000 ];
310 
311 __gshared immutable uint[256] DES_SPBOX3 = [
312     0x00000208, 0x08020200, 0x00000000, 0x08020008, 0x08000200, 0x00000000,
313     0x00020208, 0x08000200, 0x00020008, 0x08000008, 0x08000008, 0x00020000,
314     0x08020208, 0x00020008, 0x08020000, 0x00000208, 0x08000000, 0x00000008,
315     0x08020200, 0x00000200, 0x00020200, 0x08020000, 0x08020008, 0x00020208,
316     0x08000208, 0x00020200, 0x00020000, 0x08000208, 0x00000008, 0x08020208,
317     0x00000200, 0x08000000, 0x08020200, 0x08000000, 0x00020008, 0x00000208,
318     0x00020000, 0x08020200, 0x08000200, 0x00000000, 0x00000200, 0x00020008,
319     0x08020208, 0x08000200, 0x08000008, 0x00000200, 0x00000000, 0x08020008,
320     0x08000208, 0x00020000, 0x08000000, 0x08020208, 0x00000008, 0x00020208,
321     0x00020200, 0x08000008, 0x08020000, 0x08000208, 0x00000208, 0x08020000,
322     0x00020208, 0x00000008, 0x08020008, 0x00020200, 0x00000208, 0x08020200,
323     0x00000000, 0x08020008, 0x08000200, 0x00000000, 0x00020208, 0x08000200,
324     0x00020008, 0x08000008, 0x08000008, 0x00020000, 0x08020208, 0x00020008,
325     0x08020000, 0x00000208, 0x08000000, 0x00000008, 0x08020200, 0x00000200,
326     0x00020200, 0x08020000, 0x08020008, 0x00020208, 0x08000208, 0x00020200,
327     0x00020000, 0x08000208, 0x00000008, 0x08020208, 0x00000200, 0x08000000,
328     0x08020200, 0x08000000, 0x00020008, 0x00000208, 0x00020000, 0x08020200,
329     0x08000200, 0x00000000, 0x00000200, 0x00020008, 0x08020208, 0x08000200,
330     0x08000008, 0x00000200, 0x00000000, 0x08020008, 0x08000208, 0x00020000,
331     0x08000000, 0x08020208, 0x00000008, 0x00020208, 0x00020200, 0x08000008,
332     0x08020000, 0x08000208, 0x00000208, 0x08020000, 0x00020208, 0x00000008,
333     0x08020008, 0x00020200, 0x00000208, 0x08020200, 0x00000000, 0x08020008,
334     0x08000200, 0x00000000, 0x00020208, 0x08000200, 0x00020008, 0x08000008,
335     0x08000008, 0x00020000, 0x08020208, 0x00020008, 0x08020000, 0x00000208,
336     0x08000000, 0x00000008, 0x08020200, 0x00000200, 0x00020200, 0x08020000,
337     0x08020008, 0x00020208, 0x08000208, 0x00020200, 0x00020000, 0x08000208,
338     0x00000008, 0x08020208, 0x00000200, 0x08000000, 0x08020200, 0x08000000,
339     0x00020008, 0x00000208, 0x00020000, 0x08020200, 0x08000200, 0x00000000,
340     0x00000200, 0x00020008, 0x08020208, 0x08000200, 0x08000008, 0x00000200,
341     0x00000000, 0x08020008, 0x08000208, 0x00020000, 0x08000000, 0x08020208,
342     0x00000008, 0x00020208, 0x00020200, 0x08000008, 0x08020000, 0x08000208,
343     0x00000208, 0x08020000, 0x00020208, 0x00000008, 0x08020008, 0x00020200,
344     0x00000208, 0x08020200, 0x00000000, 0x08020008, 0x08000200, 0x00000000,
345     0x00020208, 0x08000200, 0x00020008, 0x08000008, 0x08000008, 0x00020000,
346     0x08020208, 0x00020008, 0x08020000, 0x00000208, 0x08000000, 0x00000008,
347     0x08020200, 0x00000200, 0x00020200, 0x08020000, 0x08020008, 0x00020208,
348     0x08000208, 0x00020200, 0x00020000, 0x08000208, 0x00000008, 0x08020208,
349     0x00000200, 0x08000000, 0x08020200, 0x08000000, 0x00020008, 0x00000208,
350     0x00020000, 0x08020200, 0x08000200, 0x00000000, 0x00000200, 0x00020008,
351     0x08020208, 0x08000200, 0x08000008, 0x00000200, 0x00000000, 0x08020008,
352     0x08000208, 0x00020000, 0x08000000, 0x08020208, 0x00000008, 0x00020208,
353     0x00020200, 0x08000008, 0x08020000, 0x08000208, 0x00000208, 0x08020000,
354     0x00020208, 0x00000008, 0x08020008, 0x00020200 ];
355 
356 __gshared immutable uint[256] DES_SPBOX4 = [
357     0x00802001, 0x00002081, 0x00002081, 0x00000080, 0x00802080, 0x00800081,
358     0x00800001, 0x00002001, 0x00000000, 0x00802000, 0x00802000, 0x00802081,
359     0x00000081, 0x00000000, 0x00800080, 0x00800001, 0x00000001, 0x00002000,
360     0x00800000, 0x00802001, 0x00000080, 0x00800000, 0x00002001, 0x00002080,
361     0x00800081, 0x00000001, 0x00002080, 0x00800080, 0x00002000, 0x00802080,
362     0x00802081, 0x00000081, 0x00800080, 0x00800001, 0x00802000, 0x00802081,
363     0x00000081, 0x00000000, 0x00000000, 0x00802000, 0x00002080, 0x00800080,
364     0x00800081, 0x00000001, 0x00802001, 0x00002081, 0x00002081, 0x00000080,
365     0x00802081, 0x00000081, 0x00000001, 0x00002000, 0x00800001, 0x00002001,
366     0x00802080, 0x00800081, 0x00002001, 0x00002080, 0x00800000, 0x00802001,
367     0x00000080, 0x00800000, 0x00002000, 0x00802080, 0x00802001, 0x00002081,
368     0x00002081, 0x00000080, 0x00802080, 0x00800081, 0x00800001, 0x00002001,
369     0x00000000, 0x00802000, 0x00802000, 0x00802081, 0x00000081, 0x00000000,
370     0x00800080, 0x00800001, 0x00000001, 0x00002000, 0x00800000, 0x00802001,
371     0x00000080, 0x00800000, 0x00002001, 0x00002080, 0x00800081, 0x00000001,
372     0x00002080, 0x00800080, 0x00002000, 0x00802080, 0x00802081, 0x00000081,
373     0x00800080, 0x00800001, 0x00802000, 0x00802081, 0x00000081, 0x00000000,
374     0x00000000, 0x00802000, 0x00002080, 0x00800080, 0x00800081, 0x00000001,
375     0x00802001, 0x00002081, 0x00002081, 0x00000080, 0x00802081, 0x00000081,
376     0x00000001, 0x00002000, 0x00800001, 0x00002001, 0x00802080, 0x00800081,
377     0x00002001, 0x00002080, 0x00800000, 0x00802001, 0x00000080, 0x00800000,
378     0x00002000, 0x00802080, 0x00802001, 0x00002081, 0x00002081, 0x00000080,
379     0x00802080, 0x00800081, 0x00800001, 0x00002001, 0x00000000, 0x00802000,
380     0x00802000, 0x00802081, 0x00000081, 0x00000000, 0x00800080, 0x00800001,
381     0x00000001, 0x00002000, 0x00800000, 0x00802001, 0x00000080, 0x00800000,
382     0x00002001, 0x00002080, 0x00800081, 0x00000001, 0x00002080, 0x00800080,
383     0x00002000, 0x00802080, 0x00802081, 0x00000081, 0x00800080, 0x00800001,
384     0x00802000, 0x00802081, 0x00000081, 0x00000000, 0x00000000, 0x00802000,
385     0x00002080, 0x00800080, 0x00800081, 0x00000001, 0x00802001, 0x00002081,
386     0x00002081, 0x00000080, 0x00802081, 0x00000081, 0x00000001, 0x00002000,
387     0x00800001, 0x00002001, 0x00802080, 0x00800081, 0x00002001, 0x00002080,
388     0x00800000, 0x00802001, 0x00000080, 0x00800000, 0x00002000, 0x00802080,
389     0x00802001, 0x00002081, 0x00002081, 0x00000080, 0x00802080, 0x00800081,
390     0x00800001, 0x00002001, 0x00000000, 0x00802000, 0x00802000, 0x00802081,
391     0x00000081, 0x00000000, 0x00800080, 0x00800001, 0x00000001, 0x00002000,
392     0x00800000, 0x00802001, 0x00000080, 0x00800000, 0x00002001, 0x00002080,
393     0x00800081, 0x00000001, 0x00002080, 0x00800080, 0x00002000, 0x00802080,
394     0x00802081, 0x00000081, 0x00800080, 0x00800001, 0x00802000, 0x00802081,
395     0x00000081, 0x00000000, 0x00000000, 0x00802000, 0x00002080, 0x00800080,
396     0x00800081, 0x00000001, 0x00802001, 0x00002081, 0x00002081, 0x00000080,
397     0x00802081, 0x00000081, 0x00000001, 0x00002000, 0x00800001, 0x00002001,
398     0x00802080, 0x00800081, 0x00002001, 0x00002080, 0x00800000, 0x00802001,
399     0x00000080, 0x00800000, 0x00002000, 0x00802080 ];
400 
401 __gshared immutable uint[256] DES_SPBOX5 = [
402     0x00000100, 0x02080100, 0x02080000, 0x42000100, 0x00080000, 0x00000100,
403     0x40000000, 0x02080000, 0x40080100, 0x00080000, 0x02000100, 0x40080100,
404     0x42000100, 0x42080000, 0x00080100, 0x40000000, 0x02000000, 0x40080000,
405     0x40080000, 0x00000000, 0x40000100, 0x42080100, 0x42080100, 0x02000100,
406     0x42080000, 0x40000100, 0x00000000, 0x42000000, 0x02080100, 0x02000000,
407     0x42000000, 0x00080100, 0x00080000, 0x42000100, 0x00000100, 0x02000000,
408     0x40000000, 0x02080000, 0x42000100, 0x40080100, 0x02000100, 0x40000000,
409     0x42080000, 0x02080100, 0x40080100, 0x00000100, 0x02000000, 0x42080000,
410     0x42080100, 0x00080100, 0x42000000, 0x42080100, 0x02080000, 0x00000000,
411     0x40080000, 0x42000000, 0x00080100, 0x02000100, 0x40000100, 0x00080000,
412     0x00000000, 0x40080000, 0x02080100, 0x40000100, 0x00000100, 0x02080100,
413     0x02080000, 0x42000100, 0x00080000, 0x00000100, 0x40000000, 0x02080000,
414     0x40080100, 0x00080000, 0x02000100, 0x40080100, 0x42000100, 0x42080000,
415     0x00080100, 0x40000000, 0x02000000, 0x40080000, 0x40080000, 0x00000000,
416     0x40000100, 0x42080100, 0x42080100, 0x02000100, 0x42080000, 0x40000100,
417     0x00000000, 0x42000000, 0x02080100, 0x02000000, 0x42000000, 0x00080100,
418     0x00080000, 0x42000100, 0x00000100, 0x02000000, 0x40000000, 0x02080000,
419     0x42000100, 0x40080100, 0x02000100, 0x40000000, 0x42080000, 0x02080100,
420     0x40080100, 0x00000100, 0x02000000, 0x42080000, 0x42080100, 0x00080100,
421     0x42000000, 0x42080100, 0x02080000, 0x00000000, 0x40080000, 0x42000000,
422     0x00080100, 0x02000100, 0x40000100, 0x00080000, 0x00000000, 0x40080000,
423     0x02080100, 0x40000100, 0x00000100, 0x02080100, 0x02080000, 0x42000100,
424     0x00080000, 0x00000100, 0x40000000, 0x02080000, 0x40080100, 0x00080000,
425     0x02000100, 0x40080100, 0x42000100, 0x42080000, 0x00080100, 0x40000000,
426     0x02000000, 0x40080000, 0x40080000, 0x00000000, 0x40000100, 0x42080100,
427     0x42080100, 0x02000100, 0x42080000, 0x40000100, 0x00000000, 0x42000000,
428     0x02080100, 0x02000000, 0x42000000, 0x00080100, 0x00080000, 0x42000100,
429     0x00000100, 0x02000000, 0x40000000, 0x02080000, 0x42000100, 0x40080100,
430     0x02000100, 0x40000000, 0x42080000, 0x02080100, 0x40080100, 0x00000100,
431     0x02000000, 0x42080000, 0x42080100, 0x00080100, 0x42000000, 0x42080100,
432     0x02080000, 0x00000000, 0x40080000, 0x42000000, 0x00080100, 0x02000100,
433     0x40000100, 0x00080000, 0x00000000, 0x40080000, 0x02080100, 0x40000100,
434     0x00000100, 0x02080100, 0x02080000, 0x42000100, 0x00080000, 0x00000100,
435     0x40000000, 0x02080000, 0x40080100, 0x00080000, 0x02000100, 0x40080100,
436     0x42000100, 0x42080000, 0x00080100, 0x40000000, 0x02000000, 0x40080000,
437     0x40080000, 0x00000000, 0x40000100, 0x42080100, 0x42080100, 0x02000100,
438     0x42080000, 0x40000100, 0x00000000, 0x42000000, 0x02080100, 0x02000000,
439     0x42000000, 0x00080100, 0x00080000, 0x42000100, 0x00000100, 0x02000000,
440     0x40000000, 0x02080000, 0x42000100, 0x40080100, 0x02000100, 0x40000000,
441     0x42080000, 0x02080100, 0x40080100, 0x00000100, 0x02000000, 0x42080000,
442     0x42080100, 0x00080100, 0x42000000, 0x42080100, 0x02080000, 0x00000000,
443     0x40080000, 0x42000000, 0x00080100, 0x02000100, 0x40000100, 0x00080000,
444     0x00000000, 0x40080000, 0x02080100, 0x40000100 ];
445 
446 __gshared immutable uint[256] DES_SPBOX6 = [
447     0x20000010, 0x20400000, 0x00004000, 0x20404010, 0x20400000, 0x00000010,
448     0x20404010, 0x00400000, 0x20004000, 0x00404010, 0x00400000, 0x20000010,
449     0x00400010, 0x20004000, 0x20000000, 0x00004010, 0x00000000, 0x00400010,
450     0x20004010, 0x00004000, 0x00404000, 0x20004010, 0x00000010, 0x20400010,
451     0x20400010, 0x00000000, 0x00404010, 0x20404000, 0x00004010, 0x00404000,
452     0x20404000, 0x20000000, 0x20004000, 0x00000010, 0x20400010, 0x00404000,
453     0x20404010, 0x00400000, 0x00004010, 0x20000010, 0x00400000, 0x20004000,
454     0x20000000, 0x00004010, 0x20000010, 0x20404010, 0x00404000, 0x20400000,
455     0x00404010, 0x20404000, 0x00000000, 0x20400010, 0x00000010, 0x00004000,
456     0x20400000, 0x00404010, 0x00004000, 0x00400010, 0x20004010, 0x00000000,
457     0x20404000, 0x20000000, 0x00400010, 0x20004010, 0x20000010, 0x20400000,
458     0x00004000, 0x20404010, 0x20400000, 0x00000010, 0x20404010, 0x00400000,
459     0x20004000, 0x00404010, 0x00400000, 0x20000010, 0x00400010, 0x20004000,
460     0x20000000, 0x00004010, 0x00000000, 0x00400010, 0x20004010, 0x00004000,
461     0x00404000, 0x20004010, 0x00000010, 0x20400010, 0x20400010, 0x00000000,
462     0x00404010, 0x20404000, 0x00004010, 0x00404000, 0x20404000, 0x20000000,
463     0x20004000, 0x00000010, 0x20400010, 0x00404000, 0x20404010, 0x00400000,
464     0x00004010, 0x20000010, 0x00400000, 0x20004000, 0x20000000, 0x00004010,
465     0x20000010, 0x20404010, 0x00404000, 0x20400000, 0x00404010, 0x20404000,
466     0x00000000, 0x20400010, 0x00000010, 0x00004000, 0x20400000, 0x00404010,
467     0x00004000, 0x00400010, 0x20004010, 0x00000000, 0x20404000, 0x20000000,
468     0x00400010, 0x20004010, 0x20000010, 0x20400000, 0x00004000, 0x20404010,
469     0x20400000, 0x00000010, 0x20404010, 0x00400000, 0x20004000, 0x00404010,
470     0x00400000, 0x20000010, 0x00400010, 0x20004000, 0x20000000, 0x00004010,
471     0x00000000, 0x00400010, 0x20004010, 0x00004000, 0x00404000, 0x20004010,
472     0x00000010, 0x20400010, 0x20400010, 0x00000000, 0x00404010, 0x20404000,
473     0x00004010, 0x00404000, 0x20404000, 0x20000000, 0x20004000, 0x00000010,
474     0x20400010, 0x00404000, 0x20404010, 0x00400000, 0x00004010, 0x20000010,
475     0x00400000, 0x20004000, 0x20000000, 0x00004010, 0x20000010, 0x20404010,
476     0x00404000, 0x20400000, 0x00404010, 0x20404000, 0x00000000, 0x20400010,
477     0x00000010, 0x00004000, 0x20400000, 0x00404010, 0x00004000, 0x00400010,
478     0x20004010, 0x00000000, 0x20404000, 0x20000000, 0x00400010, 0x20004010,
479     0x20000010, 0x20400000, 0x00004000, 0x20404010, 0x20400000, 0x00000010,
480     0x20404010, 0x00400000, 0x20004000, 0x00404010, 0x00400000, 0x20000010,
481     0x00400010, 0x20004000, 0x20000000, 0x00004010, 0x00000000, 0x00400010,
482     0x20004010, 0x00004000, 0x00404000, 0x20004010, 0x00000010, 0x20400010,
483     0x20400010, 0x00000000, 0x00404010, 0x20404000, 0x00004010, 0x00404000,
484     0x20404000, 0x20000000, 0x20004000, 0x00000010, 0x20400010, 0x00404000,
485     0x20404010, 0x00400000, 0x00004010, 0x20000010, 0x00400000, 0x20004000,
486     0x20000000, 0x00004010, 0x20000010, 0x20404010, 0x00404000, 0x20400000,
487     0x00404010, 0x20404000, 0x00000000, 0x20400010, 0x00000010, 0x00004000,
488     0x20400000, 0x00404010, 0x00004000, 0x00400010, 0x20004010, 0x00000000,
489     0x20404000, 0x20000000, 0x00400010, 0x20004010 ];
490 
491 __gshared immutable uint[256] DES_SPBOX7 = [
492     0x00200000, 0x04200002, 0x04000802, 0x00000000, 0x00000800, 0x04000802,
493     0x00200802, 0x04200800, 0x04200802, 0x00200000, 0x00000000, 0x04000002,
494     0x00000002, 0x04000000, 0x04200002, 0x00000802, 0x04000800, 0x00200802,
495     0x00200002, 0x04000800, 0x04000002, 0x04200000, 0x04200800, 0x00200002,
496     0x04200000, 0x00000800, 0x00000802, 0x04200802, 0x00200800, 0x00000002,
497     0x04000000, 0x00200800, 0x04000000, 0x00200800, 0x00200000, 0x04000802,
498     0x04000802, 0x04200002, 0x04200002, 0x00000002, 0x00200002, 0x04000000,
499     0x04000800, 0x00200000, 0x04200800, 0x00000802, 0x00200802, 0x04200800,
500     0x00000802, 0x04000002, 0x04200802, 0x04200000, 0x00200800, 0x00000000,
501     0x00000002, 0x04200802, 0x00000000, 0x00200802, 0x04200000, 0x00000800,
502     0x04000002, 0x04000800, 0x00000800, 0x00200002, 0x00200000, 0x04200002,
503     0x04000802, 0x00000000, 0x00000800, 0x04000802, 0x00200802, 0x04200800,
504     0x04200802, 0x00200000, 0x00000000, 0x04000002, 0x00000002, 0x04000000,
505     0x04200002, 0x00000802, 0x04000800, 0x00200802, 0x00200002, 0x04000800,
506     0x04000002, 0x04200000, 0x04200800, 0x00200002, 0x04200000, 0x00000800,
507     0x00000802, 0x04200802, 0x00200800, 0x00000002, 0x04000000, 0x00200800,
508     0x04000000, 0x00200800, 0x00200000, 0x04000802, 0x04000802, 0x04200002,
509     0x04200002, 0x00000002, 0x00200002, 0x04000000, 0x04000800, 0x00200000,
510     0x04200800, 0x00000802, 0x00200802, 0x04200800, 0x00000802, 0x04000002,
511     0x04200802, 0x04200000, 0x00200800, 0x00000000, 0x00000002, 0x04200802,
512     0x00000000, 0x00200802, 0x04200000, 0x00000800, 0x04000002, 0x04000800,
513     0x00000800, 0x00200002, 0x00200000, 0x04200002, 0x04000802, 0x00000000,
514     0x00000800, 0x04000802, 0x00200802, 0x04200800, 0x04200802, 0x00200000,
515     0x00000000, 0x04000002, 0x00000002, 0x04000000, 0x04200002, 0x00000802,
516     0x04000800, 0x00200802, 0x00200002, 0x04000800, 0x04000002, 0x04200000,
517     0x04200800, 0x00200002, 0x04200000, 0x00000800, 0x00000802, 0x04200802,
518     0x00200800, 0x00000002, 0x04000000, 0x00200800, 0x04000000, 0x00200800,
519     0x00200000, 0x04000802, 0x04000802, 0x04200002, 0x04200002, 0x00000002,
520     0x00200002, 0x04000000, 0x04000800, 0x00200000, 0x04200800, 0x00000802,
521     0x00200802, 0x04200800, 0x00000802, 0x04000002, 0x04200802, 0x04200000,
522     0x00200800, 0x00000000, 0x00000002, 0x04200802, 0x00000000, 0x00200802,
523     0x04200000, 0x00000800, 0x04000002, 0x04000800, 0x00000800, 0x00200002,
524     0x00200000, 0x04200002, 0x04000802, 0x00000000, 0x00000800, 0x04000802,
525     0x00200802, 0x04200800, 0x04200802, 0x00200000, 0x00000000, 0x04000002,
526     0x00000002, 0x04000000, 0x04200002, 0x00000802, 0x04000800, 0x00200802,
527     0x00200002, 0x04000800, 0x04000002, 0x04200000, 0x04200800, 0x00200002,
528     0x04200000, 0x00000800, 0x00000802, 0x04200802, 0x00200800, 0x00000002,
529     0x04000000, 0x00200800, 0x04000000, 0x00200800, 0x00200000, 0x04000802,
530     0x04000802, 0x04200002, 0x04200002, 0x00000002, 0x00200002, 0x04000000,
531     0x04000800, 0x00200000, 0x04200800, 0x00000802, 0x00200802, 0x04200800,
532     0x00000802, 0x04000002, 0x04200802, 0x04200000, 0x00200800, 0x00000000,
533     0x00000002, 0x04200802, 0x00000000, 0x00200802, 0x04200000, 0x00000800,
534     0x04000002, 0x04000800, 0x00000800, 0x00200002 ];
535 
536 __gshared immutable uint[256] DES_SPBOX8 = [
537     0x10001040, 0x00001000, 0x00040000, 0x10041040, 0x10000000, 0x10001040,
538     0x00000040, 0x10000000, 0x00040040, 0x10040000, 0x10041040, 0x00041000,
539     0x10041000, 0x00041040, 0x00001000, 0x00000040, 0x10040000, 0x10000040,
540     0x10001000, 0x00001040, 0x00041000, 0x00040040, 0x10040040, 0x10041000,
541     0x00001040, 0x00000000, 0x00000000, 0x10040040, 0x10000040, 0x10001000,
542     0x00041040, 0x00040000, 0x00041040, 0x00040000, 0x10041000, 0x00001000,
543     0x00000040, 0x10040040, 0x00001000, 0x00041040, 0x10001000, 0x00000040,
544     0x10000040, 0x10040000, 0x10040040, 0x10000000, 0x00040000, 0x10001040,
545     0x00000000, 0x10041040, 0x00040040, 0x10000040, 0x10040000, 0x10001000,
546     0x10001040, 0x00000000, 0x10041040, 0x00041000, 0x00041000, 0x00001040,
547     0x00001040, 0x00040040, 0x10000000, 0x10041000, 0x10001040, 0x00001000,
548     0x00040000, 0x10041040, 0x10000000, 0x10001040, 0x00000040, 0x10000000,
549     0x00040040, 0x10040000, 0x10041040, 0x00041000, 0x10041000, 0x00041040,
550     0x00001000, 0x00000040, 0x10040000, 0x10000040, 0x10001000, 0x00001040,
551     0x00041000, 0x00040040, 0x10040040, 0x10041000, 0x00001040, 0x00000000,
552     0x00000000, 0x10040040, 0x10000040, 0x10001000, 0x00041040, 0x00040000,
553     0x00041040, 0x00040000, 0x10041000, 0x00001000, 0x00000040, 0x10040040,
554     0x00001000, 0x00041040, 0x10001000, 0x00000040, 0x10000040, 0x10040000,
555     0x10040040, 0x10000000, 0x00040000, 0x10001040, 0x00000000, 0x10041040,
556     0x00040040, 0x10000040, 0x10040000, 0x10001000, 0x10001040, 0x00000000,
557     0x10041040, 0x00041000, 0x00041000, 0x00001040, 0x00001040, 0x00040040,
558     0x10000000, 0x10041000, 0x10001040, 0x00001000, 0x00040000, 0x10041040,
559     0x10000000, 0x10001040, 0x00000040, 0x10000000, 0x00040040, 0x10040000,
560     0x10041040, 0x00041000, 0x10041000, 0x00041040, 0x00001000, 0x00000040,
561     0x10040000, 0x10000040, 0x10001000, 0x00001040, 0x00041000, 0x00040040,
562     0x10040040, 0x10041000, 0x00001040, 0x00000000, 0x00000000, 0x10040040,
563     0x10000040, 0x10001000, 0x00041040, 0x00040000, 0x00041040, 0x00040000,
564     0x10041000, 0x00001000, 0x00000040, 0x10040040, 0x00001000, 0x00041040,
565     0x10001000, 0x00000040, 0x10000040, 0x10040000, 0x10040040, 0x10000000,
566     0x00040000, 0x10001040, 0x00000000, 0x10041040, 0x00040040, 0x10000040,
567     0x10040000, 0x10001000, 0x10001040, 0x00000000, 0x10041040, 0x00041000,
568     0x00041000, 0x00001040, 0x00001040, 0x00040040, 0x10000000, 0x10041000,
569     0x10001040, 0x00001000, 0x00040000, 0x10041040, 0x10000000, 0x10001040,
570     0x00000040, 0x10000000, 0x00040040, 0x10040000, 0x10041040, 0x00041000,
571     0x10041000, 0x00041040, 0x00001000, 0x00000040, 0x10040000, 0x10000040,
572     0x10001000, 0x00001040, 0x00041000, 0x00040040, 0x10040040, 0x10041000,
573     0x00001040, 0x00000000, 0x00000000, 0x10040040, 0x10000040, 0x10001000,
574     0x00041040, 0x00040000, 0x00041040, 0x00040000, 0x10041000, 0x00001000,
575     0x00000040, 0x10040040, 0x00001000, 0x00041040, 0x10001000, 0x00000040,
576     0x10000040, 0x10040000, 0x10040040, 0x10000000, 0x00040000, 0x10001040,
577     0x00000000, 0x10041040, 0x00040040, 0x10000040, 0x10040000, 0x10001000,
578     0x10001040, 0x00000000, 0x10041040, 0x00041000, 0x00041000, 0x00001040,
579     0x00001040, 0x00040040, 0x10000000, 0x10041000 ];
580 
581 __gshared immutable ulong[256] DES_IPTAB1 = [
582     0x0000000000000000, 0x0000000200000000, 0x0000000000000002, 0x0000000200000002,
583     0x0000020000000000, 0x0000020200000000, 0x0000020000000002, 0x0000020200000002,
584     0x0000000000000200, 0x0000000200000200, 0x0000000000000202, 0x0000000200000202,
585     0x0000020000000200, 0x0000020200000200, 0x0000020000000202, 0x0000020200000202,
586     0x0002000000000000, 0x0002000200000000, 0x0002000000000002, 0x0002000200000002,
587     0x0002020000000000, 0x0002020200000000, 0x0002020000000002, 0x0002020200000002,
588     0x0002000000000200, 0x0002000200000200, 0x0002000000000202, 0x0002000200000202,
589     0x0002020000000200, 0x0002020200000200, 0x0002020000000202, 0x0002020200000202,
590     0x0000000000020000, 0x0000000200020000, 0x0000000000020002, 0x0000000200020002,
591     0x0000020000020000, 0x0000020200020000, 0x0000020000020002, 0x0000020200020002,
592     0x0000000000020200, 0x0000000200020200, 0x0000000000020202, 0x0000000200020202,
593     0x0000020000020200, 0x0000020200020200, 0x0000020000020202, 0x0000020200020202,
594     0x0002000000020000, 0x0002000200020000, 0x0002000000020002, 0x0002000200020002,
595     0x0002020000020000, 0x0002020200020000, 0x0002020000020002, 0x0002020200020002,
596     0x0002000000020200, 0x0002000200020200, 0x0002000000020202, 0x0002000200020202,
597     0x0002020000020200, 0x0002020200020200, 0x0002020000020202, 0x0002020200020202,
598     0x0200000000000000, 0x0200000200000000, 0x0200000000000002, 0x0200000200000002,
599     0x0200020000000000, 0x0200020200000000, 0x0200020000000002, 0x0200020200000002,
600     0x0200000000000200, 0x0200000200000200, 0x0200000000000202, 0x0200000200000202,
601     0x0200020000000200, 0x0200020200000200, 0x0200020000000202, 0x0200020200000202,
602     0x0202000000000000, 0x0202000200000000, 0x0202000000000002, 0x0202000200000002,
603     0x0202020000000000, 0x0202020200000000, 0x0202020000000002, 0x0202020200000002,
604     0x0202000000000200, 0x0202000200000200, 0x0202000000000202, 0x0202000200000202,
605     0x0202020000000200, 0x0202020200000200, 0x0202020000000202, 0x0202020200000202,
606     0x0200000000020000, 0x0200000200020000, 0x0200000000020002, 0x0200000200020002,
607     0x0200020000020000, 0x0200020200020000, 0x0200020000020002, 0x0200020200020002,
608     0x0200000000020200, 0x0200000200020200, 0x0200000000020202, 0x0200000200020202,
609     0x0200020000020200, 0x0200020200020200, 0x0200020000020202, 0x0200020200020202,
610     0x0202000000020000, 0x0202000200020000, 0x0202000000020002, 0x0202000200020002,
611     0x0202020000020000, 0x0202020200020000, 0x0202020000020002, 0x0202020200020002,
612     0x0202000000020200, 0x0202000200020200, 0x0202000000020202, 0x0202000200020202,
613     0x0202020000020200, 0x0202020200020200, 0x0202020000020202, 0x0202020200020202,
614     0x0000000002000000, 0x0000000202000000, 0x0000000002000002, 0x0000000202000002,
615     0x0000020002000000, 0x0000020202000000, 0x0000020002000002, 0x0000020202000002,
616     0x0000000002000200, 0x0000000202000200, 0x0000000002000202, 0x0000000202000202,
617     0x0000020002000200, 0x0000020202000200, 0x0000020002000202, 0x0000020202000202,
618     0x0002000002000000, 0x0002000202000000, 0x0002000002000002, 0x0002000202000002,
619     0x0002020002000000, 0x0002020202000000, 0x0002020002000002, 0x0002020202000002,
620     0x0002000002000200, 0x0002000202000200, 0x0002000002000202, 0x0002000202000202,
621     0x0002020002000200, 0x0002020202000200, 0x0002020002000202, 0x0002020202000202,
622     0x0000000002020000, 0x0000000202020000, 0x0000000002020002, 0x0000000202020002,
623     0x0000020002020000, 0x0000020202020000, 0x0000020002020002, 0x0000020202020002,
624     0x0000000002020200, 0x0000000202020200, 0x0000000002020202, 0x0000000202020202,
625     0x0000020002020200, 0x0000020202020200, 0x0000020002020202, 0x0000020202020202,
626     0x0002000002020000, 0x0002000202020000, 0x0002000002020002, 0x0002000202020002,
627     0x0002020002020000, 0x0002020202020000, 0x0002020002020002, 0x0002020202020002,
628     0x0002000002020200, 0x0002000202020200, 0x0002000002020202, 0x0002000202020202,
629     0x0002020002020200, 0x0002020202020200, 0x0002020002020202, 0x0002020202020202,
630     0x0200000002000000, 0x0200000202000000, 0x0200000002000002, 0x0200000202000002,
631     0x0200020002000000, 0x0200020202000000, 0x0200020002000002, 0x0200020202000002,
632     0x0200000002000200, 0x0200000202000200, 0x0200000002000202, 0x0200000202000202,
633     0x0200020002000200, 0x0200020202000200, 0x0200020002000202, 0x0200020202000202,
634     0x0202000002000000, 0x0202000202000000, 0x0202000002000002, 0x0202000202000002,
635     0x0202020002000000, 0x0202020202000000, 0x0202020002000002, 0x0202020202000002,
636     0x0202000002000200, 0x0202000202000200, 0x0202000002000202, 0x0202000202000202,
637     0x0202020002000200, 0x0202020202000200, 0x0202020002000202, 0x0202020202000202,
638     0x0200000002020000, 0x0200000202020000, 0x0200000002020002, 0x0200000202020002,
639     0x0200020002020000, 0x0200020202020000, 0x0200020002020002, 0x0200020202020002,
640     0x0200000002020200, 0x0200000202020200, 0x0200000002020202, 0x0200000202020202,
641     0x0200020002020200, 0x0200020202020200, 0x0200020002020202, 0x0200020202020202,
642     0x0202000002020000, 0x0202000202020000, 0x0202000002020002, 0x0202000202020002,
643     0x0202020002020000, 0x0202020202020000, 0x0202020002020002, 0x0202020202020002,
644     0x0202000002020200, 0x0202000202020200, 0x0202000002020202, 0x0202000202020202,
645     0x0202020002020200, 0x0202020202020200, 0x0202020002020202, 0x0202020202020202 ];
646 
647 __gshared immutable ulong[256] DES_IPTAB2 = [
648     0x0000000000000000, 0x0000010000000000, 0x0000000000000100, 0x0000010000000100,
649     0x0001000000000000, 0x0001010000000000, 0x0001000000000100, 0x0001010000000100,
650     0x0000000000010000, 0x0000010000010000, 0x0000000000010100, 0x0000010000010100,
651     0x0001000000010000, 0x0001010000010000, 0x0001000000010100, 0x0001010000010100,
652     0x0100000000000000, 0x0100010000000000, 0x0100000000000100, 0x0100010000000100,
653     0x0101000000000000, 0x0101010000000000, 0x0101000000000100, 0x0101010000000100,
654     0x0100000000010000, 0x0100010000010000, 0x0100000000010100, 0x0100010000010100,
655     0x0101000000010000, 0x0101010000010000, 0x0101000000010100, 0x0101010000010100,
656     0x0000000001000000, 0x0000010001000000, 0x0000000001000100, 0x0000010001000100,
657     0x0001000001000000, 0x0001010001000000, 0x0001000001000100, 0x0001010001000100,
658     0x0000000001010000, 0x0000010001010000, 0x0000000001010100, 0x0000010001010100,
659     0x0001000001010000, 0x0001010001010000, 0x0001000001010100, 0x0001010001010100,
660     0x0100000001000000, 0x0100010001000000, 0x0100000001000100, 0x0100010001000100,
661     0x0101000001000000, 0x0101010001000000, 0x0101000001000100, 0x0101010001000100,
662     0x0100000001010000, 0x0100010001010000, 0x0100000001010100, 0x0100010001010100,
663     0x0101000001010000, 0x0101010001010000, 0x0101000001010100, 0x0101010001010100,
664     0x0000000100000000, 0x0000010100000000, 0x0000000100000100, 0x0000010100000100,
665     0x0001000100000000, 0x0001010100000000, 0x0001000100000100, 0x0001010100000100,
666     0x0000000100010000, 0x0000010100010000, 0x0000000100010100, 0x0000010100010100,
667     0x0001000100010000, 0x0001010100010000, 0x0001000100010100, 0x0001010100010100,
668     0x0100000100000000, 0x0100010100000000, 0x0100000100000100, 0x0100010100000100,
669     0x0101000100000000, 0x0101010100000000, 0x0101000100000100, 0x0101010100000100,
670     0x0100000100010000, 0x0100010100010000, 0x0100000100010100, 0x0100010100010100,
671     0x0101000100010000, 0x0101010100010000, 0x0101000100010100, 0x0101010100010100,
672     0x0000000101000000, 0x0000010101000000, 0x0000000101000100, 0x0000010101000100,
673     0x0001000101000000, 0x0001010101000000, 0x0001000101000100, 0x0001010101000100,
674     0x0000000101010000, 0x0000010101010000, 0x0000000101010100, 0x0000010101010100,
675     0x0001000101010000, 0x0001010101010000, 0x0001000101010100, 0x0001010101010100,
676     0x0100000101000000, 0x0100010101000000, 0x0100000101000100, 0x0100010101000100,
677     0x0101000101000000, 0x0101010101000000, 0x0101000101000100, 0x0101010101000100,
678     0x0100000101010000, 0x0100010101010000, 0x0100000101010100, 0x0100010101010100,
679     0x0101000101010000, 0x0101010101010000, 0x0101000101010100, 0x0101010101010100,
680     0x0000000000000001, 0x0000010000000001, 0x0000000000000101, 0x0000010000000101,
681     0x0001000000000001, 0x0001010000000001, 0x0001000000000101, 0x0001010000000101,
682     0x0000000000010001, 0x0000010000010001, 0x0000000000010101, 0x0000010000010101,
683     0x0001000000010001, 0x0001010000010001, 0x0001000000010101, 0x0001010000010101,
684     0x0100000000000001, 0x0100010000000001, 0x0100000000000101, 0x0100010000000101,
685     0x0101000000000001, 0x0101010000000001, 0x0101000000000101, 0x0101010000000101,
686     0x0100000000010001, 0x0100010000010001, 0x0100000000010101, 0x0100010000010101,
687     0x0101000000010001, 0x0101010000010001, 0x0101000000010101, 0x0101010000010101,
688     0x0000000001000001, 0x0000010001000001, 0x0000000001000101, 0x0000010001000101,
689     0x0001000001000001, 0x0001010001000001, 0x0001000001000101, 0x0001010001000101,
690     0x0000000001010001, 0x0000010001010001, 0x0000000001010101, 0x0000010001010101,
691     0x0001000001010001, 0x0001010001010001, 0x0001000001010101, 0x0001010001010101,
692     0x0100000001000001, 0x0100010001000001, 0x0100000001000101, 0x0100010001000101,
693     0x0101000001000001, 0x0101010001000001, 0x0101000001000101, 0x0101010001000101,
694     0x0100000001010001, 0x0100010001010001, 0x0100000001010101, 0x0100010001010101,
695     0x0101000001010001, 0x0101010001010001, 0x0101000001010101, 0x0101010001010101,
696     0x0000000100000001, 0x0000010100000001, 0x0000000100000101, 0x0000010100000101,
697     0x0001000100000001, 0x0001010100000001, 0x0001000100000101, 0x0001010100000101,
698     0x0000000100010001, 0x0000010100010001, 0x0000000100010101, 0x0000010100010101,
699     0x0001000100010001, 0x0001010100010001, 0x0001000100010101, 0x0001010100010101,
700     0x0100000100000001, 0x0100010100000001, 0x0100000100000101, 0x0100010100000101,
701     0x0101000100000001, 0x0101010100000001, 0x0101000100000101, 0x0101010100000101,
702     0x0100000100010001, 0x0100010100010001, 0x0100000100010101, 0x0100010100010101,
703     0x0101000100010001, 0x0101010100010001, 0x0101000100010101, 0x0101010100010101,
704     0x0000000101000001, 0x0000010101000001, 0x0000000101000101, 0x0000010101000101,
705     0x0001000101000001, 0x0001010101000001, 0x0001000101000101, 0x0001010101000101,
706     0x0000000101010001, 0x0000010101010001, 0x0000000101010101, 0x0000010101010101,
707     0x0001000101010001, 0x0001010101010001, 0x0001000101010101, 0x0001010101010101,
708     0x0100000101000001, 0x0100010101000001, 0x0100000101000101, 0x0100010101000101,
709     0x0101000101000001, 0x0101010101000001, 0x0101000101000101, 0x0101010101000101,
710     0x0100000101010001, 0x0100010101010001, 0x0100000101010101, 0x0100010101010101,
711     0x0101000101010001, 0x0101010101010001, 0x0101000101010101, 0x0101010101010101 ];
712 
713 __gshared immutable ulong[256] DES_FPTAB1 = [
714     0x0000000000000000, 0x0000000100000000, 0x0000000004000000, 0x0000000104000000,
715     0x0000000000040000, 0x0000000100040000, 0x0000000004040000, 0x0000000104040000,
716     0x0000000000000400, 0x0000000100000400, 0x0000000004000400, 0x0000000104000400,
717     0x0000000000040400, 0x0000000100040400, 0x0000000004040400, 0x0000000104040400,
718     0x0000000000000004, 0x0000000100000004, 0x0000000004000004, 0x0000000104000004,
719     0x0000000000040004, 0x0000000100040004, 0x0000000004040004, 0x0000000104040004,
720     0x0000000000000404, 0x0000000100000404, 0x0000000004000404, 0x0000000104000404,
721     0x0000000000040404, 0x0000000100040404, 0x0000000004040404, 0x0000000104040404,
722     0x0400000000000000, 0x0400000100000000, 0x0400000004000000, 0x0400000104000000,
723     0x0400000000040000, 0x0400000100040000, 0x0400000004040000, 0x0400000104040000,
724     0x0400000000000400, 0x0400000100000400, 0x0400000004000400, 0x0400000104000400,
725     0x0400000000040400, 0x0400000100040400, 0x0400000004040400, 0x0400000104040400,
726     0x0400000000000004, 0x0400000100000004, 0x0400000004000004, 0x0400000104000004,
727     0x0400000000040004, 0x0400000100040004, 0x0400000004040004, 0x0400000104040004,
728     0x0400000000000404, 0x0400000100000404, 0x0400000004000404, 0x0400000104000404,
729     0x0400000000040404, 0x0400000100040404, 0x0400000004040404, 0x0400000104040404,
730     0x0004000000000000, 0x0004000100000000, 0x0004000004000000, 0x0004000104000000,
731     0x0004000000040000, 0x0004000100040000, 0x0004000004040000, 0x0004000104040000,
732     0x0004000000000400, 0x0004000100000400, 0x0004000004000400, 0x0004000104000400,
733     0x0004000000040400, 0x0004000100040400, 0x0004000004040400, 0x0004000104040400,
734     0x0004000000000004, 0x0004000100000004, 0x0004000004000004, 0x0004000104000004,
735     0x0004000000040004, 0x0004000100040004, 0x0004000004040004, 0x0004000104040004,
736     0x0004000000000404, 0x0004000100000404, 0x0004000004000404, 0x0004000104000404,
737     0x0004000000040404, 0x0004000100040404, 0x0004000004040404, 0x0004000104040404,
738     0x0404000000000000, 0x0404000100000000, 0x0404000004000000, 0x0404000104000000,
739     0x0404000000040000, 0x0404000100040000, 0x0404000004040000, 0x0404000104040000,
740     0x0404000000000400, 0x0404000100000400, 0x0404000004000400, 0x0404000104000400,
741     0x0404000000040400, 0x0404000100040400, 0x0404000004040400, 0x0404000104040400,
742     0x0404000000000004, 0x0404000100000004, 0x0404000004000004, 0x0404000104000004,
743     0x0404000000040004, 0x0404000100040004, 0x0404000004040004, 0x0404000104040004,
744     0x0404000000000404, 0x0404000100000404, 0x0404000004000404, 0x0404000104000404,
745     0x0404000000040404, 0x0404000100040404, 0x0404000004040404, 0x0404000104040404,
746     0x0000040000000000, 0x0000040100000000, 0x0000040004000000, 0x0000040104000000,
747     0x0000040000040000, 0x0000040100040000, 0x0000040004040000, 0x0000040104040000,
748     0x0000040000000400, 0x0000040100000400, 0x0000040004000400, 0x0000040104000400,
749     0x0000040000040400, 0x0000040100040400, 0x0000040004040400, 0x0000040104040400,
750     0x0000040000000004, 0x0000040100000004, 0x0000040004000004, 0x0000040104000004,
751     0x0000040000040004, 0x0000040100040004, 0x0000040004040004, 0x0000040104040004,
752     0x0000040000000404, 0x0000040100000404, 0x0000040004000404, 0x0000040104000404,
753     0x0000040000040404, 0x0000040100040404, 0x0000040004040404, 0x0000040104040404,
754     0x0400040000000000, 0x0400040100000000, 0x0400040004000000, 0x0400040104000000,
755     0x0400040000040000, 0x0400040100040000, 0x0400040004040000, 0x0400040104040000,
756     0x0400040000000400, 0x0400040100000400, 0x0400040004000400, 0x0400040104000400,
757     0x0400040000040400, 0x0400040100040400, 0x0400040004040400, 0x0400040104040400,
758     0x0400040000000004, 0x0400040100000004, 0x0400040004000004, 0x0400040104000004,
759     0x0400040000040004, 0x0400040100040004, 0x0400040004040004, 0x0400040104040004,
760     0x0400040000000404, 0x0400040100000404, 0x0400040004000404, 0x0400040104000404,
761     0x0400040000040404, 0x0400040100040404, 0x0400040004040404, 0x0400040104040404,
762     0x0004040000000000, 0x0004040100000000, 0x0004040004000000, 0x0004040104000000,
763     0x0004040000040000, 0x0004040100040000, 0x0004040004040000, 0x0004040104040000,
764     0x0004040000000400, 0x0004040100000400, 0x0004040004000400, 0x0004040104000400,
765     0x0004040000040400, 0x0004040100040400, 0x0004040004040400, 0x0004040104040400,
766     0x0004040000000004, 0x0004040100000004, 0x0004040004000004, 0x0004040104000004,
767     0x0004040000040004, 0x0004040100040004, 0x0004040004040004, 0x0004040104040004,
768     0x0004040000000404, 0x0004040100000404, 0x0004040004000404, 0x0004040104000404,
769     0x0004040000040404, 0x0004040100040404, 0x0004040004040404, 0x0004040104040404,
770     0x0404040000000000, 0x0404040100000000, 0x0404040004000000, 0x0404040104000000,
771     0x0404040000040000, 0x0404040100040000, 0x0404040004040000, 0x0404040104040000,
772     0x0404040000000400, 0x0404040100000400, 0x0404040004000400, 0x0404040104000400,
773     0x0404040000040400, 0x0404040100040400, 0x0404040004040400, 0x0404040104040400,
774     0x0404040000000004, 0x0404040100000004, 0x0404040004000004, 0x0404040104000004,
775     0x0404040000040004, 0x0404040100040004, 0x0404040004040004, 0x0404040104040004,
776     0x0404040000000404, 0x0404040100000404, 0x0404040004000404, 0x0404040104000404,
777     0x0404040000040404, 0x0404040100040404, 0x0404040004040404, 0x0404040104040404 ];
778 
779 __gshared immutable ulong[256] DES_FPTAB2 = [
780     0x0000000000000000, 0x0000004000000000, 0x0000000001000000, 0x0000004001000000,
781     0x0000000000010000, 0x0000004000010000, 0x0000000001010000, 0x0000004001010000,
782     0x0000000000000100, 0x0000004000000100, 0x0000000001000100, 0x0000004001000100,
783     0x0000000000010100, 0x0000004000010100, 0x0000000001010100, 0x0000004001010100,
784     0x0000000000000001, 0x0000004000000001, 0x0000000001000001, 0x0000004001000001,
785     0x0000000000010001, 0x0000004000010001, 0x0000000001010001, 0x0000004001010001,
786     0x0000000000000101, 0x0000004000000101, 0x0000000001000101, 0x0000004001000101,
787     0x0000000000010101, 0x0000004000010101, 0x0000000001010101, 0x0000004001010101,
788     0x0100000000000000, 0x0100004000000000, 0x0100000001000000, 0x0100004001000000,
789     0x0100000000010000, 0x0100004000010000, 0x0100000001010000, 0x0100004001010000,
790     0x0100000000000100, 0x0100004000000100, 0x0100000001000100, 0x0100004001000100,
791     0x0100000000010100, 0x0100004000010100, 0x0100000001010100, 0x0100004001010100,
792     0x0100000000000001, 0x0100004000000001, 0x0100000001000001, 0x0100004001000001,
793     0x0100000000010001, 0x0100004000010001, 0x0100000001010001, 0x0100004001010001,
794     0x0100000000000101, 0x0100004000000101, 0x0100000001000101, 0x0100004001000101,
795     0x0100000000010101, 0x0100004000010101, 0x0100000001010101, 0x0100004001010101,
796     0x0001000000000000, 0x0001004000000000, 0x0001000001000000, 0x0001004001000000,
797     0x0001000000010000, 0x0001004000010000, 0x0001000001010000, 0x0001004001010000,
798     0x0001000000000100, 0x0001004000000100, 0x0001000001000100, 0x0001004001000100,
799     0x0001000000010100, 0x0001004000010100, 0x0001000001010100, 0x0001004001010100,
800     0x0001000000000001, 0x0001004000000001, 0x0001000001000001, 0x0001004001000001,
801     0x0001000000010001, 0x0001004000010001, 0x0001000001010001, 0x0001004001010001,
802     0x0001000000000101, 0x0001004000000101, 0x0001000001000101, 0x0001004001000101,
803     0x0001000000010101, 0x0001004000010101, 0x0001000001010101, 0x0001004001010101,
804     0x0101000000000000, 0x0101004000000000, 0x0101000001000000, 0x0101004001000000,
805     0x0101000000010000, 0x0101004000010000, 0x0101000001010000, 0x0101004001010000,
806     0x0101000000000100, 0x0101004000000100, 0x0101000001000100, 0x0101004001000100,
807     0x0101000000010100, 0x0101004000010100, 0x0101000001010100, 0x0101004001010100,
808     0x0101000000000001, 0x0101004000000001, 0x0101000001000001, 0x0101004001000001,
809     0x0101000000010001, 0x0101004000010001, 0x0101000001010001, 0x0101004001010001,
810     0x0101000000000101, 0x0101004000000101, 0x0101000001000101, 0x0101004001000101,
811     0x0101000000010101, 0x0101004000010101, 0x0101000001010101, 0x0101004001010101,
812     0x0000010000000000, 0x0000014000000000, 0x0000010001000000, 0x0000014001000000,
813     0x0000010000010000, 0x0000014000010000, 0x0000010001010000, 0x0000014001010000,
814     0x0000010000000100, 0x0000014000000100, 0x0000010001000100, 0x0000014001000100,
815     0x0000010000010100, 0x0000014000010100, 0x0000010001010100, 0x0000014001010100,
816     0x0000010000000001, 0x0000014000000001, 0x0000010001000001, 0x0000014001000001,
817     0x0000010000010001, 0x0000014000010001, 0x0000010001010001, 0x0000014001010001,
818     0x0000010000000101, 0x0000014000000101, 0x0000010001000101, 0x0000014001000101,
819     0x0000010000010101, 0x0000014000010101, 0x0000010001010101, 0x0000014001010101,
820     0x0100010000000000, 0x0100014000000000, 0x0100010001000000, 0x0100014001000000,
821     0x0100010000010000, 0x0100014000010000, 0x0100010001010000, 0x0100014001010000,
822     0x0100010000000100, 0x0100014000000100, 0x0100010001000100, 0x0100014001000100,
823     0x0100010000010100, 0x0100014000010100, 0x0100010001010100, 0x0100014001010100,
824     0x0100010000000001, 0x0100014000000001, 0x0100010001000001, 0x0100014001000001,
825     0x0100010000010001, 0x0100014000010001, 0x0100010001010001, 0x0100014001010001,
826     0x0100010000000101, 0x0100014000000101, 0x0100010001000101, 0x0100014001000101,
827     0x0100010000010101, 0x0100014000010101, 0x0100010001010101, 0x0100014001010101,
828     0x0001010000000000, 0x0001014000000000, 0x0001010001000000, 0x0001014001000000,
829     0x0001010000010000, 0x0001014000010000, 0x0001010001010000, 0x0001014001010000,
830     0x0001010000000100, 0x0001014000000100, 0x0001010001000100, 0x0001014001000100,
831     0x0001010000010100, 0x0001014000010100, 0x0001010001010100, 0x0001014001010100,
832     0x0001010000000001, 0x0001014000000001, 0x0001010001000001, 0x0001014001000001,
833     0x0001010000010001, 0x0001014000010001, 0x0001010001010001, 0x0001014001010001,
834     0x0001010000000101, 0x0001014000000101, 0x0001010001000101, 0x0001014001000101,
835     0x0001010000010101, 0x0001014000010101, 0x0001010001010101, 0x0001014001010101,
836     0x0101010000000000, 0x0101014000000000, 0x0101010001000000, 0x0101014001000000,
837     0x0101010000010000, 0x0101014000010000, 0x0101010001010000, 0x0101014001010000,
838     0x0101010000000100, 0x0101014000000100, 0x0101010001000100, 0x0101014001000100,
839     0x0101010000010100, 0x0101014000010100, 0x0101010001010100, 0x0101014001010100,
840     0x0101010000000001, 0x0101014000000001, 0x0101010001000001, 0x0101014001000001,
841     0x0101010000010001, 0x0101014000010001, 0x0101010001010001, 0x0101014001010001,
842     0x0101010000000101, 0x0101014000000101, 0x0101010001000101, 0x0101014001000101,
843     0x0101010000010101, 0x0101014000010101, 0x0101010001010101, 0x0101014001010101 ];
844     
845 package: //used by desx as well
846 
847 /*
848 * DES Key Schedule
849 */
850 void des_key_schedule(ref uint[32] round_key, in ubyte[8] key)
851 {
852     __gshared immutable ubyte[16] ROT = [ 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1 ];
853     
854     uint C =    ((key[7] & 0x80) << 20) | ((key[6] & 0x80) << 19) |
855                 ((key[5] & 0x80) << 18) | ((key[4] & 0x80) << 17) |
856                 ((key[3] & 0x80) << 16) | ((key[2] & 0x80) << 15) |
857                 ((key[1] & 0x80) << 14) | ((key[0] & 0x80) << 13) |
858                 ((key[7] & 0x40) << 13) | ((key[6] & 0x40) << 12) |
859                 ((key[5] & 0x40) << 11) | ((key[4] & 0x40) << 10) |
860                 ((key[3] & 0x40) <<  9) | ((key[2] & 0x40) <<  8) |
861                 ((key[1] & 0x40) <<  7) | ((key[0] & 0x40) <<  6) |
862                 ((key[7] & 0x20) <<  6) | ((key[6] & 0x20) <<  5) |
863                 ((key[5] & 0x20) <<  4) | ((key[4] & 0x20) <<  3) |
864                 ((key[3] & 0x20) <<  2) | ((key[2] & 0x20) <<  1) |
865                 ((key[1] & 0x20)      ) | ((key[0] & 0x20) >>  1) |
866                 ((key[7] & 0x10) >>  1) | ((key[6] & 0x10) >>  2) |
867                 ((key[5] & 0x10) >>  3) | ((key[4] & 0x10) >>  4);
868     uint D =     ((key[7] & 0x02) << 26) | ((key[6] & 0x02) << 25) |
869                 ((key[5] & 0x02) << 24) | ((key[4] & 0x02) << 23) |
870                 ((key[3] & 0x02) << 22) | ((key[2] & 0x02) << 21) |
871                 ((key[1] & 0x02) << 20) | ((key[0] & 0x02) << 19) |
872                 ((key[7] & 0x04) << 17) | ((key[6] & 0x04) << 16) |
873                 ((key[5] & 0x04) << 15) | ((key[4] & 0x04) << 14) |
874                 ((key[3] & 0x04) << 13) | ((key[2] & 0x04) << 12) |
875                 ((key[1] & 0x04) << 11) | ((key[0] & 0x04) << 10) |
876                 ((key[7] & 0x08) <<  8) | ((key[6] & 0x08) <<  7) |
877                 ((key[5] & 0x08) <<  6) | ((key[4] & 0x08) <<  5) |
878                 ((key[3] & 0x08) <<  4) | ((key[2] & 0x08) <<  3) |
879                 ((key[1] & 0x08) <<  2) | ((key[0] & 0x08) <<  1) |
880                 ((key[3] & 0x10) >>  1) | ((key[2] & 0x10) >>  2) |
881                 ((key[1] & 0x10) >>  3) | ((key[0] & 0x10) >>  4);
882     
883     foreach (size_t i; 0 .. 16)
884     {
885         C = ((C << ROT[i]) | (C >> (28-ROT[i]))) & 0x0FFFFFFF;
886         D = ((D << ROT[i]) | (D >> (28-ROT[i]))) & 0x0FFFFFFF;
887         round_key[2*i  ] =  ((C & 0x00000010) << 22) | ((C & 0x00000800) << 17) |
888                             ((C & 0x00000020) << 16) | ((C & 0x00004004) << 15) |
889                             ((C & 0x00000200) << 11) | ((C & 0x00020000) << 10) |
890                             ((C & 0x01000000) >>  6) | ((C & 0x00100000) >>  4) |
891                             ((C & 0x00010000) <<  3) | ((C & 0x08000000) >>  2) |
892                             ((C & 0x00800000) <<  1) | ((D & 0x00000010) <<  8) |
893                             ((D & 0x00000002) <<  7) | ((D & 0x00000001) <<  2) |
894                             ((D & 0x00000200)       ) | ((D & 0x00008000) >>  2) |
895                             ((D & 0x00000088) >>  3) | ((D & 0x00001000) >>  7) |
896                             ((D & 0x00080000) >>  9) | ((D & 0x02020000) >> 14) |
897                             ((D & 0x00400000) >> 21);
898         round_key[2*i+1] =  ((C & 0x00000001) << 28) | ((C & 0x00000082) << 18) |
899                             ((C & 0x00002000) << 14) | ((C & 0x00000100) << 10) |
900                             ((C & 0x00001000) <<  9) | ((C & 0x00040000) <<  6) |
901                             ((C & 0x02400000) <<  4) | ((C & 0x00008000) <<  2) |
902                             ((C & 0x00200000) >>  1) | ((C & 0x04000000) >> 10) |
903                             ((D & 0x00000020) <<  6) | ((D & 0x00000100)      ) |
904                             ((D & 0x00000800) >>  1) | ((D & 0x00000040) >>  3) |
905                             ((D & 0x00010000) >>  4) | ((D & 0x00000400) >>  5) |
906                             ((D & 0x00004000) >> 10) | ((D & 0x04000000) >> 13) |
907                             ((D & 0x00800000) >> 14) | ((D & 0x00100000) >> 18) |
908                             ((D & 0x01000000) >> 24) | ((D & 0x08000000) >> 26);
909     }
910 }
911 
912 /*
913 * DES Encryption
914 */
915 void des_encrypt(ref uint L, ref uint R, in uint[32] round_key) pure
916 {
917     foreach (size_t i; iota(0, 16, 2))
918     {
919         uint T0, T1;
920         
921         T0 = rotateRight(R, 4) ^ round_key[2*i];
922         T1 =                 R ^ round_key[2*i + 1];
923         
924         L ^=    DES_SPBOX1[get_byte(0, T0)] ^ DES_SPBOX2[get_byte(0, T1)] ^
925                 DES_SPBOX3[get_byte(1, T0)] ^ DES_SPBOX4[get_byte(1, T1)] ^
926                 DES_SPBOX5[get_byte(2, T0)] ^ DES_SPBOX6[get_byte(2, T1)] ^
927                 DES_SPBOX7[get_byte(3, T0)] ^ DES_SPBOX8[get_byte(3, T1)];
928         
929         T0 = rotateRight(L, 4) ^ round_key[2*i + 2];
930         T1 =                 L ^ round_key[2*i + 3];
931         
932         R ^=    DES_SPBOX1[get_byte(0, T0)] ^ DES_SPBOX2[get_byte(0, T1)] ^
933                 DES_SPBOX3[get_byte(1, T0)] ^ DES_SPBOX4[get_byte(1, T1)] ^
934                 DES_SPBOX5[get_byte(2, T0)] ^ DES_SPBOX6[get_byte(2, T1)] ^
935                 DES_SPBOX7[get_byte(3, T0)] ^ DES_SPBOX8[get_byte(3, T1)];
936     }
937 }
938 
939 /*
940 * DES Decryption
941 */
942 void des_decrypt(ref uint L, ref uint R, in uint[32] round_key) pure
943 {
944     for (size_t i = 16; i != 0; i -= 2)
945     {
946         uint T0, T1;
947         
948         T0 = rotateRight(R, 4) ^ round_key[2*i - 2];
949         T1 =                 R ^ round_key[2*i - 1];
950         
951         L ^=    DES_SPBOX1[get_byte(0, T0)] ^ DES_SPBOX2[get_byte(0, T1)] ^
952                 DES_SPBOX3[get_byte(1, T0)] ^ DES_SPBOX4[get_byte(1, T1)] ^
953                 DES_SPBOX5[get_byte(2, T0)] ^ DES_SPBOX6[get_byte(2, T1)] ^
954                 DES_SPBOX7[get_byte(3, T0)] ^ DES_SPBOX8[get_byte(3, T1)];
955         
956         T0 = rotateRight(L, 4) ^ round_key[2*i - 4];
957         T1 =                 L ^ round_key[2*i - 3];
958         
959         R ^=    DES_SPBOX1[get_byte(0, T0)] ^ DES_SPBOX2[get_byte(0, T1)] ^
960                 DES_SPBOX3[get_byte(1, T0)] ^ DES_SPBOX4[get_byte(1, T1)] ^
961                 DES_SPBOX5[get_byte(2, T0)] ^ DES_SPBOX6[get_byte(2, T1)] ^
962                 DES_SPBOX7[get_byte(3, T0)] ^ DES_SPBOX8[get_byte(3, T1)];
963     }
964 }