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