]> git.mxchange.org Git - friendica-addons.git/blob - securemail/vendor/phpseclib/phpseclib/phpseclib/Crypt/DES.php
securemail: update pgp library
[friendica-addons.git] / securemail / vendor / phpseclib / phpseclib / phpseclib / Crypt / DES.php
1 <?php
2
3 /**
4  * Pure-PHP implementation of DES.
5  *
6  * Uses mcrypt, if available, and an internal implementation, otherwise.
7  *
8  * PHP versions 4 and 5
9  *
10  * Useful resources are as follows:
11  *
12  *  - {@link http://en.wikipedia.org/wiki/DES_supplementary_material Wikipedia: DES supplementary material}
13  *  - {@link http://www.itl.nist.gov/fipspubs/fip46-2.htm FIPS 46-2 - (DES), Data Encryption Standard}
14  *  - {@link http://www.cs.eku.edu/faculty/styer/460/Encrypt/JS-DES.html JavaScript DES Example}
15  *
16  * Here's a short example of how to use this library:
17  * <code>
18  * <?php
19  *    include 'Crypt/DES.php';
20  *
21  *    $des = new Crypt_DES();
22  *
23  *    $des->setKey('abcdefgh');
24  *
25  *    $size = 10 * 1024;
26  *    $plaintext = '';
27  *    for ($i = 0; $i < $size; $i++) {
28  *        $plaintext.= 'a';
29  *    }
30  *
31  *    echo $des->decrypt($des->encrypt($plaintext));
32  * ?>
33  * </code>
34  *
35  * LICENSE: Permission is hereby granted, free of charge, to any person obtaining a copy
36  * of this software and associated documentation files (the "Software"), to deal
37  * in the Software without restriction, including without limitation the rights
38  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
39  * copies of the Software, and to permit persons to whom the Software is
40  * furnished to do so, subject to the following conditions:
41  *
42  * The above copyright notice and this permission notice shall be included in
43  * all copies or substantial portions of the Software.
44  *
45  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
46  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
47  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
48  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
49  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
50  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
51  * THE SOFTWARE.
52  *
53  * @category  Crypt
54  * @package   Crypt_DES
55  * @author    Jim Wigginton <terrafrost@php.net>
56  * @copyright 2007 Jim Wigginton
57  * @license   http://www.opensource.org/licenses/mit-license.html  MIT License
58  * @link      http://phpseclib.sourceforge.net
59  */
60
61 /**
62  * Include Crypt_Base
63  *
64  * Base cipher class
65  */
66 if (!class_exists('Crypt_Base')) {
67     include_once 'Base.php';
68 }
69
70 /**#@+
71  * @access private
72  * @see Crypt_DES::_setupKey()
73  * @see Crypt_DES::_processBlock()
74  */
75 /**
76  * Contains $keys[CRYPT_DES_ENCRYPT]
77  */
78 define('CRYPT_DES_ENCRYPT', 0);
79 /**
80  * Contains $keys[CRYPT_DES_DECRYPT]
81  */
82 define('CRYPT_DES_DECRYPT', 1);
83 /**#@-*/
84
85 /**#@+
86  * @access public
87  * @see Crypt_DES::encrypt()
88  * @see Crypt_DES::decrypt()
89  */
90 /**
91  * Encrypt / decrypt using the Counter mode.
92  *
93  * Set to -1 since that's what Crypt/Random.php uses to index the CTR mode.
94  *
95  * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Counter_.28CTR.29
96  */
97 define('CRYPT_DES_MODE_CTR', CRYPT_MODE_CTR);
98 /**
99  * Encrypt / decrypt using the Electronic Code Book mode.
100  *
101  * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Electronic_codebook_.28ECB.29
102  */
103 define('CRYPT_DES_MODE_ECB', CRYPT_MODE_ECB);
104 /**
105  * Encrypt / decrypt using the Code Book Chaining mode.
106  *
107  * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Cipher-block_chaining_.28CBC.29
108  */
109 define('CRYPT_DES_MODE_CBC', CRYPT_MODE_CBC);
110 /**
111  * Encrypt / decrypt using the Cipher Feedback mode.
112  *
113  * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Cipher_feedback_.28CFB.29
114  */
115 define('CRYPT_DES_MODE_CFB', CRYPT_MODE_CFB);
116 /**
117  * Encrypt / decrypt using the Cipher Feedback mode.
118  *
119  * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Output_feedback_.28OFB.29
120  */
121 define('CRYPT_DES_MODE_OFB', CRYPT_MODE_OFB);
122 /**#@-*/
123
124 /**#@+
125  * @access private
126  * @see Crypt_Base::Crypt_Base()
127  */
128 /**
129  * Toggles the internal implementation
130  */
131 define('CRYPT_DES_MODE_INTERNAL', CRYPT_MODE_INTERNAL);
132 /**
133  * Toggles the mcrypt implementation
134  */
135 define('CRYPT_DES_MODE_MCRYPT', CRYPT_MODE_MCRYPT);
136 /**#@-*/
137
138 /**
139  * Pure-PHP implementation of DES.
140  *
141  * @package Crypt_DES
142  * @author  Jim Wigginton <terrafrost@php.net>
143  * @access  public
144  */
145 class Crypt_DES extends Crypt_Base
146 {
147     /**
148      * Block Length of the cipher
149      *
150      * @see Crypt_Base::block_size
151      * @var Integer
152      * @access private
153      */
154     var $block_size = 8;
155
156     /**
157      * The Key
158      *
159      * @see Crypt_Base::key
160      * @see setKey()
161      * @var String
162      * @access private
163      */
164     var $key = "\0\0\0\0\0\0\0\0";
165
166     /**
167      * The default password key_size used by setPassword()
168      *
169      * @see Crypt_Base::password_key_size
170      * @see Crypt_Base::setPassword()
171      * @var Integer
172      * @access private
173      */
174     var $password_key_size = 8;
175
176     /**
177      * The namespace used by the cipher for its constants.
178      *
179      * @see Crypt_Base::const_namespace
180      * @var String
181      * @access private
182      */
183     var $const_namespace = 'DES';
184
185     /**
186      * The mcrypt specific name of the cipher
187      *
188      * @see Crypt_Base::cipher_name_mcrypt
189      * @var String
190      * @access private
191      */
192     var $cipher_name_mcrypt = 'des';
193
194     /**
195      * Optimizing value while CFB-encrypting
196      *
197      * @see Crypt_Base::cfb_init_len
198      * @var Integer
199      * @access private
200      */
201     var $cfb_init_len = 500;
202
203     /**
204      * Switch for DES/3DES encryption
205      *
206      * Used only if $engine == CRYPT_DES_MODE_INTERNAL
207      *
208      * @see Crypt_DES::_setupKey()
209      * @see Crypt_DES::_processBlock()
210      * @var Integer
211      * @access private
212      */
213     var $des_rounds = 1;
214
215     /**
216      * max possible size of $key
217      *
218      * @see Crypt_DES::setKey()
219      * @var String
220      * @access private
221      */
222     var $key_size_max = 8;
223
224     /**
225      * The Key Schedule
226      *
227      * @see Crypt_DES::_setupKey()
228      * @var Array
229      * @access private
230      */
231     var $keys;
232
233     /**
234      * Shuffle table.
235      *
236      * For each byte value index, the entry holds an 8-byte string
237      * with each byte containing all bits in the same state as the
238      * corresponding bit in the index value.
239      *
240      * @see Crypt_DES::_processBlock()
241      * @see Crypt_DES::_setupKey()
242      * @var Array
243      * @access private
244      */
245     var $shuffle = array(
246         "\x00\x00\x00\x00\x00\x00\x00\x00", "\x00\x00\x00\x00\x00\x00\x00\xFF",
247         "\x00\x00\x00\x00\x00\x00\xFF\x00", "\x00\x00\x00\x00\x00\x00\xFF\xFF",
248         "\x00\x00\x00\x00\x00\xFF\x00\x00", "\x00\x00\x00\x00\x00\xFF\x00\xFF",
249         "\x00\x00\x00\x00\x00\xFF\xFF\x00", "\x00\x00\x00\x00\x00\xFF\xFF\xFF",
250         "\x00\x00\x00\x00\xFF\x00\x00\x00", "\x00\x00\x00\x00\xFF\x00\x00\xFF",
251         "\x00\x00\x00\x00\xFF\x00\xFF\x00", "\x00\x00\x00\x00\xFF\x00\xFF\xFF",
252         "\x00\x00\x00\x00\xFF\xFF\x00\x00", "\x00\x00\x00\x00\xFF\xFF\x00\xFF",
253         "\x00\x00\x00\x00\xFF\xFF\xFF\x00", "\x00\x00\x00\x00\xFF\xFF\xFF\xFF",
254         "\x00\x00\x00\xFF\x00\x00\x00\x00", "\x00\x00\x00\xFF\x00\x00\x00\xFF",
255         "\x00\x00\x00\xFF\x00\x00\xFF\x00", "\x00\x00\x00\xFF\x00\x00\xFF\xFF",
256         "\x00\x00\x00\xFF\x00\xFF\x00\x00", "\x00\x00\x00\xFF\x00\xFF\x00\xFF",
257         "\x00\x00\x00\xFF\x00\xFF\xFF\x00", "\x00\x00\x00\xFF\x00\xFF\xFF\xFF",
258         "\x00\x00\x00\xFF\xFF\x00\x00\x00", "\x00\x00\x00\xFF\xFF\x00\x00\xFF",
259         "\x00\x00\x00\xFF\xFF\x00\xFF\x00", "\x00\x00\x00\xFF\xFF\x00\xFF\xFF",
260         "\x00\x00\x00\xFF\xFF\xFF\x00\x00", "\x00\x00\x00\xFF\xFF\xFF\x00\xFF",
261         "\x00\x00\x00\xFF\xFF\xFF\xFF\x00", "\x00\x00\x00\xFF\xFF\xFF\xFF\xFF",
262         "\x00\x00\xFF\x00\x00\x00\x00\x00", "\x00\x00\xFF\x00\x00\x00\x00\xFF",
263         "\x00\x00\xFF\x00\x00\x00\xFF\x00", "\x00\x00\xFF\x00\x00\x00\xFF\xFF",
264         "\x00\x00\xFF\x00\x00\xFF\x00\x00", "\x00\x00\xFF\x00\x00\xFF\x00\xFF",
265         "\x00\x00\xFF\x00\x00\xFF\xFF\x00", "\x00\x00\xFF\x00\x00\xFF\xFF\xFF",
266         "\x00\x00\xFF\x00\xFF\x00\x00\x00", "\x00\x00\xFF\x00\xFF\x00\x00\xFF",
267         "\x00\x00\xFF\x00\xFF\x00\xFF\x00", "\x00\x00\xFF\x00\xFF\x00\xFF\xFF",
268         "\x00\x00\xFF\x00\xFF\xFF\x00\x00", "\x00\x00\xFF\x00\xFF\xFF\x00\xFF",
269         "\x00\x00\xFF\x00\xFF\xFF\xFF\x00", "\x00\x00\xFF\x00\xFF\xFF\xFF\xFF",
270         "\x00\x00\xFF\xFF\x00\x00\x00\x00", "\x00\x00\xFF\xFF\x00\x00\x00\xFF",
271         "\x00\x00\xFF\xFF\x00\x00\xFF\x00", "\x00\x00\xFF\xFF\x00\x00\xFF\xFF",
272         "\x00\x00\xFF\xFF\x00\xFF\x00\x00", "\x00\x00\xFF\xFF\x00\xFF\x00\xFF",
273         "\x00\x00\xFF\xFF\x00\xFF\xFF\x00", "\x00\x00\xFF\xFF\x00\xFF\xFF\xFF",
274         "\x00\x00\xFF\xFF\xFF\x00\x00\x00", "\x00\x00\xFF\xFF\xFF\x00\x00\xFF",
275         "\x00\x00\xFF\xFF\xFF\x00\xFF\x00", "\x00\x00\xFF\xFF\xFF\x00\xFF\xFF",
276         "\x00\x00\xFF\xFF\xFF\xFF\x00\x00", "\x00\x00\xFF\xFF\xFF\xFF\x00\xFF",
277         "\x00\x00\xFF\xFF\xFF\xFF\xFF\x00", "\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF",
278         "\x00\xFF\x00\x00\x00\x00\x00\x00", "\x00\xFF\x00\x00\x00\x00\x00\xFF",
279         "\x00\xFF\x00\x00\x00\x00\xFF\x00", "\x00\xFF\x00\x00\x00\x00\xFF\xFF",
280         "\x00\xFF\x00\x00\x00\xFF\x00\x00", "\x00\xFF\x00\x00\x00\xFF\x00\xFF",
281         "\x00\xFF\x00\x00\x00\xFF\xFF\x00", "\x00\xFF\x00\x00\x00\xFF\xFF\xFF",
282         "\x00\xFF\x00\x00\xFF\x00\x00\x00", "\x00\xFF\x00\x00\xFF\x00\x00\xFF",
283         "\x00\xFF\x00\x00\xFF\x00\xFF\x00", "\x00\xFF\x00\x00\xFF\x00\xFF\xFF",
284         "\x00\xFF\x00\x00\xFF\xFF\x00\x00", "\x00\xFF\x00\x00\xFF\xFF\x00\xFF",
285         "\x00\xFF\x00\x00\xFF\xFF\xFF\x00", "\x00\xFF\x00\x00\xFF\xFF\xFF\xFF",
286         "\x00\xFF\x00\xFF\x00\x00\x00\x00", "\x00\xFF\x00\xFF\x00\x00\x00\xFF",
287         "\x00\xFF\x00\xFF\x00\x00\xFF\x00", "\x00\xFF\x00\xFF\x00\x00\xFF\xFF",
288         "\x00\xFF\x00\xFF\x00\xFF\x00\x00", "\x00\xFF\x00\xFF\x00\xFF\x00\xFF",
289         "\x00\xFF\x00\xFF\x00\xFF\xFF\x00", "\x00\xFF\x00\xFF\x00\xFF\xFF\xFF",
290         "\x00\xFF\x00\xFF\xFF\x00\x00\x00", "\x00\xFF\x00\xFF\xFF\x00\x00\xFF",
291         "\x00\xFF\x00\xFF\xFF\x00\xFF\x00", "\x00\xFF\x00\xFF\xFF\x00\xFF\xFF",
292         "\x00\xFF\x00\xFF\xFF\xFF\x00\x00", "\x00\xFF\x00\xFF\xFF\xFF\x00\xFF",
293         "\x00\xFF\x00\xFF\xFF\xFF\xFF\x00", "\x00\xFF\x00\xFF\xFF\xFF\xFF\xFF",
294         "\x00\xFF\xFF\x00\x00\x00\x00\x00", "\x00\xFF\xFF\x00\x00\x00\x00\xFF",
295         "\x00\xFF\xFF\x00\x00\x00\xFF\x00", "\x00\xFF\xFF\x00\x00\x00\xFF\xFF",
296         "\x00\xFF\xFF\x00\x00\xFF\x00\x00", "\x00\xFF\xFF\x00\x00\xFF\x00\xFF",
297         "\x00\xFF\xFF\x00\x00\xFF\xFF\x00", "\x00\xFF\xFF\x00\x00\xFF\xFF\xFF",
298         "\x00\xFF\xFF\x00\xFF\x00\x00\x00", "\x00\xFF\xFF\x00\xFF\x00\x00\xFF",
299         "\x00\xFF\xFF\x00\xFF\x00\xFF\x00", "\x00\xFF\xFF\x00\xFF\x00\xFF\xFF",
300         "\x00\xFF\xFF\x00\xFF\xFF\x00\x00", "\x00\xFF\xFF\x00\xFF\xFF\x00\xFF",
301         "\x00\xFF\xFF\x00\xFF\xFF\xFF\x00", "\x00\xFF\xFF\x00\xFF\xFF\xFF\xFF",
302         "\x00\xFF\xFF\xFF\x00\x00\x00\x00", "\x00\xFF\xFF\xFF\x00\x00\x00\xFF",
303         "\x00\xFF\xFF\xFF\x00\x00\xFF\x00", "\x00\xFF\xFF\xFF\x00\x00\xFF\xFF",
304         "\x00\xFF\xFF\xFF\x00\xFF\x00\x00", "\x00\xFF\xFF\xFF\x00\xFF\x00\xFF",
305         "\x00\xFF\xFF\xFF\x00\xFF\xFF\x00", "\x00\xFF\xFF\xFF\x00\xFF\xFF\xFF",
306         "\x00\xFF\xFF\xFF\xFF\x00\x00\x00", "\x00\xFF\xFF\xFF\xFF\x00\x00\xFF",
307         "\x00\xFF\xFF\xFF\xFF\x00\xFF\x00", "\x00\xFF\xFF\xFF\xFF\x00\xFF\xFF",
308         "\x00\xFF\xFF\xFF\xFF\xFF\x00\x00", "\x00\xFF\xFF\xFF\xFF\xFF\x00\xFF",
309         "\x00\xFF\xFF\xFF\xFF\xFF\xFF\x00", "\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF",
310         "\xFF\x00\x00\x00\x00\x00\x00\x00", "\xFF\x00\x00\x00\x00\x00\x00\xFF",
311         "\xFF\x00\x00\x00\x00\x00\xFF\x00", "\xFF\x00\x00\x00\x00\x00\xFF\xFF",
312         "\xFF\x00\x00\x00\x00\xFF\x00\x00", "\xFF\x00\x00\x00\x00\xFF\x00\xFF",
313         "\xFF\x00\x00\x00\x00\xFF\xFF\x00", "\xFF\x00\x00\x00\x00\xFF\xFF\xFF",
314         "\xFF\x00\x00\x00\xFF\x00\x00\x00", "\xFF\x00\x00\x00\xFF\x00\x00\xFF",
315         "\xFF\x00\x00\x00\xFF\x00\xFF\x00", "\xFF\x00\x00\x00\xFF\x00\xFF\xFF",
316         "\xFF\x00\x00\x00\xFF\xFF\x00\x00", "\xFF\x00\x00\x00\xFF\xFF\x00\xFF",
317         "\xFF\x00\x00\x00\xFF\xFF\xFF\x00", "\xFF\x00\x00\x00\xFF\xFF\xFF\xFF",
318         "\xFF\x00\x00\xFF\x00\x00\x00\x00", "\xFF\x00\x00\xFF\x00\x00\x00\xFF",
319         "\xFF\x00\x00\xFF\x00\x00\xFF\x00", "\xFF\x00\x00\xFF\x00\x00\xFF\xFF",
320         "\xFF\x00\x00\xFF\x00\xFF\x00\x00", "\xFF\x00\x00\xFF\x00\xFF\x00\xFF",
321         "\xFF\x00\x00\xFF\x00\xFF\xFF\x00", "\xFF\x00\x00\xFF\x00\xFF\xFF\xFF",
322         "\xFF\x00\x00\xFF\xFF\x00\x00\x00", "\xFF\x00\x00\xFF\xFF\x00\x00\xFF",
323         "\xFF\x00\x00\xFF\xFF\x00\xFF\x00", "\xFF\x00\x00\xFF\xFF\x00\xFF\xFF",
324         "\xFF\x00\x00\xFF\xFF\xFF\x00\x00", "\xFF\x00\x00\xFF\xFF\xFF\x00\xFF",
325         "\xFF\x00\x00\xFF\xFF\xFF\xFF\x00", "\xFF\x00\x00\xFF\xFF\xFF\xFF\xFF",
326         "\xFF\x00\xFF\x00\x00\x00\x00\x00", "\xFF\x00\xFF\x00\x00\x00\x00\xFF",
327         "\xFF\x00\xFF\x00\x00\x00\xFF\x00", "\xFF\x00\xFF\x00\x00\x00\xFF\xFF",
328         "\xFF\x00\xFF\x00\x00\xFF\x00\x00", "\xFF\x00\xFF\x00\x00\xFF\x00\xFF",
329         "\xFF\x00\xFF\x00\x00\xFF\xFF\x00", "\xFF\x00\xFF\x00\x00\xFF\xFF\xFF",
330         "\xFF\x00\xFF\x00\xFF\x00\x00\x00", "\xFF\x00\xFF\x00\xFF\x00\x00\xFF",
331         "\xFF\x00\xFF\x00\xFF\x00\xFF\x00", "\xFF\x00\xFF\x00\xFF\x00\xFF\xFF",
332         "\xFF\x00\xFF\x00\xFF\xFF\x00\x00", "\xFF\x00\xFF\x00\xFF\xFF\x00\xFF",
333         "\xFF\x00\xFF\x00\xFF\xFF\xFF\x00", "\xFF\x00\xFF\x00\xFF\xFF\xFF\xFF",
334         "\xFF\x00\xFF\xFF\x00\x00\x00\x00", "\xFF\x00\xFF\xFF\x00\x00\x00\xFF",
335         "\xFF\x00\xFF\xFF\x00\x00\xFF\x00", "\xFF\x00\xFF\xFF\x00\x00\xFF\xFF",
336         "\xFF\x00\xFF\xFF\x00\xFF\x00\x00", "\xFF\x00\xFF\xFF\x00\xFF\x00\xFF",
337         "\xFF\x00\xFF\xFF\x00\xFF\xFF\x00", "\xFF\x00\xFF\xFF\x00\xFF\xFF\xFF",
338         "\xFF\x00\xFF\xFF\xFF\x00\x00\x00", "\xFF\x00\xFF\xFF\xFF\x00\x00\xFF",
339         "\xFF\x00\xFF\xFF\xFF\x00\xFF\x00", "\xFF\x00\xFF\xFF\xFF\x00\xFF\xFF",
340         "\xFF\x00\xFF\xFF\xFF\xFF\x00\x00", "\xFF\x00\xFF\xFF\xFF\xFF\x00\xFF",
341         "\xFF\x00\xFF\xFF\xFF\xFF\xFF\x00", "\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF",
342         "\xFF\xFF\x00\x00\x00\x00\x00\x00", "\xFF\xFF\x00\x00\x00\x00\x00\xFF",
343         "\xFF\xFF\x00\x00\x00\x00\xFF\x00", "\xFF\xFF\x00\x00\x00\x00\xFF\xFF",
344         "\xFF\xFF\x00\x00\x00\xFF\x00\x00", "\xFF\xFF\x00\x00\x00\xFF\x00\xFF",
345         "\xFF\xFF\x00\x00\x00\xFF\xFF\x00", "\xFF\xFF\x00\x00\x00\xFF\xFF\xFF",
346         "\xFF\xFF\x00\x00\xFF\x00\x00\x00", "\xFF\xFF\x00\x00\xFF\x00\x00\xFF",
347         "\xFF\xFF\x00\x00\xFF\x00\xFF\x00", "\xFF\xFF\x00\x00\xFF\x00\xFF\xFF",
348         "\xFF\xFF\x00\x00\xFF\xFF\x00\x00", "\xFF\xFF\x00\x00\xFF\xFF\x00\xFF",
349         "\xFF\xFF\x00\x00\xFF\xFF\xFF\x00", "\xFF\xFF\x00\x00\xFF\xFF\xFF\xFF",
350         "\xFF\xFF\x00\xFF\x00\x00\x00\x00", "\xFF\xFF\x00\xFF\x00\x00\x00\xFF",
351         "\xFF\xFF\x00\xFF\x00\x00\xFF\x00", "\xFF\xFF\x00\xFF\x00\x00\xFF\xFF",
352         "\xFF\xFF\x00\xFF\x00\xFF\x00\x00", "\xFF\xFF\x00\xFF\x00\xFF\x00\xFF",
353         "\xFF\xFF\x00\xFF\x00\xFF\xFF\x00", "\xFF\xFF\x00\xFF\x00\xFF\xFF\xFF",
354         "\xFF\xFF\x00\xFF\xFF\x00\x00\x00", "\xFF\xFF\x00\xFF\xFF\x00\x00\xFF",
355         "\xFF\xFF\x00\xFF\xFF\x00\xFF\x00", "\xFF\xFF\x00\xFF\xFF\x00\xFF\xFF",
356         "\xFF\xFF\x00\xFF\xFF\xFF\x00\x00", "\xFF\xFF\x00\xFF\xFF\xFF\x00\xFF",
357         "\xFF\xFF\x00\xFF\xFF\xFF\xFF\x00", "\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF",
358         "\xFF\xFF\xFF\x00\x00\x00\x00\x00", "\xFF\xFF\xFF\x00\x00\x00\x00\xFF",
359         "\xFF\xFF\xFF\x00\x00\x00\xFF\x00", "\xFF\xFF\xFF\x00\x00\x00\xFF\xFF",
360         "\xFF\xFF\xFF\x00\x00\xFF\x00\x00", "\xFF\xFF\xFF\x00\x00\xFF\x00\xFF",
361         "\xFF\xFF\xFF\x00\x00\xFF\xFF\x00", "\xFF\xFF\xFF\x00\x00\xFF\xFF\xFF",
362         "\xFF\xFF\xFF\x00\xFF\x00\x00\x00", "\xFF\xFF\xFF\x00\xFF\x00\x00\xFF",
363         "\xFF\xFF\xFF\x00\xFF\x00\xFF\x00", "\xFF\xFF\xFF\x00\xFF\x00\xFF\xFF",
364         "\xFF\xFF\xFF\x00\xFF\xFF\x00\x00", "\xFF\xFF\xFF\x00\xFF\xFF\x00\xFF",
365         "\xFF\xFF\xFF\x00\xFF\xFF\xFF\x00", "\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF",
366         "\xFF\xFF\xFF\xFF\x00\x00\x00\x00", "\xFF\xFF\xFF\xFF\x00\x00\x00\xFF",
367         "\xFF\xFF\xFF\xFF\x00\x00\xFF\x00", "\xFF\xFF\xFF\xFF\x00\x00\xFF\xFF",
368         "\xFF\xFF\xFF\xFF\x00\xFF\x00\x00", "\xFF\xFF\xFF\xFF\x00\xFF\x00\xFF",
369         "\xFF\xFF\xFF\xFF\x00\xFF\xFF\x00", "\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF",
370         "\xFF\xFF\xFF\xFF\xFF\x00\x00\x00", "\xFF\xFF\xFF\xFF\xFF\x00\x00\xFF",
371         "\xFF\xFF\xFF\xFF\xFF\x00\xFF\x00", "\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF",
372         "\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00", "\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF",
373         "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00", "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
374     );
375
376     /**
377      * IP mapping helper table.
378      *
379      * Indexing this table with each source byte performs the initial bit permutation.
380      *
381      * @var Array
382      * @access private
383      */
384     var $ipmap = array(
385         0x00, 0x10, 0x01, 0x11, 0x20, 0x30, 0x21, 0x31,
386         0x02, 0x12, 0x03, 0x13, 0x22, 0x32, 0x23, 0x33,
387         0x40, 0x50, 0x41, 0x51, 0x60, 0x70, 0x61, 0x71,
388         0x42, 0x52, 0x43, 0x53, 0x62, 0x72, 0x63, 0x73,
389         0x04, 0x14, 0x05, 0x15, 0x24, 0x34, 0x25, 0x35,
390         0x06, 0x16, 0x07, 0x17, 0x26, 0x36, 0x27, 0x37,
391         0x44, 0x54, 0x45, 0x55, 0x64, 0x74, 0x65, 0x75,
392         0x46, 0x56, 0x47, 0x57, 0x66, 0x76, 0x67, 0x77,
393         0x80, 0x90, 0x81, 0x91, 0xA0, 0xB0, 0xA1, 0xB1,
394         0x82, 0x92, 0x83, 0x93, 0xA2, 0xB2, 0xA3, 0xB3,
395         0xC0, 0xD0, 0xC1, 0xD1, 0xE0, 0xF0, 0xE1, 0xF1,
396         0xC2, 0xD2, 0xC3, 0xD3, 0xE2, 0xF2, 0xE3, 0xF3,
397         0x84, 0x94, 0x85, 0x95, 0xA4, 0xB4, 0xA5, 0xB5,
398         0x86, 0x96, 0x87, 0x97, 0xA6, 0xB6, 0xA7, 0xB7,
399         0xC4, 0xD4, 0xC5, 0xD5, 0xE4, 0xF4, 0xE5, 0xF5,
400         0xC6, 0xD6, 0xC7, 0xD7, 0xE6, 0xF6, 0xE7, 0xF7,
401         0x08, 0x18, 0x09, 0x19, 0x28, 0x38, 0x29, 0x39,
402         0x0A, 0x1A, 0x0B, 0x1B, 0x2A, 0x3A, 0x2B, 0x3B,
403         0x48, 0x58, 0x49, 0x59, 0x68, 0x78, 0x69, 0x79,
404         0x4A, 0x5A, 0x4B, 0x5B, 0x6A, 0x7A, 0x6B, 0x7B,
405         0x0C, 0x1C, 0x0D, 0x1D, 0x2C, 0x3C, 0x2D, 0x3D,
406         0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
407         0x4C, 0x5C, 0x4D, 0x5D, 0x6C, 0x7C, 0x6D, 0x7D,
408         0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
409         0x88, 0x98, 0x89, 0x99, 0xA8, 0xB8, 0xA9, 0xB9,
410         0x8A, 0x9A, 0x8B, 0x9B, 0xAA, 0xBA, 0xAB, 0xBB,
411         0xC8, 0xD8, 0xC9, 0xD9, 0xE8, 0xF8, 0xE9, 0xF9,
412         0xCA, 0xDA, 0xCB, 0xDB, 0xEA, 0xFA, 0xEB, 0xFB,
413         0x8C, 0x9C, 0x8D, 0x9D, 0xAC, 0xBC, 0xAD, 0xBD,
414         0x8E, 0x9E, 0x8F, 0x9F, 0xAE, 0xBE, 0xAF, 0xBF,
415         0xCC, 0xDC, 0xCD, 0xDD, 0xEC, 0xFC, 0xED, 0xFD,
416         0xCE, 0xDE, 0xCF, 0xDF, 0xEE, 0xFE, 0xEF, 0xFF
417     );
418
419     /**
420      * Inverse IP mapping helper table.
421      * Indexing this table with a byte value reverses the bit order.
422      *
423      * @var Array
424      * @access private
425      */
426     var $invipmap = array(
427         0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0,
428         0x10, 0x90, 0x50, 0xD0, 0x30, 0xB0, 0x70, 0xF0,
429         0x08, 0x88, 0x48, 0xC8, 0x28, 0xA8, 0x68, 0xE8,
430         0x18, 0x98, 0x58, 0xD8, 0x38, 0xB8, 0x78, 0xF8,
431         0x04, 0x84, 0x44, 0xC4, 0x24, 0xA4, 0x64, 0xE4,
432         0x14, 0x94, 0x54, 0xD4, 0x34, 0xB4, 0x74, 0xF4,
433         0x0C, 0x8C, 0x4C, 0xCC, 0x2C, 0xAC, 0x6C, 0xEC,
434         0x1C, 0x9C, 0x5C, 0xDC, 0x3C, 0xBC, 0x7C, 0xFC,
435         0x02, 0x82, 0x42, 0xC2, 0x22, 0xA2, 0x62, 0xE2,
436         0x12, 0x92, 0x52, 0xD2, 0x32, 0xB2, 0x72, 0xF2,
437         0x0A, 0x8A, 0x4A, 0xCA, 0x2A, 0xAA, 0x6A, 0xEA,
438         0x1A, 0x9A, 0x5A, 0xDA, 0x3A, 0xBA, 0x7A, 0xFA,
439         0x06, 0x86, 0x46, 0xC6, 0x26, 0xA6, 0x66, 0xE6,
440         0x16, 0x96, 0x56, 0xD6, 0x36, 0xB6, 0x76, 0xF6,
441         0x0E, 0x8E, 0x4E, 0xCE, 0x2E, 0xAE, 0x6E, 0xEE,
442         0x1E, 0x9E, 0x5E, 0xDE, 0x3E, 0xBE, 0x7E, 0xFE,
443         0x01, 0x81, 0x41, 0xC1, 0x21, 0xA1, 0x61, 0xE1,
444         0x11, 0x91, 0x51, 0xD1, 0x31, 0xB1, 0x71, 0xF1,
445         0x09, 0x89, 0x49, 0xC9, 0x29, 0xA9, 0x69, 0xE9,
446         0x19, 0x99, 0x59, 0xD9, 0x39, 0xB9, 0x79, 0xF9,
447         0x05, 0x85, 0x45, 0xC5, 0x25, 0xA5, 0x65, 0xE5,
448         0x15, 0x95, 0x55, 0xD5, 0x35, 0xB5, 0x75, 0xF5,
449         0x0D, 0x8D, 0x4D, 0xCD, 0x2D, 0xAD, 0x6D, 0xED,
450         0x1D, 0x9D, 0x5D, 0xDD, 0x3D, 0xBD, 0x7D, 0xFD,
451         0x03, 0x83, 0x43, 0xC3, 0x23, 0xA3, 0x63, 0xE3,
452         0x13, 0x93, 0x53, 0xD3, 0x33, 0xB3, 0x73, 0xF3,
453         0x0B, 0x8B, 0x4B, 0xCB, 0x2B, 0xAB, 0x6B, 0xEB,
454         0x1B, 0x9B, 0x5B, 0xDB, 0x3B, 0xBB, 0x7B, 0xFB,
455         0x07, 0x87, 0x47, 0xC7, 0x27, 0xA7, 0x67, 0xE7,
456         0x17, 0x97, 0x57, 0xD7, 0x37, 0xB7, 0x77, 0xF7,
457         0x0F, 0x8F, 0x4F, 0xCF, 0x2F, 0xAF, 0x6F, 0xEF,
458         0x1F, 0x9F, 0x5F, 0xDF, 0x3F, 0xBF, 0x7F, 0xFF
459     );
460
461     /**
462      * Pre-permuted S-box1
463      *
464      * Each box ($sbox1-$sbox8) has been vectorized, then each value pre-permuted using the
465      * P table: concatenation can then be replaced by exclusive ORs.
466      *
467      * @var Array
468      * @access private
469      */
470     var $sbox1 = array(
471         0x00808200, 0x00000000, 0x00008000, 0x00808202,
472         0x00808002, 0x00008202, 0x00000002, 0x00008000,
473         0x00000200, 0x00808200, 0x00808202, 0x00000200,
474         0x00800202, 0x00808002, 0x00800000, 0x00000002,
475         0x00000202, 0x00800200, 0x00800200, 0x00008200,
476         0x00008200, 0x00808000, 0x00808000, 0x00800202,
477         0x00008002, 0x00800002, 0x00800002, 0x00008002,
478         0x00000000, 0x00000202, 0x00008202, 0x00800000,
479         0x00008000, 0x00808202, 0x00000002, 0x00808000,
480         0x00808200, 0x00800000, 0x00800000, 0x00000200,
481         0x00808002, 0x00008000, 0x00008200, 0x00800002,
482         0x00000200, 0x00000002, 0x00800202, 0x00008202,
483         0x00808202, 0x00008002, 0x00808000, 0x00800202,
484         0x00800002, 0x00000202, 0x00008202, 0x00808200,
485         0x00000202, 0x00800200, 0x00800200, 0x00000000,
486         0x00008002, 0x00008200, 0x00000000, 0x00808002
487     );
488
489     /**
490      * Pre-permuted S-box2
491      *
492      * @var Array
493      * @access private
494      */
495     var $sbox2 = array(
496         0x40084010, 0x40004000, 0x00004000, 0x00084010,
497         0x00080000, 0x00000010, 0x40080010, 0x40004010,
498         0x40000010, 0x40084010, 0x40084000, 0x40000000,
499         0x40004000, 0x00080000, 0x00000010, 0x40080010,
500         0x00084000, 0x00080010, 0x40004010, 0x00000000,
501         0x40000000, 0x00004000, 0x00084010, 0x40080000,
502         0x00080010, 0x40000010, 0x00000000, 0x00084000,
503         0x00004010, 0x40084000, 0x40080000, 0x00004010,
504         0x00000000, 0x00084010, 0x40080010, 0x00080000,
505         0x40004010, 0x40080000, 0x40084000, 0x00004000,
506         0x40080000, 0x40004000, 0x00000010, 0x40084010,
507         0x00084010, 0x00000010, 0x00004000, 0x40000000,
508         0x00004010, 0x40084000, 0x00080000, 0x40000010,
509         0x00080010, 0x40004010, 0x40000010, 0x00080010,
510         0x00084000, 0x00000000, 0x40004000, 0x00004010,
511         0x40000000, 0x40080010, 0x40084010, 0x00084000
512     );
513
514     /**
515      * Pre-permuted S-box3
516      *
517      * @var Array
518      * @access private
519      */
520     var $sbox3 = array(
521         0x00000104, 0x04010100, 0x00000000, 0x04010004,
522         0x04000100, 0x00000000, 0x00010104, 0x04000100,
523         0x00010004, 0x04000004, 0x04000004, 0x00010000,
524         0x04010104, 0x00010004, 0x04010000, 0x00000104,
525         0x04000000, 0x00000004, 0x04010100, 0x00000100,
526         0x00010100, 0x04010000, 0x04010004, 0x00010104,
527         0x04000104, 0x00010100, 0x00010000, 0x04000104,
528         0x00000004, 0x04010104, 0x00000100, 0x04000000,
529         0x04010100, 0x04000000, 0x00010004, 0x00000104,
530         0x00010000, 0x04010100, 0x04000100, 0x00000000,
531         0x00000100, 0x00010004, 0x04010104, 0x04000100,
532         0x04000004, 0x00000100, 0x00000000, 0x04010004,
533         0x04000104, 0x00010000, 0x04000000, 0x04010104,
534         0x00000004, 0x00010104, 0x00010100, 0x04000004,
535         0x04010000, 0x04000104, 0x00000104, 0x04010000,
536         0x00010104, 0x00000004, 0x04010004, 0x00010100
537     );
538
539     /**
540      * Pre-permuted S-box4
541      *
542      * @var Array
543      * @access private
544      */
545     var $sbox4 = array(
546         0x80401000, 0x80001040, 0x80001040, 0x00000040,
547         0x00401040, 0x80400040, 0x80400000, 0x80001000,
548         0x00000000, 0x00401000, 0x00401000, 0x80401040,
549         0x80000040, 0x00000000, 0x00400040, 0x80400000,
550         0x80000000, 0x00001000, 0x00400000, 0x80401000,
551         0x00000040, 0x00400000, 0x80001000, 0x00001040,
552         0x80400040, 0x80000000, 0x00001040, 0x00400040,
553         0x00001000, 0x00401040, 0x80401040, 0x80000040,
554         0x00400040, 0x80400000, 0x00401000, 0x80401040,
555         0x80000040, 0x00000000, 0x00000000, 0x00401000,
556         0x00001040, 0x00400040, 0x80400040, 0x80000000,
557         0x80401000, 0x80001040, 0x80001040, 0x00000040,
558         0x80401040, 0x80000040, 0x80000000, 0x00001000,
559         0x80400000, 0x80001000, 0x00401040, 0x80400040,
560         0x80001000, 0x00001040, 0x00400000, 0x80401000,
561         0x00000040, 0x00400000, 0x00001000, 0x00401040
562     );
563
564     /**
565      * Pre-permuted S-box5
566      *
567      * @var Array
568      * @access private
569      */
570     var $sbox5 = array(
571         0x00000080, 0x01040080, 0x01040000, 0x21000080,
572         0x00040000, 0x00000080, 0x20000000, 0x01040000,
573         0x20040080, 0x00040000, 0x01000080, 0x20040080,
574         0x21000080, 0x21040000, 0x00040080, 0x20000000,
575         0x01000000, 0x20040000, 0x20040000, 0x00000000,
576         0x20000080, 0x21040080, 0x21040080, 0x01000080,
577         0x21040000, 0x20000080, 0x00000000, 0x21000000,
578         0x01040080, 0x01000000, 0x21000000, 0x00040080,
579         0x00040000, 0x21000080, 0x00000080, 0x01000000,
580         0x20000000, 0x01040000, 0x21000080, 0x20040080,
581         0x01000080, 0x20000000, 0x21040000, 0x01040080,
582         0x20040080, 0x00000080, 0x01000000, 0x21040000,
583         0x21040080, 0x00040080, 0x21000000, 0x21040080,
584         0x01040000, 0x00000000, 0x20040000, 0x21000000,
585         0x00040080, 0x01000080, 0x20000080, 0x00040000,
586         0x00000000, 0x20040000, 0x01040080, 0x20000080
587     );
588
589     /**
590      * Pre-permuted S-box6
591      *
592      * @var Array
593      * @access private
594      */
595     var $sbox6 = array(
596         0x10000008, 0x10200000, 0x00002000, 0x10202008,
597         0x10200000, 0x00000008, 0x10202008, 0x00200000,
598         0x10002000, 0x00202008, 0x00200000, 0x10000008,
599         0x00200008, 0x10002000, 0x10000000, 0x00002008,
600         0x00000000, 0x00200008, 0x10002008, 0x00002000,
601         0x00202000, 0x10002008, 0x00000008, 0x10200008,
602         0x10200008, 0x00000000, 0x00202008, 0x10202000,
603         0x00002008, 0x00202000, 0x10202000, 0x10000000,
604         0x10002000, 0x00000008, 0x10200008, 0x00202000,
605         0x10202008, 0x00200000, 0x00002008, 0x10000008,
606         0x00200000, 0x10002000, 0x10000000, 0x00002008,
607         0x10000008, 0x10202008, 0x00202000, 0x10200000,
608         0x00202008, 0x10202000, 0x00000000, 0x10200008,
609         0x00000008, 0x00002000, 0x10200000, 0x00202008,
610         0x00002000, 0x00200008, 0x10002008, 0x00000000,
611         0x10202000, 0x10000000, 0x00200008, 0x10002008
612     );
613
614     /**
615      * Pre-permuted S-box7
616      *
617      * @var Array
618      * @access private
619      */
620     var $sbox7 = array(
621         0x00100000, 0x02100001, 0x02000401, 0x00000000,
622         0x00000400, 0x02000401, 0x00100401, 0x02100400,
623         0x02100401, 0x00100000, 0x00000000, 0x02000001,
624         0x00000001, 0x02000000, 0x02100001, 0x00000401,
625         0x02000400, 0x00100401, 0x00100001, 0x02000400,
626         0x02000001, 0x02100000, 0x02100400, 0x00100001,
627         0x02100000, 0x00000400, 0x00000401, 0x02100401,
628         0x00100400, 0x00000001, 0x02000000, 0x00100400,
629         0x02000000, 0x00100400, 0x00100000, 0x02000401,
630         0x02000401, 0x02100001, 0x02100001, 0x00000001,
631         0x00100001, 0x02000000, 0x02000400, 0x00100000,
632         0x02100400, 0x00000401, 0x00100401, 0x02100400,
633         0x00000401, 0x02000001, 0x02100401, 0x02100000,
634         0x00100400, 0x00000000, 0x00000001, 0x02100401,
635         0x00000000, 0x00100401, 0x02100000, 0x00000400,
636         0x02000001, 0x02000400, 0x00000400, 0x00100001
637     );
638
639     /**
640      * Pre-permuted S-box8
641      *
642      * @var Array
643      * @access private
644      */
645     var $sbox8 = array(
646         0x08000820, 0x00000800, 0x00020000, 0x08020820,
647         0x08000000, 0x08000820, 0x00000020, 0x08000000,
648         0x00020020, 0x08020000, 0x08020820, 0x00020800,
649         0x08020800, 0x00020820, 0x00000800, 0x00000020,
650         0x08020000, 0x08000020, 0x08000800, 0x00000820,
651         0x00020800, 0x00020020, 0x08020020, 0x08020800,
652         0x00000820, 0x00000000, 0x00000000, 0x08020020,
653         0x08000020, 0x08000800, 0x00020820, 0x00020000,
654         0x00020820, 0x00020000, 0x08020800, 0x00000800,
655         0x00000020, 0x08020020, 0x00000800, 0x00020820,
656         0x08000800, 0x00000020, 0x08000020, 0x08020000,
657         0x08020020, 0x08000000, 0x00020000, 0x08000820,
658         0x00000000, 0x08020820, 0x00020020, 0x08000020,
659         0x08020000, 0x08000800, 0x08000820, 0x00000000,
660         0x08020820, 0x00020800, 0x00020800, 0x00000820,
661         0x00000820, 0x00020020, 0x08000000, 0x08020800
662     );
663
664     /**
665      * Sets the key.
666      *
667      * Keys can be of any length.  DES, itself, uses 64-bit keys (eg. strlen($key) == 8), however, we
668      * only use the first eight, if $key has more then eight characters in it, and pad $key with the
669      * null byte if it is less then eight characters long.
670      *
671      * DES also requires that every eighth bit be a parity bit, however, we'll ignore that.
672      *
673      * If the key is not explicitly set, it'll be assumed to be all zero's.
674      *
675      * @see Crypt_Base::setKey()
676      * @access public
677      * @param String $key
678      */
679     function setKey($key)
680     {
681         // We check/cut here only up to max length of the key.
682         // Key padding to the proper length will be done in _setupKey()
683         if (strlen($key) > $this->key_size_max) {
684             $key = substr($key, 0, $this->key_size_max);
685         }
686
687         // Sets the key
688         parent::setKey($key);
689     }
690
691     /**
692      * Encrypts a block
693      *
694      * @see Crypt_Base::_encryptBlock()
695      * @see Crypt_Base::encrypt()
696      * @see Crypt_DES::encrypt()
697      * @access private
698      * @param String $in
699      * @return String
700      */
701     function _encryptBlock($in)
702     {
703         return $this->_processBlock($in, CRYPT_DES_ENCRYPT);
704     }
705
706     /**
707      * Decrypts a block
708      *
709      * @see Crypt_Base::_decryptBlock()
710      * @see Crypt_Base::decrypt()
711      * @see Crypt_DES::decrypt()
712      * @access private
713      * @param String $in
714      * @return String
715      */
716     function _decryptBlock($in)
717     {
718         return $this->_processBlock($in, CRYPT_DES_DECRYPT);
719     }
720
721     /**
722      * Encrypts or decrypts a 64-bit block
723      *
724      * $mode should be either CRYPT_DES_ENCRYPT or CRYPT_DES_DECRYPT.  See
725      * {@link http://en.wikipedia.org/wiki/Image:Feistel.png Feistel.png} to get a general
726      * idea of what this function does.
727      *
728      * @see Crypt_DES::_encryptBlock()
729      * @see Crypt_DES::_decryptBlock()
730      * @access private
731      * @param String $block
732      * @param Integer $mode
733      * @return String
734      */
735     function _processBlock($block, $mode)
736     {
737         static $sbox1, $sbox2, $sbox3, $sbox4, $sbox5, $sbox6, $sbox7, $sbox8, $shuffleip, $shuffleinvip;
738         if (!$sbox1) {
739             $sbox1 = array_map("intval", $this->sbox1);
740             $sbox2 = array_map("intval", $this->sbox2);
741             $sbox3 = array_map("intval", $this->sbox3);
742             $sbox4 = array_map("intval", $this->sbox4);
743             $sbox5 = array_map("intval", $this->sbox5);
744             $sbox6 = array_map("intval", $this->sbox6);
745             $sbox7 = array_map("intval", $this->sbox7);
746             $sbox8 = array_map("intval", $this->sbox8);
747             /* Merge $shuffle with $[inv]ipmap */
748             for ($i = 0; $i < 256; ++$i) {
749                 $shuffleip[]    =  $this->shuffle[$this->ipmap[$i]];
750                 $shuffleinvip[] =  $this->shuffle[$this->invipmap[$i]];
751             }
752         }
753
754         $keys  = $this->keys[$mode];
755         $ki    = -1;
756
757         // Do the initial IP permutation.
758         $t = unpack('Nl/Nr', $block);
759         list($l, $r) = array($t['l'], $t['r']);
760         $block = ($shuffleip[ $r        & 0xFF] & "\x80\x80\x80\x80\x80\x80\x80\x80") |
761                  ($shuffleip[($r >>  8) & 0xFF] & "\x40\x40\x40\x40\x40\x40\x40\x40") |
762                  ($shuffleip[($r >> 16) & 0xFF] & "\x20\x20\x20\x20\x20\x20\x20\x20") |
763                  ($shuffleip[($r >> 24) & 0xFF] & "\x10\x10\x10\x10\x10\x10\x10\x10") |
764                  ($shuffleip[ $l        & 0xFF] & "\x08\x08\x08\x08\x08\x08\x08\x08") |
765                  ($shuffleip[($l >>  8) & 0xFF] & "\x04\x04\x04\x04\x04\x04\x04\x04") |
766                  ($shuffleip[($l >> 16) & 0xFF] & "\x02\x02\x02\x02\x02\x02\x02\x02") |
767                  ($shuffleip[($l >> 24) & 0xFF] & "\x01\x01\x01\x01\x01\x01\x01\x01");
768
769         // Extract L0 and R0.
770         $t = unpack('Nl/Nr', $block);
771         list($l, $r) = array($t['l'], $t['r']);
772
773         for ($des_round = 0; $des_round < $this->des_rounds; ++$des_round) {
774             // Perform the 16 steps.
775             for ($i = 0; $i < 16; $i++) {
776                 // start of "the Feistel (F) function" - see the following URL:
777                 // http://en.wikipedia.org/wiki/Image:Data_Encryption_Standard_InfoBox_Diagram.png
778                 // Merge key schedule.
779                 $b1 = (($r >>  3) & 0x1FFFFFFF) ^ ($r << 29) ^ $keys[++$ki];
780                 $b2 = (($r >> 31) & 0x00000001) ^ ($r <<  1) ^ $keys[++$ki];
781
782                 // S-box indexing.
783                 $t = $sbox1[($b1 >> 24) & 0x3F] ^ $sbox2[($b2 >> 24) & 0x3F] ^
784                      $sbox3[($b1 >> 16) & 0x3F] ^ $sbox4[($b2 >> 16) & 0x3F] ^
785                      $sbox5[($b1 >>  8) & 0x3F] ^ $sbox6[($b2 >>  8) & 0x3F] ^
786                      $sbox7[ $b1        & 0x3F] ^ $sbox8[ $b2        & 0x3F] ^ $l;
787                 // end of "the Feistel (F) function"
788
789                 $l = $r;
790                 $r = $t;
791             }
792
793             // Last step should not permute L & R.
794             $t = $l;
795             $l = $r;
796             $r = $t;
797         }
798
799         // Perform the inverse IP permutation.
800         return ($shuffleinvip[($r >> 24) & 0xFF] & "\x80\x80\x80\x80\x80\x80\x80\x80") |
801                ($shuffleinvip[($l >> 24) & 0xFF] & "\x40\x40\x40\x40\x40\x40\x40\x40") |
802                ($shuffleinvip[($r >> 16) & 0xFF] & "\x20\x20\x20\x20\x20\x20\x20\x20") |
803                ($shuffleinvip[($l >> 16) & 0xFF] & "\x10\x10\x10\x10\x10\x10\x10\x10") |
804                ($shuffleinvip[($r >>  8) & 0xFF] & "\x08\x08\x08\x08\x08\x08\x08\x08") |
805                ($shuffleinvip[($l >>  8) & 0xFF] & "\x04\x04\x04\x04\x04\x04\x04\x04") |
806                ($shuffleinvip[ $r        & 0xFF] & "\x02\x02\x02\x02\x02\x02\x02\x02") |
807                ($shuffleinvip[ $l        & 0xFF] & "\x01\x01\x01\x01\x01\x01\x01\x01");
808     }
809
810     /**
811      * Creates the key schedule
812      *
813      * @see Crypt_Base::_setupKey()
814      * @access private
815      */
816     function _setupKey()
817     {
818         if (isset($this->kl['key']) && $this->key === $this->kl['key'] && $this->des_rounds === $this->kl['des_rounds']) {
819             // already expanded
820             return;
821         }
822         $this->kl = array('key' => $this->key, 'des_rounds' => $this->des_rounds);
823
824         static $shifts = array( // number of key bits shifted per round
825             1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1
826         );
827
828         static $pc1map = array(
829             0x00, 0x00, 0x08, 0x08, 0x04, 0x04, 0x0C, 0x0C,
830             0x02, 0x02, 0x0A, 0x0A, 0x06, 0x06, 0x0E, 0x0E,
831             0x10, 0x10, 0x18, 0x18, 0x14, 0x14, 0x1C, 0x1C,
832             0x12, 0x12, 0x1A, 0x1A, 0x16, 0x16, 0x1E, 0x1E,
833             0x20, 0x20, 0x28, 0x28, 0x24, 0x24, 0x2C, 0x2C,
834             0x22, 0x22, 0x2A, 0x2A, 0x26, 0x26, 0x2E, 0x2E,
835             0x30, 0x30, 0x38, 0x38, 0x34, 0x34, 0x3C, 0x3C,
836             0x32, 0x32, 0x3A, 0x3A, 0x36, 0x36, 0x3E, 0x3E,
837             0x40, 0x40, 0x48, 0x48, 0x44, 0x44, 0x4C, 0x4C,
838             0x42, 0x42, 0x4A, 0x4A, 0x46, 0x46, 0x4E, 0x4E,
839             0x50, 0x50, 0x58, 0x58, 0x54, 0x54, 0x5C, 0x5C,
840             0x52, 0x52, 0x5A, 0x5A, 0x56, 0x56, 0x5E, 0x5E,
841             0x60, 0x60, 0x68, 0x68, 0x64, 0x64, 0x6C, 0x6C,
842             0x62, 0x62, 0x6A, 0x6A, 0x66, 0x66, 0x6E, 0x6E,
843             0x70, 0x70, 0x78, 0x78, 0x74, 0x74, 0x7C, 0x7C,
844             0x72, 0x72, 0x7A, 0x7A, 0x76, 0x76, 0x7E, 0x7E,
845             0x80, 0x80, 0x88, 0x88, 0x84, 0x84, 0x8C, 0x8C,
846             0x82, 0x82, 0x8A, 0x8A, 0x86, 0x86, 0x8E, 0x8E,
847             0x90, 0x90, 0x98, 0x98, 0x94, 0x94, 0x9C, 0x9C,
848             0x92, 0x92, 0x9A, 0x9A, 0x96, 0x96, 0x9E, 0x9E,
849             0xA0, 0xA0, 0xA8, 0xA8, 0xA4, 0xA4, 0xAC, 0xAC,
850             0xA2, 0xA2, 0xAA, 0xAA, 0xA6, 0xA6, 0xAE, 0xAE,
851             0xB0, 0xB0, 0xB8, 0xB8, 0xB4, 0xB4, 0xBC, 0xBC,
852             0xB2, 0xB2, 0xBA, 0xBA, 0xB6, 0xB6, 0xBE, 0xBE,
853             0xC0, 0xC0, 0xC8, 0xC8, 0xC4, 0xC4, 0xCC, 0xCC,
854             0xC2, 0xC2, 0xCA, 0xCA, 0xC6, 0xC6, 0xCE, 0xCE,
855             0xD0, 0xD0, 0xD8, 0xD8, 0xD4, 0xD4, 0xDC, 0xDC,
856             0xD2, 0xD2, 0xDA, 0xDA, 0xD6, 0xD6, 0xDE, 0xDE,
857             0xE0, 0xE0, 0xE8, 0xE8, 0xE4, 0xE4, 0xEC, 0xEC,
858             0xE2, 0xE2, 0xEA, 0xEA, 0xE6, 0xE6, 0xEE, 0xEE,
859             0xF0, 0xF0, 0xF8, 0xF8, 0xF4, 0xF4, 0xFC, 0xFC,
860             0xF2, 0xF2, 0xFA, 0xFA, 0xF6, 0xF6, 0xFE, 0xFE
861         );
862
863         // Mapping tables for the PC-2 transformation.
864         static $pc2mapc1 = array(
865             0x00000000, 0x00000400, 0x00200000, 0x00200400,
866             0x00000001, 0x00000401, 0x00200001, 0x00200401,
867             0x02000000, 0x02000400, 0x02200000, 0x02200400,
868             0x02000001, 0x02000401, 0x02200001, 0x02200401
869         );
870         static $pc2mapc2 = array(
871             0x00000000, 0x00000800, 0x08000000, 0x08000800,
872             0x00010000, 0x00010800, 0x08010000, 0x08010800,
873             0x00000000, 0x00000800, 0x08000000, 0x08000800,
874             0x00010000, 0x00010800, 0x08010000, 0x08010800,
875             0x00000100, 0x00000900, 0x08000100, 0x08000900,
876             0x00010100, 0x00010900, 0x08010100, 0x08010900,
877             0x00000100, 0x00000900, 0x08000100, 0x08000900,
878             0x00010100, 0x00010900, 0x08010100, 0x08010900,
879             0x00000010, 0x00000810, 0x08000010, 0x08000810,
880             0x00010010, 0x00010810, 0x08010010, 0x08010810,
881             0x00000010, 0x00000810, 0x08000010, 0x08000810,
882             0x00010010, 0x00010810, 0x08010010, 0x08010810,
883             0x00000110, 0x00000910, 0x08000110, 0x08000910,
884             0x00010110, 0x00010910, 0x08010110, 0x08010910,
885             0x00000110, 0x00000910, 0x08000110, 0x08000910,
886             0x00010110, 0x00010910, 0x08010110, 0x08010910,
887             0x00040000, 0x00040800, 0x08040000, 0x08040800,
888             0x00050000, 0x00050800, 0x08050000, 0x08050800,
889             0x00040000, 0x00040800, 0x08040000, 0x08040800,
890             0x00050000, 0x00050800, 0x08050000, 0x08050800,
891             0x00040100, 0x00040900, 0x08040100, 0x08040900,
892             0x00050100, 0x00050900, 0x08050100, 0x08050900,
893             0x00040100, 0x00040900, 0x08040100, 0x08040900,
894             0x00050100, 0x00050900, 0x08050100, 0x08050900,
895             0x00040010, 0x00040810, 0x08040010, 0x08040810,
896             0x00050010, 0x00050810, 0x08050010, 0x08050810,
897             0x00040010, 0x00040810, 0x08040010, 0x08040810,
898             0x00050010, 0x00050810, 0x08050010, 0x08050810,
899             0x00040110, 0x00040910, 0x08040110, 0x08040910,
900             0x00050110, 0x00050910, 0x08050110, 0x08050910,
901             0x00040110, 0x00040910, 0x08040110, 0x08040910,
902             0x00050110, 0x00050910, 0x08050110, 0x08050910,
903             0x01000000, 0x01000800, 0x09000000, 0x09000800,
904             0x01010000, 0x01010800, 0x09010000, 0x09010800,
905             0x01000000, 0x01000800, 0x09000000, 0x09000800,
906             0x01010000, 0x01010800, 0x09010000, 0x09010800,
907             0x01000100, 0x01000900, 0x09000100, 0x09000900,
908             0x01010100, 0x01010900, 0x09010100, 0x09010900,
909             0x01000100, 0x01000900, 0x09000100, 0x09000900,
910             0x01010100, 0x01010900, 0x09010100, 0x09010900,
911             0x01000010, 0x01000810, 0x09000010, 0x09000810,
912             0x01010010, 0x01010810, 0x09010010, 0x09010810,
913             0x01000010, 0x01000810, 0x09000010, 0x09000810,
914             0x01010010, 0x01010810, 0x09010010, 0x09010810,
915             0x01000110, 0x01000910, 0x09000110, 0x09000910,
916             0x01010110, 0x01010910, 0x09010110, 0x09010910,
917             0x01000110, 0x01000910, 0x09000110, 0x09000910,
918             0x01010110, 0x01010910, 0x09010110, 0x09010910,
919             0x01040000, 0x01040800, 0x09040000, 0x09040800,
920             0x01050000, 0x01050800, 0x09050000, 0x09050800,
921             0x01040000, 0x01040800, 0x09040000, 0x09040800,
922             0x01050000, 0x01050800, 0x09050000, 0x09050800,
923             0x01040100, 0x01040900, 0x09040100, 0x09040900,
924             0x01050100, 0x01050900, 0x09050100, 0x09050900,
925             0x01040100, 0x01040900, 0x09040100, 0x09040900,
926             0x01050100, 0x01050900, 0x09050100, 0x09050900,
927             0x01040010, 0x01040810, 0x09040010, 0x09040810,
928             0x01050010, 0x01050810, 0x09050010, 0x09050810,
929             0x01040010, 0x01040810, 0x09040010, 0x09040810,
930             0x01050010, 0x01050810, 0x09050010, 0x09050810,
931             0x01040110, 0x01040910, 0x09040110, 0x09040910,
932             0x01050110, 0x01050910, 0x09050110, 0x09050910,
933             0x01040110, 0x01040910, 0x09040110, 0x09040910,
934             0x01050110, 0x01050910, 0x09050110, 0x09050910
935         );
936         static $pc2mapc3 = array(
937             0x00000000, 0x00000004, 0x00001000, 0x00001004,
938             0x00000000, 0x00000004, 0x00001000, 0x00001004,
939             0x10000000, 0x10000004, 0x10001000, 0x10001004,
940             0x10000000, 0x10000004, 0x10001000, 0x10001004,
941             0x00000020, 0x00000024, 0x00001020, 0x00001024,
942             0x00000020, 0x00000024, 0x00001020, 0x00001024,
943             0x10000020, 0x10000024, 0x10001020, 0x10001024,
944             0x10000020, 0x10000024, 0x10001020, 0x10001024,
945             0x00080000, 0x00080004, 0x00081000, 0x00081004,
946             0x00080000, 0x00080004, 0x00081000, 0x00081004,
947             0x10080000, 0x10080004, 0x10081000, 0x10081004,
948             0x10080000, 0x10080004, 0x10081000, 0x10081004,
949             0x00080020, 0x00080024, 0x00081020, 0x00081024,
950             0x00080020, 0x00080024, 0x00081020, 0x00081024,
951             0x10080020, 0x10080024, 0x10081020, 0x10081024,
952             0x10080020, 0x10080024, 0x10081020, 0x10081024,
953             0x20000000, 0x20000004, 0x20001000, 0x20001004,
954             0x20000000, 0x20000004, 0x20001000, 0x20001004,
955             0x30000000, 0x30000004, 0x30001000, 0x30001004,
956             0x30000000, 0x30000004, 0x30001000, 0x30001004,
957             0x20000020, 0x20000024, 0x20001020, 0x20001024,
958             0x20000020, 0x20000024, 0x20001020, 0x20001024,
959             0x30000020, 0x30000024, 0x30001020, 0x30001024,
960             0x30000020, 0x30000024, 0x30001020, 0x30001024,
961             0x20080000, 0x20080004, 0x20081000, 0x20081004,
962             0x20080000, 0x20080004, 0x20081000, 0x20081004,
963             0x30080000, 0x30080004, 0x30081000, 0x30081004,
964             0x30080000, 0x30080004, 0x30081000, 0x30081004,
965             0x20080020, 0x20080024, 0x20081020, 0x20081024,
966             0x20080020, 0x20080024, 0x20081020, 0x20081024,
967             0x30080020, 0x30080024, 0x30081020, 0x30081024,
968             0x30080020, 0x30080024, 0x30081020, 0x30081024,
969             0x00000002, 0x00000006, 0x00001002, 0x00001006,
970             0x00000002, 0x00000006, 0x00001002, 0x00001006,
971             0x10000002, 0x10000006, 0x10001002, 0x10001006,
972             0x10000002, 0x10000006, 0x10001002, 0x10001006,
973             0x00000022, 0x00000026, 0x00001022, 0x00001026,
974             0x00000022, 0x00000026, 0x00001022, 0x00001026,
975             0x10000022, 0x10000026, 0x10001022, 0x10001026,
976             0x10000022, 0x10000026, 0x10001022, 0x10001026,
977             0x00080002, 0x00080006, 0x00081002, 0x00081006,
978             0x00080002, 0x00080006, 0x00081002, 0x00081006,
979             0x10080002, 0x10080006, 0x10081002, 0x10081006,
980             0x10080002, 0x10080006, 0x10081002, 0x10081006,
981             0x00080022, 0x00080026, 0x00081022, 0x00081026,
982             0x00080022, 0x00080026, 0x00081022, 0x00081026,
983             0x10080022, 0x10080026, 0x10081022, 0x10081026,
984             0x10080022, 0x10080026, 0x10081022, 0x10081026,
985             0x20000002, 0x20000006, 0x20001002, 0x20001006,
986             0x20000002, 0x20000006, 0x20001002, 0x20001006,
987             0x30000002, 0x30000006, 0x30001002, 0x30001006,
988             0x30000002, 0x30000006, 0x30001002, 0x30001006,
989             0x20000022, 0x20000026, 0x20001022, 0x20001026,
990             0x20000022, 0x20000026, 0x20001022, 0x20001026,
991             0x30000022, 0x30000026, 0x30001022, 0x30001026,
992             0x30000022, 0x30000026, 0x30001022, 0x30001026,
993             0x20080002, 0x20080006, 0x20081002, 0x20081006,
994             0x20080002, 0x20080006, 0x20081002, 0x20081006,
995             0x30080002, 0x30080006, 0x30081002, 0x30081006,
996             0x30080002, 0x30080006, 0x30081002, 0x30081006,
997             0x20080022, 0x20080026, 0x20081022, 0x20081026,
998             0x20080022, 0x20080026, 0x20081022, 0x20081026,
999             0x30080022, 0x30080026, 0x30081022, 0x30081026,
1000             0x30080022, 0x30080026, 0x30081022, 0x30081026
1001         );
1002         static $pc2mapc4 = array(
1003             0x00000000, 0x00100000, 0x00000008, 0x00100008,
1004             0x00000200, 0x00100200, 0x00000208, 0x00100208,
1005             0x00000000, 0x00100000, 0x00000008, 0x00100008,
1006             0x00000200, 0x00100200, 0x00000208, 0x00100208,
1007             0x04000000, 0x04100000, 0x04000008, 0x04100008,
1008             0x04000200, 0x04100200, 0x04000208, 0x04100208,
1009             0x04000000, 0x04100000, 0x04000008, 0x04100008,
1010             0x04000200, 0x04100200, 0x04000208, 0x04100208,
1011             0x00002000, 0x00102000, 0x00002008, 0x00102008,
1012             0x00002200, 0x00102200, 0x00002208, 0x00102208,
1013             0x00002000, 0x00102000, 0x00002008, 0x00102008,
1014             0x00002200, 0x00102200, 0x00002208, 0x00102208,
1015             0x04002000, 0x04102000, 0x04002008, 0x04102008,
1016             0x04002200, 0x04102200, 0x04002208, 0x04102208,
1017             0x04002000, 0x04102000, 0x04002008, 0x04102008,
1018             0x04002200, 0x04102200, 0x04002208, 0x04102208,
1019             0x00000000, 0x00100000, 0x00000008, 0x00100008,
1020             0x00000200, 0x00100200, 0x00000208, 0x00100208,
1021             0x00000000, 0x00100000, 0x00000008, 0x00100008,
1022             0x00000200, 0x00100200, 0x00000208, 0x00100208,
1023             0x04000000, 0x04100000, 0x04000008, 0x04100008,
1024             0x04000200, 0x04100200, 0x04000208, 0x04100208,
1025             0x04000000, 0x04100000, 0x04000008, 0x04100008,
1026             0x04000200, 0x04100200, 0x04000208, 0x04100208,
1027             0x00002000, 0x00102000, 0x00002008, 0x00102008,
1028             0x00002200, 0x00102200, 0x00002208, 0x00102208,
1029             0x00002000, 0x00102000, 0x00002008, 0x00102008,
1030             0x00002200, 0x00102200, 0x00002208, 0x00102208,
1031             0x04002000, 0x04102000, 0x04002008, 0x04102008,
1032             0x04002200, 0x04102200, 0x04002208, 0x04102208,
1033             0x04002000, 0x04102000, 0x04002008, 0x04102008,
1034             0x04002200, 0x04102200, 0x04002208, 0x04102208,
1035             0x00020000, 0x00120000, 0x00020008, 0x00120008,
1036             0x00020200, 0x00120200, 0x00020208, 0x00120208,
1037             0x00020000, 0x00120000, 0x00020008, 0x00120008,
1038             0x00020200, 0x00120200, 0x00020208, 0x00120208,
1039             0x04020000, 0x04120000, 0x04020008, 0x04120008,
1040             0x04020200, 0x04120200, 0x04020208, 0x04120208,
1041             0x04020000, 0x04120000, 0x04020008, 0x04120008,
1042             0x04020200, 0x04120200, 0x04020208, 0x04120208,
1043             0x00022000, 0x00122000, 0x00022008, 0x00122008,
1044             0x00022200, 0x00122200, 0x00022208, 0x00122208,
1045             0x00022000, 0x00122000, 0x00022008, 0x00122008,
1046             0x00022200, 0x00122200, 0x00022208, 0x00122208,
1047             0x04022000, 0x04122000, 0x04022008, 0x04122008,
1048             0x04022200, 0x04122200, 0x04022208, 0x04122208,
1049             0x04022000, 0x04122000, 0x04022008, 0x04122008,
1050             0x04022200, 0x04122200, 0x04022208, 0x04122208,
1051             0x00020000, 0x00120000, 0x00020008, 0x00120008,
1052             0x00020200, 0x00120200, 0x00020208, 0x00120208,
1053             0x00020000, 0x00120000, 0x00020008, 0x00120008,
1054             0x00020200, 0x00120200, 0x00020208, 0x00120208,
1055             0x04020000, 0x04120000, 0x04020008, 0x04120008,
1056             0x04020200, 0x04120200, 0x04020208, 0x04120208,
1057             0x04020000, 0x04120000, 0x04020008, 0x04120008,
1058             0x04020200, 0x04120200, 0x04020208, 0x04120208,
1059             0x00022000, 0x00122000, 0x00022008, 0x00122008,
1060             0x00022200, 0x00122200, 0x00022208, 0x00122208,
1061             0x00022000, 0x00122000, 0x00022008, 0x00122008,
1062             0x00022200, 0x00122200, 0x00022208, 0x00122208,
1063             0x04022000, 0x04122000, 0x04022008, 0x04122008,
1064             0x04022200, 0x04122200, 0x04022208, 0x04122208,
1065             0x04022000, 0x04122000, 0x04022008, 0x04122008,
1066             0x04022200, 0x04122200, 0x04022208, 0x04122208
1067         );
1068         static $pc2mapd1 = array(
1069             0x00000000, 0x00000001, 0x08000000, 0x08000001,
1070             0x00200000, 0x00200001, 0x08200000, 0x08200001,
1071             0x00000002, 0x00000003, 0x08000002, 0x08000003,
1072             0x00200002, 0x00200003, 0x08200002, 0x08200003
1073         );
1074         static $pc2mapd2 = array(
1075             0x00000000, 0x00100000, 0x00000800, 0x00100800,
1076             0x00000000, 0x00100000, 0x00000800, 0x00100800,
1077             0x04000000, 0x04100000, 0x04000800, 0x04100800,
1078             0x04000000, 0x04100000, 0x04000800, 0x04100800,
1079             0x00000004, 0x00100004, 0x00000804, 0x00100804,
1080             0x00000004, 0x00100004, 0x00000804, 0x00100804,
1081             0x04000004, 0x04100004, 0x04000804, 0x04100804,
1082             0x04000004, 0x04100004, 0x04000804, 0x04100804,
1083             0x00000000, 0x00100000, 0x00000800, 0x00100800,
1084             0x00000000, 0x00100000, 0x00000800, 0x00100800,
1085             0x04000000, 0x04100000, 0x04000800, 0x04100800,
1086             0x04000000, 0x04100000, 0x04000800, 0x04100800,
1087             0x00000004, 0x00100004, 0x00000804, 0x00100804,
1088             0x00000004, 0x00100004, 0x00000804, 0x00100804,
1089             0x04000004, 0x04100004, 0x04000804, 0x04100804,
1090             0x04000004, 0x04100004, 0x04000804, 0x04100804,
1091             0x00000200, 0x00100200, 0x00000A00, 0x00100A00,
1092             0x00000200, 0x00100200, 0x00000A00, 0x00100A00,
1093             0x04000200, 0x04100200, 0x04000A00, 0x04100A00,
1094             0x04000200, 0x04100200, 0x04000A00, 0x04100A00,
1095             0x00000204, 0x00100204, 0x00000A04, 0x00100A04,
1096             0x00000204, 0x00100204, 0x00000A04, 0x00100A04,
1097             0x04000204, 0x04100204, 0x04000A04, 0x04100A04,
1098             0x04000204, 0x04100204, 0x04000A04, 0x04100A04,
1099             0x00000200, 0x00100200, 0x00000A00, 0x00100A00,
1100             0x00000200, 0x00100200, 0x00000A00, 0x00100A00,
1101             0x04000200, 0x04100200, 0x04000A00, 0x04100A00,
1102             0x04000200, 0x04100200, 0x04000A00, 0x04100A00,
1103             0x00000204, 0x00100204, 0x00000A04, 0x00100A04,
1104             0x00000204, 0x00100204, 0x00000A04, 0x00100A04,
1105             0x04000204, 0x04100204, 0x04000A04, 0x04100A04,
1106             0x04000204, 0x04100204, 0x04000A04, 0x04100A04,
1107             0x00020000, 0x00120000, 0x00020800, 0x00120800,
1108             0x00020000, 0x00120000, 0x00020800, 0x00120800,
1109             0x04020000, 0x04120000, 0x04020800, 0x04120800,
1110             0x04020000, 0x04120000, 0x04020800, 0x04120800,
1111             0x00020004, 0x00120004, 0x00020804, 0x00120804,
1112             0x00020004, 0x00120004, 0x00020804, 0x00120804,
1113             0x04020004, 0x04120004, 0x04020804, 0x04120804,
1114             0x04020004, 0x04120004, 0x04020804, 0x04120804,
1115             0x00020000, 0x00120000, 0x00020800, 0x00120800,
1116             0x00020000, 0x00120000, 0x00020800, 0x00120800,
1117             0x04020000, 0x04120000, 0x04020800, 0x04120800,
1118             0x04020000, 0x04120000, 0x04020800, 0x04120800,
1119             0x00020004, 0x00120004, 0x00020804, 0x00120804,
1120             0x00020004, 0x00120004, 0x00020804, 0x00120804,
1121             0x04020004, 0x04120004, 0x04020804, 0x04120804,
1122             0x04020004, 0x04120004, 0x04020804, 0x04120804,
1123             0x00020200, 0x00120200, 0x00020A00, 0x00120A00,
1124             0x00020200, 0x00120200, 0x00020A00, 0x00120A00,
1125             0x04020200, 0x04120200, 0x04020A00, 0x04120A00,
1126             0x04020200, 0x04120200, 0x04020A00, 0x04120A00,
1127             0x00020204, 0x00120204, 0x00020A04, 0x00120A04,
1128             0x00020204, 0x00120204, 0x00020A04, 0x00120A04,
1129             0x04020204, 0x04120204, 0x04020A04, 0x04120A04,
1130             0x04020204, 0x04120204, 0x04020A04, 0x04120A04,
1131             0x00020200, 0x00120200, 0x00020A00, 0x00120A00,
1132             0x00020200, 0x00120200, 0x00020A00, 0x00120A00,
1133             0x04020200, 0x04120200, 0x04020A00, 0x04120A00,
1134             0x04020200, 0x04120200, 0x04020A00, 0x04120A00,
1135             0x00020204, 0x00120204, 0x00020A04, 0x00120A04,
1136             0x00020204, 0x00120204, 0x00020A04, 0x00120A04,
1137             0x04020204, 0x04120204, 0x04020A04, 0x04120A04,
1138             0x04020204, 0x04120204, 0x04020A04, 0x04120A04
1139         );
1140         static $pc2mapd3 = array(
1141             0x00000000, 0x00010000, 0x02000000, 0x02010000,
1142             0x00000020, 0x00010020, 0x02000020, 0x02010020,
1143             0x00040000, 0x00050000, 0x02040000, 0x02050000,
1144             0x00040020, 0x00050020, 0x02040020, 0x02050020,
1145             0x00002000, 0x00012000, 0x02002000, 0x02012000,
1146             0x00002020, 0x00012020, 0x02002020, 0x02012020,
1147             0x00042000, 0x00052000, 0x02042000, 0x02052000,
1148             0x00042020, 0x00052020, 0x02042020, 0x02052020,
1149             0x00000000, 0x00010000, 0x02000000, 0x02010000,
1150             0x00000020, 0x00010020, 0x02000020, 0x02010020,
1151             0x00040000, 0x00050000, 0x02040000, 0x02050000,
1152             0x00040020, 0x00050020, 0x02040020, 0x02050020,
1153             0x00002000, 0x00012000, 0x02002000, 0x02012000,
1154             0x00002020, 0x00012020, 0x02002020, 0x02012020,
1155             0x00042000, 0x00052000, 0x02042000, 0x02052000,
1156             0x00042020, 0x00052020, 0x02042020, 0x02052020,
1157             0x00000010, 0x00010010, 0x02000010, 0x02010010,
1158             0x00000030, 0x00010030, 0x02000030, 0x02010030,
1159             0x00040010, 0x00050010, 0x02040010, 0x02050010,
1160             0x00040030, 0x00050030, 0x02040030, 0x02050030,
1161             0x00002010, 0x00012010, 0x02002010, 0x02012010,
1162             0x00002030, 0x00012030, 0x02002030, 0x02012030,
1163             0x00042010, 0x00052010, 0x02042010, 0x02052010,
1164             0x00042030, 0x00052030, 0x02042030, 0x02052030,
1165             0x00000010, 0x00010010, 0x02000010, 0x02010010,
1166             0x00000030, 0x00010030, 0x02000030, 0x02010030,
1167             0x00040010, 0x00050010, 0x02040010, 0x02050010,
1168             0x00040030, 0x00050030, 0x02040030, 0x02050030,
1169             0x00002010, 0x00012010, 0x02002010, 0x02012010,
1170             0x00002030, 0x00012030, 0x02002030, 0x02012030,
1171             0x00042010, 0x00052010, 0x02042010, 0x02052010,
1172             0x00042030, 0x00052030, 0x02042030, 0x02052030,
1173             0x20000000, 0x20010000, 0x22000000, 0x22010000,
1174             0x20000020, 0x20010020, 0x22000020, 0x22010020,
1175             0x20040000, 0x20050000, 0x22040000, 0x22050000,
1176             0x20040020, 0x20050020, 0x22040020, 0x22050020,
1177             0x20002000, 0x20012000, 0x22002000, 0x22012000,
1178             0x20002020, 0x20012020, 0x22002020, 0x22012020,
1179             0x20042000, 0x20052000, 0x22042000, 0x22052000,
1180             0x20042020, 0x20052020, 0x22042020, 0x22052020,
1181             0x20000000, 0x20010000, 0x22000000, 0x22010000,
1182             0x20000020, 0x20010020, 0x22000020, 0x22010020,
1183             0x20040000, 0x20050000, 0x22040000, 0x22050000,
1184             0x20040020, 0x20050020, 0x22040020, 0x22050020,
1185             0x20002000, 0x20012000, 0x22002000, 0x22012000,
1186             0x20002020, 0x20012020, 0x22002020, 0x22012020,
1187             0x20042000, 0x20052000, 0x22042000, 0x22052000,
1188             0x20042020, 0x20052020, 0x22042020, 0x22052020,
1189             0x20000010, 0x20010010, 0x22000010, 0x22010010,
1190             0x20000030, 0x20010030, 0x22000030, 0x22010030,
1191             0x20040010, 0x20050010, 0x22040010, 0x22050010,
1192             0x20040030, 0x20050030, 0x22040030, 0x22050030,
1193             0x20002010, 0x20012010, 0x22002010, 0x22012010,
1194             0x20002030, 0x20012030, 0x22002030, 0x22012030,
1195             0x20042010, 0x20052010, 0x22042010, 0x22052010,
1196             0x20042030, 0x20052030, 0x22042030, 0x22052030,
1197             0x20000010, 0x20010010, 0x22000010, 0x22010010,
1198             0x20000030, 0x20010030, 0x22000030, 0x22010030,
1199             0x20040010, 0x20050010, 0x22040010, 0x22050010,
1200             0x20040030, 0x20050030, 0x22040030, 0x22050030,
1201             0x20002010, 0x20012010, 0x22002010, 0x22012010,
1202             0x20002030, 0x20012030, 0x22002030, 0x22012030,
1203             0x20042010, 0x20052010, 0x22042010, 0x22052010,
1204             0x20042030, 0x20052030, 0x22042030, 0x22052030
1205         );
1206         static $pc2mapd4 = array(
1207             0x00000000, 0x00000400, 0x01000000, 0x01000400,
1208             0x00000000, 0x00000400, 0x01000000, 0x01000400,
1209             0x00000100, 0x00000500, 0x01000100, 0x01000500,
1210             0x00000100, 0x00000500, 0x01000100, 0x01000500,
1211             0x10000000, 0x10000400, 0x11000000, 0x11000400,
1212             0x10000000, 0x10000400, 0x11000000, 0x11000400,
1213             0x10000100, 0x10000500, 0x11000100, 0x11000500,
1214             0x10000100, 0x10000500, 0x11000100, 0x11000500,
1215             0x00080000, 0x00080400, 0x01080000, 0x01080400,
1216             0x00080000, 0x00080400, 0x01080000, 0x01080400,
1217             0x00080100, 0x00080500, 0x01080100, 0x01080500,
1218             0x00080100, 0x00080500, 0x01080100, 0x01080500,
1219             0x10080000, 0x10080400, 0x11080000, 0x11080400,
1220             0x10080000, 0x10080400, 0x11080000, 0x11080400,
1221             0x10080100, 0x10080500, 0x11080100, 0x11080500,
1222             0x10080100, 0x10080500, 0x11080100, 0x11080500,
1223             0x00000008, 0x00000408, 0x01000008, 0x01000408,
1224             0x00000008, 0x00000408, 0x01000008, 0x01000408,
1225             0x00000108, 0x00000508, 0x01000108, 0x01000508,
1226             0x00000108, 0x00000508, 0x01000108, 0x01000508,
1227             0x10000008, 0x10000408, 0x11000008, 0x11000408,
1228             0x10000008, 0x10000408, 0x11000008, 0x11000408,
1229             0x10000108, 0x10000508, 0x11000108, 0x11000508,
1230             0x10000108, 0x10000508, 0x11000108, 0x11000508,
1231             0x00080008, 0x00080408, 0x01080008, 0x01080408,
1232             0x00080008, 0x00080408, 0x01080008, 0x01080408,
1233             0x00080108, 0x00080508, 0x01080108, 0x01080508,
1234             0x00080108, 0x00080508, 0x01080108, 0x01080508,
1235             0x10080008, 0x10080408, 0x11080008, 0x11080408,
1236             0x10080008, 0x10080408, 0x11080008, 0x11080408,
1237             0x10080108, 0x10080508, 0x11080108, 0x11080508,
1238             0x10080108, 0x10080508, 0x11080108, 0x11080508,
1239             0x00001000, 0x00001400, 0x01001000, 0x01001400,
1240             0x00001000, 0x00001400, 0x01001000, 0x01001400,
1241             0x00001100, 0x00001500, 0x01001100, 0x01001500,
1242             0x00001100, 0x00001500, 0x01001100, 0x01001500,
1243             0x10001000, 0x10001400, 0x11001000, 0x11001400,
1244             0x10001000, 0x10001400, 0x11001000, 0x11001400,
1245             0x10001100, 0x10001500, 0x11001100, 0x11001500,
1246             0x10001100, 0x10001500, 0x11001100, 0x11001500,
1247             0x00081000, 0x00081400, 0x01081000, 0x01081400,
1248             0x00081000, 0x00081400, 0x01081000, 0x01081400,
1249             0x00081100, 0x00081500, 0x01081100, 0x01081500,
1250             0x00081100, 0x00081500, 0x01081100, 0x01081500,
1251             0x10081000, 0x10081400, 0x11081000, 0x11081400,
1252             0x10081000, 0x10081400, 0x11081000, 0x11081400,
1253             0x10081100, 0x10081500, 0x11081100, 0x11081500,
1254             0x10081100, 0x10081500, 0x11081100, 0x11081500,
1255             0x00001008, 0x00001408, 0x01001008, 0x01001408,
1256             0x00001008, 0x00001408, 0x01001008, 0x01001408,
1257             0x00001108, 0x00001508, 0x01001108, 0x01001508,
1258             0x00001108, 0x00001508, 0x01001108, 0x01001508,
1259             0x10001008, 0x10001408, 0x11001008, 0x11001408,
1260             0x10001008, 0x10001408, 0x11001008, 0x11001408,
1261             0x10001108, 0x10001508, 0x11001108, 0x11001508,
1262             0x10001108, 0x10001508, 0x11001108, 0x11001508,
1263             0x00081008, 0x00081408, 0x01081008, 0x01081408,
1264             0x00081008, 0x00081408, 0x01081008, 0x01081408,
1265             0x00081108, 0x00081508, 0x01081108, 0x01081508,
1266             0x00081108, 0x00081508, 0x01081108, 0x01081508,
1267             0x10081008, 0x10081408, 0x11081008, 0x11081408,
1268             0x10081008, 0x10081408, 0x11081008, 0x11081408,
1269             0x10081108, 0x10081508, 0x11081108, 0x11081508,
1270             0x10081108, 0x10081508, 0x11081108, 0x11081508
1271         );
1272
1273         $keys = array();
1274         for ($des_round = 0; $des_round < $this->des_rounds; ++$des_round) {
1275             // pad the key and remove extra characters as appropriate.
1276             $key = str_pad(substr($this->key, $des_round * 8, 8), 8, "\0");
1277
1278             // Perform the PC/1 transformation and compute C and D.
1279             $t = unpack('Nl/Nr', $key);
1280             list($l, $r) = array($t['l'], $t['r']);
1281             $key = ($this->shuffle[$pc1map[ $r        & 0xFF]] & "\x80\x80\x80\x80\x80\x80\x80\x00") |
1282                    ($this->shuffle[$pc1map[($r >>  8) & 0xFF]] & "\x40\x40\x40\x40\x40\x40\x40\x00") |
1283                    ($this->shuffle[$pc1map[($r >> 16) & 0xFF]] & "\x20\x20\x20\x20\x20\x20\x20\x00") |
1284                    ($this->shuffle[$pc1map[($r >> 24) & 0xFF]] & "\x10\x10\x10\x10\x10\x10\x10\x00") |
1285                    ($this->shuffle[$pc1map[ $l        & 0xFF]] & "\x08\x08\x08\x08\x08\x08\x08\x00") |
1286                    ($this->shuffle[$pc1map[($l >>  8) & 0xFF]] & "\x04\x04\x04\x04\x04\x04\x04\x00") |
1287                    ($this->shuffle[$pc1map[($l >> 16) & 0xFF]] & "\x02\x02\x02\x02\x02\x02\x02\x00") |
1288                    ($this->shuffle[$pc1map[($l >> 24) & 0xFF]] & "\x01\x01\x01\x01\x01\x01\x01\x00");
1289             $key = unpack('Nc/Nd', $key);
1290             $c = ( $key['c'] >> 4) & 0x0FFFFFFF;
1291             $d = (($key['d'] >> 4) & 0x0FFFFFF0) | ($key['c'] & 0x0F);
1292
1293             $keys[$des_round] = array(
1294                 CRYPT_DES_ENCRYPT => array(),
1295                 CRYPT_DES_DECRYPT => array_fill(0, 32, 0)
1296             );
1297             for ($i = 0, $ki = 31; $i < 16; ++$i, $ki-= 2) {
1298                 $c <<= $shifts[$i];
1299                 $c = ($c | ($c >> 28)) & 0x0FFFFFFF;
1300                 $d <<= $shifts[$i];
1301                 $d = ($d | ($d >> 28)) & 0x0FFFFFFF;
1302
1303                 // Perform the PC-2 transformation.
1304                 $cp = $pc2mapc1[ $c >> 24        ] | $pc2mapc2[($c >> 16) & 0xFF] |
1305                       $pc2mapc3[($c >>  8) & 0xFF] | $pc2mapc4[ $c        & 0xFF];
1306                 $dp = $pc2mapd1[ $d >> 24        ] | $pc2mapd2[($d >> 16) & 0xFF] |
1307                       $pc2mapd3[($d >>  8) & 0xFF] | $pc2mapd4[ $d        & 0xFF];
1308
1309                 // Reorder: odd bytes/even bytes. Push the result in key schedule.
1310                 $val1 = ( $cp        & 0xFF000000) | (($cp <<  8) & 0x00FF0000) |
1311                         (($dp >> 16) & 0x0000FF00) | (($dp >>  8) & 0x000000FF);
1312                 $val2 = (($cp <<  8) & 0xFF000000) | (($cp << 16) & 0x00FF0000) |
1313                         (($dp >>  8) & 0x0000FF00) | ( $dp        & 0x000000FF);
1314                 $keys[$des_round][CRYPT_DES_ENCRYPT][       ] = $val1;
1315                 $keys[$des_round][CRYPT_DES_DECRYPT][$ki - 1] = $val1;
1316                 $keys[$des_round][CRYPT_DES_ENCRYPT][       ] = $val2;
1317                 $keys[$des_round][CRYPT_DES_DECRYPT][$ki    ] = $val2;
1318             }
1319         }
1320
1321         switch ($this->des_rounds) {
1322             case 3: // 3DES keys
1323                 $this->keys = array(
1324                     CRYPT_DES_ENCRYPT => array_merge(
1325                         $keys[0][CRYPT_DES_ENCRYPT],
1326                         $keys[1][CRYPT_DES_DECRYPT],
1327                         $keys[2][CRYPT_DES_ENCRYPT]
1328                     ),
1329                     CRYPT_DES_DECRYPT => array_merge(
1330                         $keys[2][CRYPT_DES_DECRYPT],
1331                         $keys[1][CRYPT_DES_ENCRYPT],
1332                         $keys[0][CRYPT_DES_DECRYPT]
1333                     )
1334                 );
1335                 break;
1336             // case 1: // DES keys
1337             default:
1338                 $this->keys = array(
1339                     CRYPT_DES_ENCRYPT => $keys[0][CRYPT_DES_ENCRYPT],
1340                     CRYPT_DES_DECRYPT => $keys[0][CRYPT_DES_DECRYPT]
1341                 );
1342         }
1343     }
1344
1345     /**
1346      * Setup the performance-optimized function for de/encrypt()
1347      *
1348      * @see Crypt_Base::_setupInlineCrypt()
1349      * @access private
1350      */
1351     function _setupInlineCrypt()
1352     {
1353         $lambda_functions =& Crypt_DES::_getLambdaFunctions();
1354
1355         // Engine configuration for:
1356         // -  DES ($des_rounds == 1) or
1357         // - 3DES ($des_rounds == 3)
1358         $des_rounds = $this->des_rounds;
1359
1360         // We create max. 10 hi-optimized code for memory reason. Means: For each $key one ultra fast inline-crypt function.
1361         // After that, we'll still create very fast optimized code but not the hi-ultimative code, for each $mode one
1362         $gen_hi_opt_code = (bool)( count($lambda_functions) < 10 );
1363
1364         // Generation of a uniqe hash for our generated code
1365         switch (true) {
1366             case $gen_hi_opt_code:
1367                 // For hi-optimized code, we create for each combination of
1368                 // $mode, $des_rounds and $this->key its own encrypt/decrypt function.
1369                 $code_hash = md5(str_pad("Crypt_DES, $des_rounds, {$this->mode}, ", 32, "\0") . $this->key);
1370                 break;
1371             default:
1372                 // After max 10 hi-optimized functions, we create generic
1373                 // (still very fast.. but not ultra) functions for each $mode/$des_rounds
1374                 // Currently 2 * 5 generic functions will be then max. possible.
1375                 $code_hash = "Crypt_DES, $des_rounds, {$this->mode}";
1376         }
1377
1378         // Is there a re-usable $lambda_functions in there? If not, we have to create it.
1379         if (!isset($lambda_functions[$code_hash])) {
1380             // Init code for both, encrypt and decrypt.
1381             $init_crypt = 'static $sbox1, $sbox2, $sbox3, $sbox4, $sbox5, $sbox6, $sbox7, $sbox8, $shuffleip, $shuffleinvip;
1382                 if (!$sbox1) {
1383                     $sbox1 = array_map("intval", $self->sbox1);
1384                     $sbox2 = array_map("intval", $self->sbox2);
1385                     $sbox3 = array_map("intval", $self->sbox3);
1386                     $sbox4 = array_map("intval", $self->sbox4);
1387                     $sbox5 = array_map("intval", $self->sbox5);
1388                     $sbox6 = array_map("intval", $self->sbox6);
1389                     $sbox7 = array_map("intval", $self->sbox7);
1390                     $sbox8 = array_map("intval", $self->sbox8);'
1391                     /* Merge $shuffle with $[inv]ipmap */ . '
1392                     for ($i = 0; $i < 256; ++$i) {
1393                         $shuffleip[]    =  $self->shuffle[$self->ipmap[$i]];
1394                         $shuffleinvip[] =  $self->shuffle[$self->invipmap[$i]];
1395                     }
1396                 }
1397             ';
1398
1399             switch (true) {
1400                 case $gen_hi_opt_code:
1401                     // In Hi-optimized code mode, we use our [3]DES key schedule as hardcoded integers.
1402                     // No futher initialisation of the $keys schedule is necessary.
1403                     // That is the extra performance boost.
1404                     $k = array(
1405                         CRYPT_DES_ENCRYPT => $this->keys[CRYPT_DES_ENCRYPT],
1406                         CRYPT_DES_DECRYPT => $this->keys[CRYPT_DES_DECRYPT]
1407                     );
1408                     $init_encrypt = '';
1409                     $init_decrypt = '';
1410                     break;
1411                 default:
1412                     // In generic optimized code mode, we have to use, as the best compromise [currently],
1413                     // our key schedule as $ke/$kd arrays. (with hardcoded indexes...)
1414                     $k = array(
1415                         CRYPT_DES_ENCRYPT => array(),
1416                         CRYPT_DES_DECRYPT => array()
1417                     );
1418                     for ($i = 0, $c = count($this->keys[CRYPT_DES_ENCRYPT]); $i < $c; ++$i) {
1419                         $k[CRYPT_DES_ENCRYPT][$i] = '$ke[' . $i . ']';
1420                         $k[CRYPT_DES_DECRYPT][$i] = '$kd[' . $i . ']';
1421                     }
1422                     $init_encrypt = '$ke = $self->keys[CRYPT_DES_ENCRYPT];';
1423                     $init_decrypt = '$kd = $self->keys[CRYPT_DES_DECRYPT];';
1424                     break;
1425             }
1426
1427             // Creating code for en- and decryption.
1428             $crypt_block = array();
1429             foreach (array(CRYPT_DES_ENCRYPT, CRYPT_DES_DECRYPT) as $c) {
1430
1431                 /* Do the initial IP permutation. */
1432                 $crypt_block[$c] = '
1433                     $in = unpack("N*", $in);
1434                     $l  = $in[1];
1435                     $r  = $in[2];
1436                     $in = unpack("N*",
1437                         ($shuffleip[ $r        & 0xFF] & "\x80\x80\x80\x80\x80\x80\x80\x80") |
1438                         ($shuffleip[($r >>  8) & 0xFF] & "\x40\x40\x40\x40\x40\x40\x40\x40") |
1439                         ($shuffleip[($r >> 16) & 0xFF] & "\x20\x20\x20\x20\x20\x20\x20\x20") |
1440                         ($shuffleip[($r >> 24) & 0xFF] & "\x10\x10\x10\x10\x10\x10\x10\x10") |
1441                         ($shuffleip[ $l        & 0xFF] & "\x08\x08\x08\x08\x08\x08\x08\x08") |
1442                         ($shuffleip[($l >>  8) & 0xFF] & "\x04\x04\x04\x04\x04\x04\x04\x04") |
1443                         ($shuffleip[($l >> 16) & 0xFF] & "\x02\x02\x02\x02\x02\x02\x02\x02") |
1444                         ($shuffleip[($l >> 24) & 0xFF] & "\x01\x01\x01\x01\x01\x01\x01\x01")
1445                     );
1446                     ' . /* Extract L0 and R0 */ '
1447                     $l = $in[1];
1448                     $r = $in[2];
1449                 ';
1450
1451                 $l = '$l';
1452                 $r = '$r';
1453
1454                 // Perform DES or 3DES.
1455                 for ($ki = -1, $des_round = 0; $des_round < $des_rounds; ++$des_round) {
1456                     // Perform the 16 steps.
1457                     for ($i = 0; $i < 16; ++$i) {
1458                         // start of "the Feistel (F) function" - see the following URL:
1459                         // http://en.wikipedia.org/wiki/Image:Data_Encryption_Standard_InfoBox_Diagram.png
1460                         // Merge key schedule.
1461                         $crypt_block[$c].= '
1462                             $b1 = ((' . $r . ' >>  3) & 0x1FFFFFFF)  ^ (' . $r . ' << 29) ^ ' . $k[$c][++$ki] . ';
1463                             $b2 = ((' . $r . ' >> 31) & 0x00000001)  ^ (' . $r . ' <<  1) ^ ' . $k[$c][++$ki] . ';' .
1464                             /* S-box indexing. */
1465                             $l . ' = $sbox1[($b1 >> 24) & 0x3F] ^ $sbox2[($b2 >> 24) & 0x3F] ^
1466                                      $sbox3[($b1 >> 16) & 0x3F] ^ $sbox4[($b2 >> 16) & 0x3F] ^
1467                                      $sbox5[($b1 >>  8) & 0x3F] ^ $sbox6[($b2 >>  8) & 0x3F] ^
1468                                      $sbox7[ $b1        & 0x3F] ^ $sbox8[ $b2        & 0x3F] ^ ' . $l . ';
1469                         ';
1470                         // end of "the Feistel (F) function"
1471
1472                         // swap L & R
1473                         list($l, $r) = array($r, $l);
1474                     }
1475                     list($l, $r) = array($r, $l);
1476                 }
1477
1478                 // Perform the inverse IP permutation.
1479                 $crypt_block[$c].= '$in =
1480                     ($shuffleinvip[($l >> 24) & 0xFF] & "\x80\x80\x80\x80\x80\x80\x80\x80") |
1481                     ($shuffleinvip[($r >> 24) & 0xFF] & "\x40\x40\x40\x40\x40\x40\x40\x40") |
1482                     ($shuffleinvip[($l >> 16) & 0xFF] & "\x20\x20\x20\x20\x20\x20\x20\x20") |
1483                     ($shuffleinvip[($r >> 16) & 0xFF] & "\x10\x10\x10\x10\x10\x10\x10\x10") |
1484                     ($shuffleinvip[($l >>  8) & 0xFF] & "\x08\x08\x08\x08\x08\x08\x08\x08") |
1485                     ($shuffleinvip[($r >>  8) & 0xFF] & "\x04\x04\x04\x04\x04\x04\x04\x04") |
1486                     ($shuffleinvip[ $l        & 0xFF] & "\x02\x02\x02\x02\x02\x02\x02\x02") |
1487                     ($shuffleinvip[ $r        & 0xFF] & "\x01\x01\x01\x01\x01\x01\x01\x01");
1488                 ';
1489             }
1490
1491             // Creates the inline-crypt function
1492             $lambda_functions[$code_hash] = $this->_createInlineCryptFunction(
1493                 array(
1494                    'init_crypt'    => $init_crypt,
1495                    'init_encrypt'  => $init_encrypt,
1496                    'init_decrypt'  => $init_decrypt,
1497                    'encrypt_block' => $crypt_block[CRYPT_DES_ENCRYPT],
1498                    'decrypt_block' => $crypt_block[CRYPT_DES_DECRYPT]
1499                 )
1500             );
1501         }
1502
1503         // Set the inline-crypt function as callback in: $this->inline_crypt
1504         $this->inline_crypt = $lambda_functions[$code_hash];
1505     }
1506 }