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