From c4752cbeba6389e8abbc8ee8b8b1a066c2c1634a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hans-J=C3=BCrgen=20Petrich?= Date: Thu, 25 Apr 2013 14:16:10 +0700 Subject: [PATCH] DES / 3DES Performance Update DES / 3DES Performance Update. Inline en/decrypting gives additional ~25% performance. 100% compatible with the current DES/TribleDES.php Strong testet on Windows/Linux 32/64bit with php4/5.0/5.1//5.2/5.3/5.4 --- phpseclib/Crypt/DES.php | 1329 +++++++++++++++++++++++---------- phpseclib/Crypt/TripleDES.php | 317 +------- 2 files changed, 975 insertions(+), 671 deletions(-) diff --git a/phpseclib/Crypt/DES.php b/phpseclib/Crypt/DES.php index be99d6a5..fdec996e 100644 --- a/phpseclib/Crypt/DES.php +++ b/phpseclib/Crypt/DES.php @@ -73,6 +73,14 @@ define('CRYPT_DES_ENCRYPT', 0); * Contains array_reverse($keys[CRYPT_DES_ENCRYPT]) */ define('CRYPT_DES_DECRYPT', 1); +/** + * Contains $keys[CRYPT_DES_ENCRYPT] as 1-dim array + */ +define('CRYPT_DES_ENCRYPT_1DIM', 2); +/** + * Contains $keys[CRYPT_DES_DECRYPT] as 1-dim array + */ +define('CRYPT_DES_DECRYPT_1DIM', 3); /**#@-*/ /**#@+ @@ -281,17 +289,452 @@ class Crypt_DES { */ var $ecb; + /** + * Performance-optimized callback function for en/decrypt() + * + * @var Callback + * @access private + */ + var $inline_crypt; + + /** + * Holds whether performance-optimized $inline_crypt should be used or not. + * + * @var Boolean + * @access private + */ + var $use_inline_crypt = false; + /** * Shuffle table. + * * For each byte value index, the entry holds an 8-byte string * with each byte containing all bits in the same state as the * corresponding bit in the index value. + * * @see Crypt_DES::_processBlock() * @see Crypt_DES::_prepareKey() * @var Array * @access private */ - var $shuffle; + var $shuffle = array( + "\x00\x00\x00\x00\x00\x00\x00\x00", "\x00\x00\x00\x00\x00\x00\x00\xFF", + "\x00\x00\x00\x00\x00\x00\xFF\x00", "\x00\x00\x00\x00\x00\x00\xFF\xFF", + "\x00\x00\x00\x00\x00\xFF\x00\x00", "\x00\x00\x00\x00\x00\xFF\x00\xFF", + "\x00\x00\x00\x00\x00\xFF\xFF\x00", "\x00\x00\x00\x00\x00\xFF\xFF\xFF", + "\x00\x00\x00\x00\xFF\x00\x00\x00", "\x00\x00\x00\x00\xFF\x00\x00\xFF", + "\x00\x00\x00\x00\xFF\x00\xFF\x00", "\x00\x00\x00\x00\xFF\x00\xFF\xFF", + "\x00\x00\x00\x00\xFF\xFF\x00\x00", "\x00\x00\x00\x00\xFF\xFF\x00\xFF", + "\x00\x00\x00\x00\xFF\xFF\xFF\x00", "\x00\x00\x00\x00\xFF\xFF\xFF\xFF", + "\x00\x00\x00\xFF\x00\x00\x00\x00", "\x00\x00\x00\xFF\x00\x00\x00\xFF", + "\x00\x00\x00\xFF\x00\x00\xFF\x00", "\x00\x00\x00\xFF\x00\x00\xFF\xFF", + "\x00\x00\x00\xFF\x00\xFF\x00\x00", "\x00\x00\x00\xFF\x00\xFF\x00\xFF", + "\x00\x00\x00\xFF\x00\xFF\xFF\x00", "\x00\x00\x00\xFF\x00\xFF\xFF\xFF", + "\x00\x00\x00\xFF\xFF\x00\x00\x00", "\x00\x00\x00\xFF\xFF\x00\x00\xFF", + "\x00\x00\x00\xFF\xFF\x00\xFF\x00", "\x00\x00\x00\xFF\xFF\x00\xFF\xFF", + "\x00\x00\x00\xFF\xFF\xFF\x00\x00", "\x00\x00\x00\xFF\xFF\xFF\x00\xFF", + "\x00\x00\x00\xFF\xFF\xFF\xFF\x00", "\x00\x00\x00\xFF\xFF\xFF\xFF\xFF", + "\x00\x00\xFF\x00\x00\x00\x00\x00", "\x00\x00\xFF\x00\x00\x00\x00\xFF", + "\x00\x00\xFF\x00\x00\x00\xFF\x00", "\x00\x00\xFF\x00\x00\x00\xFF\xFF", + "\x00\x00\xFF\x00\x00\xFF\x00\x00", "\x00\x00\xFF\x00\x00\xFF\x00\xFF", + "\x00\x00\xFF\x00\x00\xFF\xFF\x00", "\x00\x00\xFF\x00\x00\xFF\xFF\xFF", + "\x00\x00\xFF\x00\xFF\x00\x00\x00", "\x00\x00\xFF\x00\xFF\x00\x00\xFF", + "\x00\x00\xFF\x00\xFF\x00\xFF\x00", "\x00\x00\xFF\x00\xFF\x00\xFF\xFF", + "\x00\x00\xFF\x00\xFF\xFF\x00\x00", "\x00\x00\xFF\x00\xFF\xFF\x00\xFF", + "\x00\x00\xFF\x00\xFF\xFF\xFF\x00", "\x00\x00\xFF\x00\xFF\xFF\xFF\xFF", + "\x00\x00\xFF\xFF\x00\x00\x00\x00", "\x00\x00\xFF\xFF\x00\x00\x00\xFF", + "\x00\x00\xFF\xFF\x00\x00\xFF\x00", "\x00\x00\xFF\xFF\x00\x00\xFF\xFF", + "\x00\x00\xFF\xFF\x00\xFF\x00\x00", "\x00\x00\xFF\xFF\x00\xFF\x00\xFF", + "\x00\x00\xFF\xFF\x00\xFF\xFF\x00", "\x00\x00\xFF\xFF\x00\xFF\xFF\xFF", + "\x00\x00\xFF\xFF\xFF\x00\x00\x00", "\x00\x00\xFF\xFF\xFF\x00\x00\xFF", + "\x00\x00\xFF\xFF\xFF\x00\xFF\x00", "\x00\x00\xFF\xFF\xFF\x00\xFF\xFF", + "\x00\x00\xFF\xFF\xFF\xFF\x00\x00", "\x00\x00\xFF\xFF\xFF\xFF\x00\xFF", + "\x00\x00\xFF\xFF\xFF\xFF\xFF\x00", "\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF", + "\x00\xFF\x00\x00\x00\x00\x00\x00", "\x00\xFF\x00\x00\x00\x00\x00\xFF", + "\x00\xFF\x00\x00\x00\x00\xFF\x00", "\x00\xFF\x00\x00\x00\x00\xFF\xFF", + "\x00\xFF\x00\x00\x00\xFF\x00\x00", "\x00\xFF\x00\x00\x00\xFF\x00\xFF", + "\x00\xFF\x00\x00\x00\xFF\xFF\x00", "\x00\xFF\x00\x00\x00\xFF\xFF\xFF", + "\x00\xFF\x00\x00\xFF\x00\x00\x00", "\x00\xFF\x00\x00\xFF\x00\x00\xFF", + "\x00\xFF\x00\x00\xFF\x00\xFF\x00", "\x00\xFF\x00\x00\xFF\x00\xFF\xFF", + "\x00\xFF\x00\x00\xFF\xFF\x00\x00", "\x00\xFF\x00\x00\xFF\xFF\x00\xFF", + "\x00\xFF\x00\x00\xFF\xFF\xFF\x00", "\x00\xFF\x00\x00\xFF\xFF\xFF\xFF", + "\x00\xFF\x00\xFF\x00\x00\x00\x00", "\x00\xFF\x00\xFF\x00\x00\x00\xFF", + "\x00\xFF\x00\xFF\x00\x00\xFF\x00", "\x00\xFF\x00\xFF\x00\x00\xFF\xFF", + "\x00\xFF\x00\xFF\x00\xFF\x00\x00", "\x00\xFF\x00\xFF\x00\xFF\x00\xFF", + "\x00\xFF\x00\xFF\x00\xFF\xFF\x00", "\x00\xFF\x00\xFF\x00\xFF\xFF\xFF", + "\x00\xFF\x00\xFF\xFF\x00\x00\x00", "\x00\xFF\x00\xFF\xFF\x00\x00\xFF", + "\x00\xFF\x00\xFF\xFF\x00\xFF\x00", "\x00\xFF\x00\xFF\xFF\x00\xFF\xFF", + "\x00\xFF\x00\xFF\xFF\xFF\x00\x00", "\x00\xFF\x00\xFF\xFF\xFF\x00\xFF", + "\x00\xFF\x00\xFF\xFF\xFF\xFF\x00", "\x00\xFF\x00\xFF\xFF\xFF\xFF\xFF", + "\x00\xFF\xFF\x00\x00\x00\x00\x00", "\x00\xFF\xFF\x00\x00\x00\x00\xFF", + "\x00\xFF\xFF\x00\x00\x00\xFF\x00", "\x00\xFF\xFF\x00\x00\x00\xFF\xFF", + "\x00\xFF\xFF\x00\x00\xFF\x00\x00", "\x00\xFF\xFF\x00\x00\xFF\x00\xFF", + "\x00\xFF\xFF\x00\x00\xFF\xFF\x00", "\x00\xFF\xFF\x00\x00\xFF\xFF\xFF", + "\x00\xFF\xFF\x00\xFF\x00\x00\x00", "\x00\xFF\xFF\x00\xFF\x00\x00\xFF", + "\x00\xFF\xFF\x00\xFF\x00\xFF\x00", "\x00\xFF\xFF\x00\xFF\x00\xFF\xFF", + "\x00\xFF\xFF\x00\xFF\xFF\x00\x00", "\x00\xFF\xFF\x00\xFF\xFF\x00\xFF", + "\x00\xFF\xFF\x00\xFF\xFF\xFF\x00", "\x00\xFF\xFF\x00\xFF\xFF\xFF\xFF", + "\x00\xFF\xFF\xFF\x00\x00\x00\x00", "\x00\xFF\xFF\xFF\x00\x00\x00\xFF", + "\x00\xFF\xFF\xFF\x00\x00\xFF\x00", "\x00\xFF\xFF\xFF\x00\x00\xFF\xFF", + "\x00\xFF\xFF\xFF\x00\xFF\x00\x00", "\x00\xFF\xFF\xFF\x00\xFF\x00\xFF", + "\x00\xFF\xFF\xFF\x00\xFF\xFF\x00", "\x00\xFF\xFF\xFF\x00\xFF\xFF\xFF", + "\x00\xFF\xFF\xFF\xFF\x00\x00\x00", "\x00\xFF\xFF\xFF\xFF\x00\x00\xFF", + "\x00\xFF\xFF\xFF\xFF\x00\xFF\x00", "\x00\xFF\xFF\xFF\xFF\x00\xFF\xFF", + "\x00\xFF\xFF\xFF\xFF\xFF\x00\x00", "\x00\xFF\xFF\xFF\xFF\xFF\x00\xFF", + "\x00\xFF\xFF\xFF\xFF\xFF\xFF\x00", "\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF", + "\xFF\x00\x00\x00\x00\x00\x00\x00", "\xFF\x00\x00\x00\x00\x00\x00\xFF", + "\xFF\x00\x00\x00\x00\x00\xFF\x00", "\xFF\x00\x00\x00\x00\x00\xFF\xFF", + "\xFF\x00\x00\x00\x00\xFF\x00\x00", "\xFF\x00\x00\x00\x00\xFF\x00\xFF", + "\xFF\x00\x00\x00\x00\xFF\xFF\x00", "\xFF\x00\x00\x00\x00\xFF\xFF\xFF", + "\xFF\x00\x00\x00\xFF\x00\x00\x00", "\xFF\x00\x00\x00\xFF\x00\x00\xFF", + "\xFF\x00\x00\x00\xFF\x00\xFF\x00", "\xFF\x00\x00\x00\xFF\x00\xFF\xFF", + "\xFF\x00\x00\x00\xFF\xFF\x00\x00", "\xFF\x00\x00\x00\xFF\xFF\x00\xFF", + "\xFF\x00\x00\x00\xFF\xFF\xFF\x00", "\xFF\x00\x00\x00\xFF\xFF\xFF\xFF", + "\xFF\x00\x00\xFF\x00\x00\x00\x00", "\xFF\x00\x00\xFF\x00\x00\x00\xFF", + "\xFF\x00\x00\xFF\x00\x00\xFF\x00", "\xFF\x00\x00\xFF\x00\x00\xFF\xFF", + "\xFF\x00\x00\xFF\x00\xFF\x00\x00", "\xFF\x00\x00\xFF\x00\xFF\x00\xFF", + "\xFF\x00\x00\xFF\x00\xFF\xFF\x00", "\xFF\x00\x00\xFF\x00\xFF\xFF\xFF", + "\xFF\x00\x00\xFF\xFF\x00\x00\x00", "\xFF\x00\x00\xFF\xFF\x00\x00\xFF", + "\xFF\x00\x00\xFF\xFF\x00\xFF\x00", "\xFF\x00\x00\xFF\xFF\x00\xFF\xFF", + "\xFF\x00\x00\xFF\xFF\xFF\x00\x00", "\xFF\x00\x00\xFF\xFF\xFF\x00\xFF", + "\xFF\x00\x00\xFF\xFF\xFF\xFF\x00", "\xFF\x00\x00\xFF\xFF\xFF\xFF\xFF", + "\xFF\x00\xFF\x00\x00\x00\x00\x00", "\xFF\x00\xFF\x00\x00\x00\x00\xFF", + "\xFF\x00\xFF\x00\x00\x00\xFF\x00", "\xFF\x00\xFF\x00\x00\x00\xFF\xFF", + "\xFF\x00\xFF\x00\x00\xFF\x00\x00", "\xFF\x00\xFF\x00\x00\xFF\x00\xFF", + "\xFF\x00\xFF\x00\x00\xFF\xFF\x00", "\xFF\x00\xFF\x00\x00\xFF\xFF\xFF", + "\xFF\x00\xFF\x00\xFF\x00\x00\x00", "\xFF\x00\xFF\x00\xFF\x00\x00\xFF", + "\xFF\x00\xFF\x00\xFF\x00\xFF\x00", "\xFF\x00\xFF\x00\xFF\x00\xFF\xFF", + "\xFF\x00\xFF\x00\xFF\xFF\x00\x00", "\xFF\x00\xFF\x00\xFF\xFF\x00\xFF", + "\xFF\x00\xFF\x00\xFF\xFF\xFF\x00", "\xFF\x00\xFF\x00\xFF\xFF\xFF\xFF", + "\xFF\x00\xFF\xFF\x00\x00\x00\x00", "\xFF\x00\xFF\xFF\x00\x00\x00\xFF", + "\xFF\x00\xFF\xFF\x00\x00\xFF\x00", "\xFF\x00\xFF\xFF\x00\x00\xFF\xFF", + "\xFF\x00\xFF\xFF\x00\xFF\x00\x00", "\xFF\x00\xFF\xFF\x00\xFF\x00\xFF", + "\xFF\x00\xFF\xFF\x00\xFF\xFF\x00", "\xFF\x00\xFF\xFF\x00\xFF\xFF\xFF", + "\xFF\x00\xFF\xFF\xFF\x00\x00\x00", "\xFF\x00\xFF\xFF\xFF\x00\x00\xFF", + "\xFF\x00\xFF\xFF\xFF\x00\xFF\x00", "\xFF\x00\xFF\xFF\xFF\x00\xFF\xFF", + "\xFF\x00\xFF\xFF\xFF\xFF\x00\x00", "\xFF\x00\xFF\xFF\xFF\xFF\x00\xFF", + "\xFF\x00\xFF\xFF\xFF\xFF\xFF\x00", "\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF", + "\xFF\xFF\x00\x00\x00\x00\x00\x00", "\xFF\xFF\x00\x00\x00\x00\x00\xFF", + "\xFF\xFF\x00\x00\x00\x00\xFF\x00", "\xFF\xFF\x00\x00\x00\x00\xFF\xFF", + "\xFF\xFF\x00\x00\x00\xFF\x00\x00", "\xFF\xFF\x00\x00\x00\xFF\x00\xFF", + "\xFF\xFF\x00\x00\x00\xFF\xFF\x00", "\xFF\xFF\x00\x00\x00\xFF\xFF\xFF", + "\xFF\xFF\x00\x00\xFF\x00\x00\x00", "\xFF\xFF\x00\x00\xFF\x00\x00\xFF", + "\xFF\xFF\x00\x00\xFF\x00\xFF\x00", "\xFF\xFF\x00\x00\xFF\x00\xFF\xFF", + "\xFF\xFF\x00\x00\xFF\xFF\x00\x00", "\xFF\xFF\x00\x00\xFF\xFF\x00\xFF", + "\xFF\xFF\x00\x00\xFF\xFF\xFF\x00", "\xFF\xFF\x00\x00\xFF\xFF\xFF\xFF", + "\xFF\xFF\x00\xFF\x00\x00\x00\x00", "\xFF\xFF\x00\xFF\x00\x00\x00\xFF", + "\xFF\xFF\x00\xFF\x00\x00\xFF\x00", "\xFF\xFF\x00\xFF\x00\x00\xFF\xFF", + "\xFF\xFF\x00\xFF\x00\xFF\x00\x00", "\xFF\xFF\x00\xFF\x00\xFF\x00\xFF", + "\xFF\xFF\x00\xFF\x00\xFF\xFF\x00", "\xFF\xFF\x00\xFF\x00\xFF\xFF\xFF", + "\xFF\xFF\x00\xFF\xFF\x00\x00\x00", "\xFF\xFF\x00\xFF\xFF\x00\x00\xFF", + "\xFF\xFF\x00\xFF\xFF\x00\xFF\x00", "\xFF\xFF\x00\xFF\xFF\x00\xFF\xFF", + "\xFF\xFF\x00\xFF\xFF\xFF\x00\x00", "\xFF\xFF\x00\xFF\xFF\xFF\x00\xFF", + "\xFF\xFF\x00\xFF\xFF\xFF\xFF\x00", "\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF", + "\xFF\xFF\xFF\x00\x00\x00\x00\x00", "\xFF\xFF\xFF\x00\x00\x00\x00\xFF", + "\xFF\xFF\xFF\x00\x00\x00\xFF\x00", "\xFF\xFF\xFF\x00\x00\x00\xFF\xFF", + "\xFF\xFF\xFF\x00\x00\xFF\x00\x00", "\xFF\xFF\xFF\x00\x00\xFF\x00\xFF", + "\xFF\xFF\xFF\x00\x00\xFF\xFF\x00", "\xFF\xFF\xFF\x00\x00\xFF\xFF\xFF", + "\xFF\xFF\xFF\x00\xFF\x00\x00\x00", "\xFF\xFF\xFF\x00\xFF\x00\x00\xFF", + "\xFF\xFF\xFF\x00\xFF\x00\xFF\x00", "\xFF\xFF\xFF\x00\xFF\x00\xFF\xFF", + "\xFF\xFF\xFF\x00\xFF\xFF\x00\x00", "\xFF\xFF\xFF\x00\xFF\xFF\x00\xFF", + "\xFF\xFF\xFF\x00\xFF\xFF\xFF\x00", "\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF", + "\xFF\xFF\xFF\xFF\x00\x00\x00\x00", "\xFF\xFF\xFF\xFF\x00\x00\x00\xFF", + "\xFF\xFF\xFF\xFF\x00\x00\xFF\x00", "\xFF\xFF\xFF\xFF\x00\x00\xFF\xFF", + "\xFF\xFF\xFF\xFF\x00\xFF\x00\x00", "\xFF\xFF\xFF\xFF\x00\xFF\x00\xFF", + "\xFF\xFF\xFF\xFF\x00\xFF\xFF\x00", "\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF", + "\xFF\xFF\xFF\xFF\xFF\x00\x00\x00", "\xFF\xFF\xFF\xFF\xFF\x00\x00\xFF", + "\xFF\xFF\xFF\xFF\xFF\x00\xFF\x00", "\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF", + "\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00", "\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF", + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00", "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + ); + + /** + * IP mapping helper table. + * + * Indexing this table with each source byte performs the initial bit permutation. + * + * @var Array + * @access private + */ + var $ipmap = array( + 0x00, 0x10, 0x01, 0x11, 0x20, 0x30, 0x21, 0x31, + 0x02, 0x12, 0x03, 0x13, 0x22, 0x32, 0x23, 0x33, + 0x40, 0x50, 0x41, 0x51, 0x60, 0x70, 0x61, 0x71, + 0x42, 0x52, 0x43, 0x53, 0x62, 0x72, 0x63, 0x73, + 0x04, 0x14, 0x05, 0x15, 0x24, 0x34, 0x25, 0x35, + 0x06, 0x16, 0x07, 0x17, 0x26, 0x36, 0x27, 0x37, + 0x44, 0x54, 0x45, 0x55, 0x64, 0x74, 0x65, 0x75, + 0x46, 0x56, 0x47, 0x57, 0x66, 0x76, 0x67, 0x77, + 0x80, 0x90, 0x81, 0x91, 0xA0, 0xB0, 0xA1, 0xB1, + 0x82, 0x92, 0x83, 0x93, 0xA2, 0xB2, 0xA3, 0xB3, + 0xC0, 0xD0, 0xC1, 0xD1, 0xE0, 0xF0, 0xE1, 0xF1, + 0xC2, 0xD2, 0xC3, 0xD3, 0xE2, 0xF2, 0xE3, 0xF3, + 0x84, 0x94, 0x85, 0x95, 0xA4, 0xB4, 0xA5, 0xB5, + 0x86, 0x96, 0x87, 0x97, 0xA6, 0xB6, 0xA7, 0xB7, + 0xC4, 0xD4, 0xC5, 0xD5, 0xE4, 0xF4, 0xE5, 0xF5, + 0xC6, 0xD6, 0xC7, 0xD7, 0xE6, 0xF6, 0xE7, 0xF7, + 0x08, 0x18, 0x09, 0x19, 0x28, 0x38, 0x29, 0x39, + 0x0A, 0x1A, 0x0B, 0x1B, 0x2A, 0x3A, 0x2B, 0x3B, + 0x48, 0x58, 0x49, 0x59, 0x68, 0x78, 0x69, 0x79, + 0x4A, 0x5A, 0x4B, 0x5B, 0x6A, 0x7A, 0x6B, 0x7B, + 0x0C, 0x1C, 0x0D, 0x1D, 0x2C, 0x3C, 0x2D, 0x3D, + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4C, 0x5C, 0x4D, 0x5D, 0x6C, 0x7C, 0x6D, 0x7D, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x88, 0x98, 0x89, 0x99, 0xA8, 0xB8, 0xA9, 0xB9, + 0x8A, 0x9A, 0x8B, 0x9B, 0xAA, 0xBA, 0xAB, 0xBB, + 0xC8, 0xD8, 0xC9, 0xD9, 0xE8, 0xF8, 0xE9, 0xF9, + 0xCA, 0xDA, 0xCB, 0xDB, 0xEA, 0xFA, 0xEB, 0xFB, + 0x8C, 0x9C, 0x8D, 0x9D, 0xAC, 0xBC, 0xAD, 0xBD, + 0x8E, 0x9E, 0x8F, 0x9F, 0xAE, 0xBE, 0xAF, 0xBF, + 0xCC, 0xDC, 0xCD, 0xDD, 0xEC, 0xFC, 0xED, 0xFD, + 0xCE, 0xDE, 0xCF, 0xDF, 0xEE, 0xFE, 0xEF, 0xFF + ); + + /** + * Inverse IP mapping helper table. + * Indexing this table with a byte value reverses the bit order. + * + * @var Array + * @access private + */ + var $invipmap = array( + 0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0, + 0x10, 0x90, 0x50, 0xD0, 0x30, 0xB0, 0x70, 0xF0, + 0x08, 0x88, 0x48, 0xC8, 0x28, 0xA8, 0x68, 0xE8, + 0x18, 0x98, 0x58, 0xD8, 0x38, 0xB8, 0x78, 0xF8, + 0x04, 0x84, 0x44, 0xC4, 0x24, 0xA4, 0x64, 0xE4, + 0x14, 0x94, 0x54, 0xD4, 0x34, 0xB4, 0x74, 0xF4, + 0x0C, 0x8C, 0x4C, 0xCC, 0x2C, 0xAC, 0x6C, 0xEC, + 0x1C, 0x9C, 0x5C, 0xDC, 0x3C, 0xBC, 0x7C, 0xFC, + 0x02, 0x82, 0x42, 0xC2, 0x22, 0xA2, 0x62, 0xE2, + 0x12, 0x92, 0x52, 0xD2, 0x32, 0xB2, 0x72, 0xF2, + 0x0A, 0x8A, 0x4A, 0xCA, 0x2A, 0xAA, 0x6A, 0xEA, + 0x1A, 0x9A, 0x5A, 0xDA, 0x3A, 0xBA, 0x7A, 0xFA, + 0x06, 0x86, 0x46, 0xC6, 0x26, 0xA6, 0x66, 0xE6, + 0x16, 0x96, 0x56, 0xD6, 0x36, 0xB6, 0x76, 0xF6, + 0x0E, 0x8E, 0x4E, 0xCE, 0x2E, 0xAE, 0x6E, 0xEE, + 0x1E, 0x9E, 0x5E, 0xDE, 0x3E, 0xBE, 0x7E, 0xFE, + 0x01, 0x81, 0x41, 0xC1, 0x21, 0xA1, 0x61, 0xE1, + 0x11, 0x91, 0x51, 0xD1, 0x31, 0xB1, 0x71, 0xF1, + 0x09, 0x89, 0x49, 0xC9, 0x29, 0xA9, 0x69, 0xE9, + 0x19, 0x99, 0x59, 0xD9, 0x39, 0xB9, 0x79, 0xF9, + 0x05, 0x85, 0x45, 0xC5, 0x25, 0xA5, 0x65, 0xE5, + 0x15, 0x95, 0x55, 0xD5, 0x35, 0xB5, 0x75, 0xF5, + 0x0D, 0x8D, 0x4D, 0xCD, 0x2D, 0xAD, 0x6D, 0xED, + 0x1D, 0x9D, 0x5D, 0xDD, 0x3D, 0xBD, 0x7D, 0xFD, + 0x03, 0x83, 0x43, 0xC3, 0x23, 0xA3, 0x63, 0xE3, + 0x13, 0x93, 0x53, 0xD3, 0x33, 0xB3, 0x73, 0xF3, + 0x0B, 0x8B, 0x4B, 0xCB, 0x2B, 0xAB, 0x6B, 0xEB, + 0x1B, 0x9B, 0x5B, 0xDB, 0x3B, 0xBB, 0x7B, 0xFB, + 0x07, 0x87, 0x47, 0xC7, 0x27, 0xA7, 0x67, 0xE7, + 0x17, 0x97, 0x57, 0xD7, 0x37, 0xB7, 0x77, 0xF7, + 0x0F, 0x8F, 0x4F, 0xCF, 0x2F, 0xAF, 0x6F, 0xEF, + 0x1F, 0x9F, 0x5F, 0xDF, 0x3F, 0xBF, 0x7F, 0xFF + ); + + /** + * Pre-permuted S-box1 + * + * Each box ($sbox1-$sbox8) has been vectorized, then each value pre-permuted using the + * P table: concatenation can then be replaced by exclusive ORs. + * + * @var Array + * @access private + */ + var $sbox1 = array( + 0x00808200, 0x00000000, 0x00008000, 0x00808202, + 0x00808002, 0x00008202, 0x00000002, 0x00008000, + 0x00000200, 0x00808200, 0x00808202, 0x00000200, + 0x00800202, 0x00808002, 0x00800000, 0x00000002, + 0x00000202, 0x00800200, 0x00800200, 0x00008200, + 0x00008200, 0x00808000, 0x00808000, 0x00800202, + 0x00008002, 0x00800002, 0x00800002, 0x00008002, + 0x00000000, 0x00000202, 0x00008202, 0x00800000, + 0x00008000, 0x00808202, 0x00000002, 0x00808000, + 0x00808200, 0x00800000, 0x00800000, 0x00000200, + 0x00808002, 0x00008000, 0x00008200, 0x00800002, + 0x00000200, 0x00000002, 0x00800202, 0x00008202, + 0x00808202, 0x00008002, 0x00808000, 0x00800202, + 0x00800002, 0x00000202, 0x00008202, 0x00808200, + 0x00000202, 0x00800200, 0x00800200, 0x00000000, + 0x00008002, 0x00008200, 0x00000000, 0x00808002 + ); + + /** + * Pre-permuted S-box2 + * + * @var Array + * @access private + */ + var $sbox2 = array( + 0x40084010, 0x40004000, 0x00004000, 0x00084010, + 0x00080000, 0x00000010, 0x40080010, 0x40004010, + 0x40000010, 0x40084010, 0x40084000, 0x40000000, + 0x40004000, 0x00080000, 0x00000010, 0x40080010, + 0x00084000, 0x00080010, 0x40004010, 0x00000000, + 0x40000000, 0x00004000, 0x00084010, 0x40080000, + 0x00080010, 0x40000010, 0x00000000, 0x00084000, + 0x00004010, 0x40084000, 0x40080000, 0x00004010, + 0x00000000, 0x00084010, 0x40080010, 0x00080000, + 0x40004010, 0x40080000, 0x40084000, 0x00004000, + 0x40080000, 0x40004000, 0x00000010, 0x40084010, + 0x00084010, 0x00000010, 0x00004000, 0x40000000, + 0x00004010, 0x40084000, 0x00080000, 0x40000010, + 0x00080010, 0x40004010, 0x40000010, 0x00080010, + 0x00084000, 0x00000000, 0x40004000, 0x00004010, + 0x40000000, 0x40080010, 0x40084010, 0x00084000 + ); + + /** + * Pre-permuted S-box3 + * + * @var Array + * @access private + */ + var $sbox3 = array( + 0x00000104, 0x04010100, 0x00000000, 0x04010004, + 0x04000100, 0x00000000, 0x00010104, 0x04000100, + 0x00010004, 0x04000004, 0x04000004, 0x00010000, + 0x04010104, 0x00010004, 0x04010000, 0x00000104, + 0x04000000, 0x00000004, 0x04010100, 0x00000100, + 0x00010100, 0x04010000, 0x04010004, 0x00010104, + 0x04000104, 0x00010100, 0x00010000, 0x04000104, + 0x00000004, 0x04010104, 0x00000100, 0x04000000, + 0x04010100, 0x04000000, 0x00010004, 0x00000104, + 0x00010000, 0x04010100, 0x04000100, 0x00000000, + 0x00000100, 0x00010004, 0x04010104, 0x04000100, + 0x04000004, 0x00000100, 0x00000000, 0x04010004, + 0x04000104, 0x00010000, 0x04000000, 0x04010104, + 0x00000004, 0x00010104, 0x00010100, 0x04000004, + 0x04010000, 0x04000104, 0x00000104, 0x04010000, + 0x00010104, 0x00000004, 0x04010004, 0x00010100 + ); + + /** + * Pre-permuted S-box4 + * + * @var Array + * @access private + */ + var $sbox4 = array( + 0x80401000, 0x80001040, 0x80001040, 0x00000040, + 0x00401040, 0x80400040, 0x80400000, 0x80001000, + 0x00000000, 0x00401000, 0x00401000, 0x80401040, + 0x80000040, 0x00000000, 0x00400040, 0x80400000, + 0x80000000, 0x00001000, 0x00400000, 0x80401000, + 0x00000040, 0x00400000, 0x80001000, 0x00001040, + 0x80400040, 0x80000000, 0x00001040, 0x00400040, + 0x00001000, 0x00401040, 0x80401040, 0x80000040, + 0x00400040, 0x80400000, 0x00401000, 0x80401040, + 0x80000040, 0x00000000, 0x00000000, 0x00401000, + 0x00001040, 0x00400040, 0x80400040, 0x80000000, + 0x80401000, 0x80001040, 0x80001040, 0x00000040, + 0x80401040, 0x80000040, 0x80000000, 0x00001000, + 0x80400000, 0x80001000, 0x00401040, 0x80400040, + 0x80001000, 0x00001040, 0x00400000, 0x80401000, + 0x00000040, 0x00400000, 0x00001000, 0x00401040 + ); + + /** + * Pre-permuted S-box5 + * + * @var Array + * @access private + */ + var $sbox5 = array( + 0x00000080, 0x01040080, 0x01040000, 0x21000080, + 0x00040000, 0x00000080, 0x20000000, 0x01040000, + 0x20040080, 0x00040000, 0x01000080, 0x20040080, + 0x21000080, 0x21040000, 0x00040080, 0x20000000, + 0x01000000, 0x20040000, 0x20040000, 0x00000000, + 0x20000080, 0x21040080, 0x21040080, 0x01000080, + 0x21040000, 0x20000080, 0x00000000, 0x21000000, + 0x01040080, 0x01000000, 0x21000000, 0x00040080, + 0x00040000, 0x21000080, 0x00000080, 0x01000000, + 0x20000000, 0x01040000, 0x21000080, 0x20040080, + 0x01000080, 0x20000000, 0x21040000, 0x01040080, + 0x20040080, 0x00000080, 0x01000000, 0x21040000, + 0x21040080, 0x00040080, 0x21000000, 0x21040080, + 0x01040000, 0x00000000, 0x20040000, 0x21000000, + 0x00040080, 0x01000080, 0x20000080, 0x00040000, + 0x00000000, 0x20040000, 0x01040080, 0x20000080 + ); + + /** + * Pre-permuted S-box6 + * + * @var Array + * @access private + */ + var $sbox6 = array( + 0x10000008, 0x10200000, 0x00002000, 0x10202008, + 0x10200000, 0x00000008, 0x10202008, 0x00200000, + 0x10002000, 0x00202008, 0x00200000, 0x10000008, + 0x00200008, 0x10002000, 0x10000000, 0x00002008, + 0x00000000, 0x00200008, 0x10002008, 0x00002000, + 0x00202000, 0x10002008, 0x00000008, 0x10200008, + 0x10200008, 0x00000000, 0x00202008, 0x10202000, + 0x00002008, 0x00202000, 0x10202000, 0x10000000, + 0x10002000, 0x00000008, 0x10200008, 0x00202000, + 0x10202008, 0x00200000, 0x00002008, 0x10000008, + 0x00200000, 0x10002000, 0x10000000, 0x00002008, + 0x10000008, 0x10202008, 0x00202000, 0x10200000, + 0x00202008, 0x10202000, 0x00000000, 0x10200008, + 0x00000008, 0x00002000, 0x10200000, 0x00202008, + 0x00002000, 0x00200008, 0x10002008, 0x00000000, + 0x10202000, 0x10000000, 0x00200008, 0x10002008 + ); + + /** + * Pre-permuted S-box7 + * + * @var Array + * @access private + */ + var $sbox7 = array( + 0x00100000, 0x02100001, 0x02000401, 0x00000000, + 0x00000400, 0x02000401, 0x00100401, 0x02100400, + 0x02100401, 0x00100000, 0x00000000, 0x02000001, + 0x00000001, 0x02000000, 0x02100001, 0x00000401, + 0x02000400, 0x00100401, 0x00100001, 0x02000400, + 0x02000001, 0x02100000, 0x02100400, 0x00100001, + 0x02100000, 0x00000400, 0x00000401, 0x02100401, + 0x00100400, 0x00000001, 0x02000000, 0x00100400, + 0x02000000, 0x00100400, 0x00100000, 0x02000401, + 0x02000401, 0x02100001, 0x02100001, 0x00000001, + 0x00100001, 0x02000000, 0x02000400, 0x00100000, + 0x02100400, 0x00000401, 0x00100401, 0x02100400, + 0x00000401, 0x02000001, 0x02100401, 0x02100000, + 0x00100400, 0x00000000, 0x00000001, 0x02100401, + 0x00000000, 0x00100401, 0x02100000, 0x00000400, + 0x02000001, 0x02000400, 0x00000400, 0x00100001 + ); + + /** + * Pre-permuted S-box8 + * + * @var Array + * @access private + */ + var $sbox8 = array( + 0x08000820, 0x00000800, 0x00020000, 0x08020820, + 0x08000000, 0x08000820, 0x00000020, 0x08000000, + 0x00020020, 0x08020000, 0x08020820, 0x00020800, + 0x08020800, 0x00020820, 0x00000800, 0x00000020, + 0x08020000, 0x08000020, 0x08000800, 0x00000820, + 0x00020800, 0x00020020, 0x08020020, 0x08020800, + 0x00000820, 0x00000000, 0x00000000, 0x08020020, + 0x08000020, 0x08000800, 0x00020820, 0x00020000, + 0x00020820, 0x00020000, 0x08020800, 0x00000800, + 0x00000020, 0x08020020, 0x00000800, 0x00020820, + 0x08000800, 0x00000020, 0x08000020, 0x08020000, + 0x08020020, 0x08000000, 0x00020000, 0x08000820, + 0x00000000, 0x08020820, 0x00020020, 0x08000020, + 0x08020000, 0x08000800, 0x08000820, 0x00000000, + 0x08020820, 0x00020800, 0x00020800, 0x00000820, + 0x00000820, 0x00020020, 0x08000000, 0x08020800 + ); /** * Default Constructor. @@ -305,143 +748,6 @@ class Crypt_DES { */ function Crypt_DES($mode = CRYPT_DES_MODE_CBC) { - - /** - * Shuffle table. - * For each byte value index, the entry holds an 8-byte string - * with each byte containing all bits in the same state as the - * corresponding bit in the index value. - */ - static $shuffle = array( - "\x00\x00\x00\x00\x00\x00\x00\x00", "\x00\x00\x00\x00\x00\x00\x00\xFF", - "\x00\x00\x00\x00\x00\x00\xFF\x00", "\x00\x00\x00\x00\x00\x00\xFF\xFF", - "\x00\x00\x00\x00\x00\xFF\x00\x00", "\x00\x00\x00\x00\x00\xFF\x00\xFF", - "\x00\x00\x00\x00\x00\xFF\xFF\x00", "\x00\x00\x00\x00\x00\xFF\xFF\xFF", - "\x00\x00\x00\x00\xFF\x00\x00\x00", "\x00\x00\x00\x00\xFF\x00\x00\xFF", - "\x00\x00\x00\x00\xFF\x00\xFF\x00", "\x00\x00\x00\x00\xFF\x00\xFF\xFF", - "\x00\x00\x00\x00\xFF\xFF\x00\x00", "\x00\x00\x00\x00\xFF\xFF\x00\xFF", - "\x00\x00\x00\x00\xFF\xFF\xFF\x00", "\x00\x00\x00\x00\xFF\xFF\xFF\xFF", - "\x00\x00\x00\xFF\x00\x00\x00\x00", "\x00\x00\x00\xFF\x00\x00\x00\xFF", - "\x00\x00\x00\xFF\x00\x00\xFF\x00", "\x00\x00\x00\xFF\x00\x00\xFF\xFF", - "\x00\x00\x00\xFF\x00\xFF\x00\x00", "\x00\x00\x00\xFF\x00\xFF\x00\xFF", - "\x00\x00\x00\xFF\x00\xFF\xFF\x00", "\x00\x00\x00\xFF\x00\xFF\xFF\xFF", - "\x00\x00\x00\xFF\xFF\x00\x00\x00", "\x00\x00\x00\xFF\xFF\x00\x00\xFF", - "\x00\x00\x00\xFF\xFF\x00\xFF\x00", "\x00\x00\x00\xFF\xFF\x00\xFF\xFF", - "\x00\x00\x00\xFF\xFF\xFF\x00\x00", "\x00\x00\x00\xFF\xFF\xFF\x00\xFF", - "\x00\x00\x00\xFF\xFF\xFF\xFF\x00", "\x00\x00\x00\xFF\xFF\xFF\xFF\xFF", - "\x00\x00\xFF\x00\x00\x00\x00\x00", "\x00\x00\xFF\x00\x00\x00\x00\xFF", - "\x00\x00\xFF\x00\x00\x00\xFF\x00", "\x00\x00\xFF\x00\x00\x00\xFF\xFF", - "\x00\x00\xFF\x00\x00\xFF\x00\x00", "\x00\x00\xFF\x00\x00\xFF\x00\xFF", - "\x00\x00\xFF\x00\x00\xFF\xFF\x00", "\x00\x00\xFF\x00\x00\xFF\xFF\xFF", - "\x00\x00\xFF\x00\xFF\x00\x00\x00", "\x00\x00\xFF\x00\xFF\x00\x00\xFF", - "\x00\x00\xFF\x00\xFF\x00\xFF\x00", "\x00\x00\xFF\x00\xFF\x00\xFF\xFF", - "\x00\x00\xFF\x00\xFF\xFF\x00\x00", "\x00\x00\xFF\x00\xFF\xFF\x00\xFF", - "\x00\x00\xFF\x00\xFF\xFF\xFF\x00", "\x00\x00\xFF\x00\xFF\xFF\xFF\xFF", - "\x00\x00\xFF\xFF\x00\x00\x00\x00", "\x00\x00\xFF\xFF\x00\x00\x00\xFF", - "\x00\x00\xFF\xFF\x00\x00\xFF\x00", "\x00\x00\xFF\xFF\x00\x00\xFF\xFF", - "\x00\x00\xFF\xFF\x00\xFF\x00\x00", "\x00\x00\xFF\xFF\x00\xFF\x00\xFF", - "\x00\x00\xFF\xFF\x00\xFF\xFF\x00", "\x00\x00\xFF\xFF\x00\xFF\xFF\xFF", - "\x00\x00\xFF\xFF\xFF\x00\x00\x00", "\x00\x00\xFF\xFF\xFF\x00\x00\xFF", - "\x00\x00\xFF\xFF\xFF\x00\xFF\x00", "\x00\x00\xFF\xFF\xFF\x00\xFF\xFF", - "\x00\x00\xFF\xFF\xFF\xFF\x00\x00", "\x00\x00\xFF\xFF\xFF\xFF\x00\xFF", - "\x00\x00\xFF\xFF\xFF\xFF\xFF\x00", "\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF", - "\x00\xFF\x00\x00\x00\x00\x00\x00", "\x00\xFF\x00\x00\x00\x00\x00\xFF", - "\x00\xFF\x00\x00\x00\x00\xFF\x00", "\x00\xFF\x00\x00\x00\x00\xFF\xFF", - "\x00\xFF\x00\x00\x00\xFF\x00\x00", "\x00\xFF\x00\x00\x00\xFF\x00\xFF", - "\x00\xFF\x00\x00\x00\xFF\xFF\x00", "\x00\xFF\x00\x00\x00\xFF\xFF\xFF", - "\x00\xFF\x00\x00\xFF\x00\x00\x00", "\x00\xFF\x00\x00\xFF\x00\x00\xFF", - "\x00\xFF\x00\x00\xFF\x00\xFF\x00", "\x00\xFF\x00\x00\xFF\x00\xFF\xFF", - "\x00\xFF\x00\x00\xFF\xFF\x00\x00", "\x00\xFF\x00\x00\xFF\xFF\x00\xFF", - "\x00\xFF\x00\x00\xFF\xFF\xFF\x00", "\x00\xFF\x00\x00\xFF\xFF\xFF\xFF", - "\x00\xFF\x00\xFF\x00\x00\x00\x00", "\x00\xFF\x00\xFF\x00\x00\x00\xFF", - "\x00\xFF\x00\xFF\x00\x00\xFF\x00", "\x00\xFF\x00\xFF\x00\x00\xFF\xFF", - "\x00\xFF\x00\xFF\x00\xFF\x00\x00", "\x00\xFF\x00\xFF\x00\xFF\x00\xFF", - "\x00\xFF\x00\xFF\x00\xFF\xFF\x00", "\x00\xFF\x00\xFF\x00\xFF\xFF\xFF", - "\x00\xFF\x00\xFF\xFF\x00\x00\x00", "\x00\xFF\x00\xFF\xFF\x00\x00\xFF", - "\x00\xFF\x00\xFF\xFF\x00\xFF\x00", "\x00\xFF\x00\xFF\xFF\x00\xFF\xFF", - "\x00\xFF\x00\xFF\xFF\xFF\x00\x00", "\x00\xFF\x00\xFF\xFF\xFF\x00\xFF", - "\x00\xFF\x00\xFF\xFF\xFF\xFF\x00", "\x00\xFF\x00\xFF\xFF\xFF\xFF\xFF", - "\x00\xFF\xFF\x00\x00\x00\x00\x00", "\x00\xFF\xFF\x00\x00\x00\x00\xFF", - "\x00\xFF\xFF\x00\x00\x00\xFF\x00", "\x00\xFF\xFF\x00\x00\x00\xFF\xFF", - "\x00\xFF\xFF\x00\x00\xFF\x00\x00", "\x00\xFF\xFF\x00\x00\xFF\x00\xFF", - "\x00\xFF\xFF\x00\x00\xFF\xFF\x00", "\x00\xFF\xFF\x00\x00\xFF\xFF\xFF", - "\x00\xFF\xFF\x00\xFF\x00\x00\x00", "\x00\xFF\xFF\x00\xFF\x00\x00\xFF", - "\x00\xFF\xFF\x00\xFF\x00\xFF\x00", "\x00\xFF\xFF\x00\xFF\x00\xFF\xFF", - "\x00\xFF\xFF\x00\xFF\xFF\x00\x00", "\x00\xFF\xFF\x00\xFF\xFF\x00\xFF", - "\x00\xFF\xFF\x00\xFF\xFF\xFF\x00", "\x00\xFF\xFF\x00\xFF\xFF\xFF\xFF", - "\x00\xFF\xFF\xFF\x00\x00\x00\x00", "\x00\xFF\xFF\xFF\x00\x00\x00\xFF", - "\x00\xFF\xFF\xFF\x00\x00\xFF\x00", "\x00\xFF\xFF\xFF\x00\x00\xFF\xFF", - "\x00\xFF\xFF\xFF\x00\xFF\x00\x00", "\x00\xFF\xFF\xFF\x00\xFF\x00\xFF", - "\x00\xFF\xFF\xFF\x00\xFF\xFF\x00", "\x00\xFF\xFF\xFF\x00\xFF\xFF\xFF", - "\x00\xFF\xFF\xFF\xFF\x00\x00\x00", "\x00\xFF\xFF\xFF\xFF\x00\x00\xFF", - "\x00\xFF\xFF\xFF\xFF\x00\xFF\x00", "\x00\xFF\xFF\xFF\xFF\x00\xFF\xFF", - "\x00\xFF\xFF\xFF\xFF\xFF\x00\x00", "\x00\xFF\xFF\xFF\xFF\xFF\x00\xFF", - "\x00\xFF\xFF\xFF\xFF\xFF\xFF\x00", "\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF", - "\xFF\x00\x00\x00\x00\x00\x00\x00", "\xFF\x00\x00\x00\x00\x00\x00\xFF", - "\xFF\x00\x00\x00\x00\x00\xFF\x00", "\xFF\x00\x00\x00\x00\x00\xFF\xFF", - "\xFF\x00\x00\x00\x00\xFF\x00\x00", "\xFF\x00\x00\x00\x00\xFF\x00\xFF", - "\xFF\x00\x00\x00\x00\xFF\xFF\x00", "\xFF\x00\x00\x00\x00\xFF\xFF\xFF", - "\xFF\x00\x00\x00\xFF\x00\x00\x00", "\xFF\x00\x00\x00\xFF\x00\x00\xFF", - "\xFF\x00\x00\x00\xFF\x00\xFF\x00", "\xFF\x00\x00\x00\xFF\x00\xFF\xFF", - "\xFF\x00\x00\x00\xFF\xFF\x00\x00", "\xFF\x00\x00\x00\xFF\xFF\x00\xFF", - "\xFF\x00\x00\x00\xFF\xFF\xFF\x00", "\xFF\x00\x00\x00\xFF\xFF\xFF\xFF", - "\xFF\x00\x00\xFF\x00\x00\x00\x00", "\xFF\x00\x00\xFF\x00\x00\x00\xFF", - "\xFF\x00\x00\xFF\x00\x00\xFF\x00", "\xFF\x00\x00\xFF\x00\x00\xFF\xFF", - "\xFF\x00\x00\xFF\x00\xFF\x00\x00", "\xFF\x00\x00\xFF\x00\xFF\x00\xFF", - "\xFF\x00\x00\xFF\x00\xFF\xFF\x00", "\xFF\x00\x00\xFF\x00\xFF\xFF\xFF", - "\xFF\x00\x00\xFF\xFF\x00\x00\x00", "\xFF\x00\x00\xFF\xFF\x00\x00\xFF", - "\xFF\x00\x00\xFF\xFF\x00\xFF\x00", "\xFF\x00\x00\xFF\xFF\x00\xFF\xFF", - "\xFF\x00\x00\xFF\xFF\xFF\x00\x00", "\xFF\x00\x00\xFF\xFF\xFF\x00\xFF", - "\xFF\x00\x00\xFF\xFF\xFF\xFF\x00", "\xFF\x00\x00\xFF\xFF\xFF\xFF\xFF", - "\xFF\x00\xFF\x00\x00\x00\x00\x00", "\xFF\x00\xFF\x00\x00\x00\x00\xFF", - "\xFF\x00\xFF\x00\x00\x00\xFF\x00", "\xFF\x00\xFF\x00\x00\x00\xFF\xFF", - "\xFF\x00\xFF\x00\x00\xFF\x00\x00", "\xFF\x00\xFF\x00\x00\xFF\x00\xFF", - "\xFF\x00\xFF\x00\x00\xFF\xFF\x00", "\xFF\x00\xFF\x00\x00\xFF\xFF\xFF", - "\xFF\x00\xFF\x00\xFF\x00\x00\x00", "\xFF\x00\xFF\x00\xFF\x00\x00\xFF", - "\xFF\x00\xFF\x00\xFF\x00\xFF\x00", "\xFF\x00\xFF\x00\xFF\x00\xFF\xFF", - "\xFF\x00\xFF\x00\xFF\xFF\x00\x00", "\xFF\x00\xFF\x00\xFF\xFF\x00\xFF", - "\xFF\x00\xFF\x00\xFF\xFF\xFF\x00", "\xFF\x00\xFF\x00\xFF\xFF\xFF\xFF", - "\xFF\x00\xFF\xFF\x00\x00\x00\x00", "\xFF\x00\xFF\xFF\x00\x00\x00\xFF", - "\xFF\x00\xFF\xFF\x00\x00\xFF\x00", "\xFF\x00\xFF\xFF\x00\x00\xFF\xFF", - "\xFF\x00\xFF\xFF\x00\xFF\x00\x00", "\xFF\x00\xFF\xFF\x00\xFF\x00\xFF", - "\xFF\x00\xFF\xFF\x00\xFF\xFF\x00", "\xFF\x00\xFF\xFF\x00\xFF\xFF\xFF", - "\xFF\x00\xFF\xFF\xFF\x00\x00\x00", "\xFF\x00\xFF\xFF\xFF\x00\x00\xFF", - "\xFF\x00\xFF\xFF\xFF\x00\xFF\x00", "\xFF\x00\xFF\xFF\xFF\x00\xFF\xFF", - "\xFF\x00\xFF\xFF\xFF\xFF\x00\x00", "\xFF\x00\xFF\xFF\xFF\xFF\x00\xFF", - "\xFF\x00\xFF\xFF\xFF\xFF\xFF\x00", "\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF", - "\xFF\xFF\x00\x00\x00\x00\x00\x00", "\xFF\xFF\x00\x00\x00\x00\x00\xFF", - "\xFF\xFF\x00\x00\x00\x00\xFF\x00", "\xFF\xFF\x00\x00\x00\x00\xFF\xFF", - "\xFF\xFF\x00\x00\x00\xFF\x00\x00", "\xFF\xFF\x00\x00\x00\xFF\x00\xFF", - "\xFF\xFF\x00\x00\x00\xFF\xFF\x00", "\xFF\xFF\x00\x00\x00\xFF\xFF\xFF", - "\xFF\xFF\x00\x00\xFF\x00\x00\x00", "\xFF\xFF\x00\x00\xFF\x00\x00\xFF", - "\xFF\xFF\x00\x00\xFF\x00\xFF\x00", "\xFF\xFF\x00\x00\xFF\x00\xFF\xFF", - "\xFF\xFF\x00\x00\xFF\xFF\x00\x00", "\xFF\xFF\x00\x00\xFF\xFF\x00\xFF", - "\xFF\xFF\x00\x00\xFF\xFF\xFF\x00", "\xFF\xFF\x00\x00\xFF\xFF\xFF\xFF", - "\xFF\xFF\x00\xFF\x00\x00\x00\x00", "\xFF\xFF\x00\xFF\x00\x00\x00\xFF", - "\xFF\xFF\x00\xFF\x00\x00\xFF\x00", "\xFF\xFF\x00\xFF\x00\x00\xFF\xFF", - "\xFF\xFF\x00\xFF\x00\xFF\x00\x00", "\xFF\xFF\x00\xFF\x00\xFF\x00\xFF", - "\xFF\xFF\x00\xFF\x00\xFF\xFF\x00", "\xFF\xFF\x00\xFF\x00\xFF\xFF\xFF", - "\xFF\xFF\x00\xFF\xFF\x00\x00\x00", "\xFF\xFF\x00\xFF\xFF\x00\x00\xFF", - "\xFF\xFF\x00\xFF\xFF\x00\xFF\x00", "\xFF\xFF\x00\xFF\xFF\x00\xFF\xFF", - "\xFF\xFF\x00\xFF\xFF\xFF\x00\x00", "\xFF\xFF\x00\xFF\xFF\xFF\x00\xFF", - "\xFF\xFF\x00\xFF\xFF\xFF\xFF\x00", "\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF", - "\xFF\xFF\xFF\x00\x00\x00\x00\x00", "\xFF\xFF\xFF\x00\x00\x00\x00\xFF", - "\xFF\xFF\xFF\x00\x00\x00\xFF\x00", "\xFF\xFF\xFF\x00\x00\x00\xFF\xFF", - "\xFF\xFF\xFF\x00\x00\xFF\x00\x00", "\xFF\xFF\xFF\x00\x00\xFF\x00\xFF", - "\xFF\xFF\xFF\x00\x00\xFF\xFF\x00", "\xFF\xFF\xFF\x00\x00\xFF\xFF\xFF", - "\xFF\xFF\xFF\x00\xFF\x00\x00\x00", "\xFF\xFF\xFF\x00\xFF\x00\x00\xFF", - "\xFF\xFF\xFF\x00\xFF\x00\xFF\x00", "\xFF\xFF\xFF\x00\xFF\x00\xFF\xFF", - "\xFF\xFF\xFF\x00\xFF\xFF\x00\x00", "\xFF\xFF\xFF\x00\xFF\xFF\x00\xFF", - "\xFF\xFF\xFF\x00\xFF\xFF\xFF\x00", "\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF", - "\xFF\xFF\xFF\xFF\x00\x00\x00\x00", "\xFF\xFF\xFF\xFF\x00\x00\x00\xFF", - "\xFF\xFF\xFF\xFF\x00\x00\xFF\x00", "\xFF\xFF\xFF\xFF\x00\x00\xFF\xFF", - "\xFF\xFF\xFF\xFF\x00\xFF\x00\x00", "\xFF\xFF\xFF\xFF\x00\xFF\x00\xFF", - "\xFF\xFF\xFF\xFF\x00\xFF\xFF\x00", "\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF", - "\xFF\xFF\xFF\xFF\xFF\x00\x00\x00", "\xFF\xFF\xFF\xFF\xFF\x00\x00\xFF", - "\xFF\xFF\xFF\xFF\xFF\x00\xFF\x00", "\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF", - "\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00", "\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF", - "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00", "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" - ); if ( !defined('CRYPT_DES_MODE') ) { switch (true) { case extension_loaded('mcrypt') && in_array('des', mcrypt_list_algorithms()): @@ -480,7 +786,6 @@ class Crypt_DES { break; default: - $this->shuffle = $shuffle; switch ($mode) { case CRYPT_DES_MODE_ECB: case CRYPT_DES_MODE_CBC: @@ -496,6 +801,10 @@ class Crypt_DES { $this->paddable = true; $this->mode = CRYPT_DES_MODE_CBC; } + if (function_exists('create_function') && is_callable('create_function')) { + $this->inline_crypt_setup(); + $this->use_inline_crypt = true; + } } } @@ -717,6 +1026,11 @@ class Crypt_DES { $this->keys = $this->_prepareKey("\0\0\0\0\0\0\0\0"); } + if ($this->use_inline_crypt) { + $inline = $this->inline_crypt; + return $inline('encrypt', $this, $plaintext); + } + $buffer = &$this->enbuffer; $continuousBuffer = $this->continuousBuffer; $ciphertext = ''; @@ -746,7 +1060,7 @@ class Crypt_DES { if (strlen($block) > strlen($buffer['encrypted'])) { $buffer['encrypted'].= $this->_processBlock($this->_generate_xor($xor), CRYPT_DES_ENCRYPT); } - $key = $this->_string_shift($buffer['encrypted'], 8); + $key = $this->_string_shift($buffer['encrypted']); $ciphertext.= $block ^ $key; } } else { @@ -811,7 +1125,7 @@ class Crypt_DES { $xor = $this->_processBlock($xor, CRYPT_DES_ENCRYPT); $buffer['xor'].= $xor; } - $key = $this->_string_shift($buffer['xor'], 8); + $key = $this->_string_shift($buffer['xor']); $ciphertext.= $block ^ $key; } } else { @@ -907,6 +1221,11 @@ class Crypt_DES { $this->keys = $this->_prepareKey("\0\0\0\0\0\0\0\0"); } + if ($this->use_inline_crypt) { + $inline = $this->inline_crypt; + return $inline('decrypt', $this, $ciphertext); + } + $buffer = &$this->debuffer; $continuousBuffer = $this->continuousBuffer; $plaintext = ''; @@ -935,7 +1254,7 @@ class Crypt_DES { if (strlen($block) > strlen($buffer['ciphertext'])) { $buffer['ciphertext'].= $this->_processBlock($this->_generate_xor($xor), CRYPT_DES_ENCRYPT); } - $key = $this->_string_shift($buffer['ciphertext'], 8); + $key = $this->_string_shift($buffer['ciphertext']); $plaintext.= $block ^ $key; } } else { @@ -1001,7 +1320,7 @@ class Crypt_DES { $xor = $this->_processBlock($xor, CRYPT_DES_ENCRYPT); $buffer['xor'].= $xor; } - $key = $this->_string_shift($buffer['xor'], 8); + $key = $this->_string_shift($buffer['xor']); $plaintext.= $block ^ $key; } } else { @@ -1183,242 +1502,30 @@ class Crypt_DES { */ function _processBlock($block, $mode) { - // IP mapping helper table. - // Indexing this table with each source byte performs the initial bit - // permutation. - static $ipmap = array( - 0x00, 0x10, 0x01, 0x11, 0x20, 0x30, 0x21, 0x31, - 0x02, 0x12, 0x03, 0x13, 0x22, 0x32, 0x23, 0x33, - 0x40, 0x50, 0x41, 0x51, 0x60, 0x70, 0x61, 0x71, - 0x42, 0x52, 0x43, 0x53, 0x62, 0x72, 0x63, 0x73, - 0x04, 0x14, 0x05, 0x15, 0x24, 0x34, 0x25, 0x35, - 0x06, 0x16, 0x07, 0x17, 0x26, 0x36, 0x27, 0x37, - 0x44, 0x54, 0x45, 0x55, 0x64, 0x74, 0x65, 0x75, - 0x46, 0x56, 0x47, 0x57, 0x66, 0x76, 0x67, 0x77, - 0x80, 0x90, 0x81, 0x91, 0xA0, 0xB0, 0xA1, 0xB1, - 0x82, 0x92, 0x83, 0x93, 0xA2, 0xB2, 0xA3, 0xB3, - 0xC0, 0xD0, 0xC1, 0xD1, 0xE0, 0xF0, 0xE1, 0xF1, - 0xC2, 0xD2, 0xC3, 0xD3, 0xE2, 0xF2, 0xE3, 0xF3, - 0x84, 0x94, 0x85, 0x95, 0xA4, 0xB4, 0xA5, 0xB5, - 0x86, 0x96, 0x87, 0x97, 0xA6, 0xB6, 0xA7, 0xB7, - 0xC4, 0xD4, 0xC5, 0xD5, 0xE4, 0xF4, 0xE5, 0xF5, - 0xC6, 0xD6, 0xC7, 0xD7, 0xE6, 0xF6, 0xE7, 0xF7, - 0x08, 0x18, 0x09, 0x19, 0x28, 0x38, 0x29, 0x39, - 0x0A, 0x1A, 0x0B, 0x1B, 0x2A, 0x3A, 0x2B, 0x3B, - 0x48, 0x58, 0x49, 0x59, 0x68, 0x78, 0x69, 0x79, - 0x4A, 0x5A, 0x4B, 0x5B, 0x6A, 0x7A, 0x6B, 0x7B, - 0x0C, 0x1C, 0x0D, 0x1D, 0x2C, 0x3C, 0x2D, 0x3D, - 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, - 0x4C, 0x5C, 0x4D, 0x5D, 0x6C, 0x7C, 0x6D, 0x7D, - 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, - 0x88, 0x98, 0x89, 0x99, 0xA8, 0xB8, 0xA9, 0xB9, - 0x8A, 0x9A, 0x8B, 0x9B, 0xAA, 0xBA, 0xAB, 0xBB, - 0xC8, 0xD8, 0xC9, 0xD9, 0xE8, 0xF8, 0xE9, 0xF9, - 0xCA, 0xDA, 0xCB, 0xDB, 0xEA, 0xFA, 0xEB, 0xFB, - 0x8C, 0x9C, 0x8D, 0x9D, 0xAC, 0xBC, 0xAD, 0xBD, - 0x8E, 0x9E, 0x8F, 0x9F, 0xAE, 0xBE, 0xAF, 0xBF, - 0xCC, 0xDC, 0xCD, 0xDD, 0xEC, 0xFC, 0xED, 0xFD, - 0xCE, 0xDE, 0xCF, 0xDF, 0xEE, 0xFE, 0xEF, 0xFF - ); - - // Inverse IP mapping helper table. - // Indexing this table with a byte value reverses the bit order. - static $invipmap = array( - 0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0, - 0x10, 0x90, 0x50, 0xD0, 0x30, 0xB0, 0x70, 0xF0, - 0x08, 0x88, 0x48, 0xC8, 0x28, 0xA8, 0x68, 0xE8, - 0x18, 0x98, 0x58, 0xD8, 0x38, 0xB8, 0x78, 0xF8, - 0x04, 0x84, 0x44, 0xC4, 0x24, 0xA4, 0x64, 0xE4, - 0x14, 0x94, 0x54, 0xD4, 0x34, 0xB4, 0x74, 0xF4, - 0x0C, 0x8C, 0x4C, 0xCC, 0x2C, 0xAC, 0x6C, 0xEC, - 0x1C, 0x9C, 0x5C, 0xDC, 0x3C, 0xBC, 0x7C, 0xFC, - 0x02, 0x82, 0x42, 0xC2, 0x22, 0xA2, 0x62, 0xE2, - 0x12, 0x92, 0x52, 0xD2, 0x32, 0xB2, 0x72, 0xF2, - 0x0A, 0x8A, 0x4A, 0xCA, 0x2A, 0xAA, 0x6A, 0xEA, - 0x1A, 0x9A, 0x5A, 0xDA, 0x3A, 0xBA, 0x7A, 0xFA, - 0x06, 0x86, 0x46, 0xC6, 0x26, 0xA6, 0x66, 0xE6, - 0x16, 0x96, 0x56, 0xD6, 0x36, 0xB6, 0x76, 0xF6, - 0x0E, 0x8E, 0x4E, 0xCE, 0x2E, 0xAE, 0x6E, 0xEE, - 0x1E, 0x9E, 0x5E, 0xDE, 0x3E, 0xBE, 0x7E, 0xFE, - 0x01, 0x81, 0x41, 0xC1, 0x21, 0xA1, 0x61, 0xE1, - 0x11, 0x91, 0x51, 0xD1, 0x31, 0xB1, 0x71, 0xF1, - 0x09, 0x89, 0x49, 0xC9, 0x29, 0xA9, 0x69, 0xE9, - 0x19, 0x99, 0x59, 0xD9, 0x39, 0xB9, 0x79, 0xF9, - 0x05, 0x85, 0x45, 0xC5, 0x25, 0xA5, 0x65, 0xE5, - 0x15, 0x95, 0x55, 0xD5, 0x35, 0xB5, 0x75, 0xF5, - 0x0D, 0x8D, 0x4D, 0xCD, 0x2D, 0xAD, 0x6D, 0xED, - 0x1D, 0x9D, 0x5D, 0xDD, 0x3D, 0xBD, 0x7D, 0xFD, - 0x03, 0x83, 0x43, 0xC3, 0x23, 0xA3, 0x63, 0xE3, - 0x13, 0x93, 0x53, 0xD3, 0x33, 0xB3, 0x73, 0xF3, - 0x0B, 0x8B, 0x4B, 0xCB, 0x2B, 0xAB, 0x6B, 0xEB, - 0x1B, 0x9B, 0x5B, 0xDB, 0x3B, 0xBB, 0x7B, 0xFB, - 0x07, 0x87, 0x47, 0xC7, 0x27, 0xA7, 0x67, 0xE7, - 0x17, 0x97, 0x57, 0xD7, 0x37, 0xB7, 0x77, 0xF7, - 0x0F, 0x8F, 0x4F, 0xCF, 0x2F, 0xAF, 0x6F, 0xEF, - 0x1F, 0x9F, 0x5F, 0xDF, 0x3F, 0xBF, 0x7F, 0xFF - ); - - // Pre-permuted S-boxes. - // Each box has been vectorized, then each value pre-permuted using the - // P table: concatenation can then be replaced by exclusive ORs. - static $sbox1 = array( - 0x00808200, 0x00000000, 0x00008000, 0x00808202, - 0x00808002, 0x00008202, 0x00000002, 0x00008000, - 0x00000200, 0x00808200, 0x00808202, 0x00000200, - 0x00800202, 0x00808002, 0x00800000, 0x00000002, - 0x00000202, 0x00800200, 0x00800200, 0x00008200, - 0x00008200, 0x00808000, 0x00808000, 0x00800202, - 0x00008002, 0x00800002, 0x00800002, 0x00008002, - 0x00000000, 0x00000202, 0x00008202, 0x00800000, - 0x00008000, 0x00808202, 0x00000002, 0x00808000, - 0x00808200, 0x00800000, 0x00800000, 0x00000200, - 0x00808002, 0x00008000, 0x00008200, 0x00800002, - 0x00000200, 0x00000002, 0x00800202, 0x00008202, - 0x00808202, 0x00008002, 0x00808000, 0x00800202, - 0x00800002, 0x00000202, 0x00008202, 0x00808200, - 0x00000202, 0x00800200, 0x00800200, 0x00000000, - 0x00008002, 0x00008200, 0x00000000, 0x00808002 - ); - static $sbox2 = array( - 0x40084010, 0x40004000, 0x00004000, 0x00084010, - 0x00080000, 0x00000010, 0x40080010, 0x40004010, - 0x40000010, 0x40084010, 0x40084000, 0x40000000, - 0x40004000, 0x00080000, 0x00000010, 0x40080010, - 0x00084000, 0x00080010, 0x40004010, 0x00000000, - 0x40000000, 0x00004000, 0x00084010, 0x40080000, - 0x00080010, 0x40000010, 0x00000000, 0x00084000, - 0x00004010, 0x40084000, 0x40080000, 0x00004010, - 0x00000000, 0x00084010, 0x40080010, 0x00080000, - 0x40004010, 0x40080000, 0x40084000, 0x00004000, - 0x40080000, 0x40004000, 0x00000010, 0x40084010, - 0x00084010, 0x00000010, 0x00004000, 0x40000000, - 0x00004010, 0x40084000, 0x00080000, 0x40000010, - 0x00080010, 0x40004010, 0x40000010, 0x00080010, - 0x00084000, 0x00000000, 0x40004000, 0x00004010, - 0x40000000, 0x40080010, 0x40084010, 0x00084000 - ); - static $sbox3 = array( - 0x00000104, 0x04010100, 0x00000000, 0x04010004, - 0x04000100, 0x00000000, 0x00010104, 0x04000100, - 0x00010004, 0x04000004, 0x04000004, 0x00010000, - 0x04010104, 0x00010004, 0x04010000, 0x00000104, - 0x04000000, 0x00000004, 0x04010100, 0x00000100, - 0x00010100, 0x04010000, 0x04010004, 0x00010104, - 0x04000104, 0x00010100, 0x00010000, 0x04000104, - 0x00000004, 0x04010104, 0x00000100, 0x04000000, - 0x04010100, 0x04000000, 0x00010004, 0x00000104, - 0x00010000, 0x04010100, 0x04000100, 0x00000000, - 0x00000100, 0x00010004, 0x04010104, 0x04000100, - 0x04000004, 0x00000100, 0x00000000, 0x04010004, - 0x04000104, 0x00010000, 0x04000000, 0x04010104, - 0x00000004, 0x00010104, 0x00010100, 0x04000004, - 0x04010000, 0x04000104, 0x00000104, 0x04010000, - 0x00010104, 0x00000004, 0x04010004, 0x00010100 - ); - static $sbox4 = array( - 0x80401000, 0x80001040, 0x80001040, 0x00000040, - 0x00401040, 0x80400040, 0x80400000, 0x80001000, - 0x00000000, 0x00401000, 0x00401000, 0x80401040, - 0x80000040, 0x00000000, 0x00400040, 0x80400000, - 0x80000000, 0x00001000, 0x00400000, 0x80401000, - 0x00000040, 0x00400000, 0x80001000, 0x00001040, - 0x80400040, 0x80000000, 0x00001040, 0x00400040, - 0x00001000, 0x00401040, 0x80401040, 0x80000040, - 0x00400040, 0x80400000, 0x00401000, 0x80401040, - 0x80000040, 0x00000000, 0x00000000, 0x00401000, - 0x00001040, 0x00400040, 0x80400040, 0x80000000, - 0x80401000, 0x80001040, 0x80001040, 0x00000040, - 0x80401040, 0x80000040, 0x80000000, 0x00001000, - 0x80400000, 0x80001000, 0x00401040, 0x80400040, - 0x80001000, 0x00001040, 0x00400000, 0x80401000, - 0x00000040, 0x00400000, 0x00001000, 0x00401040 - ); - static $sbox5 = array( - 0x00000080, 0x01040080, 0x01040000, 0x21000080, - 0x00040000, 0x00000080, 0x20000000, 0x01040000, - 0x20040080, 0x00040000, 0x01000080, 0x20040080, - 0x21000080, 0x21040000, 0x00040080, 0x20000000, - 0x01000000, 0x20040000, 0x20040000, 0x00000000, - 0x20000080, 0x21040080, 0x21040080, 0x01000080, - 0x21040000, 0x20000080, 0x00000000, 0x21000000, - 0x01040080, 0x01000000, 0x21000000, 0x00040080, - 0x00040000, 0x21000080, 0x00000080, 0x01000000, - 0x20000000, 0x01040000, 0x21000080, 0x20040080, - 0x01000080, 0x20000000, 0x21040000, 0x01040080, - 0x20040080, 0x00000080, 0x01000000, 0x21040000, - 0x21040080, 0x00040080, 0x21000000, 0x21040080, - 0x01040000, 0x00000000, 0x20040000, 0x21000000, - 0x00040080, 0x01000080, 0x20000080, 0x00040000, - 0x00000000, 0x20040000, 0x01040080, 0x20000080 - ); - static $sbox6 = array( - 0x10000008, 0x10200000, 0x00002000, 0x10202008, - 0x10200000, 0x00000008, 0x10202008, 0x00200000, - 0x10002000, 0x00202008, 0x00200000, 0x10000008, - 0x00200008, 0x10002000, 0x10000000, 0x00002008, - 0x00000000, 0x00200008, 0x10002008, 0x00002000, - 0x00202000, 0x10002008, 0x00000008, 0x10200008, - 0x10200008, 0x00000000, 0x00202008, 0x10202000, - 0x00002008, 0x00202000, 0x10202000, 0x10000000, - 0x10002000, 0x00000008, 0x10200008, 0x00202000, - 0x10202008, 0x00200000, 0x00002008, 0x10000008, - 0x00200000, 0x10002000, 0x10000000, 0x00002008, - 0x10000008, 0x10202008, 0x00202000, 0x10200000, - 0x00202008, 0x10202000, 0x00000000, 0x10200008, - 0x00000008, 0x00002000, 0x10200000, 0x00202008, - 0x00002000, 0x00200008, 0x10002008, 0x00000000, - 0x10202000, 0x10000000, 0x00200008, 0x10002008 - ); - static $sbox7 = array( - 0x00100000, 0x02100001, 0x02000401, 0x00000000, - 0x00000400, 0x02000401, 0x00100401, 0x02100400, - 0x02100401, 0x00100000, 0x00000000, 0x02000001, - 0x00000001, 0x02000000, 0x02100001, 0x00000401, - 0x02000400, 0x00100401, 0x00100001, 0x02000400, - 0x02000001, 0x02100000, 0x02100400, 0x00100001, - 0x02100000, 0x00000400, 0x00000401, 0x02100401, - 0x00100400, 0x00000001, 0x02000000, 0x00100400, - 0x02000000, 0x00100400, 0x00100000, 0x02000401, - 0x02000401, 0x02100001, 0x02100001, 0x00000001, - 0x00100001, 0x02000000, 0x02000400, 0x00100000, - 0x02100400, 0x00000401, 0x00100401, 0x02100400, - 0x00000401, 0x02000001, 0x02100401, 0x02100000, - 0x00100400, 0x00000000, 0x00000001, 0x02100401, - 0x00000000, 0x00100401, 0x02100000, 0x00000400, - 0x02000001, 0x02000400, 0x00000400, 0x00100001 - ); - static $sbox8 = array( - 0x08000820, 0x00000800, 0x00020000, 0x08020820, - 0x08000000, 0x08000820, 0x00000020, 0x08000000, - 0x00020020, 0x08020000, 0x08020820, 0x00020800, - 0x08020800, 0x00020820, 0x00000800, 0x00000020, - 0x08020000, 0x08000020, 0x08000800, 0x00000820, - 0x00020800, 0x00020020, 0x08020020, 0x08020800, - 0x00000820, 0x00000000, 0x00000000, 0x08020020, - 0x08000020, 0x08000800, 0x00020820, 0x00020000, - 0x00020820, 0x00020000, 0x08020800, 0x00000800, - 0x00000020, 0x08020020, 0x00000800, 0x00020820, - 0x08000800, 0x00000020, 0x08000020, 0x08020000, - 0x08020020, 0x08000000, 0x00020000, 0x08000820, - 0x00000000, 0x08020820, 0x00020020, 0x08000020, - 0x08020000, 0x08000800, 0x08000820, 0x00000000, - 0x08020820, 0x00020800, 0x00020800, 0x00000820, - 0x00000820, 0x00020020, 0x08000000, 0x08020800 - ); - - $keys = $this->keys[$mode]; + $shuffle = $this->shuffle; + $invipmap = $this->invipmap; + $ipmap = $this->ipmap; + $sbox1 = $this->sbox1; + $sbox2 = $this->sbox2; + $sbox3 = $this->sbox3; + $sbox4 = $this->sbox4; + $sbox5 = $this->sbox5; + $sbox6 = $this->sbox6; + $sbox7 = $this->sbox7; + $sbox8 = $this->sbox8; + $keys = $this->keys[$mode]; // Do the initial IP permutation. $t = unpack('Nl/Nr', $block); list($l, $r) = array($t['l'], $t['r']); - $block = ($this->shuffle[$ipmap[$r & 0xFF]] & "\x80\x80\x80\x80\x80\x80\x80\x80") | - ($this->shuffle[$ipmap[($r >> 8) & 0xFF]] & "\x40\x40\x40\x40\x40\x40\x40\x40") | - ($this->shuffle[$ipmap[($r >> 16) & 0xFF]] & "\x20\x20\x20\x20\x20\x20\x20\x20") | - ($this->shuffle[$ipmap[($r >> 24) & 0xFF]] & "\x10\x10\x10\x10\x10\x10\x10\x10") | - ($this->shuffle[$ipmap[$l & 0xFF]] & "\x08\x08\x08\x08\x08\x08\x08\x08") | - ($this->shuffle[$ipmap[($l >> 8) & 0xFF]] & "\x04\x04\x04\x04\x04\x04\x04\x04") | - ($this->shuffle[$ipmap[($l >> 16) & 0xFF]] & "\x02\x02\x02\x02\x02\x02\x02\x02") | - ($this->shuffle[$ipmap[($l >> 24) & 0xFF]] & "\x01\x01\x01\x01\x01\x01\x01\x01"); + $block = ($shuffle[$ipmap[$r & 0xFF]] & "\x80\x80\x80\x80\x80\x80\x80\x80") | + ($shuffle[$ipmap[($r >> 8) & 0xFF]] & "\x40\x40\x40\x40\x40\x40\x40\x40") | + ($shuffle[$ipmap[($r >> 16) & 0xFF]] & "\x20\x20\x20\x20\x20\x20\x20\x20") | + ($shuffle[$ipmap[($r >> 24) & 0xFF]] & "\x10\x10\x10\x10\x10\x10\x10\x10") | + ($shuffle[$ipmap[$l & 0xFF]] & "\x08\x08\x08\x08\x08\x08\x08\x08") | + ($shuffle[$ipmap[($l >> 8) & 0xFF]] & "\x04\x04\x04\x04\x04\x04\x04\x04") | + ($shuffle[$ipmap[($l >> 16) & 0xFF]] & "\x02\x02\x02\x02\x02\x02\x02\x02") | + ($shuffle[$ipmap[($l >> 24) & 0xFF]] & "\x01\x01\x01\x01\x01\x01\x01\x01"); // Extract L0 and R0. $t = unpack('Nl/Nr', $block); @@ -1444,14 +1551,14 @@ class Crypt_DES { } // Perform the inverse IP permutation. - return ($this->shuffle[$invipmap[($l >> 24) & 0xFF]] & "\x80\x80\x80\x80\x80\x80\x80\x80") | - ($this->shuffle[$invipmap[($r >> 24) & 0xFF]] & "\x40\x40\x40\x40\x40\x40\x40\x40") | - ($this->shuffle[$invipmap[($l >> 16) & 0xFF]] & "\x20\x20\x20\x20\x20\x20\x20\x20") | - ($this->shuffle[$invipmap[($r >> 16) & 0xFF]] & "\x10\x10\x10\x10\x10\x10\x10\x10") | - ($this->shuffle[$invipmap[($l >> 8) & 0xFF]] & "\x08\x08\x08\x08\x08\x08\x08\x08") | - ($this->shuffle[$invipmap[($r >> 8) & 0xFF]] & "\x04\x04\x04\x04\x04\x04\x04\x04") | - ($this->shuffle[$invipmap[$l & 0xFF]] & "\x02\x02\x02\x02\x02\x02\x02\x02") | - ($this->shuffle[$invipmap[$r & 0xFF]] & "\x01\x01\x01\x01\x01\x01\x01\x01"); + return ($shuffle[$invipmap[($l >> 24) & 0xFF]] & "\x80\x80\x80\x80\x80\x80\x80\x80") | + ($shuffle[$invipmap[($r >> 24) & 0xFF]] & "\x40\x40\x40\x40\x40\x40\x40\x40") | + ($shuffle[$invipmap[($l >> 16) & 0xFF]] & "\x20\x20\x20\x20\x20\x20\x20\x20") | + ($shuffle[$invipmap[($r >> 16) & 0xFF]] & "\x10\x10\x10\x10\x10\x10\x10\x10") | + ($shuffle[$invipmap[($l >> 8) & 0xFF]] & "\x08\x08\x08\x08\x08\x08\x08\x08") | + ($shuffle[$invipmap[($r >> 8) & 0xFF]] & "\x04\x04\x04\x04\x04\x04\x04\x04") | + ($shuffle[$invipmap[$l & 0xFF]] & "\x02\x02\x02\x02\x02\x02\x02\x02") | + ($shuffle[$invipmap[$r & 0xFF]] & "\x01\x01\x01\x01\x01\x01\x01\x01"); } /** @@ -1952,10 +2059,22 @@ class Crypt_DES { ); } - return array( + $keys = array( CRYPT_DES_ENCRYPT => $keys, - CRYPT_DES_DECRYPT => array_reverse($keys) + CRYPT_DES_DECRYPT => array_reverse($keys), + CRYPT_DES_ENCRYPT_1DIM => array(), + CRYPT_DES_DECRYPT_1DIM => array() ); + + // Generate 1-dim arrays for inline en/decrypting + for ($i = 0; $i < 16; ++$i) { + $keys[CRYPT_DES_ENCRYPT_1DIM][] = $keys[CRYPT_DES_ENCRYPT][$i][0]; + $keys[CRYPT_DES_ENCRYPT_1DIM][] = $keys[CRYPT_DES_ENCRYPT][$i][1]; + $keys[CRYPT_DES_DECRYPT_1DIM][] = $keys[CRYPT_DES_DECRYPT][$i][0]; + $keys[CRYPT_DES_DECRYPT_1DIM][] = $keys[CRYPT_DES_DECRYPT][$i][1]; + } + + return $keys; } /** @@ -1964,16 +2083,448 @@ class Crypt_DES { * Inspired by array_shift * * @param String $string - * @param optional Integer $index * @return String * @access private */ - function _string_shift(&$string, $index = 1) + function _string_shift(&$string) { - $substr = substr($string, 0, $index); - $string = substr($string, $index); + $substr = substr($string, 0, 8); + $string = substr($string, 8); return $substr; } + + /** + * Creates performance-optimized function for de/encrypt(), storing it in $this->inline_crypt + * + * @param optional Integer $des_rounds (1 = DES[default], 3 = TribleDES) + * @access private + */ + function inline_crypt_setup($des_rounds = 1) + { + $lambda_functions =& Crypt_DES::get_lambda_functions(); + $block_size = 8; + $mode = $this->mode; + + $code_hash = "$mode,$des_rounds"; + + if (!isset($lambda_functions[$code_hash])) { + // Generating encrypt code: + $ki = -1; + $init_cryptBlock = ' + $shuffle = $self->shuffle; + $invipmap = $self->invipmap; + $ipmap = $self->ipmap; + $sbox1 = $self->sbox1; + $sbox2 = $self->sbox2; + $sbox3 = $self->sbox3; + $sbox4 = $self->sbox4; + $sbox5 = $self->sbox5; + $sbox6 = $self->sbox6; + $sbox7 = $self->sbox7; + $sbox8 = $self->sbox8; + '; + + $_cryptBlock = '$in = unpack("N*", $in);'."\n"; + for ($des_round = 0; $des_round < $des_rounds; ++$des_round) { + // Do the initial IP permutation. + $_cryptBlock .= ' + $l = $in[1]; + $r = $in[2]; + $in = unpack("N*", + ($shuffle[$ipmap[ $r & 0xFF]] & "\x80\x80\x80\x80\x80\x80\x80\x80") | + ($shuffle[$ipmap[($r >> 8) & 0xFF]] & "\x40\x40\x40\x40\x40\x40\x40\x40") | + ($shuffle[$ipmap[($r >> 16) & 0xFF]] & "\x20\x20\x20\x20\x20\x20\x20\x20") | + ($shuffle[$ipmap[($r >> 24) & 0xFF]] & "\x10\x10\x10\x10\x10\x10\x10\x10") | + ($shuffle[$ipmap[ $l & 0xFF]] & "\x08\x08\x08\x08\x08\x08\x08\x08") | + ($shuffle[$ipmap[($l >> 8) & 0xFF]] & "\x04\x04\x04\x04\x04\x04\x04\x04") | + ($shuffle[$ipmap[($l >> 16) & 0xFF]] & "\x02\x02\x02\x02\x02\x02\x02\x02") | + ($shuffle[$ipmap[($l >> 24) & 0xFF]] & "\x01\x01\x01\x01\x01\x01\x01\x01") + ); + + '.'' /* Extract L0 and R0 */ .' + $l = $in[1]; + $r = $in[2]; + '; + + // Perform the 16 steps. + // start of "the Feistel (F) function" - see the following URL: + // http://en.wikipedia.org/wiki/Image:Data_Encryption_Standard_InfoBox_Diagram.png + // Merge key schedule. + for ($i = 0; $i < 8; ++$i) { + $_cryptBlock .= ' + $b1 = (($r >> 3) & 0x1FFFFFFF) ^ ($r << 29) ^ $k_'.(++$ki).'; + $b2 = (($r >> 31) & 0x00000001) ^ ($r << 1) ^ $k_'.(++$ki).'; + $l = $sbox1[($b1 >> 24) & 0x3F] ^ $sbox2[($b2 >> 24) & 0x3F] ^ + $sbox3[($b1 >> 16) & 0x3F] ^ $sbox4[($b2 >> 16) & 0x3F] ^ + $sbox5[($b1 >> 8) & 0x3F] ^ $sbox6[($b2 >> 8) & 0x3F] ^ + $sbox7[ $b1 & 0x3F] ^ $sbox8[ $b2 & 0x3F] ^ $l; + + $b1 = (($l >> 3) & 0x1FFFFFFF) ^ ($l << 29) ^ $k_'.(++$ki).'; + $b2 = (($l >> 31) & 0x00000001) ^ ($l << 1) ^ $k_'.(++$ki).'; + $r = $sbox1[($b1 >> 24) & 0x3F] ^ $sbox2[($b2 >> 24) & 0x3F] ^ + $sbox3[($b1 >> 16) & 0x3F] ^ $sbox4[($b2 >> 16) & 0x3F] ^ + $sbox5[($b1 >> 8) & 0x3F] ^ $sbox6[($b2 >> 8) & 0x3F] ^ + $sbox7[ $b1 & 0x3F] ^ $sbox8[ $b2 & 0x3F] ^ $r; + '; + } + + // Perform the inverse IP permutation. + $_cryptBlock .= '$in = ' . ($des_round == $des_rounds-1 ? '(' : 'unpack("N*",') . ' + ($shuffle[$invipmap[($l >> 24) & 0xFF]] & "\x80\x80\x80\x80\x80\x80\x80\x80") | + ($shuffle[$invipmap[($r >> 24) & 0xFF]] & "\x40\x40\x40\x40\x40\x40\x40\x40") | + ($shuffle[$invipmap[($l >> 16) & 0xFF]] & "\x20\x20\x20\x20\x20\x20\x20\x20") | + ($shuffle[$invipmap[($r >> 16) & 0xFF]] & "\x10\x10\x10\x10\x10\x10\x10\x10") | + ($shuffle[$invipmap[($l >> 8) & 0xFF]] & "\x08\x08\x08\x08\x08\x08\x08\x08") | + ($shuffle[$invipmap[($r >> 8) & 0xFF]] & "\x04\x04\x04\x04\x04\x04\x04\x04") | + ($shuffle[$invipmap[ $l & 0xFF]] & "\x02\x02\x02\x02\x02\x02\x02\x02") | + ($shuffle[$invipmap[ $r & 0xFF]] & "\x01\x01\x01\x01\x01\x01\x01\x01") + ); + '; + } + + // Generating mode of operation code: + switch ($mode) { + case CRYPT_DES_MODE_ECB: + $encrypt = $init_cryptBlock . ' + extract($self->keys[CRYPT_DES_ENCRYPT_1DIM], EXTR_PREFIX_ALL, "k"); + $ciphertext = ""; + $plaintext_len = strlen($text); + + for ($i = 0; $i < $plaintext_len; $i+= '.$block_size.') { + $in = substr($text, $i, '.$block_size.'); + '.$_cryptBlock.' + $ciphertext.= $in; + } + + return $ciphertext; + '; + + $decrypt = $init_cryptBlock . ' + extract($self->keys[CRYPT_DES_DECRYPT_1DIM], EXTR_PREFIX_ALL, "k"); + $plaintext = ""; + $ciphertext_len = strlen($text); + + for ($i = 0; $i < $ciphertext_len; $i+= '.$block_size.') { + $in = substr($text, $i, '.$block_size.'); + '.$_cryptBlock.' + $plaintext.= $in; + } + + return $self->_unpad($plaintext); + '; + break; + case CRYPT_DES_MODE_CBC: + $encrypt = $init_cryptBlock . ' + extract($self->keys[CRYPT_DES_ENCRYPT_1DIM], EXTR_PREFIX_ALL, "k"); + $ciphertext = ""; + $plaintext_len = strlen($text); + + $in = $self->encryptIV; + + for ($i = 0; $i < $plaintext_len; $i+= '.$block_size.') { + $in = substr($text, $i, '.$block_size.') ^ $in; + '.$_cryptBlock.' + $ciphertext.= $in; + } + + if ($self->continuousBuffer) { + $self->encryptIV = $in; + } + + return $ciphertext; + '; + + $decrypt = $init_cryptBlock . ' + extract($self->keys[CRYPT_DES_DECRYPT_1DIM], EXTR_PREFIX_ALL, "k"); + $plaintext = ""; + $ciphertext_len = strlen($text); + + $iv = $self->decryptIV; + + for ($i = 0; $i < $ciphertext_len; $i+= '.$block_size.') { + $in = $block = substr($text, $i, '.$block_size.'); + '.$_cryptBlock.' + $plaintext.= $in ^ $iv; + $iv = $block; + } + + if ($self->continuousBuffer) { + $self->decryptIV = $iv; + } + + return $self->_unpad($plaintext); + '; + break; + case CRYPT_DES_MODE_CTR: + $encrypt = $init_cryptBlock . ' + extract($self->keys[CRYPT_DES_ENCRYPT_1DIM], EXTR_PREFIX_ALL, "k"); + $ciphertext = ""; + $plaintext_len = strlen($text); + $xor = $self->encryptIV; + $buffer = &$self->enbuffer; + + if (strlen($buffer["encrypted"])) { + for ($i = 0; $i < $plaintext_len; $i+= '.$block_size.') { + $block = substr($text, $i, '.$block_size.'); + if (strlen($block) > strlen($buffer["encrypted"])) { + $in = $self->_generate_xor($xor); + '.$_cryptBlock.' + $buffer["encrypted"].= $in; + } + $key = $self->_string_shift($buffer["encrypted"]); + $ciphertext.= $block ^ $key; + } + } else { + for ($i = 0; $i < $plaintext_len; $i+= '.$block_size.') { + $block = substr($text, $i, '.$block_size.'); + $in = $self->_generate_xor($xor); + '.$_cryptBlock.' + $key = $in; + $ciphertext.= $block ^ $key; + } + } + if ($self->continuousBuffer) { + $self->encryptIV = $xor; + if ($start = $plaintext_len % '.$block_size.') { + $buffer["encrypted"] = substr($key, $start) . $buffer["encrypted"]; + } + } + + return $ciphertext; + '; + + $decrypt = $init_cryptBlock . ' + extract($self->keys[CRYPT_DES_ENCRYPT_1DIM], EXTR_PREFIX_ALL, "k"); + $plaintext = ""; + $ciphertext_len = strlen($text); + $xor = $self->decryptIV; + $buffer = &$self->debuffer; + + if (strlen($buffer["ciphertext"])) { + for ($i = 0; $i < $ciphertext_len; $i+= '.$block_size.') { + $block = substr($text, $i, '.$block_size.'); + if (strlen($block) > strlen($buffer["ciphertext"])) { + $in = $self->_generate_xor($xor); + '.$_cryptBlock.' + $buffer["ciphertext"].= $in; + } + $key = $self->_string_shift($buffer["ciphertext"]); + $plaintext.= $block ^ $key; + } + } else { + for ($i = 0; $i < $ciphertext_len; $i+= '.$block_size.') { + $block = substr($text, $i, '.$block_size.'); + $in = $self->_generate_xor($xor); + '.$_cryptBlock.' + $key = $in; + $plaintext.= $block ^ $key; + } + } + if ($self->continuousBuffer) { + $self->decryptIV = $xor; + if ($start = $ciphertext_len % '.$block_size.') { + $buffer["ciphertext"] = substr($key, $start) . $buffer["ciphertext"]; + } + } + + return $plaintext; + '; + break; + case CRYPT_DES_MODE_CFB: + $encrypt = $init_cryptBlock . ' + extract($self->keys[CRYPT_DES_ENCRYPT_1DIM], EXTR_PREFIX_ALL, "k"); + $ciphertext = ""; + $buffer = &$self->enbuffer; + + if ($self->continuousBuffer) { + $iv = &$self->encryptIV; + $pos = &$buffer["pos"]; + } else { + $iv = $self->encryptIV; + $pos = 0; + } + $len = strlen($text); + $i = 0; + if ($pos) { + $orig_pos = $pos; + $max = '.$block_size.' - $pos; + if ($len >= $max) { + $i = $max; + $len-= $max; + $pos = 0; + } else { + $i = $len; + $pos+= $len; + $len = 0; + } + $ciphertext = substr($iv, $orig_pos) ^ $text; + $iv = substr_replace($iv, $ciphertext, $orig_pos, $i); + } + while ($len >= '.$block_size.') { + $in = $iv; + '.$_cryptBlock.'; + $iv = $in ^ substr($text, $i, '.$block_size.'); + $ciphertext.= $iv; + $len-= '.$block_size.'; + $i+= '.$block_size.'; + } + if ($len) { + $in = $iv; + '.$_cryptBlock.' + $iv = $in; + $block = $iv ^ substr($text, $i); + $iv = substr_replace($iv, $block, 0, $len); + $ciphertext.= $block; + $pos = $len; + } + return $ciphertext; + '; + + $decrypt = $init_cryptBlock . ' + extract($self->keys[CRYPT_DES_ENCRYPT_1DIM], EXTR_PREFIX_ALL, "k"); + $plaintext = ""; + $buffer = &$self->debuffer; + + if ($self->continuousBuffer) { + $iv = &$self->decryptIV; + $pos = &$buffer["pos"]; + } else { + $iv = $self->decryptIV; + $pos = 0; + } + $len = strlen($text); + $i = 0; + if ($pos) { + $orig_pos = $pos; + $max = '.$block_size.' - $pos; + if ($len >= $max) { + $i = $max; + $len-= $max; + $pos = 0; + } else { + $i = $len; + $pos+= $len; + $len = 0; + } + $plaintext = substr($iv, $orig_pos) ^ $text; + $iv = substr_replace($iv, substr($text, 0, $i), $orig_pos, $i); + } + while ($len >= '.$block_size.') { + $in = $iv; + '.$_cryptBlock.' + $iv = $in; + $cb = substr($text, $i, '.$block_size.'); + $plaintext.= $iv ^ $cb; + $iv = $cb; + $len-= '.$block_size.'; + $i+= '.$block_size.'; + } + if ($len) { + $in = $iv; + '.$_cryptBlock.' + $iv = $in; + $plaintext.= $iv ^ substr($text, $i); + $iv = substr_replace($iv, substr($text, $i), 0, $len); + $pos = $len; + } + + return $plaintext; + '; + break; + case CRYPT_DES_MODE_OFB: + $encrypt = $init_cryptBlock . ' + extract($self->keys[CRYPT_DES_ENCRYPT_1DIM], EXTR_PREFIX_ALL, "k"); + $ciphertext = ""; + $plaintext_len = strlen($text); + $xor = $self->encryptIV; + $buffer = &$self->enbuffer; + + if (strlen($buffer["xor"])) { + for ($i = 0; $i < $plaintext_len; $i+= '.$block_size.') { + $block = substr($text, $i, '.$block_size.'); + if (strlen($block) > strlen($buffer["xor"])) { + $in = $xor; + '.$_cryptBlock.' + $xor = $in; + $buffer["xor"].= $xor; + } + $key = $self->_string_shift($buffer["xor"]); + $ciphertext.= $block ^ $key; + } + } else { + for ($i = 0; $i < $plaintext_len; $i+= '.$block_size.') { + $in = $xor; + '.$_cryptBlock.' + $xor = $in; + $ciphertext.= substr($text, $i, '.$block_size.') ^ $xor; + } + $key = $xor; + } + if ($self->continuousBuffer) { + $self->encryptIV = $xor; + if ($start = $plaintext_len % '.$block_size.') { + $buffer["xor"] = substr($key, $start) . $buffer["xor"]; + } + } + return $ciphertext; + '; + + $decrypt = $init_cryptBlock . ' + extract($self->keys[CRYPT_DES_ENCRYPT_1DIM], EXTR_PREFIX_ALL, "k"); + $plaintext = ""; + $ciphertext_len = strlen($text); + $xor = $self->decryptIV; + $buffer = &$self->debuffer; + + if (strlen($buffer["xor"])) { + for ($i = 0; $i < $ciphertext_len; $i+= '.$block_size.') { + $block = substr($text, $i, '.$block_size.'); + if (strlen($block) > strlen($buffer["xor"])) { + $in = $xor; + '.$_cryptBlock.' + $xor = $in; + $buffer["xor"].= $xor; + } + $key = $self->_string_shift($buffer["xor"]); + $plaintext.= $block ^ $key; + } + } else { + for ($i = 0; $i < $ciphertext_len; $i+= '.$block_size.') { + $in = $xor; + '.$_cryptBlock.' + $xor = $in; + $plaintext.= substr($text, $i, '.$block_size.') ^ $xor; + } + $key = $xor; + } + if ($self->continuousBuffer) { + $self->decryptIV = $xor; + if ($start = $ciphertext_len % '.$block_size.') { + $buffer["xor"] = substr($key, $start) . $buffer["xor"]; + } + } + return $plaintext; + '; + break; + } + $lambda_functions[$code_hash] = create_function('$action, &$self, $text', 'if ($action == "encrypt") { '.$encrypt.' } else { '.$decrypt.' }'); + #echo $encrypt; + } + $this->inline_crypt = $lambda_functions[$code_hash]; + } + + /** + * Holds the lambda_functions table (classwide) + * + * @see inline_crypt_setup() + * @return Array + * @access private + */ + function &get_lambda_functions() + { + static $functions = array(); + return $functions; + } } // vim: ts=4:sw=4:et: diff --git a/phpseclib/Crypt/TripleDES.php b/phpseclib/Crypt/TripleDES.php index 28cdc588..8d463554 100644 --- a/phpseclib/Crypt/TripleDES.php +++ b/phpseclib/Crypt/TripleDES.php @@ -83,70 +83,7 @@ define('CRYPT_DES_MODE_CBC3', CRYPT_DES_MODE_CBC); * @access public * @package Crypt_TerraDES */ -class Crypt_TripleDES { - /** - * The Three Keys - * - * @see Crypt_TripleDES::setKey() - * @var String - * @access private - */ - var $key = "\0\0\0\0\0\0\0\0"; - - /** - * The Encryption Mode - * - * @see Crypt_TripleDES::Crypt_TripleDES() - * @var Integer - * @access private - */ - var $mode = CRYPT_DES_MODE_CBC; - - /** - * Continuous Buffer status - * - * @see Crypt_TripleDES::enableContinuousBuffer() - * @var Boolean - * @access private - */ - var $continuousBuffer = false; - - /** - * Padding status - * - * @see Crypt_TripleDES::enablePadding() - * @var Boolean - * @access private - */ - var $padding = true; - - /** - * The Initialization Vector - * - * @see Crypt_TripleDES::setIV() - * @var String - * @access private - */ - var $iv = "\0\0\0\0\0\0\0\0"; - - /** - * A "sliding" Initialization Vector - * - * @see Crypt_TripleDES::enableContinuousBuffer() - * @var String - * @access private - */ - var $encryptIV = "\0\0\0\0\0\0\0\0"; - - /** - * A "sliding" Initialization Vector - * - * @see Crypt_TripleDES::enableContinuousBuffer() - * @var String - * @access private - */ - var $decryptIV = "\0\0\0\0\0\0\0\0"; - +class Crypt_TripleDES extends Crypt_DES { /** * The Crypt_DES objects * @@ -155,87 +92,6 @@ class Crypt_TripleDES { */ var $des; - /** - * mcrypt resource for encryption - * - * The mcrypt resource can be recreated every time something needs to be created or it can be created just once. - * Since mcrypt operates in continuous mode, by default, it'll need to be recreated when in non-continuous mode. - * - * @see Crypt_TripleDES::encrypt() - * @var String - * @access private - */ - var $enmcrypt; - - /** - * mcrypt resource for decryption - * - * The mcrypt resource can be recreated every time something needs to be created or it can be created just once. - * Since mcrypt operates in continuous mode, by default, it'll need to be recreated when in non-continuous mode. - * - * @see Crypt_TripleDES::decrypt() - * @var String - * @access private - */ - var $demcrypt; - - /** - * Does the enmcrypt resource need to be (re)initialized? - * - * @see Crypt_TripleDES::setKey() - * @see Crypt_TripleDES::setIV() - * @var Boolean - * @access private - */ - var $enchanged = true; - - /** - * Does the demcrypt resource need to be (re)initialized? - * - * @see Crypt_TripleDES::setKey() - * @see Crypt_TripleDES::setIV() - * @var Boolean - * @access private - */ - var $dechanged = true; - - /** - * Is the mode one that is paddable? - * - * @see Crypt_TripleDES::Crypt_TripleDES() - * @var Boolean - * @access private - */ - var $paddable = false; - - /** - * Encryption buffer for CTR, OFB and CFB modes - * - * @see Crypt_TripleDES::encrypt() - * @var Array - * @access private - */ - var $enbuffer = array('encrypted' => '', 'xor' => '', 'pos' => 0, 'enmcrypt_init' => true); - - /** - * Decryption buffer for CTR, OFB and CFB modes - * - * @see Crypt_TripleDES::decrypt() - * @var Array - * @access private - */ - var $debuffer = array('ciphertext' => '', 'xor' => '', 'pos' => 0, 'demcrypt_init' => true); - - /** - * mcrypt resource for CFB mode - * - * @see Crypt_TripleDES::encrypt() - * @see Crypt_TripleDES::decrypt() - * @var String - * @access private - */ - var $ecb; - /** * Default Constructor. * @@ -328,6 +184,10 @@ class Crypt_TripleDES { $this->paddable = true; $this->mode = CRYPT_DES_MODE_CBC; } + if (function_exists('create_function') && is_callable('create_function')) { + $this->inline_crypt_setup(3); + $this->use_inline_crypt = true; + } } } @@ -362,6 +222,22 @@ class Crypt_TripleDES { $this->des[0]->setKey(substr($key, 0, 8)); $this->des[1]->setKey(substr($key, 8, 8)); $this->des[2]->setKey(substr($key, 16, 8)); + + // Merge the three DES-1-dim-key-arrays for 3DES-inline-en/decrypting + if ($this->use_inline_crypt && $this->mode != CRYPT_DES_MODE_3CBC) { + $this->keys = array( + CRYPT_DES_ENCRYPT_1DIM => array_merge( + $this->des[0]->keys[CRYPT_DES_ENCRYPT_1DIM], + $this->des[1]->keys[CRYPT_DES_DECRYPT_1DIM], + $this->des[2]->keys[CRYPT_DES_ENCRYPT_1DIM] + ), + CRYPT_DES_DECRYPT_1DIM => array_merge( + $this->des[2]->keys[CRYPT_DES_DECRYPT_1DIM], + $this->des[1]->keys[CRYPT_DES_ENCRYPT_1DIM], + $this->des[0]->keys[CRYPT_DES_DECRYPT_1DIM] + ), + ); + } } $this->enchanged = $this->dechanged = true; } @@ -438,39 +314,6 @@ class Crypt_TripleDES { $this->enchanged = $this->dechanged = true; } - /** - * Generate CTR XOR encryption key - * - * Encrypt the output of this and XOR it against the ciphertext / plaintext to get the - * plaintext / ciphertext in CTR mode. - * - * @see Crypt_TripleDES::decrypt() - * @see Crypt_TripleDES::encrypt() - * @access private - * @param String $iv - */ - function _generate_xor(&$iv) - { - $xor = $iv; - for ($j = 4; $j <= 8; $j+=4) { - $temp = substr($iv, -$j, 4); - switch ($temp) { - case "\xFF\xFF\xFF\xFF": - $iv = substr_replace($iv, "\x00\x00\x00\x00", -$j, 4); - break; - case "\x7F\xFF\xFF\xFF": - $iv = substr_replace($iv, "\x80\x00\x00\x00", -$j, 4); - break 2; - default: - extract(unpack('Ncount', $temp)); - $iv = substr_replace($iv, pack('N', $count + 1), -$j, 4); - break 2; - } - } - - return $xor; - } - /** * Encrypts a message. * @@ -565,6 +408,11 @@ class Crypt_TripleDES { return $this->des[0]->encrypt($plaintext); } + if ($this->use_inline_crypt) { + $inline = $this->inline_crypt; + return $inline('encrypt', $this, $plaintext); + } + $des = $this->des; $buffer = &$this->enbuffer; @@ -612,7 +460,7 @@ class Crypt_TripleDES { $key = $des[2]->_processBlock($key, CRYPT_DES_ENCRYPT); $buffer['encrypted'].= $key; } - $key = $this->_string_shift($buffer['encrypted'], 8); + $key = $this->_string_shift($buffer['encrypted']); $ciphertext.= $block ^ $key; } } else { @@ -676,7 +524,7 @@ class Crypt_TripleDES { $xor = $des[2]->_processBlock($xor, CRYPT_DES_ENCRYPT); $buffer['xor'].= $xor; } - $key = $this->_string_shift($buffer['xor'], 8); + $key = $this->_string_shift($buffer['xor']); $ciphertext.= $block ^ $key; } } else { @@ -780,6 +628,11 @@ class Crypt_TripleDES { return $this->paddable ? $this->_unpad($plaintext) : $plaintext; } + if ($this->use_inline_crypt) { + $inline = $this->inline_crypt; + return $inline('decrypt', $this, $ciphertext); + } + $des = $this->des; $buffer = &$this->debuffer; @@ -821,7 +674,7 @@ class Crypt_TripleDES { $key = $des[2]->_processBlock($key, CRYPT_DES_ENCRYPT); $buffer['ciphertext'].= $key; } - $key = $this->_string_shift($buffer['ciphertext'], 8); + $key = $this->_string_shift($buffer['ciphertext']); $plaintext.= $block ^ $key; } } else { @@ -890,7 +743,7 @@ class Crypt_TripleDES { $xor = $des[2]->_processBlock($xor, CRYPT_DES_ENCRYPT); $buffer['xor'].= $xor; } - $key = $this->_string_shift($buffer['xor'], 8); + $key = $this->_string_shift($buffer['xor']); $plaintext.= $block ^ $key; } } else { @@ -984,106 +837,6 @@ class Crypt_TripleDES { $this->des[2]->disableContinuousBuffer(); } } - - /** - * Pad "packets". - * - * DES works by encrypting eight bytes at a time. If you ever need to encrypt or decrypt something that's not - * a multiple of eight, it becomes necessary to pad the input so that it's length is a multiple of eight. - * - * Padding is enabled by default. Sometimes, however, it is undesirable to pad strings. Such is the case in SSH1, - * where "packets" are padded with random bytes before being encrypted. Unpad these packets and you risk stripping - * away characters that shouldn't be stripped away. (SSH knows how many bytes are added because the length is - * transmitted separately) - * - * @see Crypt_TripleDES::disablePadding() - * @access public - */ - function enablePadding() - { - $this->padding = true; - } - - /** - * Do not pad packets. - * - * @see Crypt_TripleDES::enablePadding() - * @access public - */ - function disablePadding() - { - $this->padding = false; - } - - /** - * Pads a string - * - * Pads a string using the RSA PKCS padding standards so that its length is a multiple of the blocksize (8). - * 8 - (strlen($text) & 7) bytes are added, each of which is equal to chr(8 - (strlen($text) & 7) - * - * If padding is disabled and $text is not a multiple of the blocksize, the string will be padded regardless - * and padding will, hence forth, be enabled. - * - * @see Crypt_TripleDES::_unpad() - * @access private - */ - function _pad($text) - { - $length = strlen($text); - - if (!$this->padding) { - if (($length & 7) == 0) { - return $text; - } else { - user_error("The plaintext's length ($length) is not a multiple of the block size (8)", E_USER_NOTICE); - $this->padding = true; - } - } - - $pad = 8 - ($length & 7); - return str_pad($text, $length + $pad, chr($pad)); - } - - /** - * Unpads a string - * - * If padding is enabled and the reported padding length is invalid the encryption key will be assumed to be wrong - * and false will be returned. - * - * @see Crypt_TripleDES::_pad() - * @access private - */ - function _unpad($text) - { - if (!$this->padding) { - return $text; - } - - $length = ord($text[strlen($text) - 1]); - - if (!$length || $length > 8) { - return false; - } - - return substr($text, 0, -$length); - } - - /** - * String Shift - * - * Inspired by array_shift - * - * @param String $string - * @param optional Integer $index - * @return String - * @access private - */ - function _string_shift(&$string, $index = 1) - { - $substr = substr($string, 0, $index); - $string = substr($string, $index); - return $substr; - } } // vim: ts=4:sw=4:et: