]> git.mxchange.org Git - quix0rs-gnu-social.git/blob - plugins/OStatus/extlib/Crypt/DES.php
is_a() with 3 params only supported in 5.3.9 anyway
[quix0rs-gnu-social.git] / plugins / OStatus / extlib / Crypt / DES.php
1 <?php\r
2 /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */\r
3 \r
4 /**\r
5  * Pure-PHP implementation of DES.\r
6  *\r
7  * Uses mcrypt, if available, and an internal implementation, otherwise.\r
8  *\r
9  * PHP versions 4 and 5\r
10  *\r
11  * Useful resources are as follows:\r
12  *\r
13  *  - {@link http://en.wikipedia.org/wiki/DES_supplementary_material Wikipedia: DES supplementary material}\r
14  *  - {@link http://www.itl.nist.gov/fipspubs/fip46-2.htm FIPS 46-2 - (DES), Data Encryption Standard}\r
15  *  - {@link http://www.cs.eku.edu/faculty/styer/460/Encrypt/JS-DES.html JavaScript DES Example}\r
16  *\r
17  * Here's a short example of how to use this library:\r
18  * <code>\r
19  * <?php\r
20  *    include('Crypt/DES.php');\r
21  *\r
22  *    $des = new Crypt_DES();\r
23  *\r
24  *    $des->setKey('abcdefgh');\r
25  *\r
26  *    $size = 10 * 1024;\r
27  *    $plaintext = '';\r
28  *    for ($i = 0; $i < $size; $i++) {\r
29  *        $plaintext.= 'a';\r
30  *    }\r
31  *\r
32  *    echo $des->decrypt($des->encrypt($plaintext));\r
33  * ?>\r
34  * </code>\r
35  *\r
36  * LICENSE: Permission is hereby granted, free of charge, to any person obtaining a copy\r
37  * of this software and associated documentation files (the "Software"), to deal\r
38  * in the Software without restriction, including without limitation the rights\r
39  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
40  * copies of the Software, and to permit persons to whom the Software is\r
41  * furnished to do so, subject to the following conditions:\r
42  * \r
43  * The above copyright notice and this permission notice shall be included in\r
44  * all copies or substantial portions of the Software.\r
45  * \r
46  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
47  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
48  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
49  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
50  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
51  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\r
52  * THE SOFTWARE.\r
53  *\r
54  * @category   Crypt\r
55  * @package    Crypt_DES\r
56  * @author     Jim Wigginton <terrafrost@php.net>\r
57  * @copyright  MMVII Jim Wigginton\r
58  * @license    http://www.opensource.org/licenses/mit-license.html  MIT License\r
59  * @link       http://phpseclib.sourceforge.net\r
60  */\r
61 \r
62 /**#@+\r
63  * @access private\r
64  * @see Crypt_DES::_prepareKey()\r
65  * @see Crypt_DES::_processBlock()\r
66  */\r
67 /**\r
68  * Contains array_reverse($keys[CRYPT_DES_DECRYPT])\r
69  */\r
70 define('CRYPT_DES_ENCRYPT', 0);\r
71 /**\r
72  * Contains array_reverse($keys[CRYPT_DES_ENCRYPT])\r
73  */\r
74 define('CRYPT_DES_DECRYPT', 1);\r
75 /**\r
76  * Contains $keys[CRYPT_DES_ENCRYPT] as 1-dim array\r
77  */\r
78 define('CRYPT_DES_ENCRYPT_1DIM', 2);\r
79 /**\r
80  * Contains $keys[CRYPT_DES_DECRYPT] as 1-dim array\r
81  */\r
82 define('CRYPT_DES_DECRYPT_1DIM', 3);\r
83 /**#@-*/\r
84 \r
85 /**#@+\r
86  * @access public\r
87  * @see Crypt_DES::encrypt()\r
88  * @see Crypt_DES::decrypt()\r
89  */\r
90 /**\r
91  * Encrypt / decrypt using the Counter mode.\r
92  *\r
93  * Set to -1 since that's what Crypt/Random.php uses to index the CTR mode.\r
94  *\r
95  * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Counter_.28CTR.29\r
96  */\r
97 define('CRYPT_DES_MODE_CTR', -1);\r
98 /**\r
99  * Encrypt / decrypt using the Electronic Code Book mode.\r
100  *\r
101  * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Electronic_codebook_.28ECB.29\r
102  */\r
103 define('CRYPT_DES_MODE_ECB', 1);\r
104 /**\r
105  * Encrypt / decrypt using the Code Book Chaining mode.\r
106  *\r
107  * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Cipher-block_chaining_.28CBC.29\r
108  */\r
109 define('CRYPT_DES_MODE_CBC', 2);\r
110 /**\r
111  * Encrypt / decrypt using the Cipher Feedback mode.\r
112  *\r
113  * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Cipher_feedback_.28CFB.29\r
114  */\r
115 define('CRYPT_DES_MODE_CFB', 3);\r
116 /**\r
117  * Encrypt / decrypt using the Cipher Feedback mode.\r
118  *\r
119  * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Output_feedback_.28OFB.29\r
120  */\r
121 define('CRYPT_DES_MODE_OFB', 4);\r
122 /**#@-*/\r
123 \r
124 /**#@+\r
125  * @access private\r
126  * @see Crypt_DES::Crypt_DES()\r
127  */\r
128 /**\r
129  * Toggles the internal implementation\r
130  */\r
131 define('CRYPT_DES_MODE_INTERNAL', 1);\r
132 /**\r
133  * Toggles the mcrypt implementation\r
134  */\r
135 define('CRYPT_DES_MODE_MCRYPT', 2);\r
136 /**#@-*/\r
137 \r
138 /**\r
139  * Pure-PHP implementation of DES.\r
140  *\r
141  * @author  Jim Wigginton <terrafrost@php.net>\r
142  * @version 0.1.0\r
143  * @access  public\r
144  * @package Crypt_DES\r
145  */\r
146 class Crypt_DES {\r
147     /**\r
148      * The Key Schedule\r
149      *\r
150      * @see Crypt_DES::setKey()\r
151      * @var Array\r
152      * @access private\r
153      */\r
154     var $keys = "\0\0\0\0\0\0\0\0";\r
155 \r
156     /**\r
157      * The Encryption Mode\r
158      *\r
159      * @see Crypt_DES::Crypt_DES()\r
160      * @var Integer\r
161      * @access private\r
162      */\r
163     var $mode;\r
164 \r
165     /**\r
166      * Continuous Buffer status\r
167      *\r
168      * @see Crypt_DES::enableContinuousBuffer()\r
169      * @var Boolean\r
170      * @access private\r
171      */\r
172     var $continuousBuffer = false;\r
173 \r
174     /**\r
175      * Padding status\r
176      *\r
177      * @see Crypt_DES::enablePadding()\r
178      * @var Boolean\r
179      * @access private\r
180      */\r
181     var $padding = true;\r
182 \r
183     /**\r
184      * The Initialization Vector\r
185      *\r
186      * @see Crypt_DES::setIV()\r
187      * @var String\r
188      * @access private\r
189      */\r
190     var $iv = "\0\0\0\0\0\0\0\0";\r
191 \r
192     /**\r
193      * A "sliding" Initialization Vector\r
194      *\r
195      * @see Crypt_DES::enableContinuousBuffer()\r
196      * @var String\r
197      * @access private\r
198      */\r
199     var $encryptIV = "\0\0\0\0\0\0\0\0";\r
200 \r
201     /**\r
202      * A "sliding" Initialization Vector\r
203      *\r
204      * @see Crypt_DES::enableContinuousBuffer()\r
205      * @var String\r
206      * @access private\r
207      */\r
208     var $decryptIV = "\0\0\0\0\0\0\0\0";\r
209 \r
210     /**\r
211      * mcrypt resource for encryption\r
212      *\r
213      * The mcrypt resource can be recreated every time something needs to be created or it can be created just once.\r
214      * Since mcrypt operates in continuous mode, by default, it'll need to be recreated when in non-continuous mode.\r
215      *\r
216      * @see Crypt_DES::encrypt()\r
217      * @var String\r
218      * @access private\r
219      */\r
220     var $enmcrypt;\r
221 \r
222     /**\r
223      * mcrypt resource for decryption\r
224      *\r
225      * The mcrypt resource can be recreated every time something needs to be created or it can be created just once.\r
226      * Since mcrypt operates in continuous mode, by default, it'll need to be recreated when in non-continuous mode.\r
227      *\r
228      * @see Crypt_DES::decrypt()\r
229      * @var String\r
230      * @access private\r
231      */\r
232     var $demcrypt;\r
233 \r
234     /**\r
235      * Does the enmcrypt resource need to be (re)initialized?\r
236      *\r
237      * @see Crypt_DES::setKey()\r
238      * @see Crypt_DES::setIV()\r
239      * @var Boolean\r
240      * @access private\r
241      */\r
242     var $enchanged = true;\r
243 \r
244     /**\r
245      * Does the demcrypt resource need to be (re)initialized?\r
246      *\r
247      * @see Crypt_DES::setKey()\r
248      * @see Crypt_DES::setIV()\r
249      * @var Boolean\r
250      * @access private\r
251      */\r
252     var $dechanged = true;\r
253 \r
254     /**\r
255      * Is the mode one that is paddable?\r
256      *\r
257      * @see Crypt_DES::Crypt_DES()\r
258      * @var Boolean\r
259      * @access private\r
260      */\r
261     var $paddable = false;\r
262 \r
263     /**\r
264      * Encryption buffer for CTR, OFB and CFB modes\r
265      *\r
266      * @see Crypt_DES::encrypt()\r
267      * @var Array\r
268      * @access private\r
269      */\r
270     var $enbuffer = array('encrypted' => '', 'xor' => '', 'pos' => 0, 'enmcrypt_init' => true);\r
271 \r
272     /**\r
273      * Decryption buffer for CTR, OFB and CFB modes\r
274      *\r
275      * @see Crypt_DES::decrypt()\r
276      * @var Array\r
277      * @access private\r
278      */\r
279     var $debuffer = array('ciphertext' => '', 'xor' => '', 'pos' => 0, 'demcrypt_init' => true);\r
280 \r
281     /**\r
282      * mcrypt resource for CFB mode\r
283      *\r
284      * @see Crypt_DES::encrypt()\r
285      * @see Crypt_DES::decrypt()\r
286      * @var String\r
287      * @access private\r
288      */\r
289     var $ecb;\r
290 \r
291     /**\r
292      * Performance-optimized callback function for en/decrypt()\r
293      * \r
294      * @var Callback\r
295      * @access private\r
296      */\r
297     var $inline_crypt;\r
298 \r
299     /**\r
300      * Holds whether performance-optimized $inline_crypt should be used or not.\r
301      *\r
302      * @var Boolean\r
303      * @access private\r
304      */\r
305     var $use_inline_crypt = false;\r
306 \r
307     /**\r
308      * Shuffle table.\r
309      *\r
310      * For each byte value index, the entry holds an 8-byte string\r
311      * with each byte containing all bits in the same state as the\r
312      * corresponding bit in the index value.\r
313      *\r
314      * @see Crypt_DES::_processBlock()\r
315      * @see Crypt_DES::_prepareKey()\r
316      * @var Array\r
317      * @access private\r
318      */\r
319     var $shuffle = array(\r
320         "\x00\x00\x00\x00\x00\x00\x00\x00", "\x00\x00\x00\x00\x00\x00\x00\xFF",\r
321         "\x00\x00\x00\x00\x00\x00\xFF\x00", "\x00\x00\x00\x00\x00\x00\xFF\xFF",\r
322         "\x00\x00\x00\x00\x00\xFF\x00\x00", "\x00\x00\x00\x00\x00\xFF\x00\xFF",\r
323         "\x00\x00\x00\x00\x00\xFF\xFF\x00", "\x00\x00\x00\x00\x00\xFF\xFF\xFF",\r
324         "\x00\x00\x00\x00\xFF\x00\x00\x00", "\x00\x00\x00\x00\xFF\x00\x00\xFF",\r
325         "\x00\x00\x00\x00\xFF\x00\xFF\x00", "\x00\x00\x00\x00\xFF\x00\xFF\xFF",\r
326         "\x00\x00\x00\x00\xFF\xFF\x00\x00", "\x00\x00\x00\x00\xFF\xFF\x00\xFF",\r
327         "\x00\x00\x00\x00\xFF\xFF\xFF\x00", "\x00\x00\x00\x00\xFF\xFF\xFF\xFF",\r
328         "\x00\x00\x00\xFF\x00\x00\x00\x00", "\x00\x00\x00\xFF\x00\x00\x00\xFF",\r
329         "\x00\x00\x00\xFF\x00\x00\xFF\x00", "\x00\x00\x00\xFF\x00\x00\xFF\xFF",\r
330         "\x00\x00\x00\xFF\x00\xFF\x00\x00", "\x00\x00\x00\xFF\x00\xFF\x00\xFF",\r
331         "\x00\x00\x00\xFF\x00\xFF\xFF\x00", "\x00\x00\x00\xFF\x00\xFF\xFF\xFF",\r
332         "\x00\x00\x00\xFF\xFF\x00\x00\x00", "\x00\x00\x00\xFF\xFF\x00\x00\xFF",\r
333         "\x00\x00\x00\xFF\xFF\x00\xFF\x00", "\x00\x00\x00\xFF\xFF\x00\xFF\xFF",\r
334         "\x00\x00\x00\xFF\xFF\xFF\x00\x00", "\x00\x00\x00\xFF\xFF\xFF\x00\xFF",\r
335         "\x00\x00\x00\xFF\xFF\xFF\xFF\x00", "\x00\x00\x00\xFF\xFF\xFF\xFF\xFF",\r
336         "\x00\x00\xFF\x00\x00\x00\x00\x00", "\x00\x00\xFF\x00\x00\x00\x00\xFF",\r
337         "\x00\x00\xFF\x00\x00\x00\xFF\x00", "\x00\x00\xFF\x00\x00\x00\xFF\xFF",\r
338         "\x00\x00\xFF\x00\x00\xFF\x00\x00", "\x00\x00\xFF\x00\x00\xFF\x00\xFF",\r
339         "\x00\x00\xFF\x00\x00\xFF\xFF\x00", "\x00\x00\xFF\x00\x00\xFF\xFF\xFF",\r
340         "\x00\x00\xFF\x00\xFF\x00\x00\x00", "\x00\x00\xFF\x00\xFF\x00\x00\xFF",\r
341         "\x00\x00\xFF\x00\xFF\x00\xFF\x00", "\x00\x00\xFF\x00\xFF\x00\xFF\xFF",\r
342         "\x00\x00\xFF\x00\xFF\xFF\x00\x00", "\x00\x00\xFF\x00\xFF\xFF\x00\xFF",\r
343         "\x00\x00\xFF\x00\xFF\xFF\xFF\x00", "\x00\x00\xFF\x00\xFF\xFF\xFF\xFF",\r
344         "\x00\x00\xFF\xFF\x00\x00\x00\x00", "\x00\x00\xFF\xFF\x00\x00\x00\xFF",\r
345         "\x00\x00\xFF\xFF\x00\x00\xFF\x00", "\x00\x00\xFF\xFF\x00\x00\xFF\xFF",\r
346         "\x00\x00\xFF\xFF\x00\xFF\x00\x00", "\x00\x00\xFF\xFF\x00\xFF\x00\xFF",\r
347         "\x00\x00\xFF\xFF\x00\xFF\xFF\x00", "\x00\x00\xFF\xFF\x00\xFF\xFF\xFF",\r
348         "\x00\x00\xFF\xFF\xFF\x00\x00\x00", "\x00\x00\xFF\xFF\xFF\x00\x00\xFF",\r
349         "\x00\x00\xFF\xFF\xFF\x00\xFF\x00", "\x00\x00\xFF\xFF\xFF\x00\xFF\xFF",\r
350         "\x00\x00\xFF\xFF\xFF\xFF\x00\x00", "\x00\x00\xFF\xFF\xFF\xFF\x00\xFF",\r
351         "\x00\x00\xFF\xFF\xFF\xFF\xFF\x00", "\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF",\r
352         "\x00\xFF\x00\x00\x00\x00\x00\x00", "\x00\xFF\x00\x00\x00\x00\x00\xFF",\r
353         "\x00\xFF\x00\x00\x00\x00\xFF\x00", "\x00\xFF\x00\x00\x00\x00\xFF\xFF",\r
354         "\x00\xFF\x00\x00\x00\xFF\x00\x00", "\x00\xFF\x00\x00\x00\xFF\x00\xFF",\r
355         "\x00\xFF\x00\x00\x00\xFF\xFF\x00", "\x00\xFF\x00\x00\x00\xFF\xFF\xFF",\r
356         "\x00\xFF\x00\x00\xFF\x00\x00\x00", "\x00\xFF\x00\x00\xFF\x00\x00\xFF",\r
357         "\x00\xFF\x00\x00\xFF\x00\xFF\x00", "\x00\xFF\x00\x00\xFF\x00\xFF\xFF",\r
358         "\x00\xFF\x00\x00\xFF\xFF\x00\x00", "\x00\xFF\x00\x00\xFF\xFF\x00\xFF",\r
359         "\x00\xFF\x00\x00\xFF\xFF\xFF\x00", "\x00\xFF\x00\x00\xFF\xFF\xFF\xFF",\r
360         "\x00\xFF\x00\xFF\x00\x00\x00\x00", "\x00\xFF\x00\xFF\x00\x00\x00\xFF",\r
361         "\x00\xFF\x00\xFF\x00\x00\xFF\x00", "\x00\xFF\x00\xFF\x00\x00\xFF\xFF",\r
362         "\x00\xFF\x00\xFF\x00\xFF\x00\x00", "\x00\xFF\x00\xFF\x00\xFF\x00\xFF",\r
363         "\x00\xFF\x00\xFF\x00\xFF\xFF\x00", "\x00\xFF\x00\xFF\x00\xFF\xFF\xFF",\r
364         "\x00\xFF\x00\xFF\xFF\x00\x00\x00", "\x00\xFF\x00\xFF\xFF\x00\x00\xFF",\r
365         "\x00\xFF\x00\xFF\xFF\x00\xFF\x00", "\x00\xFF\x00\xFF\xFF\x00\xFF\xFF",\r
366         "\x00\xFF\x00\xFF\xFF\xFF\x00\x00", "\x00\xFF\x00\xFF\xFF\xFF\x00\xFF",\r
367         "\x00\xFF\x00\xFF\xFF\xFF\xFF\x00", "\x00\xFF\x00\xFF\xFF\xFF\xFF\xFF",\r
368         "\x00\xFF\xFF\x00\x00\x00\x00\x00", "\x00\xFF\xFF\x00\x00\x00\x00\xFF",\r
369         "\x00\xFF\xFF\x00\x00\x00\xFF\x00", "\x00\xFF\xFF\x00\x00\x00\xFF\xFF",\r
370         "\x00\xFF\xFF\x00\x00\xFF\x00\x00", "\x00\xFF\xFF\x00\x00\xFF\x00\xFF",\r
371         "\x00\xFF\xFF\x00\x00\xFF\xFF\x00", "\x00\xFF\xFF\x00\x00\xFF\xFF\xFF",\r
372         "\x00\xFF\xFF\x00\xFF\x00\x00\x00", "\x00\xFF\xFF\x00\xFF\x00\x00\xFF",\r
373         "\x00\xFF\xFF\x00\xFF\x00\xFF\x00", "\x00\xFF\xFF\x00\xFF\x00\xFF\xFF",\r
374         "\x00\xFF\xFF\x00\xFF\xFF\x00\x00", "\x00\xFF\xFF\x00\xFF\xFF\x00\xFF",\r
375         "\x00\xFF\xFF\x00\xFF\xFF\xFF\x00", "\x00\xFF\xFF\x00\xFF\xFF\xFF\xFF",\r
376         "\x00\xFF\xFF\xFF\x00\x00\x00\x00", "\x00\xFF\xFF\xFF\x00\x00\x00\xFF",\r
377         "\x00\xFF\xFF\xFF\x00\x00\xFF\x00", "\x00\xFF\xFF\xFF\x00\x00\xFF\xFF",\r
378         "\x00\xFF\xFF\xFF\x00\xFF\x00\x00", "\x00\xFF\xFF\xFF\x00\xFF\x00\xFF",\r
379         "\x00\xFF\xFF\xFF\x00\xFF\xFF\x00", "\x00\xFF\xFF\xFF\x00\xFF\xFF\xFF",\r
380         "\x00\xFF\xFF\xFF\xFF\x00\x00\x00", "\x00\xFF\xFF\xFF\xFF\x00\x00\xFF",\r
381         "\x00\xFF\xFF\xFF\xFF\x00\xFF\x00", "\x00\xFF\xFF\xFF\xFF\x00\xFF\xFF",\r
382         "\x00\xFF\xFF\xFF\xFF\xFF\x00\x00", "\x00\xFF\xFF\xFF\xFF\xFF\x00\xFF",\r
383         "\x00\xFF\xFF\xFF\xFF\xFF\xFF\x00", "\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF",\r
384         "\xFF\x00\x00\x00\x00\x00\x00\x00", "\xFF\x00\x00\x00\x00\x00\x00\xFF",\r
385         "\xFF\x00\x00\x00\x00\x00\xFF\x00", "\xFF\x00\x00\x00\x00\x00\xFF\xFF",\r
386         "\xFF\x00\x00\x00\x00\xFF\x00\x00", "\xFF\x00\x00\x00\x00\xFF\x00\xFF",\r
387         "\xFF\x00\x00\x00\x00\xFF\xFF\x00", "\xFF\x00\x00\x00\x00\xFF\xFF\xFF",\r
388         "\xFF\x00\x00\x00\xFF\x00\x00\x00", "\xFF\x00\x00\x00\xFF\x00\x00\xFF",\r
389         "\xFF\x00\x00\x00\xFF\x00\xFF\x00", "\xFF\x00\x00\x00\xFF\x00\xFF\xFF",\r
390         "\xFF\x00\x00\x00\xFF\xFF\x00\x00", "\xFF\x00\x00\x00\xFF\xFF\x00\xFF",\r
391         "\xFF\x00\x00\x00\xFF\xFF\xFF\x00", "\xFF\x00\x00\x00\xFF\xFF\xFF\xFF",\r
392         "\xFF\x00\x00\xFF\x00\x00\x00\x00", "\xFF\x00\x00\xFF\x00\x00\x00\xFF",\r
393         "\xFF\x00\x00\xFF\x00\x00\xFF\x00", "\xFF\x00\x00\xFF\x00\x00\xFF\xFF",\r
394         "\xFF\x00\x00\xFF\x00\xFF\x00\x00", "\xFF\x00\x00\xFF\x00\xFF\x00\xFF",\r
395         "\xFF\x00\x00\xFF\x00\xFF\xFF\x00", "\xFF\x00\x00\xFF\x00\xFF\xFF\xFF",\r
396         "\xFF\x00\x00\xFF\xFF\x00\x00\x00", "\xFF\x00\x00\xFF\xFF\x00\x00\xFF",\r
397         "\xFF\x00\x00\xFF\xFF\x00\xFF\x00", "\xFF\x00\x00\xFF\xFF\x00\xFF\xFF",\r
398         "\xFF\x00\x00\xFF\xFF\xFF\x00\x00", "\xFF\x00\x00\xFF\xFF\xFF\x00\xFF",\r
399         "\xFF\x00\x00\xFF\xFF\xFF\xFF\x00", "\xFF\x00\x00\xFF\xFF\xFF\xFF\xFF",\r
400         "\xFF\x00\xFF\x00\x00\x00\x00\x00", "\xFF\x00\xFF\x00\x00\x00\x00\xFF",\r
401         "\xFF\x00\xFF\x00\x00\x00\xFF\x00", "\xFF\x00\xFF\x00\x00\x00\xFF\xFF",\r
402         "\xFF\x00\xFF\x00\x00\xFF\x00\x00", "\xFF\x00\xFF\x00\x00\xFF\x00\xFF",\r
403         "\xFF\x00\xFF\x00\x00\xFF\xFF\x00", "\xFF\x00\xFF\x00\x00\xFF\xFF\xFF",\r
404         "\xFF\x00\xFF\x00\xFF\x00\x00\x00", "\xFF\x00\xFF\x00\xFF\x00\x00\xFF",\r
405         "\xFF\x00\xFF\x00\xFF\x00\xFF\x00", "\xFF\x00\xFF\x00\xFF\x00\xFF\xFF",\r
406         "\xFF\x00\xFF\x00\xFF\xFF\x00\x00", "\xFF\x00\xFF\x00\xFF\xFF\x00\xFF",\r
407         "\xFF\x00\xFF\x00\xFF\xFF\xFF\x00", "\xFF\x00\xFF\x00\xFF\xFF\xFF\xFF",\r
408         "\xFF\x00\xFF\xFF\x00\x00\x00\x00", "\xFF\x00\xFF\xFF\x00\x00\x00\xFF",\r
409         "\xFF\x00\xFF\xFF\x00\x00\xFF\x00", "\xFF\x00\xFF\xFF\x00\x00\xFF\xFF",\r
410         "\xFF\x00\xFF\xFF\x00\xFF\x00\x00", "\xFF\x00\xFF\xFF\x00\xFF\x00\xFF",\r
411         "\xFF\x00\xFF\xFF\x00\xFF\xFF\x00", "\xFF\x00\xFF\xFF\x00\xFF\xFF\xFF",\r
412         "\xFF\x00\xFF\xFF\xFF\x00\x00\x00", "\xFF\x00\xFF\xFF\xFF\x00\x00\xFF",\r
413         "\xFF\x00\xFF\xFF\xFF\x00\xFF\x00", "\xFF\x00\xFF\xFF\xFF\x00\xFF\xFF",\r
414         "\xFF\x00\xFF\xFF\xFF\xFF\x00\x00", "\xFF\x00\xFF\xFF\xFF\xFF\x00\xFF",\r
415         "\xFF\x00\xFF\xFF\xFF\xFF\xFF\x00", "\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF",\r
416         "\xFF\xFF\x00\x00\x00\x00\x00\x00", "\xFF\xFF\x00\x00\x00\x00\x00\xFF",\r
417         "\xFF\xFF\x00\x00\x00\x00\xFF\x00", "\xFF\xFF\x00\x00\x00\x00\xFF\xFF",\r
418         "\xFF\xFF\x00\x00\x00\xFF\x00\x00", "\xFF\xFF\x00\x00\x00\xFF\x00\xFF",\r
419         "\xFF\xFF\x00\x00\x00\xFF\xFF\x00", "\xFF\xFF\x00\x00\x00\xFF\xFF\xFF",\r
420         "\xFF\xFF\x00\x00\xFF\x00\x00\x00", "\xFF\xFF\x00\x00\xFF\x00\x00\xFF",\r
421         "\xFF\xFF\x00\x00\xFF\x00\xFF\x00", "\xFF\xFF\x00\x00\xFF\x00\xFF\xFF",\r
422         "\xFF\xFF\x00\x00\xFF\xFF\x00\x00", "\xFF\xFF\x00\x00\xFF\xFF\x00\xFF",\r
423         "\xFF\xFF\x00\x00\xFF\xFF\xFF\x00", "\xFF\xFF\x00\x00\xFF\xFF\xFF\xFF",\r
424         "\xFF\xFF\x00\xFF\x00\x00\x00\x00", "\xFF\xFF\x00\xFF\x00\x00\x00\xFF",\r
425         "\xFF\xFF\x00\xFF\x00\x00\xFF\x00", "\xFF\xFF\x00\xFF\x00\x00\xFF\xFF",\r
426         "\xFF\xFF\x00\xFF\x00\xFF\x00\x00", "\xFF\xFF\x00\xFF\x00\xFF\x00\xFF",\r
427         "\xFF\xFF\x00\xFF\x00\xFF\xFF\x00", "\xFF\xFF\x00\xFF\x00\xFF\xFF\xFF",\r
428         "\xFF\xFF\x00\xFF\xFF\x00\x00\x00", "\xFF\xFF\x00\xFF\xFF\x00\x00\xFF",\r
429         "\xFF\xFF\x00\xFF\xFF\x00\xFF\x00", "\xFF\xFF\x00\xFF\xFF\x00\xFF\xFF",\r
430         "\xFF\xFF\x00\xFF\xFF\xFF\x00\x00", "\xFF\xFF\x00\xFF\xFF\xFF\x00\xFF",\r
431         "\xFF\xFF\x00\xFF\xFF\xFF\xFF\x00", "\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF",\r
432         "\xFF\xFF\xFF\x00\x00\x00\x00\x00", "\xFF\xFF\xFF\x00\x00\x00\x00\xFF",\r
433         "\xFF\xFF\xFF\x00\x00\x00\xFF\x00", "\xFF\xFF\xFF\x00\x00\x00\xFF\xFF",\r
434         "\xFF\xFF\xFF\x00\x00\xFF\x00\x00", "\xFF\xFF\xFF\x00\x00\xFF\x00\xFF",\r
435         "\xFF\xFF\xFF\x00\x00\xFF\xFF\x00", "\xFF\xFF\xFF\x00\x00\xFF\xFF\xFF",\r
436         "\xFF\xFF\xFF\x00\xFF\x00\x00\x00", "\xFF\xFF\xFF\x00\xFF\x00\x00\xFF",\r
437         "\xFF\xFF\xFF\x00\xFF\x00\xFF\x00", "\xFF\xFF\xFF\x00\xFF\x00\xFF\xFF",\r
438         "\xFF\xFF\xFF\x00\xFF\xFF\x00\x00", "\xFF\xFF\xFF\x00\xFF\xFF\x00\xFF",\r
439         "\xFF\xFF\xFF\x00\xFF\xFF\xFF\x00", "\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF",\r
440         "\xFF\xFF\xFF\xFF\x00\x00\x00\x00", "\xFF\xFF\xFF\xFF\x00\x00\x00\xFF",\r
441         "\xFF\xFF\xFF\xFF\x00\x00\xFF\x00", "\xFF\xFF\xFF\xFF\x00\x00\xFF\xFF",\r
442         "\xFF\xFF\xFF\xFF\x00\xFF\x00\x00", "\xFF\xFF\xFF\xFF\x00\xFF\x00\xFF",\r
443         "\xFF\xFF\xFF\xFF\x00\xFF\xFF\x00", "\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF",\r
444         "\xFF\xFF\xFF\xFF\xFF\x00\x00\x00", "\xFF\xFF\xFF\xFF\xFF\x00\x00\xFF",\r
445         "\xFF\xFF\xFF\xFF\xFF\x00\xFF\x00", "\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF",\r
446         "\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00", "\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF",\r
447         "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00", "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"\r
448     );\r
449 \r
450     /**\r
451      * IP mapping helper table.\r
452      *\r
453      * Indexing this table with each source byte performs the initial bit permutation.\r
454      *\r
455      * @var Array\r
456      * @access private\r
457      */\r
458     var $ipmap = array(\r
459         0x00, 0x10, 0x01, 0x11, 0x20, 0x30, 0x21, 0x31,\r
460         0x02, 0x12, 0x03, 0x13, 0x22, 0x32, 0x23, 0x33,\r
461         0x40, 0x50, 0x41, 0x51, 0x60, 0x70, 0x61, 0x71,\r
462         0x42, 0x52, 0x43, 0x53, 0x62, 0x72, 0x63, 0x73,\r
463         0x04, 0x14, 0x05, 0x15, 0x24, 0x34, 0x25, 0x35,\r
464         0x06, 0x16, 0x07, 0x17, 0x26, 0x36, 0x27, 0x37,\r
465         0x44, 0x54, 0x45, 0x55, 0x64, 0x74, 0x65, 0x75,\r
466         0x46, 0x56, 0x47, 0x57, 0x66, 0x76, 0x67, 0x77,\r
467         0x80, 0x90, 0x81, 0x91, 0xA0, 0xB0, 0xA1, 0xB1,\r
468         0x82, 0x92, 0x83, 0x93, 0xA2, 0xB2, 0xA3, 0xB3,\r
469         0xC0, 0xD0, 0xC1, 0xD1, 0xE0, 0xF0, 0xE1, 0xF1,\r
470         0xC2, 0xD2, 0xC3, 0xD3, 0xE2, 0xF2, 0xE3, 0xF3,\r
471         0x84, 0x94, 0x85, 0x95, 0xA4, 0xB4, 0xA5, 0xB5,\r
472         0x86, 0x96, 0x87, 0x97, 0xA6, 0xB6, 0xA7, 0xB7,\r
473         0xC4, 0xD4, 0xC5, 0xD5, 0xE4, 0xF4, 0xE5, 0xF5,\r
474         0xC6, 0xD6, 0xC7, 0xD7, 0xE6, 0xF6, 0xE7, 0xF7,\r
475         0x08, 0x18, 0x09, 0x19, 0x28, 0x38, 0x29, 0x39,\r
476         0x0A, 0x1A, 0x0B, 0x1B, 0x2A, 0x3A, 0x2B, 0x3B,\r
477         0x48, 0x58, 0x49, 0x59, 0x68, 0x78, 0x69, 0x79,\r
478         0x4A, 0x5A, 0x4B, 0x5B, 0x6A, 0x7A, 0x6B, 0x7B,\r
479         0x0C, 0x1C, 0x0D, 0x1D, 0x2C, 0x3C, 0x2D, 0x3D,\r
480         0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,\r
481         0x4C, 0x5C, 0x4D, 0x5D, 0x6C, 0x7C, 0x6D, 0x7D,\r
482         0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,\r
483         0x88, 0x98, 0x89, 0x99, 0xA8, 0xB8, 0xA9, 0xB9,\r
484         0x8A, 0x9A, 0x8B, 0x9B, 0xAA, 0xBA, 0xAB, 0xBB,\r
485         0xC8, 0xD8, 0xC9, 0xD9, 0xE8, 0xF8, 0xE9, 0xF9,\r
486         0xCA, 0xDA, 0xCB, 0xDB, 0xEA, 0xFA, 0xEB, 0xFB,\r
487         0x8C, 0x9C, 0x8D, 0x9D, 0xAC, 0xBC, 0xAD, 0xBD,\r
488         0x8E, 0x9E, 0x8F, 0x9F, 0xAE, 0xBE, 0xAF, 0xBF,\r
489         0xCC, 0xDC, 0xCD, 0xDD, 0xEC, 0xFC, 0xED, 0xFD,\r
490         0xCE, 0xDE, 0xCF, 0xDF, 0xEE, 0xFE, 0xEF, 0xFF\r
491     );\r
492 \r
493     /**\r
494      * Inverse IP mapping helper table.\r
495      * Indexing this table with a byte value reverses the bit order.\r
496      *\r
497      * @var Array\r
498      * @access private\r
499      */\r
500     var $invipmap = array(\r
501         0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0,\r
502         0x10, 0x90, 0x50, 0xD0, 0x30, 0xB0, 0x70, 0xF0,\r
503         0x08, 0x88, 0x48, 0xC8, 0x28, 0xA8, 0x68, 0xE8,\r
504         0x18, 0x98, 0x58, 0xD8, 0x38, 0xB8, 0x78, 0xF8,\r
505         0x04, 0x84, 0x44, 0xC4, 0x24, 0xA4, 0x64, 0xE4,\r
506         0x14, 0x94, 0x54, 0xD4, 0x34, 0xB4, 0x74, 0xF4,\r
507         0x0C, 0x8C, 0x4C, 0xCC, 0x2C, 0xAC, 0x6C, 0xEC,\r
508         0x1C, 0x9C, 0x5C, 0xDC, 0x3C, 0xBC, 0x7C, 0xFC,\r
509         0x02, 0x82, 0x42, 0xC2, 0x22, 0xA2, 0x62, 0xE2,\r
510         0x12, 0x92, 0x52, 0xD2, 0x32, 0xB2, 0x72, 0xF2,\r
511         0x0A, 0x8A, 0x4A, 0xCA, 0x2A, 0xAA, 0x6A, 0xEA,\r
512         0x1A, 0x9A, 0x5A, 0xDA, 0x3A, 0xBA, 0x7A, 0xFA,\r
513         0x06, 0x86, 0x46, 0xC6, 0x26, 0xA6, 0x66, 0xE6,\r
514         0x16, 0x96, 0x56, 0xD6, 0x36, 0xB6, 0x76, 0xF6,\r
515         0x0E, 0x8E, 0x4E, 0xCE, 0x2E, 0xAE, 0x6E, 0xEE,\r
516         0x1E, 0x9E, 0x5E, 0xDE, 0x3E, 0xBE, 0x7E, 0xFE,\r
517         0x01, 0x81, 0x41, 0xC1, 0x21, 0xA1, 0x61, 0xE1,\r
518         0x11, 0x91, 0x51, 0xD1, 0x31, 0xB1, 0x71, 0xF1,\r
519         0x09, 0x89, 0x49, 0xC9, 0x29, 0xA9, 0x69, 0xE9,\r
520         0x19, 0x99, 0x59, 0xD9, 0x39, 0xB9, 0x79, 0xF9,\r
521         0x05, 0x85, 0x45, 0xC5, 0x25, 0xA5, 0x65, 0xE5,\r
522         0x15, 0x95, 0x55, 0xD5, 0x35, 0xB5, 0x75, 0xF5,\r
523         0x0D, 0x8D, 0x4D, 0xCD, 0x2D, 0xAD, 0x6D, 0xED,\r
524         0x1D, 0x9D, 0x5D, 0xDD, 0x3D, 0xBD, 0x7D, 0xFD,\r
525         0x03, 0x83, 0x43, 0xC3, 0x23, 0xA3, 0x63, 0xE3,\r
526         0x13, 0x93, 0x53, 0xD3, 0x33, 0xB3, 0x73, 0xF3,\r
527         0x0B, 0x8B, 0x4B, 0xCB, 0x2B, 0xAB, 0x6B, 0xEB,\r
528         0x1B, 0x9B, 0x5B, 0xDB, 0x3B, 0xBB, 0x7B, 0xFB,\r
529         0x07, 0x87, 0x47, 0xC7, 0x27, 0xA7, 0x67, 0xE7,\r
530         0x17, 0x97, 0x57, 0xD7, 0x37, 0xB7, 0x77, 0xF7,\r
531         0x0F, 0x8F, 0x4F, 0xCF, 0x2F, 0xAF, 0x6F, 0xEF,\r
532         0x1F, 0x9F, 0x5F, 0xDF, 0x3F, 0xBF, 0x7F, 0xFF\r
533     );\r
534 \r
535     /**\r
536      * Pre-permuted S-box1\r
537      *\r
538      * Each box ($sbox1-$sbox8) has been vectorized, then each value pre-permuted using the\r
539      * P table: concatenation can then be replaced by exclusive ORs.\r
540      *\r
541      * @var Array\r
542      * @access private\r
543      */\r
544     var $sbox1 = array(\r
545         0x00808200, 0x00000000, 0x00008000, 0x00808202,\r
546         0x00808002, 0x00008202, 0x00000002, 0x00008000,\r
547         0x00000200, 0x00808200, 0x00808202, 0x00000200,\r
548         0x00800202, 0x00808002, 0x00800000, 0x00000002,\r
549         0x00000202, 0x00800200, 0x00800200, 0x00008200,\r
550         0x00008200, 0x00808000, 0x00808000, 0x00800202,\r
551         0x00008002, 0x00800002, 0x00800002, 0x00008002,\r
552         0x00000000, 0x00000202, 0x00008202, 0x00800000,\r
553         0x00008000, 0x00808202, 0x00000002, 0x00808000,\r
554         0x00808200, 0x00800000, 0x00800000, 0x00000200,\r
555         0x00808002, 0x00008000, 0x00008200, 0x00800002,\r
556         0x00000200, 0x00000002, 0x00800202, 0x00008202,\r
557         0x00808202, 0x00008002, 0x00808000, 0x00800202,\r
558         0x00800002, 0x00000202, 0x00008202, 0x00808200,\r
559         0x00000202, 0x00800200, 0x00800200, 0x00000000,\r
560         0x00008002, 0x00008200, 0x00000000, 0x00808002\r
561     );\r
562 \r
563     /**\r
564      * Pre-permuted S-box2\r
565      *\r
566      * @var Array\r
567      * @access private\r
568      */\r
569     var $sbox2 = array(\r
570         0x40084010, 0x40004000, 0x00004000, 0x00084010,\r
571         0x00080000, 0x00000010, 0x40080010, 0x40004010,\r
572         0x40000010, 0x40084010, 0x40084000, 0x40000000,\r
573         0x40004000, 0x00080000, 0x00000010, 0x40080010,\r
574         0x00084000, 0x00080010, 0x40004010, 0x00000000,\r
575         0x40000000, 0x00004000, 0x00084010, 0x40080000,\r
576         0x00080010, 0x40000010, 0x00000000, 0x00084000,\r
577         0x00004010, 0x40084000, 0x40080000, 0x00004010,\r
578         0x00000000, 0x00084010, 0x40080010, 0x00080000,\r
579         0x40004010, 0x40080000, 0x40084000, 0x00004000,\r
580         0x40080000, 0x40004000, 0x00000010, 0x40084010,\r
581         0x00084010, 0x00000010, 0x00004000, 0x40000000,\r
582         0x00004010, 0x40084000, 0x00080000, 0x40000010,\r
583         0x00080010, 0x40004010, 0x40000010, 0x00080010,\r
584         0x00084000, 0x00000000, 0x40004000, 0x00004010,\r
585         0x40000000, 0x40080010, 0x40084010, 0x00084000\r
586     );\r
587 \r
588     /**\r
589      * Pre-permuted S-box3\r
590      *\r
591      * @var Array\r
592      * @access private\r
593      */\r
594     var $sbox3 = array(\r
595         0x00000104, 0x04010100, 0x00000000, 0x04010004,\r
596         0x04000100, 0x00000000, 0x00010104, 0x04000100,\r
597         0x00010004, 0x04000004, 0x04000004, 0x00010000,\r
598         0x04010104, 0x00010004, 0x04010000, 0x00000104,\r
599         0x04000000, 0x00000004, 0x04010100, 0x00000100,\r
600         0x00010100, 0x04010000, 0x04010004, 0x00010104,\r
601         0x04000104, 0x00010100, 0x00010000, 0x04000104,\r
602         0x00000004, 0x04010104, 0x00000100, 0x04000000,\r
603         0x04010100, 0x04000000, 0x00010004, 0x00000104,\r
604         0x00010000, 0x04010100, 0x04000100, 0x00000000,\r
605         0x00000100, 0x00010004, 0x04010104, 0x04000100,\r
606         0x04000004, 0x00000100, 0x00000000, 0x04010004,\r
607         0x04000104, 0x00010000, 0x04000000, 0x04010104,\r
608         0x00000004, 0x00010104, 0x00010100, 0x04000004,\r
609         0x04010000, 0x04000104, 0x00000104, 0x04010000,\r
610         0x00010104, 0x00000004, 0x04010004, 0x00010100\r
611     );\r
612 \r
613     /**\r
614      * Pre-permuted S-box4\r
615      *\r
616      * @var Array\r
617      * @access private\r
618      */\r
619     var $sbox4 = array(\r
620         0x80401000, 0x80001040, 0x80001040, 0x00000040,\r
621         0x00401040, 0x80400040, 0x80400000, 0x80001000,\r
622         0x00000000, 0x00401000, 0x00401000, 0x80401040,\r
623         0x80000040, 0x00000000, 0x00400040, 0x80400000,\r
624         0x80000000, 0x00001000, 0x00400000, 0x80401000,\r
625         0x00000040, 0x00400000, 0x80001000, 0x00001040,\r
626         0x80400040, 0x80000000, 0x00001040, 0x00400040,\r
627         0x00001000, 0x00401040, 0x80401040, 0x80000040,\r
628         0x00400040, 0x80400000, 0x00401000, 0x80401040,\r
629         0x80000040, 0x00000000, 0x00000000, 0x00401000,\r
630         0x00001040, 0x00400040, 0x80400040, 0x80000000,\r
631         0x80401000, 0x80001040, 0x80001040, 0x00000040,\r
632         0x80401040, 0x80000040, 0x80000000, 0x00001000,\r
633         0x80400000, 0x80001000, 0x00401040, 0x80400040,\r
634         0x80001000, 0x00001040, 0x00400000, 0x80401000,\r
635         0x00000040, 0x00400000, 0x00001000, 0x00401040\r
636     );\r
637 \r
638     /**\r
639      * Pre-permuted S-box5\r
640      *\r
641      * @var Array\r
642      * @access private\r
643      */\r
644     var $sbox5 = array(\r
645         0x00000080, 0x01040080, 0x01040000, 0x21000080,\r
646         0x00040000, 0x00000080, 0x20000000, 0x01040000,\r
647         0x20040080, 0x00040000, 0x01000080, 0x20040080,\r
648         0x21000080, 0x21040000, 0x00040080, 0x20000000,\r
649         0x01000000, 0x20040000, 0x20040000, 0x00000000,\r
650         0x20000080, 0x21040080, 0x21040080, 0x01000080,\r
651         0x21040000, 0x20000080, 0x00000000, 0x21000000,\r
652         0x01040080, 0x01000000, 0x21000000, 0x00040080,\r
653         0x00040000, 0x21000080, 0x00000080, 0x01000000,\r
654         0x20000000, 0x01040000, 0x21000080, 0x20040080,\r
655         0x01000080, 0x20000000, 0x21040000, 0x01040080,\r
656         0x20040080, 0x00000080, 0x01000000, 0x21040000,\r
657         0x21040080, 0x00040080, 0x21000000, 0x21040080,\r
658         0x01040000, 0x00000000, 0x20040000, 0x21000000,\r
659         0x00040080, 0x01000080, 0x20000080, 0x00040000,\r
660         0x00000000, 0x20040000, 0x01040080, 0x20000080\r
661     );\r
662 \r
663     /**\r
664      * Pre-permuted S-box6\r
665      *\r
666      * @var Array\r
667      * @access private\r
668      */\r
669     var $sbox6 = array(\r
670         0x10000008, 0x10200000, 0x00002000, 0x10202008,\r
671         0x10200000, 0x00000008, 0x10202008, 0x00200000,\r
672         0x10002000, 0x00202008, 0x00200000, 0x10000008,\r
673         0x00200008, 0x10002000, 0x10000000, 0x00002008,\r
674         0x00000000, 0x00200008, 0x10002008, 0x00002000,\r
675         0x00202000, 0x10002008, 0x00000008, 0x10200008,\r
676         0x10200008, 0x00000000, 0x00202008, 0x10202000,\r
677         0x00002008, 0x00202000, 0x10202000, 0x10000000,\r
678         0x10002000, 0x00000008, 0x10200008, 0x00202000,\r
679         0x10202008, 0x00200000, 0x00002008, 0x10000008,\r
680         0x00200000, 0x10002000, 0x10000000, 0x00002008,\r
681         0x10000008, 0x10202008, 0x00202000, 0x10200000,\r
682         0x00202008, 0x10202000, 0x00000000, 0x10200008,\r
683         0x00000008, 0x00002000, 0x10200000, 0x00202008,\r
684         0x00002000, 0x00200008, 0x10002008, 0x00000000,\r
685         0x10202000, 0x10000000, 0x00200008, 0x10002008\r
686     );\r
687 \r
688     /**\r
689      * Pre-permuted S-box7\r
690      *\r
691      * @var Array\r
692      * @access private\r
693      */\r
694     var $sbox7 = array(\r
695         0x00100000, 0x02100001, 0x02000401, 0x00000000,\r
696         0x00000400, 0x02000401, 0x00100401, 0x02100400,\r
697         0x02100401, 0x00100000, 0x00000000, 0x02000001,\r
698         0x00000001, 0x02000000, 0x02100001, 0x00000401,\r
699         0x02000400, 0x00100401, 0x00100001, 0x02000400,\r
700         0x02000001, 0x02100000, 0x02100400, 0x00100001,\r
701         0x02100000, 0x00000400, 0x00000401, 0x02100401,\r
702         0x00100400, 0x00000001, 0x02000000, 0x00100400,\r
703         0x02000000, 0x00100400, 0x00100000, 0x02000401,\r
704         0x02000401, 0x02100001, 0x02100001, 0x00000001,\r
705         0x00100001, 0x02000000, 0x02000400, 0x00100000,\r
706         0x02100400, 0x00000401, 0x00100401, 0x02100400,\r
707         0x00000401, 0x02000001, 0x02100401, 0x02100000,\r
708         0x00100400, 0x00000000, 0x00000001, 0x02100401,\r
709         0x00000000, 0x00100401, 0x02100000, 0x00000400,\r
710         0x02000001, 0x02000400, 0x00000400, 0x00100001\r
711     );\r
712 \r
713     /**\r
714      * Pre-permuted S-box8\r
715      *\r
716      * @var Array\r
717      * @access private\r
718      */\r
719     var $sbox8 = array(\r
720         0x08000820, 0x00000800, 0x00020000, 0x08020820,\r
721         0x08000000, 0x08000820, 0x00000020, 0x08000000,\r
722         0x00020020, 0x08020000, 0x08020820, 0x00020800,\r
723         0x08020800, 0x00020820, 0x00000800, 0x00000020,\r
724         0x08020000, 0x08000020, 0x08000800, 0x00000820,\r
725         0x00020800, 0x00020020, 0x08020020, 0x08020800,\r
726         0x00000820, 0x00000000, 0x00000000, 0x08020020,\r
727         0x08000020, 0x08000800, 0x00020820, 0x00020000,\r
728         0x00020820, 0x00020000, 0x08020800, 0x00000800,\r
729         0x00000020, 0x08020020, 0x00000800, 0x00020820,\r
730         0x08000800, 0x00000020, 0x08000020, 0x08020000,\r
731         0x08020020, 0x08000000, 0x00020000, 0x08000820,\r
732         0x00000000, 0x08020820, 0x00020020, 0x08000020,\r
733         0x08020000, 0x08000800, 0x08000820, 0x00000000,\r
734         0x08020820, 0x00020800, 0x00020800, 0x00000820,\r
735         0x00000820, 0x00020020, 0x08000000, 0x08020800\r
736     );\r
737 \r
738     /**\r
739      * Default Constructor.\r
740      *\r
741      * Determines whether or not the mcrypt extension should be used.  $mode should only, at present, be\r
742      * CRYPT_DES_MODE_ECB or CRYPT_DES_MODE_CBC.  If not explictly set, CRYPT_DES_MODE_CBC will be used.\r
743      *\r
744      * @param optional Integer $mode\r
745      * @return Crypt_DES\r
746      * @access public\r
747      */\r
748     function Crypt_DES($mode = CRYPT_DES_MODE_CBC)\r
749     {\r
750         if ( !defined('CRYPT_DES_MODE') ) {\r
751             switch (true) {\r
752                 case extension_loaded('mcrypt') && in_array('des', mcrypt_list_algorithms()):\r
753                     define('CRYPT_DES_MODE', CRYPT_DES_MODE_MCRYPT);\r
754                     break;\r
755                 default:\r
756                     define('CRYPT_DES_MODE', CRYPT_DES_MODE_INTERNAL);\r
757             }\r
758         }\r
759 \r
760         switch ( CRYPT_DES_MODE ) {\r
761             case CRYPT_DES_MODE_MCRYPT:\r
762                 switch ($mode) {\r
763                     case CRYPT_DES_MODE_ECB:\r
764                         $this->paddable = true;\r
765                         $this->mode = MCRYPT_MODE_ECB;\r
766                         break;\r
767                     case CRYPT_DES_MODE_CTR:\r
768                         $this->mode = 'ctr';\r
769                         //$this->mode = in_array('ctr', mcrypt_list_modes()) ? 'ctr' : CRYPT_DES_MODE_CTR;\r
770                         break;\r
771                     case CRYPT_DES_MODE_CFB:\r
772                         $this->mode = 'ncfb';\r
773                         $this->ecb = mcrypt_module_open(MCRYPT_DES, '', MCRYPT_MODE_ECB, '');\r
774                         break;\r
775                     case CRYPT_DES_MODE_OFB:\r
776                         $this->mode = MCRYPT_MODE_NOFB;\r
777                         break;\r
778                     case CRYPT_DES_MODE_CBC:\r
779                     default:\r
780                         $this->paddable = true;\r
781                         $this->mode = MCRYPT_MODE_CBC;\r
782                 }\r
783                 $this->enmcrypt = mcrypt_module_open(MCRYPT_DES, '', $this->mode, '');\r
784                 $this->demcrypt = mcrypt_module_open(MCRYPT_DES, '', $this->mode, '');\r
785 \r
786                 break;\r
787             default:\r
788                 switch ($mode) {\r
789                     case CRYPT_DES_MODE_ECB:\r
790                     case CRYPT_DES_MODE_CBC:\r
791                         $this->paddable = true;\r
792                         $this->mode = $mode;\r
793                         break;\r
794                     case CRYPT_DES_MODE_CTR:\r
795                     case CRYPT_DES_MODE_CFB:\r
796                     case CRYPT_DES_MODE_OFB:\r
797                         $this->mode = $mode;\r
798                         break;\r
799                     default:\r
800                         $this->paddable = true;\r
801                         $this->mode = CRYPT_DES_MODE_CBC;\r
802                 }\r
803                 if (function_exists('create_function') && is_callable('create_function')) {\r
804                     $this->inline_crypt_setup();\r
805                     $this->use_inline_crypt = true;\r
806                 }\r
807         }\r
808     }\r
809 \r
810     /**\r
811      * Sets the key.\r
812      *\r
813      * Keys can be of any length.  DES, itself, uses 64-bit keys (eg. strlen($key) == 8), however, we\r
814      * only use the first eight, if $key has more then eight characters in it, and pad $key with the\r
815      * null byte if it is less then eight characters long.\r
816      *\r
817      * DES also requires that every eighth bit be a parity bit, however, we'll ignore that.\r
818      *\r
819      * If the key is not explicitly set, it'll be assumed to be all zero's.\r
820      *\r
821      * @access public\r
822      * @param String $key\r
823      */\r
824     function setKey($key)\r
825     {\r
826         $this->keys = ( CRYPT_DES_MODE == CRYPT_DES_MODE_MCRYPT ) ? str_pad(substr($key, 0, 8), 8, chr(0)) : $this->_prepareKey($key);\r
827         $this->enchanged = true;\r
828         $this->dechanged = true;\r
829     }\r
830 \r
831     /**\r
832      * Sets the password.\r
833      *\r
834      * Depending on what $method is set to, setPassword()'s (optional) parameters are as follows:\r
835      *     {@link http://en.wikipedia.org/wiki/PBKDF2 pbkdf2}:\r
836      *         $hash, $salt, $count\r
837      *\r
838      * @param String $password\r
839      * @param optional String $method\r
840      * @access public\r
841      */\r
842     function setPassword($password, $method = 'pbkdf2')\r
843     {\r
844         $key = '';\r
845 \r
846         switch ($method) {\r
847             default: // 'pbkdf2'\r
848                 list(, , $hash, $salt, $count) = func_get_args();\r
849                 if (!isset($hash)) {\r
850                     $hash = 'sha1';\r
851                 }\r
852                 // WPA and WPA2 use the SSID as the salt\r
853                 if (!isset($salt)) {\r
854                     $salt = 'phpseclib/salt';\r
855                 }\r
856                 // RFC2898#section-4.2 uses 1,000 iterations by default\r
857                 // WPA and WPA2 use 4,096.\r
858                 if (!isset($count)) {\r
859                     $count = 1000;\r
860                 }\r
861 \r
862                 if (!class_exists('Crypt_Hash')) {\r
863                     require_once('Crypt/Hash.php');\r
864                 }\r
865 \r
866                 $i = 1;\r
867                 while (strlen($key) < 8) { // $dkLen == 8\r
868                     //$dk.= $this->_pbkdf($password, $salt, $count, $i++);\r
869                     $hmac = new Crypt_Hash();\r
870                     $hmac->setHash($hash);\r
871                     $hmac->setKey($password);\r
872                     $f = $u = $hmac->hash($salt . pack('N', $i++));\r
873                     for ($j = 2; $j <= $count; $j++) {\r
874                         $u = $hmac->hash($u);\r
875                         $f^= $u;\r
876                     }\r
877                     $key.= $f;\r
878                 }\r
879         }\r
880 \r
881         $this->setKey($key);\r
882     }\r
883 \r
884     /**\r
885      * Sets the initialization vector. (optional)\r
886      *\r
887      * SetIV is not required when CRYPT_DES_MODE_ECB is being used.  If not explictly set, it'll be assumed\r
888      * to be all zero's.\r
889      *\r
890      * @access public\r
891      * @param String $iv\r
892      */\r
893     function setIV($iv)\r
894     {\r
895         $this->encryptIV = $this->decryptIV = $this->iv = str_pad(substr($iv, 0, 8), 8, chr(0));\r
896         $this->enchanged = true;\r
897         $this->dechanged = true;\r
898     }\r
899 \r
900     /**\r
901      * Generate CTR XOR encryption key\r
902      *\r
903      * Encrypt the output of this and XOR it against the ciphertext / plaintext to get the\r
904      * plaintext / ciphertext in CTR mode.\r
905      *\r
906      * @see Crypt_DES::decrypt()\r
907      * @see Crypt_DES::encrypt()\r
908      * @access public\r
909      * @param String $iv\r
910      */\r
911     function _generate_xor(&$iv)\r
912     {\r
913         $xor = $iv;\r
914         for ($j = 4; $j <= 8; $j+=4) {\r
915             $temp = substr($iv, -$j, 4);\r
916             switch ($temp) {\r
917                 case "\xFF\xFF\xFF\xFF":\r
918                     $iv = substr_replace($iv, "\x00\x00\x00\x00", -$j, 4);\r
919                     break;\r
920                 case "\x7F\xFF\xFF\xFF":\r
921                     $iv = substr_replace($iv, "\x80\x00\x00\x00", -$j, 4);\r
922                     break 2;\r
923                 default:\r
924                     extract(unpack('Ncount', $temp));\r
925                     $iv = substr_replace($iv, pack('N', $count + 1), -$j, 4);\r
926                     break 2;\r
927             }\r
928         }\r
929 \r
930         return $xor;\r
931     }\r
932 \r
933     /**\r
934      * Encrypts a message.\r
935      *\r
936      * $plaintext will be padded with up to 8 additional bytes.  Other DES implementations may or may not pad in the\r
937      * same manner.  Other common approaches to padding and the reasons why it's necessary are discussed in the following\r
938      * URL:\r
939      *\r
940      * {@link http://www.di-mgt.com.au/cryptopad.html http://www.di-mgt.com.au/cryptopad.html}\r
941      *\r
942      * An alternative to padding is to, separately, send the length of the file.  This is what SSH, in fact, does.\r
943      * strlen($plaintext) will still need to be a multiple of 8, however, arbitrary values can be added to make it that\r
944      * length.\r
945      *\r
946      * @see Crypt_DES::decrypt()\r
947      * @access public\r
948      * @param String $plaintext\r
949      */\r
950     function encrypt($plaintext)\r
951     {\r
952         if ($this->paddable) {\r
953             $plaintext = $this->_pad($plaintext);\r
954         }\r
955 \r
956         if ( CRYPT_DES_MODE == CRYPT_DES_MODE_MCRYPT ) {\r
957             if ($this->enchanged) {\r
958                 mcrypt_generic_init($this->enmcrypt, $this->keys, $this->encryptIV);\r
959                 if ($this->mode == 'ncfb') {\r
960                     mcrypt_generic_init($this->ecb, $this->keys, "\0\0\0\0\0\0\0\0");\r
961                 }\r
962                 $this->enchanged = false;\r
963             }\r
964 \r
965             if ($this->mode != 'ncfb' || !$this->continuousBuffer) {\r
966                 $ciphertext = mcrypt_generic($this->enmcrypt, $plaintext);\r
967             } else {\r
968                 $iv = &$this->encryptIV;\r
969                 $pos = &$this->enbuffer['pos'];\r
970                 $len = strlen($plaintext);\r
971                 $ciphertext = '';\r
972                 $i = 0;\r
973                 if ($pos) {\r
974                     $orig_pos = $pos;\r
975                     $max = 8 - $pos;\r
976                     if ($len >= $max) {\r
977                         $i = $max;\r
978                         $len-= $max;\r
979                         $pos = 0;\r
980                     } else {\r
981                         $i = $len;\r
982                         $pos+= $len;\r
983                         $len = 0;\r
984                     }\r
985                     $ciphertext = substr($iv, $orig_pos) ^ $plaintext;\r
986                     $iv = substr_replace($iv, $ciphertext, $orig_pos, $i);\r
987                     $this->enbuffer['enmcrypt_init'] = true;\r
988                 }\r
989                 if ($len >= 8) {\r
990                     if ($this->enbuffer['enmcrypt_init'] === false || $len > 600) {\r
991                         if ($this->enbuffer['enmcrypt_init'] === true) {\r
992                             mcrypt_generic_init($this->enmcrypt, $this->keys, $iv);\r
993                             $this->enbuffer['enmcrypt_init'] = false;\r
994                         }\r
995                         $ciphertext.= mcrypt_generic($this->enmcrypt, substr($plaintext, $i, $len - $len % 8));\r
996                         $iv = substr($ciphertext, -8);\r
997                         $len%= 8;\r
998                     } else {\r
999                         while ($len >= 8) {\r
1000                             $iv = mcrypt_generic($this->ecb, $iv) ^ substr($plaintext, $i, 8);\r
1001                             $ciphertext.= $iv;\r
1002                             $len-= 8;\r
1003                             $i+= 8;\r
1004                         }\r
1005                     }\r
1006                 } \r
1007                 if ($len) {\r
1008                     $iv = mcrypt_generic($this->ecb, $iv);\r
1009                     $block = $iv ^ substr($plaintext, -$len);\r
1010                     $iv = substr_replace($iv, $block, 0, $len);\r
1011                     $ciphertext.= $block;\r
1012                     $pos = $len;\r
1013                 }\r
1014                 return $ciphertext;\r
1015             }\r
1016 \r
1017             if (!$this->continuousBuffer) {\r
1018                 mcrypt_generic_init($this->enmcrypt, $this->keys, $this->encryptIV);\r
1019             }\r
1020 \r
1021             return $ciphertext;\r
1022         }\r
1023 \r
1024         if (!is_array($this->keys)) {\r
1025             $this->keys = $this->_prepareKey("\0\0\0\0\0\0\0\0");\r
1026         }\r
1027 \r
1028         if ($this->use_inline_crypt) {\r
1029             $inline = $this->inline_crypt;\r
1030             return $inline('encrypt', $this, $plaintext);\r
1031         }\r
1032 \r
1033         $buffer = &$this->enbuffer;\r
1034         $continuousBuffer = $this->continuousBuffer;\r
1035         $ciphertext = '';\r
1036         switch ($this->mode) {\r
1037             case CRYPT_DES_MODE_ECB:\r
1038                 for ($i = 0; $i < strlen($plaintext); $i+=8) {\r
1039                     $ciphertext.= $this->_processBlock(substr($plaintext, $i, 8), CRYPT_DES_ENCRYPT);\r
1040                 }\r
1041                 break;\r
1042             case CRYPT_DES_MODE_CBC:\r
1043                 $xor = $this->encryptIV;\r
1044                 for ($i = 0; $i < strlen($plaintext); $i+=8) {\r
1045                     $block = substr($plaintext, $i, 8);\r
1046                     $block = $this->_processBlock($block ^ $xor, CRYPT_DES_ENCRYPT);\r
1047                     $xor = $block;\r
1048                     $ciphertext.= $block;\r
1049                 }\r
1050                 if ($this->continuousBuffer) {\r
1051                     $this->encryptIV = $xor;\r
1052                 }\r
1053                 break;\r
1054             case CRYPT_DES_MODE_CTR:\r
1055                 $xor = $this->encryptIV;\r
1056                 if (strlen($buffer['encrypted'])) {\r
1057                     for ($i = 0; $i < strlen($plaintext); $i+=8) {\r
1058                         $block = substr($plaintext, $i, 8);\r
1059                         if (strlen($block) > strlen($buffer['encrypted'])) {\r
1060                             $buffer['encrypted'].= $this->_processBlock($this->_generate_xor($xor), CRYPT_DES_ENCRYPT);\r
1061                         }\r
1062                         $key = $this->_string_shift($buffer['encrypted']);\r
1063                         $ciphertext.= $block ^ $key;\r
1064                     }\r
1065                 } else {\r
1066                     for ($i = 0; $i < strlen($plaintext); $i+=8) {\r
1067                         $block = substr($plaintext, $i, 8);\r
1068                         $key = $this->_processBlock($this->_generate_xor($xor), CRYPT_DES_ENCRYPT);\r
1069                         $ciphertext.= $block ^ $key;\r
1070                     }\r
1071                 }\r
1072                 if ($this->continuousBuffer) {\r
1073                     $this->encryptIV = $xor;\r
1074                     if ($start = strlen($plaintext) & 7) {\r
1075                         $buffer['encrypted'] = substr($key, $start) . $buffer['encrypted'];\r
1076                     }\r
1077                 }\r
1078                 break;\r
1079             case CRYPT_DES_MODE_CFB:\r
1080                 if ($this->continuousBuffer) {\r
1081                     $iv = &$this->encryptIV;\r
1082                     $pos = &$buffer['pos'];\r
1083                 } else {\r
1084                     $iv = $this->encryptIV;\r
1085                     $pos = 0;\r
1086                 }\r
1087                 $len = strlen($plaintext);\r
1088                 $i = 0;\r
1089                 if ($pos) {\r
1090                     $orig_pos = $pos;\r
1091                     $max = 8 - $pos;\r
1092                     if ($len >= $max) {\r
1093                         $i = $max;\r
1094                         $len-= $max;\r
1095                         $pos = 0;\r
1096                     } else {\r
1097                         $i = $len;\r
1098                         $pos+= $len;\r
1099                         $len = 0;\r
1100                     }\r
1101                     $ciphertext = substr($iv, $orig_pos) ^ $plaintext;\r
1102                     $iv = substr_replace($iv, $ciphertext, $orig_pos, $i);\r
1103                 }\r
1104                 while ($len >= 8) {\r
1105                     $iv = $this->_processBlock($iv, CRYPT_DES_ENCRYPT) ^ substr($plaintext, $i, 8);\r
1106                     $ciphertext.= $iv;\r
1107                     $len-= 8;\r
1108                     $i+= 8;\r
1109                 }\r
1110                 if ($len) {\r
1111                     $iv = $this->_processBlock($iv, CRYPT_DES_ENCRYPT);\r
1112                     $block = $iv ^ substr($plaintext, $i);\r
1113                     $iv = substr_replace($iv, $block, 0, $len);\r
1114                     $ciphertext.= $block;\r
1115                     $pos = $len;\r
1116                 }\r
1117                 return $ciphertext;\r
1118             case CRYPT_DES_MODE_OFB:\r
1119                 $xor = $this->encryptIV;\r
1120                 if (strlen($buffer['xor'])) {\r
1121                     for ($i = 0; $i < strlen($plaintext); $i+=8) {\r
1122                         $block = substr($plaintext, $i, 8);\r
1123                         if (strlen($block) > strlen($buffer['xor'])) {\r
1124                             $xor = $this->_processBlock($xor, CRYPT_DES_ENCRYPT);\r
1125                             $buffer['xor'].= $xor;\r
1126                         }\r
1127                         $key = $this->_string_shift($buffer['xor']);\r
1128                         $ciphertext.= $block ^ $key;\r
1129                     }\r
1130                 } else {\r
1131                     for ($i = 0; $i < strlen($plaintext); $i+=8) {\r
1132                         $xor = $this->_processBlock($xor, CRYPT_DES_ENCRYPT);\r
1133                         $ciphertext.= substr($plaintext, $i, 8) ^ $xor;\r
1134                     }\r
1135                     $key = $xor;\r
1136                 }\r
1137                 if ($this->continuousBuffer) {\r
1138                     $this->encryptIV = $xor;\r
1139                     if ($start = strlen($plaintext) & 7) {\r
1140                          $buffer['xor'] = substr($key, $start) . $buffer['xor'];\r
1141                     }\r
1142                 }\r
1143         }\r
1144 \r
1145         return $ciphertext;\r
1146     }\r
1147 \r
1148     /**\r
1149      * Decrypts a message.\r
1150      *\r
1151      * If strlen($ciphertext) is not a multiple of 8, null bytes will be added to the end of the string until it is.\r
1152      *\r
1153      * @see Crypt_DES::encrypt()\r
1154      * @access public\r
1155      * @param String $ciphertext\r
1156      */\r
1157     function decrypt($ciphertext)\r
1158     {\r
1159         if ($this->paddable) {\r
1160             // we pad with chr(0) since that's what mcrypt_generic does.  to quote from http://php.net/function.mcrypt-generic :\r
1161             // "The data is padded with "\0" to make sure the length of the data is n * blocksize."\r
1162             $ciphertext = str_pad($ciphertext, (strlen($ciphertext) + 7) & 0xFFFFFFF8, chr(0));\r
1163         }\r
1164 \r
1165         if ( CRYPT_DES_MODE == CRYPT_DES_MODE_MCRYPT ) {\r
1166             if ($this->dechanged) {\r
1167                 mcrypt_generic_init($this->demcrypt, $this->keys, $this->decryptIV);\r
1168                 if ($this->mode == 'ncfb') {\r
1169                     mcrypt_generic_init($this->ecb, $this->keys, "\0\0\0\0\0\0\0\0");\r
1170                 }\r
1171                 $this->dechanged = false;\r
1172             }\r
1173 \r
1174             if ($this->mode != 'ncfb' || !$this->continuousBuffer) {\r
1175                 $plaintext = mdecrypt_generic($this->demcrypt, $ciphertext);\r
1176             } else {\r
1177                 $iv = &$this->decryptIV;\r
1178                 $pos = &$this->debuffer['pos'];\r
1179                 $len = strlen($ciphertext);\r
1180                 $plaintext = '';\r
1181                 $i = 0;\r
1182                 if ($pos) {\r
1183                     $orig_pos = $pos;\r
1184                     $max = 8 - $pos;\r
1185                     if ($len >= $max) {\r
1186                         $i = $max;\r
1187                         $len-= $max;\r
1188                         $pos = 0;\r
1189                     } else {\r
1190                         $i = $len;\r
1191                         $pos+= $len;\r
1192                         $len = 0;\r
1193                     }\r
1194                     $plaintext = substr($iv, $orig_pos) ^ $ciphertext;\r
1195                     $iv = substr_replace($iv, substr($ciphertext, 0, $i), $orig_pos, $i);\r
1196                 }\r
1197                 if ($len >= 8) {\r
1198                     $cb = substr($ciphertext, $i, $len - $len % 8);\r
1199                     $plaintext.= mcrypt_generic($this->ecb, $iv . $cb) ^ $cb;\r
1200                     $iv = substr($cb, -8);\r
1201                     $len%= 8;\r
1202                 }\r
1203                 if ($len) {\r
1204                     $iv = mcrypt_generic($this->ecb, $iv);\r
1205                     $plaintext.= $iv ^ substr($ciphertext, -$len);\r
1206                     $iv = substr_replace($iv, substr($ciphertext, -$len), 0, $len);\r
1207                     $pos = $len;\r
1208                 }\r
1209                 return $plaintext;\r
1210             }\r
1211 \r
1212             if (!$this->continuousBuffer) {\r
1213                 mcrypt_generic_init($this->demcrypt, $this->keys, $this->decryptIV);\r
1214             }\r
1215 \r
1216             return $this->paddable ? $this->_unpad($plaintext) : $plaintext;\r
1217         }\r
1218 \r
1219         if (!is_array($this->keys)) {\r
1220             $this->keys = $this->_prepareKey("\0\0\0\0\0\0\0\0");\r
1221         }\r
1222 \r
1223         if ($this->use_inline_crypt) {\r
1224             $inline = $this->inline_crypt;\r
1225             return $inline('decrypt', $this, $ciphertext);\r
1226         }\r
1227 \r
1228         $buffer = &$this->debuffer;\r
1229         $continuousBuffer = $this->continuousBuffer;\r
1230         $plaintext = '';\r
1231         switch ($this->mode) {\r
1232             case CRYPT_DES_MODE_ECB:\r
1233                 for ($i = 0; $i < strlen($ciphertext); $i+=8) {\r
1234                     $plaintext.= $this->_processBlock(substr($ciphertext, $i, 8), CRYPT_DES_DECRYPT);\r
1235                 }\r
1236                 break;\r
1237             case CRYPT_DES_MODE_CBC:\r
1238                 $xor = $this->decryptIV;\r
1239                 for ($i = 0; $i < strlen($ciphertext); $i+=8) {\r
1240                     $block = substr($ciphertext, $i, 8);\r
1241                     $plaintext.= $this->_processBlock($block, CRYPT_DES_DECRYPT) ^ $xor;\r
1242                     $xor = $block;\r
1243                 }\r
1244                 if ($this->continuousBuffer) {\r
1245                     $this->decryptIV = $xor;\r
1246                 }\r
1247                 break;\r
1248             case CRYPT_DES_MODE_CTR:\r
1249                 $xor = $this->decryptIV;\r
1250                 if (strlen($buffer['ciphertext'])) {\r
1251                     for ($i = 0; $i < strlen($ciphertext); $i+=8) {\r
1252                         $block = substr($ciphertext, $i, 8);\r
1253                         if (strlen($block) > strlen($buffer['ciphertext'])) {\r
1254                             $buffer['ciphertext'].= $this->_processBlock($this->_generate_xor($xor), CRYPT_DES_ENCRYPT);\r
1255                         }\r
1256                         $key = $this->_string_shift($buffer['ciphertext']);\r
1257                         $plaintext.= $block ^ $key;\r
1258                     }\r
1259                 } else {\r
1260                     for ($i = 0; $i < strlen($ciphertext); $i+=8) {\r
1261                         $block = substr($ciphertext, $i, 8);\r
1262                         $key = $this->_processBlock($this->_generate_xor($xor), CRYPT_DES_ENCRYPT);\r
1263                         $plaintext.= $block ^ $key;\r
1264                     }\r
1265                 }\r
1266                 if ($this->continuousBuffer) {\r
1267                     $this->decryptIV = $xor;\r
1268                     if ($start = strlen($ciphertext) % 8) {\r
1269                         $buffer['ciphertext'] = substr($key, $start) . $buffer['ciphertext'];\r
1270                     }\r
1271                 }\r
1272                 break;\r
1273             case CRYPT_DES_MODE_CFB:\r
1274                 if ($this->continuousBuffer) {\r
1275                     $iv = &$this->decryptIV;\r
1276                     $pos = &$buffer['pos'];\r
1277                 } else {\r
1278                     $iv = $this->decryptIV;\r
1279                     $pos = 0;\r
1280                 }\r
1281                 $len = strlen($ciphertext);\r
1282                 $i = 0;\r
1283                 if ($pos) {\r
1284                     $orig_pos = $pos;\r
1285                     $max = 8 - $pos;\r
1286                     if ($len >= $max) {\r
1287                         $i = $max;\r
1288                         $len-= $max;\r
1289                         $pos = 0;\r
1290                     } else {\r
1291                         $i = $len;\r
1292                         $pos+= $len;\r
1293                         $len = 0;\r
1294                     }\r
1295                     $plaintext = substr($iv, $orig_pos) ^ $ciphertext;\r
1296                     $iv = substr_replace($iv, substr($ciphertext, 0, $i), $orig_pos, $i);\r
1297                 }\r
1298                 while ($len >= 8) {\r
1299                     $iv = $this->_processBlock($iv, CRYPT_DES_ENCRYPT);\r
1300                     $cb = substr($ciphertext, $i, 8);\r
1301                     $plaintext.= $iv ^ $cb;\r
1302                     $iv = $cb;\r
1303                     $len-= 8;\r
1304                     $i+= 8;\r
1305                 }\r
1306                 if ($len) {\r
1307                     $iv = $this->_processBlock($iv, CRYPT_DES_ENCRYPT);\r
1308                     $plaintext.= $iv ^ substr($ciphertext, $i);\r
1309                     $iv = substr_replace($iv, substr($ciphertext, $i), 0, $len);\r
1310                     $pos = $len;\r
1311                 }\r
1312                 return $plaintext;\r
1313             case CRYPT_DES_MODE_OFB:\r
1314                 $xor = $this->decryptIV;\r
1315                 if (strlen($buffer['xor'])) {\r
1316                     for ($i = 0; $i < strlen($ciphertext); $i+=8) {\r
1317                         $block = substr($ciphertext, $i, 8);\r
1318                         if (strlen($block) > strlen($buffer['xor'])) {\r
1319                             $xor = $this->_processBlock($xor, CRYPT_DES_ENCRYPT);\r
1320                             $buffer['xor'].= $xor;\r
1321                         }\r
1322                         $key = $this->_string_shift($buffer['xor']);\r
1323                         $plaintext.= $block ^ $key;\r
1324                     }\r
1325                 } else {\r
1326                     for ($i = 0; $i < strlen($ciphertext); $i+=8) {\r
1327                         $xor = $this->_processBlock($xor, CRYPT_DES_ENCRYPT);\r
1328                         $plaintext.= substr($ciphertext, $i, 8) ^ $xor;\r
1329                     }\r
1330                     $key = $xor;\r
1331                 }\r
1332                 if ($this->continuousBuffer) {\r
1333                     $this->decryptIV = $xor;\r
1334                     if ($start = strlen($ciphertext) % 8) {\r
1335                          $buffer['xor'] = substr($key, $start) . $buffer['xor'];\r
1336                     }\r
1337                 }\r
1338         }\r
1339 \r
1340         return $this->paddable ? $this->_unpad($plaintext) : $plaintext;\r
1341     }\r
1342 \r
1343     /**\r
1344      * Treat consecutive "packets" as if they are a continuous buffer.\r
1345      *\r
1346      * Say you have a 16-byte plaintext $plaintext.  Using the default behavior, the two following code snippets\r
1347      * will yield different outputs:\r
1348      *\r
1349      * <code>\r
1350      *    echo $des->encrypt(substr($plaintext, 0, 8));\r
1351      *    echo $des->encrypt(substr($plaintext, 8, 8));\r
1352      * </code>\r
1353      * <code>\r
1354      *    echo $des->encrypt($plaintext);\r
1355      * </code>\r
1356      *\r
1357      * The solution is to enable the continuous buffer.  Although this will resolve the above discrepancy, it creates\r
1358      * another, as demonstrated with the following:\r
1359      *\r
1360      * <code>\r
1361      *    $des->encrypt(substr($plaintext, 0, 8));\r
1362      *    echo $des->decrypt($des->encrypt(substr($plaintext, 8, 8)));\r
1363      * </code>\r
1364      * <code>\r
1365      *    echo $des->decrypt($des->encrypt(substr($plaintext, 8, 8)));\r
1366      * </code>\r
1367      *\r
1368      * With the continuous buffer disabled, these would yield the same output.  With it enabled, they yield different\r
1369      * outputs.  The reason is due to the fact that the initialization vector's change after every encryption /\r
1370      * decryption round when the continuous buffer is enabled.  When it's disabled, they remain constant.\r
1371      *\r
1372      * Put another way, when the continuous buffer is enabled, the state of the Crypt_DES() object changes after each\r
1373      * encryption / decryption round, whereas otherwise, it'd remain constant.  For this reason, it's recommended that\r
1374      * continuous buffers not be used.  They do offer better security and are, in fact, sometimes required (SSH uses them),\r
1375      * however, they are also less intuitive and more likely to cause you problems.\r
1376      *\r
1377      * @see Crypt_DES::disableContinuousBuffer()\r
1378      * @access public\r
1379      */\r
1380     function enableContinuousBuffer()\r
1381     {\r
1382         $this->continuousBuffer = true;\r
1383     }\r
1384 \r
1385     /**\r
1386      * Treat consecutive packets as if they are a discontinuous buffer.\r
1387      *\r
1388      * The default behavior.\r
1389      *\r
1390      * @see Crypt_DES::enableContinuousBuffer()\r
1391      * @access public\r
1392      */\r
1393     function disableContinuousBuffer()\r
1394     {\r
1395         $this->continuousBuffer = false;\r
1396         $this->encryptIV = $this->iv;\r
1397         $this->decryptIV = $this->iv;\r
1398         $this->enbuffer = array('encrypted' => '', 'xor' => '', 'pos' => 0, 'enmcrypt_init' => true);\r
1399         $this->debuffer = array('ciphertext' => '', 'xor' => '', 'pos' => 0, 'demcrypt_init' => true);\r
1400 \r
1401         if (CRYPT_DES_MODE == CRYPT_DES_MODE_MCRYPT) {\r
1402             mcrypt_generic_init($this->enmcrypt, $this->keys, $this->iv);\r
1403             mcrypt_generic_init($this->demcrypt, $this->keys, $this->iv);\r
1404         }\r
1405     }\r
1406 \r
1407     /**\r
1408      * Pad "packets".\r
1409      *\r
1410      * DES works by encrypting eight bytes at a time.  If you ever need to encrypt or decrypt something that's not\r
1411      * a multiple of eight, it becomes necessary to pad the input so that it's length is a multiple of eight.\r
1412      *\r
1413      * Padding is enabled by default.  Sometimes, however, it is undesirable to pad strings.  Such is the case in SSH1,\r
1414      * where "packets" are padded with random bytes before being encrypted.  Unpad these packets and you risk stripping\r
1415      * away characters that shouldn't be stripped away. (SSH knows how many bytes are added because the length is\r
1416      * transmitted separately)\r
1417      *\r
1418      * @see Crypt_DES::disablePadding()\r
1419      * @access public\r
1420      */\r
1421     function enablePadding()\r
1422     {\r
1423         $this->padding = true;\r
1424     }\r
1425 \r
1426     /**\r
1427      * Do not pad packets.\r
1428      *\r
1429      * @see Crypt_DES::enablePadding()\r
1430      * @access public\r
1431      */\r
1432     function disablePadding()\r
1433     {\r
1434         $this->padding = false;\r
1435     }\r
1436 \r
1437     /**\r
1438      * Pads a string\r
1439      *\r
1440      * Pads a string using the RSA PKCS padding standards so that its length is a multiple of the blocksize (8).\r
1441      * 8 - (strlen($text) & 7) bytes are added, each of which is equal to chr(8 - (strlen($text) & 7)\r
1442      *\r
1443      * If padding is disabled and $text is not a multiple of the blocksize, the string will be padded regardless\r
1444      * and padding will, hence forth, be enabled.\r
1445      *\r
1446      * @see Crypt_DES::_unpad()\r
1447      * @access private\r
1448      */\r
1449     function _pad($text)\r
1450     {\r
1451         $length = strlen($text);\r
1452 \r
1453         if (!$this->padding) {\r
1454             if (($length & 7) == 0) {\r
1455                 return $text;\r
1456             } else {\r
1457                 user_error("The plaintext's length ($length) is not a multiple of the block size (8)");\r
1458                 $this->padding = true;\r
1459             }\r
1460         }\r
1461 \r
1462         $pad = 8 - ($length & 7);\r
1463         return str_pad($text, $length + $pad, chr($pad));\r
1464     }\r
1465 \r
1466     /**\r
1467      * Unpads a string\r
1468      *\r
1469      * If padding is enabled and the reported padding length is invalid the encryption key will be assumed to be wrong\r
1470      * and false will be returned.\r
1471      *\r
1472      * @see Crypt_DES::_pad()\r
1473      * @access private\r
1474      */\r
1475     function _unpad($text)\r
1476     {\r
1477         if (!$this->padding) {\r
1478             return $text;\r
1479         }\r
1480 \r
1481         $length = ord($text[strlen($text) - 1]);\r
1482 \r
1483         if (!$length || $length > 8) {\r
1484             return false;\r
1485         }\r
1486 \r
1487         return substr($text, 0, -$length);\r
1488     }\r
1489 \r
1490     /**\r
1491      * Encrypts or decrypts a 64-bit block\r
1492      *\r
1493      * $mode should be either CRYPT_DES_ENCRYPT or CRYPT_DES_DECRYPT.  See\r
1494      * {@link http://en.wikipedia.org/wiki/Image:Feistel.png Feistel.png} to get a general\r
1495      * idea of what this function does.\r
1496      *\r
1497      * @access private\r
1498      * @param String $block\r
1499      * @param Integer $mode\r
1500      * @return String\r
1501      */\r
1502     function _processBlock($block, $mode)\r
1503     {\r
1504         $shuffle  = $this->shuffle;\r
1505         $invipmap = $this->invipmap;\r
1506         $ipmap = $this->ipmap;\r
1507         $sbox1 = $this->sbox1;\r
1508         $sbox2 = $this->sbox2;\r
1509         $sbox3 = $this->sbox3;\r
1510         $sbox4 = $this->sbox4;\r
1511         $sbox5 = $this->sbox5;\r
1512         $sbox6 = $this->sbox6;\r
1513         $sbox7 = $this->sbox7;\r
1514         $sbox8 = $this->sbox8;\r
1515         $keys  = $this->keys[$mode];\r
1516 \r
1517         // Do the initial IP permutation.\r
1518         $t = unpack('Nl/Nr', $block);\r
1519         list($l, $r) = array($t['l'], $t['r']);\r
1520         $block = ($shuffle[$ipmap[$r & 0xFF]] & "\x80\x80\x80\x80\x80\x80\x80\x80") |\r
1521                  ($shuffle[$ipmap[($r >> 8) & 0xFF]] & "\x40\x40\x40\x40\x40\x40\x40\x40") |\r
1522                  ($shuffle[$ipmap[($r >> 16) & 0xFF]] & "\x20\x20\x20\x20\x20\x20\x20\x20") |\r
1523                  ($shuffle[$ipmap[($r >> 24) & 0xFF]] & "\x10\x10\x10\x10\x10\x10\x10\x10") |\r
1524                  ($shuffle[$ipmap[$l & 0xFF]] & "\x08\x08\x08\x08\x08\x08\x08\x08") |\r
1525                  ($shuffle[$ipmap[($l >> 8) & 0xFF]] & "\x04\x04\x04\x04\x04\x04\x04\x04") |\r
1526                  ($shuffle[$ipmap[($l >> 16) & 0xFF]] & "\x02\x02\x02\x02\x02\x02\x02\x02") |\r
1527                  ($shuffle[$ipmap[($l >> 24) & 0xFF]] & "\x01\x01\x01\x01\x01\x01\x01\x01");\r
1528 \r
1529         // Extract L0 and R0.\r
1530         $t = unpack('Nl/Nr', $block);\r
1531         list($l, $r) = array($t['l'], $t['r']);\r
1532 \r
1533         // Perform the 16 steps.\r
1534         for ($i = 0; $i < 16; $i++) {\r
1535             // start of "the Feistel (F) function" - see the following URL:\r
1536             // http://en.wikipedia.org/wiki/Image:Data_Encryption_Standard_InfoBox_Diagram.png\r
1537             // Merge key schedule.\r
1538             $b1 = (($r >> 3) & 0x1FFFFFFF) ^ ($r << 29) ^ $keys[$i][0];\r
1539             $b2 = (($r >> 31) & 0x00000001) ^ ($r << 1) ^ $keys[$i][1];\r
1540 \r
1541             // S-box indexing.\r
1542             $t = $sbox1[($b1 >> 24) & 0x3F] ^ $sbox2[($b2 >> 24) & 0x3F] ^\r
1543                  $sbox3[($b1 >> 16) & 0x3F] ^ $sbox4[($b2 >> 16) & 0x3F] ^\r
1544                  $sbox5[($b1 >> 8) & 0x3F] ^ $sbox6[($b2 >> 8) & 0x3F] ^\r
1545                  $sbox7[$b1 & 0x3F] ^ $sbox8[$b2 & 0x3F] ^ $l;\r
1546             // end of "the Feistel (F) function"\r
1547 \r
1548             $l = $r;\r
1549             $r = $t;\r
1550         }\r
1551 \r
1552         // Perform the inverse IP permutation.\r
1553         return ($shuffle[$invipmap[($l >> 24) & 0xFF]] & "\x80\x80\x80\x80\x80\x80\x80\x80") |\r
1554                ($shuffle[$invipmap[($r >> 24) & 0xFF]] & "\x40\x40\x40\x40\x40\x40\x40\x40") |\r
1555                ($shuffle[$invipmap[($l >> 16) & 0xFF]] & "\x20\x20\x20\x20\x20\x20\x20\x20") |\r
1556                ($shuffle[$invipmap[($r >> 16) & 0xFF]] & "\x10\x10\x10\x10\x10\x10\x10\x10") |\r
1557                ($shuffle[$invipmap[($l >> 8) & 0xFF]] & "\x08\x08\x08\x08\x08\x08\x08\x08") |\r
1558                ($shuffle[$invipmap[($r >> 8) & 0xFF]] & "\x04\x04\x04\x04\x04\x04\x04\x04") |\r
1559                ($shuffle[$invipmap[$l & 0xFF]] & "\x02\x02\x02\x02\x02\x02\x02\x02") |\r
1560                ($shuffle[$invipmap[$r & 0xFF]] & "\x01\x01\x01\x01\x01\x01\x01\x01");\r
1561     }\r
1562 \r
1563     /**\r
1564      * Creates the key schedule.\r
1565      *\r
1566      * @access private\r
1567      * @param String $key\r
1568      * @return Array\r
1569      */\r
1570     function _prepareKey($key)\r
1571     {\r
1572         static $shifts = array( // number of key bits shifted per round\r
1573             1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1\r
1574         );\r
1575 \r
1576         static $pc1map = array(\r
1577             0x00, 0x00, 0x08, 0x08, 0x04, 0x04, 0x0C, 0x0C,\r
1578             0x02, 0x02, 0x0A, 0x0A, 0x06, 0x06, 0x0E, 0x0E,\r
1579             0x10, 0x10, 0x18, 0x18, 0x14, 0x14, 0x1C, 0x1C,\r
1580             0x12, 0x12, 0x1A, 0x1A, 0x16, 0x16, 0x1E, 0x1E,\r
1581             0x20, 0x20, 0x28, 0x28, 0x24, 0x24, 0x2C, 0x2C,\r
1582             0x22, 0x22, 0x2A, 0x2A, 0x26, 0x26, 0x2E, 0x2E,\r
1583             0x30, 0x30, 0x38, 0x38, 0x34, 0x34, 0x3C, 0x3C,\r
1584             0x32, 0x32, 0x3A, 0x3A, 0x36, 0x36, 0x3E, 0x3E,\r
1585             0x40, 0x40, 0x48, 0x48, 0x44, 0x44, 0x4C, 0x4C,\r
1586             0x42, 0x42, 0x4A, 0x4A, 0x46, 0x46, 0x4E, 0x4E,\r
1587             0x50, 0x50, 0x58, 0x58, 0x54, 0x54, 0x5C, 0x5C,\r
1588             0x52, 0x52, 0x5A, 0x5A, 0x56, 0x56, 0x5E, 0x5E,\r
1589             0x60, 0x60, 0x68, 0x68, 0x64, 0x64, 0x6C, 0x6C,\r
1590             0x62, 0x62, 0x6A, 0x6A, 0x66, 0x66, 0x6E, 0x6E,\r
1591             0x70, 0x70, 0x78, 0x78, 0x74, 0x74, 0x7C, 0x7C,\r
1592             0x72, 0x72, 0x7A, 0x7A, 0x76, 0x76, 0x7E, 0x7E,\r
1593             0x80, 0x80, 0x88, 0x88, 0x84, 0x84, 0x8C, 0x8C,\r
1594             0x82, 0x82, 0x8A, 0x8A, 0x86, 0x86, 0x8E, 0x8E,\r
1595             0x90, 0x90, 0x98, 0x98, 0x94, 0x94, 0x9C, 0x9C,\r
1596             0x92, 0x92, 0x9A, 0x9A, 0x96, 0x96, 0x9E, 0x9E,\r
1597             0xA0, 0xA0, 0xA8, 0xA8, 0xA4, 0xA4, 0xAC, 0xAC,\r
1598             0xA2, 0xA2, 0xAA, 0xAA, 0xA6, 0xA6, 0xAE, 0xAE,\r
1599             0xB0, 0xB0, 0xB8, 0xB8, 0xB4, 0xB4, 0xBC, 0xBC,\r
1600             0xB2, 0xB2, 0xBA, 0xBA, 0xB6, 0xB6, 0xBE, 0xBE,\r
1601             0xC0, 0xC0, 0xC8, 0xC8, 0xC4, 0xC4, 0xCC, 0xCC,\r
1602             0xC2, 0xC2, 0xCA, 0xCA, 0xC6, 0xC6, 0xCE, 0xCE,\r
1603             0xD0, 0xD0, 0xD8, 0xD8, 0xD4, 0xD4, 0xDC, 0xDC,\r
1604             0xD2, 0xD2, 0xDA, 0xDA, 0xD6, 0xD6, 0xDE, 0xDE,\r
1605             0xE0, 0xE0, 0xE8, 0xE8, 0xE4, 0xE4, 0xEC, 0xEC,\r
1606             0xE2, 0xE2, 0xEA, 0xEA, 0xE6, 0xE6, 0xEE, 0xEE,\r
1607             0xF0, 0xF0, 0xF8, 0xF8, 0xF4, 0xF4, 0xFC, 0xFC,\r
1608             0xF2, 0xF2, 0xFA, 0xFA, 0xF6, 0xF6, 0xFE, 0xFE\r
1609         );\r
1610 \r
1611         // Mapping tables for the PC-2 transformation.\r
1612         static $pc2mapc1 = array(\r
1613             0x00000000, 0x00000400, 0x00200000, 0x00200400,\r
1614             0x00000001, 0x00000401, 0x00200001, 0x00200401,\r
1615             0x02000000, 0x02000400, 0x02200000, 0x02200400,\r
1616             0x02000001, 0x02000401, 0x02200001, 0x02200401\r
1617         );\r
1618         static $pc2mapc2 = array(\r
1619             0x00000000, 0x00000800, 0x08000000, 0x08000800,\r
1620             0x00010000, 0x00010800, 0x08010000, 0x08010800,\r
1621             0x00000000, 0x00000800, 0x08000000, 0x08000800,\r
1622             0x00010000, 0x00010800, 0x08010000, 0x08010800,\r
1623             0x00000100, 0x00000900, 0x08000100, 0x08000900,\r
1624             0x00010100, 0x00010900, 0x08010100, 0x08010900,\r
1625             0x00000100, 0x00000900, 0x08000100, 0x08000900,\r
1626             0x00010100, 0x00010900, 0x08010100, 0x08010900,\r
1627             0x00000010, 0x00000810, 0x08000010, 0x08000810,\r
1628             0x00010010, 0x00010810, 0x08010010, 0x08010810,\r
1629             0x00000010, 0x00000810, 0x08000010, 0x08000810,\r
1630             0x00010010, 0x00010810, 0x08010010, 0x08010810,\r
1631             0x00000110, 0x00000910, 0x08000110, 0x08000910,\r
1632             0x00010110, 0x00010910, 0x08010110, 0x08010910,\r
1633             0x00000110, 0x00000910, 0x08000110, 0x08000910,\r
1634             0x00010110, 0x00010910, 0x08010110, 0x08010910,\r
1635             0x00040000, 0x00040800, 0x08040000, 0x08040800,\r
1636             0x00050000, 0x00050800, 0x08050000, 0x08050800,\r
1637             0x00040000, 0x00040800, 0x08040000, 0x08040800,\r
1638             0x00050000, 0x00050800, 0x08050000, 0x08050800,\r
1639             0x00040100, 0x00040900, 0x08040100, 0x08040900,\r
1640             0x00050100, 0x00050900, 0x08050100, 0x08050900,\r
1641             0x00040100, 0x00040900, 0x08040100, 0x08040900,\r
1642             0x00050100, 0x00050900, 0x08050100, 0x08050900,\r
1643             0x00040010, 0x00040810, 0x08040010, 0x08040810,\r
1644             0x00050010, 0x00050810, 0x08050010, 0x08050810,\r
1645             0x00040010, 0x00040810, 0x08040010, 0x08040810,\r
1646             0x00050010, 0x00050810, 0x08050010, 0x08050810,\r
1647             0x00040110, 0x00040910, 0x08040110, 0x08040910,\r
1648             0x00050110, 0x00050910, 0x08050110, 0x08050910,\r
1649             0x00040110, 0x00040910, 0x08040110, 0x08040910,\r
1650             0x00050110, 0x00050910, 0x08050110, 0x08050910,\r
1651             0x01000000, 0x01000800, 0x09000000, 0x09000800,\r
1652             0x01010000, 0x01010800, 0x09010000, 0x09010800,\r
1653             0x01000000, 0x01000800, 0x09000000, 0x09000800,\r
1654             0x01010000, 0x01010800, 0x09010000, 0x09010800,\r
1655             0x01000100, 0x01000900, 0x09000100, 0x09000900,\r
1656             0x01010100, 0x01010900, 0x09010100, 0x09010900,\r
1657             0x01000100, 0x01000900, 0x09000100, 0x09000900,\r
1658             0x01010100, 0x01010900, 0x09010100, 0x09010900,\r
1659             0x01000010, 0x01000810, 0x09000010, 0x09000810,\r
1660             0x01010010, 0x01010810, 0x09010010, 0x09010810,\r
1661             0x01000010, 0x01000810, 0x09000010, 0x09000810,\r
1662             0x01010010, 0x01010810, 0x09010010, 0x09010810,\r
1663             0x01000110, 0x01000910, 0x09000110, 0x09000910,\r
1664             0x01010110, 0x01010910, 0x09010110, 0x09010910,\r
1665             0x01000110, 0x01000910, 0x09000110, 0x09000910,\r
1666             0x01010110, 0x01010910, 0x09010110, 0x09010910,\r
1667             0x01040000, 0x01040800, 0x09040000, 0x09040800,\r
1668             0x01050000, 0x01050800, 0x09050000, 0x09050800,\r
1669             0x01040000, 0x01040800, 0x09040000, 0x09040800,\r
1670             0x01050000, 0x01050800, 0x09050000, 0x09050800,\r
1671             0x01040100, 0x01040900, 0x09040100, 0x09040900,\r
1672             0x01050100, 0x01050900, 0x09050100, 0x09050900,\r
1673             0x01040100, 0x01040900, 0x09040100, 0x09040900,\r
1674             0x01050100, 0x01050900, 0x09050100, 0x09050900,\r
1675             0x01040010, 0x01040810, 0x09040010, 0x09040810,\r
1676             0x01050010, 0x01050810, 0x09050010, 0x09050810,\r
1677             0x01040010, 0x01040810, 0x09040010, 0x09040810,\r
1678             0x01050010, 0x01050810, 0x09050010, 0x09050810,\r
1679             0x01040110, 0x01040910, 0x09040110, 0x09040910,\r
1680             0x01050110, 0x01050910, 0x09050110, 0x09050910,\r
1681             0x01040110, 0x01040910, 0x09040110, 0x09040910,\r
1682             0x01050110, 0x01050910, 0x09050110, 0x09050910\r
1683         );\r
1684         static $pc2mapc3 = array(\r
1685             0x00000000, 0x00000004, 0x00001000, 0x00001004,\r
1686             0x00000000, 0x00000004, 0x00001000, 0x00001004,\r
1687             0x10000000, 0x10000004, 0x10001000, 0x10001004,\r
1688             0x10000000, 0x10000004, 0x10001000, 0x10001004,\r
1689             0x00000020, 0x00000024, 0x00001020, 0x00001024,\r
1690             0x00000020, 0x00000024, 0x00001020, 0x00001024,\r
1691             0x10000020, 0x10000024, 0x10001020, 0x10001024,\r
1692             0x10000020, 0x10000024, 0x10001020, 0x10001024,\r
1693             0x00080000, 0x00080004, 0x00081000, 0x00081004,\r
1694             0x00080000, 0x00080004, 0x00081000, 0x00081004,\r
1695             0x10080000, 0x10080004, 0x10081000, 0x10081004,\r
1696             0x10080000, 0x10080004, 0x10081000, 0x10081004,\r
1697             0x00080020, 0x00080024, 0x00081020, 0x00081024,\r
1698             0x00080020, 0x00080024, 0x00081020, 0x00081024,\r
1699             0x10080020, 0x10080024, 0x10081020, 0x10081024,\r
1700             0x10080020, 0x10080024, 0x10081020, 0x10081024,\r
1701             0x20000000, 0x20000004, 0x20001000, 0x20001004,\r
1702             0x20000000, 0x20000004, 0x20001000, 0x20001004,\r
1703             0x30000000, 0x30000004, 0x30001000, 0x30001004,\r
1704             0x30000000, 0x30000004, 0x30001000, 0x30001004,\r
1705             0x20000020, 0x20000024, 0x20001020, 0x20001024,\r
1706             0x20000020, 0x20000024, 0x20001020, 0x20001024,\r
1707             0x30000020, 0x30000024, 0x30001020, 0x30001024,\r
1708             0x30000020, 0x30000024, 0x30001020, 0x30001024,\r
1709             0x20080000, 0x20080004, 0x20081000, 0x20081004,\r
1710             0x20080000, 0x20080004, 0x20081000, 0x20081004,\r
1711             0x30080000, 0x30080004, 0x30081000, 0x30081004,\r
1712             0x30080000, 0x30080004, 0x30081000, 0x30081004,\r
1713             0x20080020, 0x20080024, 0x20081020, 0x20081024,\r
1714             0x20080020, 0x20080024, 0x20081020, 0x20081024,\r
1715             0x30080020, 0x30080024, 0x30081020, 0x30081024,\r
1716             0x30080020, 0x30080024, 0x30081020, 0x30081024,\r
1717             0x00000002, 0x00000006, 0x00001002, 0x00001006,\r
1718             0x00000002, 0x00000006, 0x00001002, 0x00001006,\r
1719             0x10000002, 0x10000006, 0x10001002, 0x10001006,\r
1720             0x10000002, 0x10000006, 0x10001002, 0x10001006,\r
1721             0x00000022, 0x00000026, 0x00001022, 0x00001026,\r
1722             0x00000022, 0x00000026, 0x00001022, 0x00001026,\r
1723             0x10000022, 0x10000026, 0x10001022, 0x10001026,\r
1724             0x10000022, 0x10000026, 0x10001022, 0x10001026,\r
1725             0x00080002, 0x00080006, 0x00081002, 0x00081006,\r
1726             0x00080002, 0x00080006, 0x00081002, 0x00081006,\r
1727             0x10080002, 0x10080006, 0x10081002, 0x10081006,\r
1728             0x10080002, 0x10080006, 0x10081002, 0x10081006,\r
1729             0x00080022, 0x00080026, 0x00081022, 0x00081026,\r
1730             0x00080022, 0x00080026, 0x00081022, 0x00081026,\r
1731             0x10080022, 0x10080026, 0x10081022, 0x10081026,\r
1732             0x10080022, 0x10080026, 0x10081022, 0x10081026,\r
1733             0x20000002, 0x20000006, 0x20001002, 0x20001006,\r
1734             0x20000002, 0x20000006, 0x20001002, 0x20001006,\r
1735             0x30000002, 0x30000006, 0x30001002, 0x30001006,\r
1736             0x30000002, 0x30000006, 0x30001002, 0x30001006,\r
1737             0x20000022, 0x20000026, 0x20001022, 0x20001026,\r
1738             0x20000022, 0x20000026, 0x20001022, 0x20001026,\r
1739             0x30000022, 0x30000026, 0x30001022, 0x30001026,\r
1740             0x30000022, 0x30000026, 0x30001022, 0x30001026,\r
1741             0x20080002, 0x20080006, 0x20081002, 0x20081006,\r
1742             0x20080002, 0x20080006, 0x20081002, 0x20081006,\r
1743             0x30080002, 0x30080006, 0x30081002, 0x30081006,\r
1744             0x30080002, 0x30080006, 0x30081002, 0x30081006,\r
1745             0x20080022, 0x20080026, 0x20081022, 0x20081026,\r
1746             0x20080022, 0x20080026, 0x20081022, 0x20081026,\r
1747             0x30080022, 0x30080026, 0x30081022, 0x30081026,\r
1748             0x30080022, 0x30080026, 0x30081022, 0x30081026\r
1749         );\r
1750         static $pc2mapc4 = array(\r
1751             0x00000000, 0x00100000, 0x00000008, 0x00100008,\r
1752             0x00000200, 0x00100200, 0x00000208, 0x00100208,\r
1753             0x00000000, 0x00100000, 0x00000008, 0x00100008,\r
1754             0x00000200, 0x00100200, 0x00000208, 0x00100208,\r
1755             0x04000000, 0x04100000, 0x04000008, 0x04100008,\r
1756             0x04000200, 0x04100200, 0x04000208, 0x04100208,\r
1757             0x04000000, 0x04100000, 0x04000008, 0x04100008,\r
1758             0x04000200, 0x04100200, 0x04000208, 0x04100208,\r
1759             0x00002000, 0x00102000, 0x00002008, 0x00102008,\r
1760             0x00002200, 0x00102200, 0x00002208, 0x00102208,\r
1761             0x00002000, 0x00102000, 0x00002008, 0x00102008,\r
1762             0x00002200, 0x00102200, 0x00002208, 0x00102208,\r
1763             0x04002000, 0x04102000, 0x04002008, 0x04102008,\r
1764             0x04002200, 0x04102200, 0x04002208, 0x04102208,\r
1765             0x04002000, 0x04102000, 0x04002008, 0x04102008,\r
1766             0x04002200, 0x04102200, 0x04002208, 0x04102208,\r
1767             0x00000000, 0x00100000, 0x00000008, 0x00100008,\r
1768             0x00000200, 0x00100200, 0x00000208, 0x00100208,\r
1769             0x00000000, 0x00100000, 0x00000008, 0x00100008,\r
1770             0x00000200, 0x00100200, 0x00000208, 0x00100208,\r
1771             0x04000000, 0x04100000, 0x04000008, 0x04100008,\r
1772             0x04000200, 0x04100200, 0x04000208, 0x04100208,\r
1773             0x04000000, 0x04100000, 0x04000008, 0x04100008,\r
1774             0x04000200, 0x04100200, 0x04000208, 0x04100208,\r
1775             0x00002000, 0x00102000, 0x00002008, 0x00102008,\r
1776             0x00002200, 0x00102200, 0x00002208, 0x00102208,\r
1777             0x00002000, 0x00102000, 0x00002008, 0x00102008,\r
1778             0x00002200, 0x00102200, 0x00002208, 0x00102208,\r
1779             0x04002000, 0x04102000, 0x04002008, 0x04102008,\r
1780             0x04002200, 0x04102200, 0x04002208, 0x04102208,\r
1781             0x04002000, 0x04102000, 0x04002008, 0x04102008,\r
1782             0x04002200, 0x04102200, 0x04002208, 0x04102208,\r
1783             0x00020000, 0x00120000, 0x00020008, 0x00120008,\r
1784             0x00020200, 0x00120200, 0x00020208, 0x00120208,\r
1785             0x00020000, 0x00120000, 0x00020008, 0x00120008,\r
1786             0x00020200, 0x00120200, 0x00020208, 0x00120208,\r
1787             0x04020000, 0x04120000, 0x04020008, 0x04120008,\r
1788             0x04020200, 0x04120200, 0x04020208, 0x04120208,\r
1789             0x04020000, 0x04120000, 0x04020008, 0x04120008,\r
1790             0x04020200, 0x04120200, 0x04020208, 0x04120208,\r
1791             0x00022000, 0x00122000, 0x00022008, 0x00122008,\r
1792             0x00022200, 0x00122200, 0x00022208, 0x00122208,\r
1793             0x00022000, 0x00122000, 0x00022008, 0x00122008,\r
1794             0x00022200, 0x00122200, 0x00022208, 0x00122208,\r
1795             0x04022000, 0x04122000, 0x04022008, 0x04122008,\r
1796             0x04022200, 0x04122200, 0x04022208, 0x04122208,\r
1797             0x04022000, 0x04122000, 0x04022008, 0x04122008,\r
1798             0x04022200, 0x04122200, 0x04022208, 0x04122208,\r
1799             0x00020000, 0x00120000, 0x00020008, 0x00120008,\r
1800             0x00020200, 0x00120200, 0x00020208, 0x00120208,\r
1801             0x00020000, 0x00120000, 0x00020008, 0x00120008,\r
1802             0x00020200, 0x00120200, 0x00020208, 0x00120208,\r
1803             0x04020000, 0x04120000, 0x04020008, 0x04120008,\r
1804             0x04020200, 0x04120200, 0x04020208, 0x04120208,\r
1805             0x04020000, 0x04120000, 0x04020008, 0x04120008,\r
1806             0x04020200, 0x04120200, 0x04020208, 0x04120208,\r
1807             0x00022000, 0x00122000, 0x00022008, 0x00122008,\r
1808             0x00022200, 0x00122200, 0x00022208, 0x00122208,\r
1809             0x00022000, 0x00122000, 0x00022008, 0x00122008,\r
1810             0x00022200, 0x00122200, 0x00022208, 0x00122208,\r
1811             0x04022000, 0x04122000, 0x04022008, 0x04122008,\r
1812             0x04022200, 0x04122200, 0x04022208, 0x04122208,\r
1813             0x04022000, 0x04122000, 0x04022008, 0x04122008,\r
1814             0x04022200, 0x04122200, 0x04022208, 0x04122208\r
1815         );\r
1816         static $pc2mapd1 = array(\r
1817             0x00000000, 0x00000001, 0x08000000, 0x08000001,\r
1818             0x00200000, 0x00200001, 0x08200000, 0x08200001,\r
1819             0x00000002, 0x00000003, 0x08000002, 0x08000003,\r
1820             0x00200002, 0x00200003, 0x08200002, 0x08200003\r
1821         );\r
1822         static $pc2mapd2 = array(\r
1823             0x00000000, 0x00100000, 0x00000800, 0x00100800,\r
1824             0x00000000, 0x00100000, 0x00000800, 0x00100800,\r
1825             0x04000000, 0x04100000, 0x04000800, 0x04100800,\r
1826             0x04000000, 0x04100000, 0x04000800, 0x04100800,\r
1827             0x00000004, 0x00100004, 0x00000804, 0x00100804,\r
1828             0x00000004, 0x00100004, 0x00000804, 0x00100804,\r
1829             0x04000004, 0x04100004, 0x04000804, 0x04100804,\r
1830             0x04000004, 0x04100004, 0x04000804, 0x04100804,\r
1831             0x00000000, 0x00100000, 0x00000800, 0x00100800,\r
1832             0x00000000, 0x00100000, 0x00000800, 0x00100800,\r
1833             0x04000000, 0x04100000, 0x04000800, 0x04100800,\r
1834             0x04000000, 0x04100000, 0x04000800, 0x04100800,\r
1835             0x00000004, 0x00100004, 0x00000804, 0x00100804,\r
1836             0x00000004, 0x00100004, 0x00000804, 0x00100804,\r
1837             0x04000004, 0x04100004, 0x04000804, 0x04100804,\r
1838             0x04000004, 0x04100004, 0x04000804, 0x04100804,\r
1839             0x00000200, 0x00100200, 0x00000A00, 0x00100A00,\r
1840             0x00000200, 0x00100200, 0x00000A00, 0x00100A00,\r
1841             0x04000200, 0x04100200, 0x04000A00, 0x04100A00,\r
1842             0x04000200, 0x04100200, 0x04000A00, 0x04100A00,\r
1843             0x00000204, 0x00100204, 0x00000A04, 0x00100A04,\r
1844             0x00000204, 0x00100204, 0x00000A04, 0x00100A04,\r
1845             0x04000204, 0x04100204, 0x04000A04, 0x04100A04,\r
1846             0x04000204, 0x04100204, 0x04000A04, 0x04100A04,\r
1847             0x00000200, 0x00100200, 0x00000A00, 0x00100A00,\r
1848             0x00000200, 0x00100200, 0x00000A00, 0x00100A00,\r
1849             0x04000200, 0x04100200, 0x04000A00, 0x04100A00,\r
1850             0x04000200, 0x04100200, 0x04000A00, 0x04100A00,\r
1851             0x00000204, 0x00100204, 0x00000A04, 0x00100A04,\r
1852             0x00000204, 0x00100204, 0x00000A04, 0x00100A04,\r
1853             0x04000204, 0x04100204, 0x04000A04, 0x04100A04,\r
1854             0x04000204, 0x04100204, 0x04000A04, 0x04100A04,\r
1855             0x00020000, 0x00120000, 0x00020800, 0x00120800,\r
1856             0x00020000, 0x00120000, 0x00020800, 0x00120800,\r
1857             0x04020000, 0x04120000, 0x04020800, 0x04120800,\r
1858             0x04020000, 0x04120000, 0x04020800, 0x04120800,\r
1859             0x00020004, 0x00120004, 0x00020804, 0x00120804,\r
1860             0x00020004, 0x00120004, 0x00020804, 0x00120804,\r
1861             0x04020004, 0x04120004, 0x04020804, 0x04120804,\r
1862             0x04020004, 0x04120004, 0x04020804, 0x04120804,\r
1863             0x00020000, 0x00120000, 0x00020800, 0x00120800,\r
1864             0x00020000, 0x00120000, 0x00020800, 0x00120800,\r
1865             0x04020000, 0x04120000, 0x04020800, 0x04120800,\r
1866             0x04020000, 0x04120000, 0x04020800, 0x04120800,\r
1867             0x00020004, 0x00120004, 0x00020804, 0x00120804,\r
1868             0x00020004, 0x00120004, 0x00020804, 0x00120804,\r
1869             0x04020004, 0x04120004, 0x04020804, 0x04120804,\r
1870             0x04020004, 0x04120004, 0x04020804, 0x04120804,\r
1871             0x00020200, 0x00120200, 0x00020A00, 0x00120A00,\r
1872             0x00020200, 0x00120200, 0x00020A00, 0x00120A00,\r
1873             0x04020200, 0x04120200, 0x04020A00, 0x04120A00,\r
1874             0x04020200, 0x04120200, 0x04020A00, 0x04120A00,\r
1875             0x00020204, 0x00120204, 0x00020A04, 0x00120A04,\r
1876             0x00020204, 0x00120204, 0x00020A04, 0x00120A04,\r
1877             0x04020204, 0x04120204, 0x04020A04, 0x04120A04,\r
1878             0x04020204, 0x04120204, 0x04020A04, 0x04120A04,\r
1879             0x00020200, 0x00120200, 0x00020A00, 0x00120A00,\r
1880             0x00020200, 0x00120200, 0x00020A00, 0x00120A00,\r
1881             0x04020200, 0x04120200, 0x04020A00, 0x04120A00,\r
1882             0x04020200, 0x04120200, 0x04020A00, 0x04120A00,\r
1883             0x00020204, 0x00120204, 0x00020A04, 0x00120A04,\r
1884             0x00020204, 0x00120204, 0x00020A04, 0x00120A04,\r
1885             0x04020204, 0x04120204, 0x04020A04, 0x04120A04,\r
1886             0x04020204, 0x04120204, 0x04020A04, 0x04120A04\r
1887         );\r
1888         static $pc2mapd3 = array(\r
1889             0x00000000, 0x00010000, 0x02000000, 0x02010000,\r
1890             0x00000020, 0x00010020, 0x02000020, 0x02010020,\r
1891             0x00040000, 0x00050000, 0x02040000, 0x02050000,\r
1892             0x00040020, 0x00050020, 0x02040020, 0x02050020,\r
1893             0x00002000, 0x00012000, 0x02002000, 0x02012000,\r
1894             0x00002020, 0x00012020, 0x02002020, 0x02012020,\r
1895             0x00042000, 0x00052000, 0x02042000, 0x02052000,\r
1896             0x00042020, 0x00052020, 0x02042020, 0x02052020,\r
1897             0x00000000, 0x00010000, 0x02000000, 0x02010000,\r
1898             0x00000020, 0x00010020, 0x02000020, 0x02010020,\r
1899             0x00040000, 0x00050000, 0x02040000, 0x02050000,\r
1900             0x00040020, 0x00050020, 0x02040020, 0x02050020,\r
1901             0x00002000, 0x00012000, 0x02002000, 0x02012000,\r
1902             0x00002020, 0x00012020, 0x02002020, 0x02012020,\r
1903             0x00042000, 0x00052000, 0x02042000, 0x02052000,\r
1904             0x00042020, 0x00052020, 0x02042020, 0x02052020,\r
1905             0x00000010, 0x00010010, 0x02000010, 0x02010010,\r
1906             0x00000030, 0x00010030, 0x02000030, 0x02010030,\r
1907             0x00040010, 0x00050010, 0x02040010, 0x02050010,\r
1908             0x00040030, 0x00050030, 0x02040030, 0x02050030,\r
1909             0x00002010, 0x00012010, 0x02002010, 0x02012010,\r
1910             0x00002030, 0x00012030, 0x02002030, 0x02012030,\r
1911             0x00042010, 0x00052010, 0x02042010, 0x02052010,\r
1912             0x00042030, 0x00052030, 0x02042030, 0x02052030,\r
1913             0x00000010, 0x00010010, 0x02000010, 0x02010010,\r
1914             0x00000030, 0x00010030, 0x02000030, 0x02010030,\r
1915             0x00040010, 0x00050010, 0x02040010, 0x02050010,\r
1916             0x00040030, 0x00050030, 0x02040030, 0x02050030,\r
1917             0x00002010, 0x00012010, 0x02002010, 0x02012010,\r
1918             0x00002030, 0x00012030, 0x02002030, 0x02012030,\r
1919             0x00042010, 0x00052010, 0x02042010, 0x02052010,\r
1920             0x00042030, 0x00052030, 0x02042030, 0x02052030,\r
1921             0x20000000, 0x20010000, 0x22000000, 0x22010000,\r
1922             0x20000020, 0x20010020, 0x22000020, 0x22010020,\r
1923             0x20040000, 0x20050000, 0x22040000, 0x22050000,\r
1924             0x20040020, 0x20050020, 0x22040020, 0x22050020,\r
1925             0x20002000, 0x20012000, 0x22002000, 0x22012000,\r
1926             0x20002020, 0x20012020, 0x22002020, 0x22012020,\r
1927             0x20042000, 0x20052000, 0x22042000, 0x22052000,\r
1928             0x20042020, 0x20052020, 0x22042020, 0x22052020,\r
1929             0x20000000, 0x20010000, 0x22000000, 0x22010000,\r
1930             0x20000020, 0x20010020, 0x22000020, 0x22010020,\r
1931             0x20040000, 0x20050000, 0x22040000, 0x22050000,\r
1932             0x20040020, 0x20050020, 0x22040020, 0x22050020,\r
1933             0x20002000, 0x20012000, 0x22002000, 0x22012000,\r
1934             0x20002020, 0x20012020, 0x22002020, 0x22012020,\r
1935             0x20042000, 0x20052000, 0x22042000, 0x22052000,\r
1936             0x20042020, 0x20052020, 0x22042020, 0x22052020,\r
1937             0x20000010, 0x20010010, 0x22000010, 0x22010010,\r
1938             0x20000030, 0x20010030, 0x22000030, 0x22010030,\r
1939             0x20040010, 0x20050010, 0x22040010, 0x22050010,\r
1940             0x20040030, 0x20050030, 0x22040030, 0x22050030,\r
1941             0x20002010, 0x20012010, 0x22002010, 0x22012010,\r
1942             0x20002030, 0x20012030, 0x22002030, 0x22012030,\r
1943             0x20042010, 0x20052010, 0x22042010, 0x22052010,\r
1944             0x20042030, 0x20052030, 0x22042030, 0x22052030,\r
1945             0x20000010, 0x20010010, 0x22000010, 0x22010010,\r
1946             0x20000030, 0x20010030, 0x22000030, 0x22010030,\r
1947             0x20040010, 0x20050010, 0x22040010, 0x22050010,\r
1948             0x20040030, 0x20050030, 0x22040030, 0x22050030,\r
1949             0x20002010, 0x20012010, 0x22002010, 0x22012010,\r
1950             0x20002030, 0x20012030, 0x22002030, 0x22012030,\r
1951             0x20042010, 0x20052010, 0x22042010, 0x22052010,\r
1952             0x20042030, 0x20052030, 0x22042030, 0x22052030\r
1953         );\r
1954         static $pc2mapd4 = array(\r
1955             0x00000000, 0x00000400, 0x01000000, 0x01000400,\r
1956             0x00000000, 0x00000400, 0x01000000, 0x01000400,\r
1957             0x00000100, 0x00000500, 0x01000100, 0x01000500,\r
1958             0x00000100, 0x00000500, 0x01000100, 0x01000500,\r
1959             0x10000000, 0x10000400, 0x11000000, 0x11000400,\r
1960             0x10000000, 0x10000400, 0x11000000, 0x11000400,\r
1961             0x10000100, 0x10000500, 0x11000100, 0x11000500,\r
1962             0x10000100, 0x10000500, 0x11000100, 0x11000500,\r
1963             0x00080000, 0x00080400, 0x01080000, 0x01080400,\r
1964             0x00080000, 0x00080400, 0x01080000, 0x01080400,\r
1965             0x00080100, 0x00080500, 0x01080100, 0x01080500,\r
1966             0x00080100, 0x00080500, 0x01080100, 0x01080500,\r
1967             0x10080000, 0x10080400, 0x11080000, 0x11080400,\r
1968             0x10080000, 0x10080400, 0x11080000, 0x11080400,\r
1969             0x10080100, 0x10080500, 0x11080100, 0x11080500,\r
1970             0x10080100, 0x10080500, 0x11080100, 0x11080500,\r
1971             0x00000008, 0x00000408, 0x01000008, 0x01000408,\r
1972             0x00000008, 0x00000408, 0x01000008, 0x01000408,\r
1973             0x00000108, 0x00000508, 0x01000108, 0x01000508,\r
1974             0x00000108, 0x00000508, 0x01000108, 0x01000508,\r
1975             0x10000008, 0x10000408, 0x11000008, 0x11000408,\r
1976             0x10000008, 0x10000408, 0x11000008, 0x11000408,\r
1977             0x10000108, 0x10000508, 0x11000108, 0x11000508,\r
1978             0x10000108, 0x10000508, 0x11000108, 0x11000508,\r
1979             0x00080008, 0x00080408, 0x01080008, 0x01080408,\r
1980             0x00080008, 0x00080408, 0x01080008, 0x01080408,\r
1981             0x00080108, 0x00080508, 0x01080108, 0x01080508,\r
1982             0x00080108, 0x00080508, 0x01080108, 0x01080508,\r
1983             0x10080008, 0x10080408, 0x11080008, 0x11080408,\r
1984             0x10080008, 0x10080408, 0x11080008, 0x11080408,\r
1985             0x10080108, 0x10080508, 0x11080108, 0x11080508,\r
1986             0x10080108, 0x10080508, 0x11080108, 0x11080508,\r
1987             0x00001000, 0x00001400, 0x01001000, 0x01001400,\r
1988             0x00001000, 0x00001400, 0x01001000, 0x01001400,\r
1989             0x00001100, 0x00001500, 0x01001100, 0x01001500,\r
1990             0x00001100, 0x00001500, 0x01001100, 0x01001500,\r
1991             0x10001000, 0x10001400, 0x11001000, 0x11001400,\r
1992             0x10001000, 0x10001400, 0x11001000, 0x11001400,\r
1993             0x10001100, 0x10001500, 0x11001100, 0x11001500,\r
1994             0x10001100, 0x10001500, 0x11001100, 0x11001500,\r
1995             0x00081000, 0x00081400, 0x01081000, 0x01081400,\r
1996             0x00081000, 0x00081400, 0x01081000, 0x01081400,\r
1997             0x00081100, 0x00081500, 0x01081100, 0x01081500,\r
1998             0x00081100, 0x00081500, 0x01081100, 0x01081500,\r
1999             0x10081000, 0x10081400, 0x11081000, 0x11081400,\r
2000             0x10081000, 0x10081400, 0x11081000, 0x11081400,\r
2001             0x10081100, 0x10081500, 0x11081100, 0x11081500,\r
2002             0x10081100, 0x10081500, 0x11081100, 0x11081500,\r
2003             0x00001008, 0x00001408, 0x01001008, 0x01001408,\r
2004             0x00001008, 0x00001408, 0x01001008, 0x01001408,\r
2005             0x00001108, 0x00001508, 0x01001108, 0x01001508,\r
2006             0x00001108, 0x00001508, 0x01001108, 0x01001508,\r
2007             0x10001008, 0x10001408, 0x11001008, 0x11001408,\r
2008             0x10001008, 0x10001408, 0x11001008, 0x11001408,\r
2009             0x10001108, 0x10001508, 0x11001108, 0x11001508,\r
2010             0x10001108, 0x10001508, 0x11001108, 0x11001508,\r
2011             0x00081008, 0x00081408, 0x01081008, 0x01081408,\r
2012             0x00081008, 0x00081408, 0x01081008, 0x01081408,\r
2013             0x00081108, 0x00081508, 0x01081108, 0x01081508,\r
2014             0x00081108, 0x00081508, 0x01081108, 0x01081508,\r
2015             0x10081008, 0x10081408, 0x11081008, 0x11081408,\r
2016             0x10081008, 0x10081408, 0x11081008, 0x11081408,\r
2017             0x10081108, 0x10081508, 0x11081108, 0x11081508,\r
2018             0x10081108, 0x10081508, 0x11081108, 0x11081508\r
2019         );\r
2020 \r
2021         // pad the key and remove extra characters as appropriate.\r
2022         $key = str_pad(substr($key, 0, 8), 8, chr(0));\r
2023 \r
2024         // Perform the PC/1 transformation and compute C and D.\r
2025         $t = unpack('Nl/Nr', $key);\r
2026         list($l, $r) = array($t['l'], $t['r']);\r
2027         $key = ($this->shuffle[$pc1map[$r & 0xFF]] & "\x80\x80\x80\x80\x80\x80\x80\x00") |\r
2028                ($this->shuffle[$pc1map[($r >> 8) & 0xFF]] & "\x40\x40\x40\x40\x40\x40\x40\x00") |\r
2029                ($this->shuffle[$pc1map[($r >> 16) & 0xFF]] & "\x20\x20\x20\x20\x20\x20\x20\x00") |\r
2030                ($this->shuffle[$pc1map[($r >> 24) & 0xFF]] & "\x10\x10\x10\x10\x10\x10\x10\x00") |\r
2031                ($this->shuffle[$pc1map[$l & 0xFF]] & "\x08\x08\x08\x08\x08\x08\x08\x00") |\r
2032                ($this->shuffle[$pc1map[($l >> 8) & 0xFF]] & "\x04\x04\x04\x04\x04\x04\x04\x00") |\r
2033                ($this->shuffle[$pc1map[($l >> 16) & 0xFF]] & "\x02\x02\x02\x02\x02\x02\x02\x00") |\r
2034                ($this->shuffle[$pc1map[($l >> 24) & 0xFF]] & "\x01\x01\x01\x01\x01\x01\x01\x00");\r
2035         $key = unpack('Nc/Nd', $key);\r
2036         $c = ($key['c'] >> 4) & 0x0FFFFFFF;\r
2037         $d = (($key['d'] >> 4) & 0x0FFFFFF0) | ($key['c'] & 0x0F);\r
2038 \r
2039         $keys = array();\r
2040         for ($i = 0; $i < 16; $i++) {\r
2041             $c <<= $shifts[$i];\r
2042             $c = ($c | ($c >> 28)) & 0x0FFFFFFF;\r
2043             $d <<= $shifts[$i];\r
2044             $d = ($d | ($d >> 28)) & 0x0FFFFFFF;\r
2045 \r
2046             // Perform the PC-2 transformation.\r
2047             $cp = $pc2mapc1[$c >> 24] | $pc2mapc2[($c >> 16) & 0xFF] |\r
2048                   $pc2mapc3[($c >> 8) & 0xFF] | $pc2mapc4[$c & 0xFF];\r
2049             $dp = $pc2mapd1[$d >> 24] | $pc2mapd2[($d >> 16) & 0xFF] |\r
2050                   $pc2mapd3[($d >> 8) & 0xFF] | $pc2mapd4[$d & 0xFF];\r
2051 \r
2052             // Reorder: odd bytes/even bytes. Push the result in key schedule.\r
2053             $keys[] = array(\r
2054                 ($cp & 0xFF000000) | (($cp << 8) & 0x00FF0000) |\r
2055                 (($dp >> 16) & 0x0000FF00) | (($dp >> 8) & 0x000000FF),\r
2056                 (($cp << 8) & 0xFF000000) | (($cp << 16) & 0x00FF0000) |\r
2057                 (($dp >> 8) & 0x0000FF00) | ($dp & 0x000000FF)\r
2058             );\r
2059         }\r
2060 \r
2061         $keys = array(\r
2062                 CRYPT_DES_ENCRYPT => $keys,\r
2063                 CRYPT_DES_DECRYPT => array_reverse($keys),\r
2064                 CRYPT_DES_ENCRYPT_1DIM => array(),\r
2065                 CRYPT_DES_DECRYPT_1DIM => array()\r
2066         );\r
2067 \r
2068         // Generate 1-dim arrays for inline en/decrypting\r
2069         for ($i = 0; $i < 16; ++$i) {\r
2070             $keys[CRYPT_DES_ENCRYPT_1DIM][] = $keys[CRYPT_DES_ENCRYPT][$i][0];\r
2071             $keys[CRYPT_DES_ENCRYPT_1DIM][] = $keys[CRYPT_DES_ENCRYPT][$i][1];\r
2072             $keys[CRYPT_DES_DECRYPT_1DIM][] = $keys[CRYPT_DES_DECRYPT][$i][0];\r
2073             $keys[CRYPT_DES_DECRYPT_1DIM][] = $keys[CRYPT_DES_DECRYPT][$i][1];\r
2074         }\r
2075 \r
2076         return $keys;\r
2077     }\r
2078 \r
2079     /**\r
2080      * String Shift\r
2081      *\r
2082      * Inspired by array_shift\r
2083      *\r
2084      * @param String $string\r
2085      * @return String\r
2086      * @access private\r
2087      */\r
2088     function _string_shift(&$string)\r
2089     {\r
2090         $substr = substr($string, 0, 8);\r
2091         $string = substr($string, 8);\r
2092         return $substr;\r
2093     }\r
2094 \r
2095     /**\r
2096      * Creates performance-optimized function for de/encrypt(), storing it in $this->inline_crypt\r
2097      *\r
2098      * @param optional Integer $des_rounds (1 = DES[default], 3 = TribleDES)\r
2099      * @access private\r
2100      */\r
2101     function inline_crypt_setup($des_rounds = 1)\r
2102     {\r
2103         $lambda_functions =& Crypt_DES::get_lambda_functions();\r
2104         $block_size = 8;\r
2105         $mode = $this->mode;\r
2106 \r
2107         $code_hash = "$mode,$des_rounds";\r
2108 \r
2109         if (!isset($lambda_functions[$code_hash])) {\r
2110             // Generating encrypt code:\r
2111             $ki = -1;\r
2112             $init_cryptBlock = '\r
2113                 $shuffle  = $self->shuffle;\r
2114                 $invipmap = $self->invipmap;\r
2115                 $ipmap = $self->ipmap;\r
2116                 $sbox1 = $self->sbox1;\r
2117                 $sbox2 = $self->sbox2;\r
2118                 $sbox3 = $self->sbox3;\r
2119                 $sbox4 = $self->sbox4;\r
2120                 $sbox5 = $self->sbox5;\r
2121                 $sbox6 = $self->sbox6;\r
2122                 $sbox7 = $self->sbox7;\r
2123                 $sbox8 = $self->sbox8;\r
2124             ';\r
2125 \r
2126             $_cryptBlock = '$in = unpack("N*", $in);'."\n";\r
2127             // Do the initial IP permutation.\r
2128             $_cryptBlock .= '\r
2129                 $l  = $in[1];\r
2130                 $r  = $in[2];\r
2131                 $in = unpack("N*",\r
2132                     ($shuffle[$ipmap[ $r        & 0xFF]] & "\x80\x80\x80\x80\x80\x80\x80\x80") |\r
2133                     ($shuffle[$ipmap[($r >>  8) & 0xFF]] & "\x40\x40\x40\x40\x40\x40\x40\x40") |\r
2134                     ($shuffle[$ipmap[($r >> 16) & 0xFF]] & "\x20\x20\x20\x20\x20\x20\x20\x20") |\r
2135                     ($shuffle[$ipmap[($r >> 24) & 0xFF]] & "\x10\x10\x10\x10\x10\x10\x10\x10") |\r
2136                     ($shuffle[$ipmap[ $l        & 0xFF]] & "\x08\x08\x08\x08\x08\x08\x08\x08") |\r
2137                     ($shuffle[$ipmap[($l >>  8) & 0xFF]] & "\x04\x04\x04\x04\x04\x04\x04\x04") |\r
2138                     ($shuffle[$ipmap[($l >> 16) & 0xFF]] & "\x02\x02\x02\x02\x02\x02\x02\x02") |\r
2139                     ($shuffle[$ipmap[($l >> 24) & 0xFF]] & "\x01\x01\x01\x01\x01\x01\x01\x01")\r
2140                 );\r
2141 \r
2142                 '.'' /* Extract L0 and R0 */ .'\r
2143                 $l = $in[1];\r
2144                 $r = $in[2];\r
2145             ';\r
2146 \r
2147             $l = 'l';\r
2148             $r = 'r';\r
2149             for ($des_round = 0; $des_round < $des_rounds; ++$des_round) {\r
2150                 // Perform the 16 steps.\r
2151                 // start of "the Feistel (F) function" - see the following URL:\r
2152                 // http://en.wikipedia.org/wiki/Image:Data_Encryption_Standard_InfoBox_Diagram.png\r
2153                 // Merge key schedule.\r
2154                 for ($i = 0; $i < 8; ++$i) {\r
2155                     $_cryptBlock .= '\r
2156                         $b1 = (($' . $r . ' >>  3) & 0x1FFFFFFF)  ^ ($' . $r . ' << 29) ^ $k_'.(++$ki).';\r
2157                         $b2 = (($' . $r . ' >> 31) & 0x00000001)  ^ ($' . $r . ' <<  1) ^ $k_'.(++$ki).';\r
2158                         $' . $l . '  = $sbox1[($b1 >> 24) & 0x3F] ^ $sbox2[($b2 >> 24) & 0x3F] ^\r
2159                               $sbox3[($b1 >> 16) & 0x3F] ^ $sbox4[($b2 >> 16) & 0x3F] ^\r
2160                               $sbox5[($b1 >>  8) & 0x3F] ^ $sbox6[($b2 >>  8) & 0x3F] ^\r
2161                               $sbox7[ $b1        & 0x3F] ^ $sbox8[ $b2        & 0x3F] ^ $' . $l . ';\r
2162 \r
2163                         $b1 = (($' . $l . ' >>  3) & 0x1FFFFFFF)  ^ ($' . $l . ' << 29) ^ $k_'.(++$ki).';\r
2164                         $b2 = (($' . $l . ' >> 31) & 0x00000001)  ^ ($' . $l . ' <<  1) ^ $k_'.(++$ki).';\r
2165                         $' . $r . '  = $sbox1[($b1 >> 24) & 0x3F] ^ $sbox2[($b2 >> 24) & 0x3F] ^\r
2166                               $sbox3[($b1 >> 16) & 0x3F] ^ $sbox4[($b2 >> 16) & 0x3F] ^\r
2167                               $sbox5[($b1 >>  8) & 0x3F] ^ $sbox6[($b2 >>  8) & 0x3F] ^\r
2168                               $sbox7[ $b1        & 0x3F] ^ $sbox8[ $b2        & 0x3F] ^ $' . $r . ';\r
2169                     ';\r
2170                 }\r
2171 \r
2172                 // Last step should not permute L & R.\r
2173                 $t = $l;\r
2174                 $l = $r;\r
2175                 $r = $t;\r
2176             }\r
2177 \r
2178             // Perform the inverse IP permutation.\r
2179             $_cryptBlock .= '$in = (\r
2180                     ($shuffle[$invipmap[($' . $r . ' >> 24) & 0xFF]] & "\x80\x80\x80\x80\x80\x80\x80\x80") |\r
2181                     ($shuffle[$invipmap[($' . $l . ' >> 24) & 0xFF]] & "\x40\x40\x40\x40\x40\x40\x40\x40") |\r
2182                     ($shuffle[$invipmap[($' . $r . ' >> 16) & 0xFF]] & "\x20\x20\x20\x20\x20\x20\x20\x20") |\r
2183                     ($shuffle[$invipmap[($' . $l . ' >> 16) & 0xFF]] & "\x10\x10\x10\x10\x10\x10\x10\x10") |\r
2184                     ($shuffle[$invipmap[($' . $r . ' >>  8) & 0xFF]] & "\x08\x08\x08\x08\x08\x08\x08\x08") |\r
2185                     ($shuffle[$invipmap[($' . $l . ' >>  8) & 0xFF]] & "\x04\x04\x04\x04\x04\x04\x04\x04") |\r
2186                     ($shuffle[$invipmap[ $' . $r . '        & 0xFF]] & "\x02\x02\x02\x02\x02\x02\x02\x02") |\r
2187                     ($shuffle[$invipmap[ $' . $l . '        & 0xFF]] & "\x01\x01\x01\x01\x01\x01\x01\x01")\r
2188                 );\r
2189             ';\r
2190 \r
2191             // Generating mode of operation code:\r
2192             switch ($mode) {\r
2193                 case CRYPT_DES_MODE_ECB:\r
2194                     $encrypt = $init_cryptBlock . '\r
2195                         extract($self->keys[CRYPT_DES_ENCRYPT_1DIM],  EXTR_PREFIX_ALL, "k");\r
2196                         $ciphertext = "";\r
2197                         $plaintext_len = strlen($text);\r
2198 \r
2199                         for ($i = 0; $i < $plaintext_len; $i+= '.$block_size.') {\r
2200                             $in = substr($text, $i, '.$block_size.');\r
2201                             '.$_cryptBlock.'\r
2202                             $ciphertext.= $in;\r
2203                         }\r
2204                        \r
2205                         return $ciphertext;\r
2206                         ';\r
2207 \r
2208                     $decrypt = $init_cryptBlock . '\r
2209                         extract($self->keys[CRYPT_DES_DECRYPT_1DIM],  EXTR_PREFIX_ALL, "k");\r
2210                         $plaintext = "";\r
2211                         $ciphertext_len = strlen($text);\r
2212 \r
2213                         for ($i = 0; $i < $ciphertext_len; $i+= '.$block_size.') {\r
2214                             $in = substr($text, $i, '.$block_size.');\r
2215                             '.$_cryptBlock.'\r
2216                             $plaintext.= $in;\r
2217                         }\r
2218 \r
2219                         return $self->_unpad($plaintext);\r
2220                         ';\r
2221                     break;\r
2222                 case CRYPT_DES_MODE_CBC:\r
2223                     $encrypt = $init_cryptBlock . '\r
2224                         extract($self->keys[CRYPT_DES_ENCRYPT_1DIM],  EXTR_PREFIX_ALL, "k");\r
2225                         $ciphertext = "";\r
2226                         $plaintext_len = strlen($text);\r
2227 \r
2228                         $in = $self->encryptIV;\r
2229 \r
2230                         for ($i = 0; $i < $plaintext_len; $i+= '.$block_size.') {\r
2231                             $in = substr($text, $i, '.$block_size.') ^ $in;\r
2232                             '.$_cryptBlock.'\r
2233                             $ciphertext.= $in;\r
2234                         }\r
2235 \r
2236                         if ($self->continuousBuffer) {\r
2237                             $self->encryptIV = $in;\r
2238                         }\r
2239 \r
2240                         return $ciphertext;\r
2241                         ';\r
2242 \r
2243                     $decrypt = $init_cryptBlock . '\r
2244                         extract($self->keys[CRYPT_DES_DECRYPT_1DIM],  EXTR_PREFIX_ALL, "k");\r
2245                         $plaintext = "";\r
2246                         $ciphertext_len = strlen($text);\r
2247 \r
2248                         $iv = $self->decryptIV;\r
2249 \r
2250                         for ($i = 0; $i < $ciphertext_len; $i+= '.$block_size.') {\r
2251                             $in = $block = substr($text, $i, '.$block_size.');\r
2252                             '.$_cryptBlock.'\r
2253                             $plaintext.= $in ^ $iv;\r
2254                             $iv = $block;\r
2255                         }\r
2256 \r
2257                         if ($self->continuousBuffer) {\r
2258                             $self->decryptIV = $iv;\r
2259                         }\r
2260 \r
2261                         return $self->_unpad($plaintext);\r
2262                         ';\r
2263                     break;\r
2264                 case CRYPT_DES_MODE_CTR:\r
2265                     $encrypt = $init_cryptBlock . '\r
2266                         extract($self->keys[CRYPT_DES_ENCRYPT_1DIM],  EXTR_PREFIX_ALL, "k");\r
2267                         $ciphertext = "";\r
2268                         $plaintext_len = strlen($text);\r
2269                         $xor = $self->encryptIV;\r
2270                         $buffer = &$self->enbuffer;\r
2271 \r
2272                         if (strlen($buffer["encrypted"])) {\r
2273                             for ($i = 0; $i < $plaintext_len; $i+= '.$block_size.') {\r
2274                                 $block = substr($text, $i, '.$block_size.');\r
2275                                 if (strlen($block) > strlen($buffer["encrypted"])) {\r
2276                                     $in = $self->_generate_xor($xor);\r
2277                                     '.$_cryptBlock.'\r
2278                                     $buffer["encrypted"].= $in;\r
2279                                 }\r
2280                                 $key = $self->_string_shift($buffer["encrypted"]);\r
2281                                 $ciphertext.= $block ^ $key;\r
2282                             }\r
2283                         } else {\r
2284                             for ($i = 0; $i < $plaintext_len; $i+= '.$block_size.') {\r
2285                                 $block = substr($text, $i, '.$block_size.');\r
2286                                 $in = $self->_generate_xor($xor);\r
2287                                 '.$_cryptBlock.'\r
2288                                 $key = $in;\r
2289                                 $ciphertext.= $block ^ $key;\r
2290                             }\r
2291                         }\r
2292                         if ($self->continuousBuffer) {\r
2293                             $self->encryptIV = $xor;\r
2294                             if ($start = $plaintext_len % '.$block_size.') {\r
2295                                 $buffer["encrypted"] = substr($key, $start) . $buffer["encrypted"];\r
2296                             }\r
2297                         }\r
2298 \r
2299                         return $ciphertext;\r
2300                     ';\r
2301 \r
2302                     $decrypt = $init_cryptBlock . '\r
2303                         extract($self->keys[CRYPT_DES_ENCRYPT_1DIM],  EXTR_PREFIX_ALL, "k");\r
2304                         $plaintext = "";\r
2305                         $ciphertext_len = strlen($text);\r
2306                         $xor = $self->decryptIV;\r
2307                         $buffer = &$self->debuffer;\r
2308 \r
2309                         if (strlen($buffer["ciphertext"])) {\r
2310                             for ($i = 0; $i < $ciphertext_len; $i+= '.$block_size.') {\r
2311                                 $block = substr($text, $i, '.$block_size.');\r
2312                                 if (strlen($block) > strlen($buffer["ciphertext"])) {\r
2313                                     $in = $self->_generate_xor($xor);\r
2314                                     '.$_cryptBlock.'\r
2315                                     $buffer["ciphertext"].= $in;\r
2316                                 }\r
2317                                 $key = $self->_string_shift($buffer["ciphertext"]);\r
2318                                 $plaintext.= $block ^ $key;\r
2319                             }\r
2320                         } else {\r
2321                             for ($i = 0; $i < $ciphertext_len; $i+= '.$block_size.') {\r
2322                                 $block = substr($text, $i, '.$block_size.');\r
2323                                 $in = $self->_generate_xor($xor);\r
2324                                 '.$_cryptBlock.'\r
2325                                 $key = $in;\r
2326                                 $plaintext.= $block ^ $key;\r
2327                             }\r
2328                         }\r
2329                         if ($self->continuousBuffer) {\r
2330                             $self->decryptIV = $xor;\r
2331                             if ($start = $ciphertext_len % '.$block_size.') {\r
2332                                 $buffer["ciphertext"] = substr($key, $start) . $buffer["ciphertext"];\r
2333                             }\r
2334                         }\r
2335                        \r
2336                         return $plaintext;\r
2337                         ';\r
2338                     break;\r
2339                 case CRYPT_DES_MODE_CFB:\r
2340                     $encrypt = $init_cryptBlock . '\r
2341                         extract($self->keys[CRYPT_DES_ENCRYPT_1DIM],  EXTR_PREFIX_ALL, "k");\r
2342                         $ciphertext = "";\r
2343                         $buffer = &$self->enbuffer;\r
2344 \r
2345                         if ($self->continuousBuffer) {\r
2346                             $iv = &$self->encryptIV;\r
2347                             $pos = &$buffer["pos"];\r
2348                         } else {\r
2349                             $iv = $self->encryptIV;\r
2350                             $pos = 0;\r
2351                         }\r
2352                         $len = strlen($text);\r
2353                         $i = 0;\r
2354                         if ($pos) {\r
2355                             $orig_pos = $pos;\r
2356                             $max = '.$block_size.' - $pos;\r
2357                             if ($len >= $max) {\r
2358                                 $i = $max;\r
2359                                 $len-= $max;\r
2360                                 $pos = 0;\r
2361                             } else {\r
2362                                 $i = $len;\r
2363                                 $pos+= $len;\r
2364                                 $len = 0;\r
2365                             }\r
2366                             $ciphertext = substr($iv, $orig_pos) ^ $text;\r
2367                             $iv = substr_replace($iv, $ciphertext, $orig_pos, $i);\r
2368                         }\r
2369                         while ($len >= '.$block_size.') {\r
2370                             $in = $iv;\r
2371                             '.$_cryptBlock.';\r
2372                             $iv = $in ^ substr($text, $i, '.$block_size.');\r
2373                             $ciphertext.= $iv;\r
2374                             $len-= '.$block_size.';\r
2375                             $i+= '.$block_size.';\r
2376                         }\r
2377                         if ($len) {\r
2378                             $in = $iv;\r
2379                             '.$_cryptBlock.'\r
2380                             $iv = $in;\r
2381                             $block = $iv ^ substr($text, $i);\r
2382                             $iv = substr_replace($iv, $block, 0, $len);\r
2383                             $ciphertext.= $block;\r
2384                             $pos = $len;\r
2385                         }\r
2386                         return $ciphertext;\r
2387                     ';\r
2388 \r
2389                     $decrypt = $init_cryptBlock . '\r
2390                         extract($self->keys[CRYPT_DES_ENCRYPT_1DIM],  EXTR_PREFIX_ALL, "k");\r
2391                         $plaintext = "";\r
2392                         $buffer = &$self->debuffer;\r
2393 \r
2394                         if ($self->continuousBuffer) {\r
2395                             $iv = &$self->decryptIV;\r
2396                             $pos = &$buffer["pos"];\r
2397                         } else {\r
2398                             $iv = $self->decryptIV;\r
2399                             $pos = 0;\r
2400                         }\r
2401                         $len = strlen($text);\r
2402                         $i = 0;\r
2403                         if ($pos) {\r
2404                             $orig_pos = $pos;\r
2405                             $max = '.$block_size.' - $pos;\r
2406                             if ($len >= $max) {\r
2407                                 $i = $max;\r
2408                                 $len-= $max;\r
2409                                 $pos = 0;\r
2410                             } else {\r
2411                                 $i = $len;\r
2412                                 $pos+= $len;\r
2413                                 $len = 0;\r
2414                             }\r
2415                             $plaintext = substr($iv, $orig_pos) ^ $text;\r
2416                             $iv = substr_replace($iv, substr($text, 0, $i), $orig_pos, $i);\r
2417                         }\r
2418                         while ($len >= '.$block_size.') {\r
2419                             $in = $iv;\r
2420                             '.$_cryptBlock.'\r
2421                             $iv = $in;\r
2422                             $cb = substr($text, $i, '.$block_size.');\r
2423                             $plaintext.= $iv ^ $cb;\r
2424                             $iv = $cb;\r
2425                             $len-= '.$block_size.';\r
2426                             $i+= '.$block_size.';\r
2427                         }\r
2428                         if ($len) {\r
2429                             $in = $iv;\r
2430                             '.$_cryptBlock.'\r
2431                             $iv = $in;\r
2432                             $plaintext.= $iv ^ substr($text, $i);\r
2433                             $iv = substr_replace($iv, substr($text, $i), 0, $len);\r
2434                             $pos = $len;\r
2435                         }\r
2436 \r
2437                         return $plaintext;\r
2438                         ';\r
2439                     break;\r
2440                 case CRYPT_DES_MODE_OFB:\r
2441                     $encrypt = $init_cryptBlock . '\r
2442                         extract($self->keys[CRYPT_DES_ENCRYPT_1DIM],  EXTR_PREFIX_ALL, "k");\r
2443                         $ciphertext = "";\r
2444                         $plaintext_len = strlen($text);\r
2445                         $xor = $self->encryptIV;\r
2446                         $buffer = &$self->enbuffer;\r
2447 \r
2448                         if (strlen($buffer["xor"])) {\r
2449                             for ($i = 0; $i < $plaintext_len; $i+= '.$block_size.') {\r
2450                                 $block = substr($text, $i, '.$block_size.');\r
2451                                 if (strlen($block) > strlen($buffer["xor"])) {\r
2452                                     $in = $xor;\r
2453                                     '.$_cryptBlock.'\r
2454                                     $xor = $in;\r
2455                                     $buffer["xor"].= $xor;\r
2456                                 }\r
2457                                 $key = $self->_string_shift($buffer["xor"]);\r
2458                                 $ciphertext.= $block ^ $key;\r
2459                             }\r
2460                         } else {\r
2461                             for ($i = 0; $i < $plaintext_len; $i+= '.$block_size.') {\r
2462                                 $in = $xor;\r
2463                                 '.$_cryptBlock.'\r
2464                                 $xor = $in;\r
2465                                 $ciphertext.= substr($text, $i, '.$block_size.') ^ $xor;\r
2466                             }\r
2467                             $key = $xor;\r
2468                         }\r
2469                         if ($self->continuousBuffer) {\r
2470                             $self->encryptIV = $xor;\r
2471                             if ($start = $plaintext_len % '.$block_size.') {\r
2472                                  $buffer["xor"] = substr($key, $start) . $buffer["xor"];\r
2473                             }\r
2474                         }\r
2475                         return $ciphertext;\r
2476                         ';\r
2477 \r
2478                     $decrypt = $init_cryptBlock . '\r
2479                         extract($self->keys[CRYPT_DES_ENCRYPT_1DIM],  EXTR_PREFIX_ALL, "k");\r
2480                         $plaintext = "";\r
2481                         $ciphertext_len = strlen($text);\r
2482                         $xor = $self->decryptIV;\r
2483                         $buffer = &$self->debuffer;\r
2484 \r
2485                         if (strlen($buffer["xor"])) {\r
2486                             for ($i = 0; $i < $ciphertext_len; $i+= '.$block_size.') {\r
2487                                 $block = substr($text, $i, '.$block_size.');\r
2488                                 if (strlen($block) > strlen($buffer["xor"])) {\r
2489                                     $in = $xor;\r
2490                                     '.$_cryptBlock.'\r
2491                                     $xor = $in;\r
2492                                     $buffer["xor"].= $xor;\r
2493                                 }\r
2494                                 $key = $self->_string_shift($buffer["xor"]);\r
2495                                 $plaintext.= $block ^ $key;\r
2496                             }\r
2497                         } else {\r
2498                             for ($i = 0; $i < $ciphertext_len; $i+= '.$block_size.') {\r
2499                                 $in = $xor;\r
2500                                 '.$_cryptBlock.'\r
2501                                 $xor = $in;\r
2502                                 $plaintext.= substr($text, $i, '.$block_size.') ^ $xor;\r
2503                             }\r
2504                             $key = $xor;\r
2505                         }\r
2506                         if ($self->continuousBuffer) {\r
2507                             $self->decryptIV = $xor;\r
2508                             if ($start = $ciphertext_len % '.$block_size.') {\r
2509                                  $buffer["xor"] = substr($key, $start) . $buffer["xor"];\r
2510                             }\r
2511                         }\r
2512                         return $plaintext;\r
2513                         ';\r
2514                     break;\r
2515             }\r
2516             $lambda_functions[$code_hash] = create_function('$action, &$self, $text', 'if ($action == "encrypt") { '.$encrypt.' } else { '.$decrypt.' }');\r
2517         }\r
2518         $this->inline_crypt = $lambda_functions[$code_hash];\r
2519     }\r
2520 \r
2521     /**\r
2522      * Holds the lambda_functions table (classwide)\r
2523      *\r
2524      * @see inline_crypt_setup()\r
2525      * @return Array\r
2526      * @access private\r
2527      */\r
2528     function &get_lambda_functions()\r
2529     {\r
2530         static $functions = array();\r
2531         return $functions;\r
2532     }\r
2533 }\r
2534 \r
2535 // vim: ts=4:sw=4:et:\r
2536 // vim6: fdl=1:\r