Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 629
0.00% covered (danger)
0.00%
0 / 7
CRAP
0.00% covered (danger)
0.00%
0 / 1
Crypt_DES
0.00% covered (danger)
0.00%
0 / 620
0.00% covered (danger)
0.00%
0 / 7
870
0.00% covered (danger)
0.00%
0 / 1
 isValidEngine
0.00% covered (danger)
0.00%
0 / 5
0.00% covered (danger)
0.00%
0 / 1
12
 setKey
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
6
 _encryptBlock
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 _decryptBlock
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 _processBlock
0.00% covered (danger)
0.00%
0 / 48
0.00% covered (danger)
0.00%
0 / 1
30
 _setupKey
0.00% covered (danger)
0.00%
0 / 504
0.00% covered (danger)
0.00%
0 / 1
72
 _setupInlineCrypt
0.00% covered (danger)
0.00%
0 / 58
0.00% covered (danger)
0.00%
0 / 1
90
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 */
66if (!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 */
78define('CRYPT_DES_ENCRYPT', 0);
79/**
80 * Contains $keys[CRYPT_DES_DECRYPT]
81 */
82define('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 */
97define('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 */
103define('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 */
109define('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 */
115define('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 */
121define('CRYPT_DES_MODE_OFB', CRYPT_MODE_OFB);
122/**#@-*/
123
124/**
125 * Pure-PHP implementation of DES.
126 *
127 * @package Crypt_DES
128 * @author  Jim Wigginton <terrafrost@php.net>
129 * @access  public
130 */
131class Crypt_DES extends Crypt_Base
132{
133    /**
134     * Block Length of the cipher
135     *
136     * @see Crypt_Base::block_size
137     * @var Integer
138     * @access private
139     */
140    var $block_size = 8;
141
142    /**
143     * The Key
144     *
145     * @see Crypt_Base::key
146     * @see setKey()
147     * @var String
148     * @access private
149     */
150    var $key = "\0\0\0\0\0\0\0\0";
151
152    /**
153     * The default password key_size used by setPassword()
154     *
155     * @see Crypt_Base::password_key_size
156     * @see Crypt_Base::setPassword()
157     * @var Integer
158     * @access private
159     */
160    var $password_key_size = 8;
161
162    /**
163     * The namespace used by the cipher for its constants.
164     *
165     * @see Crypt_Base::const_namespace
166     * @var String
167     * @access private
168     */
169    var $const_namespace = 'DES';
170
171    /**
172     * The mcrypt specific name of the cipher
173     *
174     * @see Crypt_Base::cipher_name_mcrypt
175     * @var String
176     * @access private
177     */
178    var $cipher_name_mcrypt = 'des';
179
180    /**
181     * The OpenSSL names of the cipher / modes
182     *
183     * @see Crypt_Base::openssl_mode_names
184     * @var Array
185     * @access private
186     */
187    var $openssl_mode_names = array(
188        CRYPT_MODE_ECB => 'des-ecb',
189        CRYPT_MODE_CBC => 'des-cbc',
190        CRYPT_MODE_CFB => 'des-cfb',
191        CRYPT_MODE_OFB => 'des-ofb'
192        // CRYPT_MODE_CTR is undefined for DES
193    );
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     * Test for engine validity
667     *
668     * This is mainly just a wrapper to set things up for Crypt_Base::isValidEngine()
669     *
670     * @see Crypt_Base::isValidEngine()
671     * @param Integer $engine
672     * @access public
673     * @return Boolean
674     */
675    function isValidEngine($engine)
676    {
677        if ($this->key_size_max == 8) {
678            if ($engine == CRYPT_ENGINE_OPENSSL) {
679                $this->cipher_name_openssl_ecb = 'des-ecb';
680                $this->cipher_name_openssl = 'des-' . $this->_openssl_translate_mode();
681            }
682        }
683
684        return parent::isValidEngine($engine);
685    }
686
687    /**
688     * Sets the key.
689     *
690     * Keys can be of any length.  DES, itself, uses 64-bit keys (eg. strlen($key) == 8), however, we
691     * only use the first eight, if $key has more then eight characters in it, and pad $key with the
692     * null byte if it is less then eight characters long.
693     *
694     * DES also requires that every eighth bit be a parity bit, however, we'll ignore that.
695     *
696     * If the key is not explicitly set, it'll be assumed to be all zero's.
697     *
698     * @see Crypt_Base::setKey()
699     * @access public
700     * @param String $key
701     */
702    function setKey($key)
703    {
704        // We check/cut here only up to max length of the key.
705        // Key padding to the proper length will be done in _setupKey()
706        if (strlen($key) > $this->key_size_max) {
707            $key = substr($key, 0, $this->key_size_max);
708        }
709
710        // Sets the key
711        parent::setKey($key);
712    }
713
714    /**
715     * Encrypts a block
716     *
717     * @see Crypt_Base::_encryptBlock()
718     * @see Crypt_Base::encrypt()
719     * @see Crypt_DES::encrypt()
720     * @access private
721     * @param String $in
722     * @return String
723     */
724    function _encryptBlock($in)
725    {
726        return $this->_processBlock($in, CRYPT_DES_ENCRYPT);
727    }
728
729    /**
730     * Decrypts a block
731     *
732     * @see Crypt_Base::_decryptBlock()
733     * @see Crypt_Base::decrypt()
734     * @see Crypt_DES::decrypt()
735     * @access private
736     * @param String $in
737     * @return String
738     */
739    function _decryptBlock($in)
740    {
741        return $this->_processBlock($in, CRYPT_DES_DECRYPT);
742    }
743
744    /**
745     * Encrypts or decrypts a 64-bit block
746     *
747     * $mode should be either CRYPT_DES_ENCRYPT or CRYPT_DES_DECRYPT.  See
748     * {@link http://en.wikipedia.org/wiki/Image:Feistel.png Feistel.png} to get a general
749     * idea of what this function does.
750     *
751     * @see Crypt_DES::_encryptBlock()
752     * @see Crypt_DES::_decryptBlock()
753     * @access private
754     * @param String $block
755     * @param Integer $mode
756     * @return String
757     */
758    function _processBlock($block, $mode)
759    {
760        static $sbox1, $sbox2, $sbox3, $sbox4, $sbox5, $sbox6, $sbox7, $sbox8, $shuffleip, $shuffleinvip;
761        if (!$sbox1) {
762            $sbox1 = array_map("intval", $this->sbox1);
763            $sbox2 = array_map("intval", $this->sbox2);
764            $sbox3 = array_map("intval", $this->sbox3);
765            $sbox4 = array_map("intval", $this->sbox4);
766            $sbox5 = array_map("intval", $this->sbox5);
767            $sbox6 = array_map("intval", $this->sbox6);
768            $sbox7 = array_map("intval", $this->sbox7);
769            $sbox8 = array_map("intval", $this->sbox8);
770            /* Merge $shuffle with $[inv]ipmap */
771            for ($i = 0; $i < 256; ++$i) {
772                $shuffleip[]    =  $this->shuffle[$this->ipmap[$i]];
773                $shuffleinvip[] =  $this->shuffle[$this->invipmap[$i]];
774            }
775        }
776
777        $keys  = $this->keys[$mode];
778        $ki    = -1;
779
780        // Do the initial IP permutation.
781        $t = unpack('Nl/Nr', $block);
782        list($l, $r) = array($t['l'], $t['r']);
783        $block = ($shuffleip[ $r        & 0xFF] & "\x80\x80\x80\x80\x80\x80\x80\x80") |
784                 ($shuffleip[($r >>  8) & 0xFF] & "\x40\x40\x40\x40\x40\x40\x40\x40") |
785                 ($shuffleip[($r >> 16) & 0xFF] & "\x20\x20\x20\x20\x20\x20\x20\x20") |
786                 ($shuffleip[($r >> 24) & 0xFF] & "\x10\x10\x10\x10\x10\x10\x10\x10") |
787                 ($shuffleip[ $l        & 0xFF] & "\x08\x08\x08\x08\x08\x08\x08\x08") |
788                 ($shuffleip[($l >>  8) & 0xFF] & "\x04\x04\x04\x04\x04\x04\x04\x04") |
789                 ($shuffleip[($l >> 16) & 0xFF] & "\x02\x02\x02\x02\x02\x02\x02\x02") |
790                 ($shuffleip[($l >> 24) & 0xFF] & "\x01\x01\x01\x01\x01\x01\x01\x01");
791
792        // Extract L0 and R0.
793        $t = unpack('Nl/Nr', $block);
794        list($l, $r) = array($t['l'], $t['r']);
795
796        for ($des_round = 0; $des_round < $this->des_rounds; ++$des_round) {
797            // Perform the 16 steps.
798            for ($i = 0; $i < 16; $i++) {
799                // start of "the Feistel (F) function" - see the following URL:
800                // http://en.wikipedia.org/wiki/Image:Data_Encryption_Standard_InfoBox_Diagram.png
801                // Merge key schedule.
802                $b1 = (($r >>  3) & 0x1FFFFFFF) ^ ($r << 29) ^ $keys[++$ki];
803                $b2 = (($r >> 31) & 0x00000001) ^ ($r <<  1) ^ $keys[++$ki];
804
805                // S-box indexing.
806                $t = $sbox1[($b1 >> 24) & 0x3F] ^ $sbox2[($b2 >> 24) & 0x3F] ^
807                     $sbox3[($b1 >> 16) & 0x3F] ^ $sbox4[($b2 >> 16) & 0x3F] ^
808                     $sbox5[($b1 >>  8) & 0x3F] ^ $sbox6[($b2 >>  8) & 0x3F] ^
809                     $sbox7[ $b1        & 0x3F] ^ $sbox8[ $b2        & 0x3F] ^ $l;
810                // end of "the Feistel (F) function"
811
812                $l = $r;
813                $r = $t;
814            }
815
816            // Last step should not permute L & R.
817            $t = $l;
818            $l = $r;
819            $r = $t;
820        }
821
822        // Perform the inverse IP permutation.
823        return ($shuffleinvip[($r >> 24) & 0xFF] & "\x80\x80\x80\x80\x80\x80\x80\x80") |
824               ($shuffleinvip[($l >> 24) & 0xFF] & "\x40\x40\x40\x40\x40\x40\x40\x40") |
825               ($shuffleinvip[($r >> 16) & 0xFF] & "\x20\x20\x20\x20\x20\x20\x20\x20") |
826               ($shuffleinvip[($l >> 16) & 0xFF] & "\x10\x10\x10\x10\x10\x10\x10\x10") |
827               ($shuffleinvip[($r >>  8) & 0xFF] & "\x08\x08\x08\x08\x08\x08\x08\x08") |
828               ($shuffleinvip[($l >>  8) & 0xFF] & "\x04\x04\x04\x04\x04\x04\x04\x04") |
829               ($shuffleinvip[ $r        & 0xFF] & "\x02\x02\x02\x02\x02\x02\x02\x02") |
830               ($shuffleinvip[ $l        & 0xFF] & "\x01\x01\x01\x01\x01\x01\x01\x01");
831    }
832
833    /**
834     * Creates the key schedule
835     *
836     * @see Crypt_Base::_setupKey()
837     * @access private
838     */
839    function _setupKey()
840    {
841        if (isset($this->kl['key']) && $this->key === $this->kl['key'] && $this->des_rounds === $this->kl['des_rounds']) {
842            // already expanded
843            return;
844        }
845        $this->kl = array('key' => $this->key, 'des_rounds' => $this->des_rounds);
846
847        static $shifts = array( // number of key bits shifted per round
848            1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1
849        );
850
851        static $pc1map = array(
852            0x00, 0x00, 0x08, 0x08, 0x04, 0x04, 0x0C, 0x0C,
853            0x02, 0x02, 0x0A, 0x0A, 0x06, 0x06, 0x0E, 0x0E,
854            0x10, 0x10, 0x18, 0x18, 0x14, 0x14, 0x1C, 0x1C,
855            0x12, 0x12, 0x1A, 0x1A, 0x16, 0x16, 0x1E, 0x1E,
856            0x20, 0x20, 0x28, 0x28, 0x24, 0x24, 0x2C, 0x2C,
857            0x22, 0x22, 0x2A, 0x2A, 0x26, 0x26, 0x2E, 0x2E,
858            0x30, 0x30, 0x38, 0x38, 0x34, 0x34, 0x3C, 0x3C,
859            0x32, 0x32, 0x3A, 0x3A, 0x36, 0x36, 0x3E, 0x3E,
860            0x40, 0x40, 0x48, 0x48, 0x44, 0x44, 0x4C, 0x4C,
861            0x42, 0x42, 0x4A, 0x4A, 0x46, 0x46, 0x4E, 0x4E,
862            0x50, 0x50, 0x58, 0x58, 0x54, 0x54, 0x5C, 0x5C,
863            0x52, 0x52, 0x5A, 0x5A, 0x56, 0x56, 0x5E, 0x5E,
864            0x60, 0x60, 0x68, 0x68, 0x64, 0x64, 0x6C, 0x6C,
865            0x62, 0x62, 0x6A, 0x6A, 0x66, 0x66, 0x6E, 0x6E,
866            0x70, 0x70, 0x78, 0x78, 0x74, 0x74, 0x7C, 0x7C,
867            0x72, 0x72, 0x7A, 0x7A, 0x76, 0x76, 0x7E, 0x7E,
868            0x80, 0x80, 0x88, 0x88, 0x84, 0x84, 0x8C, 0x8C,
869            0x82, 0x82, 0x8A, 0x8A, 0x86, 0x86, 0x8E, 0x8E,
870            0x90, 0x90, 0x98, 0x98, 0x94, 0x94, 0x9C, 0x9C,
871            0x92, 0x92, 0x9A, 0x9A, 0x96, 0x96, 0x9E, 0x9E,
872            0xA0, 0xA0, 0xA8, 0xA8, 0xA4, 0xA4, 0xAC, 0xAC,
873            0xA2, 0xA2, 0xAA, 0xAA, 0xA6, 0xA6, 0xAE, 0xAE,
874            0xB0, 0xB0, 0xB8, 0xB8, 0xB4, 0xB4, 0xBC, 0xBC,
875            0xB2, 0xB2, 0xBA, 0xBA, 0xB6, 0xB6, 0xBE, 0xBE,
876            0xC0, 0xC0, 0xC8, 0xC8, 0xC4, 0xC4, 0xCC, 0xCC,
877            0xC2, 0xC2, 0xCA, 0xCA, 0xC6, 0xC6, 0xCE, 0xCE,
878            0xD0, 0xD0, 0xD8, 0xD8, 0xD4, 0xD4, 0xDC, 0xDC,
879            0xD2, 0xD2, 0xDA, 0xDA, 0xD6, 0xD6, 0xDE, 0xDE,
880            0xE0, 0xE0, 0xE8, 0xE8, 0xE4, 0xE4, 0xEC, 0xEC,
881            0xE2, 0xE2, 0xEA, 0xEA, 0xE6, 0xE6, 0xEE, 0xEE,
882            0xF0, 0xF0, 0xF8, 0xF8, 0xF4, 0xF4, 0xFC, 0xFC,
883            0xF2, 0xF2, 0xFA, 0xFA, 0xF6, 0xF6, 0xFE, 0xFE
884        );
885
886        // Mapping tables for the PC-2 transformation.
887        static $pc2mapc1 = array(
888            0x00000000, 0x00000400, 0x00200000, 0x00200400,
889            0x00000001, 0x00000401, 0x00200001, 0x00200401,
890            0x02000000, 0x02000400, 0x02200000, 0x02200400,
891            0x02000001, 0x02000401, 0x02200001, 0x02200401
892        );
893        static $pc2mapc2 = array(
894            0x00000000, 0x00000800, 0x08000000, 0x08000800,
895            0x00010000, 0x00010800, 0x08010000, 0x08010800,
896            0x00000000, 0x00000800, 0x08000000, 0x08000800,
897            0x00010000, 0x00010800, 0x08010000, 0x08010800,
898            0x00000100, 0x00000900, 0x08000100, 0x08000900,
899            0x00010100, 0x00010900, 0x08010100, 0x08010900,
900            0x00000100, 0x00000900, 0x08000100, 0x08000900,
901            0x00010100, 0x00010900, 0x08010100, 0x08010900,
902            0x00000010, 0x00000810, 0x08000010, 0x08000810,
903            0x00010010, 0x00010810, 0x08010010, 0x08010810,
904            0x00000010, 0x00000810, 0x08000010, 0x08000810,
905            0x00010010, 0x00010810, 0x08010010, 0x08010810,
906            0x00000110, 0x00000910, 0x08000110, 0x08000910,
907            0x00010110, 0x00010910, 0x08010110, 0x08010910,
908            0x00000110, 0x00000910, 0x08000110, 0x08000910,
909            0x00010110, 0x00010910, 0x08010110, 0x08010910,
910            0x00040000, 0x00040800, 0x08040000, 0x08040800,
911            0x00050000, 0x00050800, 0x08050000, 0x08050800,
912            0x00040000, 0x00040800, 0x08040000, 0x08040800,
913            0x00050000, 0x00050800, 0x08050000, 0x08050800,
914            0x00040100, 0x00040900, 0x08040100, 0x08040900,
915            0x00050100, 0x00050900, 0x08050100, 0x08050900,
916            0x00040100, 0x00040900, 0x08040100, 0x08040900,
917            0x00050100, 0x00050900, 0x08050100, 0x08050900,
918            0x00040010, 0x00040810, 0x08040010, 0x08040810,
919            0x00050010, 0x00050810, 0x08050010, 0x08050810,
920            0x00040010, 0x00040810, 0x08040010, 0x08040810,
921            0x00050010, 0x00050810, 0x08050010, 0x08050810,
922            0x00040110, 0x00040910, 0x08040110, 0x08040910,
923            0x00050110, 0x00050910, 0x08050110, 0x08050910,
924            0x00040110, 0x00040910, 0x08040110, 0x08040910,
925            0x00050110, 0x00050910, 0x08050110, 0x08050910,
926            0x01000000, 0x01000800, 0x09000000, 0x09000800,
927            0x01010000, 0x01010800, 0x09010000, 0x09010800,
928            0x01000000, 0x01000800, 0x09000000, 0x09000800,
929            0x01010000, 0x01010800, 0x09010000, 0x09010800,
930            0x01000100, 0x01000900, 0x09000100, 0x09000900,
931            0x01010100, 0x01010900, 0x09010100, 0x09010900,
932            0x01000100, 0x01000900, 0x09000100, 0x09000900,
933            0x01010100, 0x01010900, 0x09010100, 0x09010900,
934            0x01000010, 0x01000810, 0x09000010, 0x09000810,
935            0x01010010, 0x01010810, 0x09010010, 0x09010810,
936            0x01000010, 0x01000810, 0x09000010, 0x09000810,
937            0x01010010, 0x01010810, 0x09010010, 0x09010810,
938            0x01000110, 0x01000910, 0x09000110, 0x09000910,
939            0x01010110, 0x01010910, 0x09010110, 0x09010910,
940            0x01000110, 0x01000910, 0x09000110, 0x09000910,
941            0x01010110, 0x01010910, 0x09010110, 0x09010910,
942            0x01040000, 0x01040800, 0x09040000, 0x09040800,
943            0x01050000, 0x01050800, 0x09050000, 0x09050800,
944            0x01040000, 0x01040800, 0x09040000, 0x09040800,
945            0x01050000, 0x01050800, 0x09050000, 0x09050800,
946            0x01040100, 0x01040900, 0x09040100, 0x09040900,
947            0x01050100, 0x01050900, 0x09050100, 0x09050900,
948            0x01040100, 0x01040900, 0x09040100, 0x09040900,
949            0x01050100, 0x01050900, 0x09050100, 0x09050900,
950            0x01040010, 0x01040810, 0x09040010, 0x09040810,
951            0x01050010, 0x01050810, 0x09050010, 0x09050810,
952            0x01040010, 0x01040810, 0x09040010, 0x09040810,
953            0x01050010, 0x01050810, 0x09050010, 0x09050810,
954            0x01040110, 0x01040910, 0x09040110, 0x09040910,
955            0x01050110, 0x01050910, 0x09050110, 0x09050910,
956            0x01040110, 0x01040910, 0x09040110, 0x09040910,
957            0x01050110, 0x01050910, 0x09050110, 0x09050910
958        );
959        static $pc2mapc3 = array(
960            0x00000000, 0x00000004, 0x00001000, 0x00001004,
961            0x00000000, 0x00000004, 0x00001000, 0x00001004,
962            0x10000000, 0x10000004, 0x10001000, 0x10001004,
963            0x10000000, 0x10000004, 0x10001000, 0x10001004,
964            0x00000020, 0x00000024, 0x00001020, 0x00001024,
965            0x00000020, 0x00000024, 0x00001020, 0x00001024,
966            0x10000020, 0x10000024, 0x10001020, 0x10001024,
967            0x10000020, 0x10000024, 0x10001020, 0x10001024,
968            0x00080000, 0x00080004, 0x00081000, 0x00081004,
969            0x00080000, 0x00080004, 0x00081000, 0x00081004,
970            0x10080000, 0x10080004, 0x10081000, 0x10081004,
971            0x10080000, 0x10080004, 0x10081000, 0x10081004,
972            0x00080020, 0x00080024, 0x00081020, 0x00081024,
973            0x00080020, 0x00080024, 0x00081020, 0x00081024,
974            0x10080020, 0x10080024, 0x10081020, 0x10081024,
975            0x10080020, 0x10080024, 0x10081020, 0x10081024,
976            0x20000000, 0x20000004, 0x20001000, 0x20001004,
977            0x20000000, 0x20000004, 0x20001000, 0x20001004,
978            0x30000000, 0x30000004, 0x30001000, 0x30001004,
979            0x30000000, 0x30000004, 0x30001000, 0x30001004,
980            0x20000020, 0x20000024, 0x20001020, 0x20001024,
981            0x20000020, 0x20000024, 0x20001020, 0x20001024,
982            0x30000020, 0x30000024, 0x30001020, 0x30001024,
983            0x30000020, 0x30000024, 0x30001020, 0x30001024,
984            0x20080000, 0x20080004, 0x20081000, 0x20081004,
985            0x20080000, 0x20080004, 0x20081000, 0x20081004,
986            0x30080000, 0x30080004, 0x30081000, 0x30081004,
987            0x30080000, 0x30080004, 0x30081000, 0x30081004,
988            0x20080020, 0x20080024, 0x20081020, 0x20081024,
989            0x20080020, 0x20080024, 0x20081020, 0x20081024,
990            0x30080020, 0x30080024, 0x30081020, 0x30081024,
991            0x30080020, 0x30080024, 0x30081020, 0x30081024,
992            0x00000002, 0x00000006, 0x00001002, 0x00001006,
993            0x00000002, 0x00000006, 0x00001002, 0x00001006,
994            0x10000002, 0x10000006, 0x10001002, 0x10001006,
995            0x10000002, 0x10000006, 0x10001002, 0x10001006,
996            0x00000022, 0x00000026, 0x00001022, 0x00001026,
997            0x00000022, 0x00000026, 0x00001022, 0x00001026,
998            0x10000022, 0x10000026, 0x10001022, 0x10001026,
999            0x10000022, 0x10000026, 0x10001022, 0x10001026,
1000            0x00080002, 0x00080006, 0x00081002, 0x00081006,
1001            0x00080002, 0x00080006, 0x00081002, 0x00081006,
1002            0x10080002, 0x10080006, 0x10081002, 0x10081006,
1003            0x10080002, 0x10080006, 0x10081002, 0x10081006,
1004            0x00080022, 0x00080026, 0x00081022, 0x00081026,
1005            0x00080022, 0x00080026, 0x00081022, 0x00081026,
1006            0x10080022, 0x10080026, 0x10081022, 0x10081026,
1007            0x10080022, 0x10080026, 0x10081022, 0x10081026,
1008            0x20000002, 0x20000006, 0x20001002, 0x20001006,
1009            0x20000002, 0x20000006, 0x20001002, 0x20001006,
1010            0x30000002, 0x30000006, 0x30001002, 0x30001006,
1011            0x30000002, 0x30000006, 0x30001002, 0x30001006,
1012            0x20000022, 0x20000026, 0x20001022, 0x20001026,
1013            0x20000022, 0x20000026, 0x20001022, 0x20001026,
1014            0x30000022, 0x30000026, 0x30001022, 0x30001026,
1015            0x30000022, 0x30000026, 0x30001022, 0x30001026,
1016            0x20080002, 0x20080006, 0x20081002, 0x20081006,
1017            0x20080002, 0x20080006, 0x20081002, 0x20081006,
1018            0x30080002, 0x30080006, 0x30081002, 0x30081006,
1019            0x30080002, 0x30080006, 0x30081002, 0x30081006,
1020            0x20080022, 0x20080026, 0x20081022, 0x20081026,
1021            0x20080022, 0x20080026, 0x20081022, 0x20081026,
1022            0x30080022, 0x30080026, 0x30081022, 0x30081026,
1023            0x30080022, 0x30080026, 0x30081022, 0x30081026
1024        );
1025        static $pc2mapc4 = array(
1026            0x00000000, 0x00100000, 0x00000008, 0x00100008,
1027            0x00000200, 0x00100200, 0x00000208, 0x00100208,
1028            0x00000000, 0x00100000, 0x00000008, 0x00100008,
1029            0x00000200, 0x00100200, 0x00000208, 0x00100208,
1030            0x04000000, 0x04100000, 0x04000008, 0x04100008,
1031            0x04000200, 0x04100200, 0x04000208, 0x04100208,
1032            0x04000000, 0x04100000, 0x04000008, 0x04100008,
1033            0x04000200, 0x04100200, 0x04000208, 0x04100208,
1034            0x00002000, 0x00102000, 0x00002008, 0x00102008,
1035            0x00002200, 0x00102200, 0x00002208, 0x00102208,
1036            0x00002000, 0x00102000, 0x00002008, 0x00102008,
1037            0x00002200, 0x00102200, 0x00002208, 0x00102208,
1038            0x04002000, 0x04102000, 0x04002008, 0x04102008,
1039            0x04002200, 0x04102200, 0x04002208, 0x04102208,
1040            0x04002000, 0x04102000, 0x04002008, 0x04102008,
1041            0x04002200, 0x04102200, 0x04002208, 0x04102208,
1042            0x00000000, 0x00100000, 0x00000008, 0x00100008,
1043            0x00000200, 0x00100200, 0x00000208, 0x00100208,
1044            0x00000000, 0x00100000, 0x00000008, 0x00100008,
1045            0x00000200, 0x00100200, 0x00000208, 0x00100208,
1046            0x04000000, 0x04100000, 0x04000008, 0x04100008,
1047            0x04000200, 0x04100200, 0x04000208, 0x04100208,
1048            0x04000000, 0x04100000, 0x04000008, 0x04100008,
1049            0x04000200, 0x04100200, 0x04000208, 0x04100208,
1050            0x00002000, 0x00102000, 0x00002008, 0x00102008,
1051            0x00002200, 0x00102200, 0x00002208, 0x00102208,
1052            0x00002000, 0x00102000, 0x00002008, 0x00102008,
1053            0x00002200, 0x00102200, 0x00002208, 0x00102208,
1054            0x04002000, 0x04102000, 0x04002008, 0x04102008,
1055            0x04002200, 0x04102200, 0x04002208, 0x04102208,
1056            0x04002000, 0x04102000, 0x04002008, 0x04102008,
1057            0x04002200, 0x04102200, 0x04002208, 0x04102208,
1058            0x00020000, 0x00120000, 0x00020008, 0x00120008,
1059            0x00020200, 0x00120200, 0x00020208, 0x00120208,
1060            0x00020000, 0x00120000, 0x00020008, 0x00120008,
1061            0x00020200, 0x00120200, 0x00020208, 0x00120208,
1062            0x04020000, 0x04120000, 0x04020008, 0x04120008,
1063            0x04020200, 0x04120200, 0x04020208, 0x04120208,
1064            0x04020000, 0x04120000, 0x04020008, 0x04120008,
1065            0x04020200, 0x04120200, 0x04020208, 0x04120208,
1066            0x00022000, 0x00122000, 0x00022008, 0x00122008,
1067            0x00022200, 0x00122200, 0x00022208, 0x00122208,
1068            0x00022000, 0x00122000, 0x00022008, 0x00122008,
1069            0x00022200, 0x00122200, 0x00022208, 0x00122208,
1070            0x04022000, 0x04122000, 0x04022008, 0x04122008,
1071            0x04022200, 0x04122200, 0x04022208, 0x04122208,
1072            0x04022000, 0x04122000, 0x04022008, 0x04122008,
1073            0x04022200, 0x04122200, 0x04022208, 0x04122208,
1074            0x00020000, 0x00120000, 0x00020008, 0x00120008,
1075            0x00020200, 0x00120200, 0x00020208, 0x00120208,
1076            0x00020000, 0x00120000, 0x00020008, 0x00120008,
1077            0x00020200, 0x00120200, 0x00020208, 0x00120208,
1078            0x04020000, 0x04120000, 0x04020008, 0x04120008,
1079            0x04020200, 0x04120200, 0x04020208, 0x04120208,
1080            0x04020000, 0x04120000, 0x04020008, 0x04120008,
1081            0x04020200, 0x04120200, 0x04020208, 0x04120208,
1082            0x00022000, 0x00122000, 0x00022008, 0x00122008,
1083            0x00022200, 0x00122200, 0x00022208, 0x00122208,
1084            0x00022000, 0x00122000, 0x00022008, 0x00122008,
1085            0x00022200, 0x00122200, 0x00022208, 0x00122208,
1086            0x04022000, 0x04122000, 0x04022008, 0x04122008,
1087            0x04022200, 0x04122200, 0x04022208, 0x04122208,
1088            0x04022000, 0x04122000, 0x04022008, 0x04122008,
1089            0x04022200, 0x04122200, 0x04022208, 0x04122208
1090        );
1091        static $pc2mapd1 = array(
1092            0x00000000, 0x00000001, 0x08000000, 0x08000001,
1093            0x00200000, 0x00200001, 0x08200000, 0x08200001,
1094            0x00000002, 0x00000003, 0x08000002, 0x08000003,
1095            0x00200002, 0x00200003, 0x08200002, 0x08200003
1096        );
1097        static $pc2mapd2 = array(
1098            0x00000000, 0x00100000, 0x00000800, 0x00100800,
1099            0x00000000, 0x00100000, 0x00000800, 0x00100800,
1100            0x04000000, 0x04100000, 0x04000800, 0x04100800,
1101            0x04000000, 0x04100000, 0x04000800, 0x04100800,
1102            0x00000004, 0x00100004, 0x00000804, 0x00100804,
1103            0x00000004, 0x00100004, 0x00000804, 0x00100804,
1104            0x04000004, 0x04100004, 0x04000804, 0x04100804,
1105            0x04000004, 0x04100004, 0x04000804, 0x04100804,
1106            0x00000000, 0x00100000, 0x00000800, 0x00100800,
1107            0x00000000, 0x00100000, 0x00000800, 0x00100800,
1108            0x04000000, 0x04100000, 0x04000800, 0x04100800,
1109            0x04000000, 0x04100000, 0x04000800, 0x04100800,
1110            0x00000004, 0x00100004, 0x00000804, 0x00100804,
1111            0x00000004, 0x00100004, 0x00000804, 0x00100804,
1112            0x04000004, 0x04100004, 0x04000804, 0x04100804,
1113            0x04000004, 0x04100004, 0x04000804, 0x04100804,
1114            0x00000200, 0x00100200, 0x00000A00, 0x00100A00,
1115            0x00000200, 0x00100200, 0x00000A00, 0x00100A00,
1116            0x04000200, 0x04100200, 0x04000A00, 0x04100A00,
1117            0x04000200, 0x04100200, 0x04000A00, 0x04100A00,
1118            0x00000204, 0x00100204, 0x00000A04, 0x00100A04,
1119            0x00000204, 0x00100204, 0x00000A04, 0x00100A04,
1120            0x04000204, 0x04100204, 0x04000A04, 0x04100A04,
1121            0x04000204, 0x04100204, 0x04000A04, 0x04100A04,
1122            0x00000200, 0x00100200, 0x00000A00, 0x00100A00,
1123            0x00000200, 0x00100200, 0x00000A00, 0x00100A00,
1124            0x04000200, 0x04100200, 0x04000A00, 0x04100A00,
1125            0x04000200, 0x04100200, 0x04000A00, 0x04100A00,
1126            0x00000204, 0x00100204, 0x00000A04, 0x00100A04,
1127            0x00000204, 0x00100204, 0x00000A04, 0x00100A04,
1128            0x04000204, 0x04100204, 0x04000A04, 0x04100A04,
1129            0x04000204, 0x04100204, 0x04000A04, 0x04100A04,
1130            0x00020000, 0x00120000, 0x00020800, 0x00120800,
1131            0x00020000, 0x00120000, 0x00020800, 0x00120800,
1132            0x04020000, 0x04120000, 0x04020800, 0x04120800,
1133            0x04020000, 0x04120000, 0x04020800, 0x04120800,
1134            0x00020004, 0x00120004, 0x00020804, 0x00120804,
1135            0x00020004, 0x00120004, 0x00020804, 0x00120804,
1136            0x04020004, 0x04120004, 0x04020804, 0x04120804,
1137            0x04020004, 0x04120004, 0x04020804, 0x04120804,
1138            0x00020000, 0x00120000, 0x00020800, 0x00120800,
1139            0x00020000, 0x00120000, 0x00020800, 0x00120800,
1140            0x04020000, 0x04120000, 0x04020800, 0x04120800,
1141            0x04020000, 0x04120000, 0x04020800, 0x04120800,
1142            0x00020004, 0x00120004, 0x00020804, 0x00120804,
1143            0x00020004, 0x00120004, 0x00020804, 0x00120804,
1144            0x04020004, 0x04120004, 0x04020804, 0x04120804,
1145            0x04020004, 0x04120004, 0x04020804, 0x04120804,
1146            0x00020200, 0x00120200, 0x00020A00, 0x00120A00,
1147            0x00020200, 0x00120200, 0x00020A00, 0x00120A00,
1148            0x04020200, 0x04120200, 0x04020A00, 0x04120A00,
1149            0x04020200, 0x04120200, 0x04020A00, 0x04120A00,
1150            0x00020204, 0x00120204, 0x00020A04, 0x00120A04,
1151            0x00020204, 0x00120204, 0x00020A04, 0x00120A04,
1152            0x04020204, 0x04120204, 0x04020A04, 0x04120A04,
1153            0x04020204, 0x04120204, 0x04020A04, 0x04120A04,
1154            0x00020200, 0x00120200, 0x00020A00, 0x00120A00,
1155            0x00020200, 0x00120200, 0x00020A00, 0x00120A00,
1156            0x04020200, 0x04120200, 0x04020A00, 0x04120A00,
1157            0x04020200, 0x04120200, 0x04020A00, 0x04120A00,
1158            0x00020204, 0x00120204, 0x00020A04, 0x00120A04,
1159            0x00020204, 0x00120204, 0x00020A04, 0x00120A04,
1160            0x04020204, 0x04120204, 0x04020A04, 0x04120A04,
1161            0x04020204, 0x04120204, 0x04020A04, 0x04120A04
1162        );
1163        static $pc2mapd3 = array(
1164            0x00000000, 0x00010000, 0x02000000, 0x02010000,
1165            0x00000020, 0x00010020, 0x02000020, 0x02010020,
1166            0x00040000, 0x00050000, 0x02040000, 0x02050000,
1167            0x00040020, 0x00050020, 0x02040020, 0x02050020,
1168            0x00002000, 0x00012000, 0x02002000, 0x02012000,
1169            0x00002020, 0x00012020, 0x02002020, 0x02012020,
1170            0x00042000, 0x00052000, 0x02042000, 0x02052000,
1171            0x00042020, 0x00052020, 0x02042020, 0x02052020,
1172            0x00000000, 0x00010000, 0x02000000, 0x02010000,
1173            0x00000020, 0x00010020, 0x02000020, 0x02010020,
1174            0x00040000, 0x00050000, 0x02040000, 0x02050000,
1175            0x00040020, 0x00050020, 0x02040020, 0x02050020,
1176            0x00002000, 0x00012000, 0x02002000, 0x02012000,
1177            0x00002020, 0x00012020, 0x02002020, 0x02012020,
1178            0x00042000, 0x00052000, 0x02042000, 0x02052000,
1179            0x00042020, 0x00052020, 0x02042020, 0x02052020,
1180            0x00000010, 0x00010010, 0x02000010, 0x02010010,
1181            0x00000030, 0x00010030, 0x02000030, 0x02010030,
1182            0x00040010, 0x00050010, 0x02040010, 0x02050010,
1183            0x00040030, 0x00050030, 0x02040030, 0x02050030,
1184            0x00002010, 0x00012010, 0x02002010, 0x02012010,
1185            0x00002030, 0x00012030, 0x02002030, 0x02012030,
1186            0x00042010, 0x00052010, 0x02042010, 0x02052010,
1187            0x00042030, 0x00052030, 0x02042030, 0x02052030,
1188            0x00000010, 0x00010010, 0x02000010, 0x02010010,
1189            0x00000030, 0x00010030, 0x02000030, 0x02010030,
1190            0x00040010, 0x00050010, 0x02040010, 0x02050010,
1191            0x00040030, 0x00050030, 0x02040030, 0x02050030,
1192            0x00002010, 0x00012010, 0x02002010, 0x02012010,
1193            0x00002030, 0x00012030, 0x02002030, 0x02012030,
1194            0x00042010, 0x00052010, 0x02042010, 0x02052010,
1195            0x00042030, 0x00052030, 0x02042030, 0x02052030,
1196            0x20000000, 0x20010000, 0x22000000, 0x22010000,
1197            0x20000020, 0x20010020, 0x22000020, 0x22010020,
1198            0x20040000, 0x20050000, 0x22040000, 0x22050000,
1199            0x20040020, 0x20050020, 0x22040020, 0x22050020,
1200            0x20002000, 0x20012000, 0x22002000, 0x22012000,
1201            0x20002020, 0x20012020, 0x22002020, 0x22012020,
1202            0x20042000, 0x20052000, 0x22042000, 0x22052000,
1203            0x20042020, 0x20052020, 0x22042020, 0x22052020,
1204            0x20000000, 0x20010000, 0x22000000, 0x22010000,
1205            0x20000020, 0x20010020, 0x22000020, 0x22010020,
1206            0x20040000, 0x20050000, 0x22040000, 0x22050000,
1207            0x20040020, 0x20050020, 0x22040020, 0x22050020,
1208            0x20002000, 0x20012000, 0x22002000, 0x22012000,
1209            0x20002020, 0x20012020, 0x22002020, 0x22012020,
1210            0x20042000, 0x20052000, 0x22042000, 0x22052000,
1211            0x20042020, 0x20052020, 0x22042020, 0x22052020,
1212            0x20000010, 0x20010010, 0x22000010, 0x22010010,
1213            0x20000030, 0x20010030, 0x22000030, 0x22010030,
1214            0x20040010, 0x20050010, 0x22040010, 0x22050010,
1215            0x20040030, 0x20050030, 0x22040030, 0x22050030,
1216            0x20002010, 0x20012010, 0x22002010, 0x22012010,
1217            0x20002030, 0x20012030, 0x22002030, 0x22012030,
1218            0x20042010, 0x20052010, 0x22042010, 0x22052010,
1219            0x20042030, 0x20052030, 0x22042030, 0x22052030,
1220            0x20000010, 0x20010010, 0x22000010, 0x22010010,
1221            0x20000030, 0x20010030, 0x22000030, 0x22010030,
1222            0x20040010, 0x20050010, 0x22040010, 0x22050010,
1223            0x20040030, 0x20050030, 0x22040030, 0x22050030,
1224            0x20002010, 0x20012010, 0x22002010, 0x22012010,
1225            0x20002030, 0x20012030, 0x22002030, 0x22012030,
1226            0x20042010, 0x20052010, 0x22042010, 0x22052010,
1227            0x20042030, 0x20052030, 0x22042030, 0x22052030
1228        );
1229        static $pc2mapd4 = array(
1230            0x00000000, 0x00000400, 0x01000000, 0x01000400,
1231            0x00000000, 0x00000400, 0x01000000, 0x01000400,
1232            0x00000100, 0x00000500, 0x01000100, 0x01000500,
1233            0x00000100, 0x00000500, 0x01000100, 0x01000500,
1234            0x10000000, 0x10000400, 0x11000000, 0x11000400,
1235            0x10000000, 0x10000400, 0x11000000, 0x11000400,
1236            0x10000100, 0x10000500, 0x11000100, 0x11000500,
1237            0x10000100, 0x10000500, 0x11000100, 0x11000500,
1238            0x00080000, 0x00080400, 0x01080000, 0x01080400,
1239            0x00080000, 0x00080400, 0x01080000, 0x01080400,
1240            0x00080100, 0x00080500, 0x01080100, 0x01080500,
1241            0x00080100, 0x00080500, 0x01080100, 0x01080500,
1242            0x10080000, 0x10080400, 0x11080000, 0x11080400,
1243            0x10080000, 0x10080400, 0x11080000, 0x11080400,
1244            0x10080100, 0x10080500, 0x11080100, 0x11080500,
1245            0x10080100, 0x10080500, 0x11080100, 0x11080500,
1246            0x00000008, 0x00000408, 0x01000008, 0x01000408,
1247            0x00000008, 0x00000408, 0x01000008, 0x01000408,
1248            0x00000108, 0x00000508, 0x01000108, 0x01000508,
1249            0x00000108, 0x00000508, 0x01000108, 0x01000508,
1250            0x10000008, 0x10000408, 0x11000008, 0x11000408,
1251            0x10000008, 0x10000408, 0x11000008, 0x11000408,
1252            0x10000108, 0x10000508, 0x11000108, 0x11000508,
1253            0x10000108, 0x10000508, 0x11000108, 0x11000508,
1254            0x00080008, 0x00080408, 0x01080008, 0x01080408,
1255            0x00080008, 0x00080408, 0x01080008, 0x01080408,
1256            0x00080108, 0x00080508, 0x01080108, 0x01080508,
1257            0x00080108, 0x00080508, 0x01080108, 0x01080508,
1258            0x10080008, 0x10080408, 0x11080008, 0x11080408,
1259            0x10080008, 0x10080408, 0x11080008, 0x11080408,
1260            0x10080108, 0x10080508, 0x11080108, 0x11080508,
1261            0x10080108, 0x10080508, 0x11080108, 0x11080508,
1262            0x00001000, 0x00001400, 0x01001000, 0x01001400,
1263            0x00001000, 0x00001400, 0x01001000, 0x01001400,
1264            0x00001100, 0x00001500, 0x01001100, 0x01001500,
1265            0x00001100, 0x00001500, 0x01001100, 0x01001500,
1266            0x10001000, 0x10001400, 0x11001000, 0x11001400,
1267            0x10001000, 0x10001400, 0x11001000, 0x11001400,
1268            0x10001100, 0x10001500, 0x11001100, 0x11001500,
1269            0x10001100, 0x10001500, 0x11001100, 0x11001500,
1270            0x00081000, 0x00081400, 0x01081000, 0x01081400,
1271            0x00081000, 0x00081400, 0x01081000, 0x01081400,
1272            0x00081100, 0x00081500, 0x01081100, 0x01081500,
1273            0x00081100, 0x00081500, 0x01081100, 0x01081500,
1274            0x10081000, 0x10081400, 0x11081000, 0x11081400,
1275            0x10081000, 0x10081400, 0x11081000, 0x11081400,
1276            0x10081100, 0x10081500, 0x11081100, 0x11081500,
1277            0x10081100, 0x10081500, 0x11081100, 0x11081500,
1278            0x00001008, 0x00001408, 0x01001008, 0x01001408,
1279            0x00001008, 0x00001408, 0x01001008, 0x01001408,
1280            0x00001108, 0x00001508, 0x01001108, 0x01001508,
1281            0x00001108, 0x00001508, 0x01001108, 0x01001508,
1282            0x10001008, 0x10001408, 0x11001008, 0x11001408,
1283            0x10001008, 0x10001408, 0x11001008, 0x11001408,
1284            0x10001108, 0x10001508, 0x11001108, 0x11001508,
1285            0x10001108, 0x10001508, 0x11001108, 0x11001508,
1286            0x00081008, 0x00081408, 0x01081008, 0x01081408,
1287            0x00081008, 0x00081408, 0x01081008, 0x01081408,
1288            0x00081108, 0x00081508, 0x01081108, 0x01081508,
1289            0x00081108, 0x00081508, 0x01081108, 0x01081508,
1290            0x10081008, 0x10081408, 0x11081008, 0x11081408,
1291            0x10081008, 0x10081408, 0x11081008, 0x11081408,
1292            0x10081108, 0x10081508, 0x11081108, 0x11081508,
1293            0x10081108, 0x10081508, 0x11081108, 0x11081508
1294        );
1295
1296        $keys = array();
1297        for ($des_round = 0; $des_round < $this->des_rounds; ++$des_round) {
1298            // pad the key and remove extra characters as appropriate.
1299            $key = str_pad(substr($this->key, $des_round * 8, 8), 8, "\0");
1300
1301            // Perform the PC/1 transformation and compute C and D.
1302            $t = unpack('Nl/Nr', $key);
1303            list($l, $r) = array($t['l'], $t['r']);
1304            $key = ($this->shuffle[$pc1map[ $r        & 0xFF]] & "\x80\x80\x80\x80\x80\x80\x80\x00") |
1305                   ($this->shuffle[$pc1map[($r >>  8) & 0xFF]] & "\x40\x40\x40\x40\x40\x40\x40\x00") |
1306                   ($this->shuffle[$pc1map[($r >> 16) & 0xFF]] & "\x20\x20\x20\x20\x20\x20\x20\x00") |
1307                   ($this->shuffle[$pc1map[($r >> 24) & 0xFF]] & "\x10\x10\x10\x10\x10\x10\x10\x00") |
1308                   ($this->shuffle[$pc1map[ $l        & 0xFF]] & "\x08\x08\x08\x08\x08\x08\x08\x00") |
1309                   ($this->shuffle[$pc1map[($l >>  8) & 0xFF]] & "\x04\x04\x04\x04\x04\x04\x04\x00") |
1310                   ($this->shuffle[$pc1map[($l >> 16) & 0xFF]] & "\x02\x02\x02\x02\x02\x02\x02\x00") |
1311                   ($this->shuffle[$pc1map[($l >> 24) & 0xFF]] & "\x01\x01\x01\x01\x01\x01\x01\x00");
1312            $key = unpack('Nc/Nd', $key);
1313            $c = ( $key['c'] >> 4) & 0x0FFFFFFF;
1314            $d = (($key['d'] >> 4) & 0x0FFFFFF0) | ($key['c'] & 0x0F);
1315
1316            $keys[$des_round] = array(
1317                CRYPT_DES_ENCRYPT => array(),
1318                CRYPT_DES_DECRYPT => array_fill(0, 32, 0)
1319            );
1320            for ($i = 0, $ki = 31; $i < 16; ++$i, $ki-= 2) {
1321                $c <<= $shifts[$i];
1322                $c = ($c | ($c >> 28)) & 0x0FFFFFFF;
1323                $d <<= $shifts[$i];
1324                $d = ($d | ($d >> 28)) & 0x0FFFFFFF;
1325
1326                // Perform the PC-2 transformation.
1327                $cp = $pc2mapc1[ $c >> 24        ] | $pc2mapc2[($c >> 16) & 0xFF] |
1328                      $pc2mapc3[($c >>  8) & 0xFF] | $pc2mapc4[ $c        & 0xFF];
1329                $dp = $pc2mapd1[ $d >> 24        ] | $pc2mapd2[($d >> 16) & 0xFF] |
1330                      $pc2mapd3[($d >>  8) & 0xFF] | $pc2mapd4[ $d        & 0xFF];
1331
1332                // Reorder: odd bytes/even bytes. Push the result in key schedule.
1333                $val1 = ( $cp        & 0xFF000000) | (($cp <<  8) & 0x00FF0000) |
1334                        (($dp >> 16) & 0x0000FF00) | (($dp >>  8) & 0x000000FF);
1335                $val2 = (($cp <<  8) & 0xFF000000) | (($cp << 16) & 0x00FF0000) |
1336                        (($dp >>  8) & 0x0000FF00) | ( $dp        & 0x000000FF);
1337                $keys[$des_round][CRYPT_DES_ENCRYPT][       ] = $val1;
1338                $keys[$des_round][CRYPT_DES_DECRYPT][$ki - 1] = $val1;
1339                $keys[$des_round][CRYPT_DES_ENCRYPT][       ] = $val2;
1340                $keys[$des_round][CRYPT_DES_DECRYPT][$ki    ] = $val2;
1341            }
1342        }
1343
1344        switch ($this->des_rounds) {
1345            case 3: // 3DES keys
1346                $this->keys = array(
1347                    CRYPT_DES_ENCRYPT => array_merge(
1348                        $keys[0][CRYPT_DES_ENCRYPT],
1349                        $keys[1][CRYPT_DES_DECRYPT],
1350                        $keys[2][CRYPT_DES_ENCRYPT]
1351                    ),
1352                    CRYPT_DES_DECRYPT => array_merge(
1353                        $keys[2][CRYPT_DES_DECRYPT],
1354                        $keys[1][CRYPT_DES_ENCRYPT],
1355                        $keys[0][CRYPT_DES_DECRYPT]
1356                    )
1357                );
1358                break;
1359            // case 1: // DES keys
1360            default:
1361                $this->keys = array(
1362                    CRYPT_DES_ENCRYPT => $keys[0][CRYPT_DES_ENCRYPT],
1363                    CRYPT_DES_DECRYPT => $keys[0][CRYPT_DES_DECRYPT]
1364                );
1365        }
1366    }
1367
1368    /**
1369     * Setup the performance-optimized function for de/encrypt()
1370     *
1371     * @see Crypt_Base::_setupInlineCrypt()
1372     * @access private
1373     */
1374    function _setupInlineCrypt()
1375    {
1376        $lambda_functions =& Crypt_DES::_getLambdaFunctions();
1377
1378        // Engine configuration for:
1379        // -  DES ($des_rounds == 1) or
1380        // - 3DES ($des_rounds == 3)
1381        $des_rounds = $this->des_rounds;
1382
1383        // We create max. 10 hi-optimized code for memory reason. Means: For each $key one ultra fast inline-crypt function.
1384        // (Currently, for Crypt_DES,       one generated $lambda_function cost on php5.5@32bit ~135kb unfreeable mem and ~230kb on php5.5@64bit)
1385        // (Currently, for Crypt_TripleDES, one generated $lambda_function cost on php5.5@32bit ~240kb unfreeable mem and ~340kb on php5.5@64bit)
1386        // After that, we'll still create very fast optimized code but not the hi-ultimative code, for each $mode one
1387        $gen_hi_opt_code = (bool)( count($lambda_functions) < 10 );
1388
1389        // Generation of a uniqe hash for our generated code
1390        $code_hash = "Crypt_DES, $des_rounds{$this->mode}";
1391        if ($gen_hi_opt_code) {
1392            // For hi-optimized code, we create for each combination of
1393            // $mode, $des_rounds and $this->key its own encrypt/decrypt function.
1394            // After max 10 hi-optimized functions, we create generic
1395            // (still very fast.. but not ultra) functions for each $mode/$des_rounds
1396            // Currently 2 * 5 generic functions will be then max. possible.
1397            $code_hash = str_pad($code_hash, 32) . $this->_hashInlineCryptFunction($this->key);
1398        }
1399
1400        // Is there a re-usable $lambda_functions in there? If not, we have to create it.
1401        if (!isset($lambda_functions[$code_hash])) {
1402            // Init code for both, encrypt and decrypt.
1403            $init_crypt = 'static $sbox1, $sbox2, $sbox3, $sbox4, $sbox5, $sbox6, $sbox7, $sbox8, $shuffleip, $shuffleinvip;
1404                if (!$sbox1) {
1405                    $sbox1 = array_map("intval", $self->sbox1);
1406                    $sbox2 = array_map("intval", $self->sbox2);
1407                    $sbox3 = array_map("intval", $self->sbox3);
1408                    $sbox4 = array_map("intval", $self->sbox4);
1409                    $sbox5 = array_map("intval", $self->sbox5);
1410                    $sbox6 = array_map("intval", $self->sbox6);
1411                    $sbox7 = array_map("intval", $self->sbox7);
1412                    $sbox8 = array_map("intval", $self->sbox8);'
1413                    /* Merge $shuffle with $[inv]ipmap */ . '
1414                    for ($i = 0; $i < 256; ++$i) {
1415                        $shuffleip[]    =  $self->shuffle[$self->ipmap[$i]];
1416                        $shuffleinvip[] =  $self->shuffle[$self->invipmap[$i]];
1417                    }
1418                }
1419            ';
1420
1421            switch (true) {
1422                case $gen_hi_opt_code:
1423                    // In Hi-optimized code mode, we use our [3]DES key schedule as hardcoded integers.
1424                    // No futher initialisation of the $keys schedule is necessary.
1425                    // That is the extra performance boost.
1426                    $k = array(
1427                        CRYPT_DES_ENCRYPT => $this->keys[CRYPT_DES_ENCRYPT],
1428                        CRYPT_DES_DECRYPT => $this->keys[CRYPT_DES_DECRYPT]
1429                    );
1430                    $init_encrypt = '';
1431                    $init_decrypt = '';
1432                    break;
1433                default:
1434                    // In generic optimized code mode, we have to use, as the best compromise [currently],
1435                    // our key schedule as $ke/$kd arrays. (with hardcoded indexes...)
1436                    $k = array(
1437                        CRYPT_DES_ENCRYPT => array(),
1438                        CRYPT_DES_DECRYPT => array()
1439                    );
1440                    for ($i = 0, $c = count($this->keys[CRYPT_DES_ENCRYPT]); $i < $c; ++$i) {
1441                        $k[CRYPT_DES_ENCRYPT][$i] = '$ke[' . $i . ']';
1442                        $k[CRYPT_DES_DECRYPT][$i] = '$kd[' . $i . ']';
1443                    }
1444                    $init_encrypt = '$ke = $self->keys[CRYPT_DES_ENCRYPT];';
1445                    $init_decrypt = '$kd = $self->keys[CRYPT_DES_DECRYPT];';
1446                    break;
1447            }
1448
1449            // Creating code for en- and decryption.
1450            $crypt_block = array();
1451            foreach (array(CRYPT_DES_ENCRYPT, CRYPT_DES_DECRYPT) as $c) {
1452                /* Do the initial IP permutation. */
1453                $crypt_block[$c] = '
1454                    $in = unpack("N*", $in);
1455                    $l  = $in[1];
1456                    $r  = $in[2];
1457                    $in = unpack("N*",
1458                        ($shuffleip[ $r        & 0xFF] & "\x80\x80\x80\x80\x80\x80\x80\x80") |
1459                        ($shuffleip[($r >>  8) & 0xFF] & "\x40\x40\x40\x40\x40\x40\x40\x40") |
1460                        ($shuffleip[($r >> 16) & 0xFF] & "\x20\x20\x20\x20\x20\x20\x20\x20") |
1461                        ($shuffleip[($r >> 24) & 0xFF] & "\x10\x10\x10\x10\x10\x10\x10\x10") |
1462                        ($shuffleip[ $l        & 0xFF] & "\x08\x08\x08\x08\x08\x08\x08\x08") |
1463                        ($shuffleip[($l >>  8) & 0xFF] & "\x04\x04\x04\x04\x04\x04\x04\x04") |
1464                        ($shuffleip[($l >> 16) & 0xFF] & "\x02\x02\x02\x02\x02\x02\x02\x02") |
1465                        ($shuffleip[($l >> 24) & 0xFF] & "\x01\x01\x01\x01\x01\x01\x01\x01")
1466                    );
1467                    ' . /* Extract L0 and R0 */ '
1468                    $l = $in[1];
1469                    $r = $in[2];
1470                ';
1471
1472                $l = '$l';
1473                $r = '$r';
1474
1475                // Perform DES or 3DES.
1476                for ($ki = -1, $des_round = 0; $des_round < $des_rounds; ++$des_round) {
1477                    // Perform the 16 steps.
1478                    for ($i = 0; $i < 16; ++$i) {
1479                        // start of "the Feistel (F) function" - see the following URL:
1480                        // http://en.wikipedia.org/wiki/Image:Data_Encryption_Standard_InfoBox_Diagram.png
1481                        // Merge key schedule.
1482                        $crypt_block[$c].= '
1483                            $b1 = ((' . $r . ' >>  3) & 0x1FFFFFFF)  ^ (' . $r . ' << 29) ^ ' . $k[$c][++$ki] . ';
1484                            $b2 = ((' . $r . ' >> 31) & 0x00000001)  ^ (' . $r . ' <<  1) ^ ' . $k[$c][++$ki] . ';' .
1485                            /* S-box indexing. */
1486                            $l . ' = $sbox1[($b1 >> 24) & 0x3F] ^ $sbox2[($b2 >> 24) & 0x3F] ^
1487                                     $sbox3[($b1 >> 16) & 0x3F] ^ $sbox4[($b2 >> 16) & 0x3F] ^
1488                                     $sbox5[($b1 >>  8) & 0x3F] ^ $sbox6[($b2 >>  8) & 0x3F] ^
1489                                     $sbox7[ $b1        & 0x3F] ^ $sbox8[ $b2        & 0x3F] ^ ' . $l . ';
1490                        ';
1491                        // end of "the Feistel (F) function"
1492
1493                        // swap L & R
1494                        list($l, $r) = array($r, $l);
1495                    }
1496                    list($l, $r) = array($r, $l);
1497                }
1498
1499                // Perform the inverse IP permutation.
1500                $crypt_block[$c].= '$in =
1501                    ($shuffleinvip[($l >> 24) & 0xFF] & "\x80\x80\x80\x80\x80\x80\x80\x80") |
1502                    ($shuffleinvip[($r >> 24) & 0xFF] & "\x40\x40\x40\x40\x40\x40\x40\x40") |
1503                    ($shuffleinvip[($l >> 16) & 0xFF] & "\x20\x20\x20\x20\x20\x20\x20\x20") |
1504                    ($shuffleinvip[($r >> 16) & 0xFF] & "\x10\x10\x10\x10\x10\x10\x10\x10") |
1505                    ($shuffleinvip[($l >>  8) & 0xFF] & "\x08\x08\x08\x08\x08\x08\x08\x08") |
1506                    ($shuffleinvip[($r >>  8) & 0xFF] & "\x04\x04\x04\x04\x04\x04\x04\x04") |
1507                    ($shuffleinvip[ $l        & 0xFF] & "\x02\x02\x02\x02\x02\x02\x02\x02") |
1508                    ($shuffleinvip[ $r        & 0xFF] & "\x01\x01\x01\x01\x01\x01\x01\x01");
1509                ';
1510            }
1511
1512            // Creates the inline-crypt function
1513            $lambda_functions[$code_hash] = $this->_createInlineCryptFunction(
1514                array(
1515                   'init_crypt'    => $init_crypt,
1516                   'init_encrypt'  => $init_encrypt,
1517                   'init_decrypt'  => $init_decrypt,
1518                   'encrypt_block' => $crypt_block[CRYPT_DES_ENCRYPT],
1519                   'decrypt_block' => $crypt_block[CRYPT_DES_DECRYPT]
1520                )
1521            );
1522        }
1523
1524        // Set the inline-crypt function as callback in: $this->inline_crypt
1525        $this->inline_crypt = $lambda_functions[$code_hash];
1526    }
1527}