mirror of
https://github.com/danog/phpseclib.git
synced 2024-12-14 01:57:20 +01:00
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
This commit is contained in:
parent
8816719671
commit
c4752cbeba
File diff suppressed because it is too large
Load Diff
@ -83,70 +83,7 @@ define('CRYPT_DES_MODE_CBC3', CRYPT_DES_MODE_CBC);
|
|||||||
* @access public
|
* @access public
|
||||||
* @package Crypt_TerraDES
|
* @package Crypt_TerraDES
|
||||||
*/
|
*/
|
||||||
class Crypt_TripleDES {
|
class Crypt_TripleDES extends Crypt_DES {
|
||||||
/**
|
|
||||||
* 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";
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The Crypt_DES objects
|
* The Crypt_DES objects
|
||||||
*
|
*
|
||||||
@ -155,87 +92,6 @@ class Crypt_TripleDES {
|
|||||||
*/
|
*/
|
||||||
var $des;
|
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.
|
* Default Constructor.
|
||||||
*
|
*
|
||||||
@ -328,6 +184,10 @@ class Crypt_TripleDES {
|
|||||||
$this->paddable = true;
|
$this->paddable = true;
|
||||||
$this->mode = CRYPT_DES_MODE_CBC;
|
$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[0]->setKey(substr($key, 0, 8));
|
||||||
$this->des[1]->setKey(substr($key, 8, 8));
|
$this->des[1]->setKey(substr($key, 8, 8));
|
||||||
$this->des[2]->setKey(substr($key, 16, 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;
|
$this->enchanged = $this->dechanged = true;
|
||||||
}
|
}
|
||||||
@ -438,39 +314,6 @@ class Crypt_TripleDES {
|
|||||||
$this->enchanged = $this->dechanged = true;
|
$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.
|
* Encrypts a message.
|
||||||
*
|
*
|
||||||
@ -565,6 +408,11 @@ class Crypt_TripleDES {
|
|||||||
return $this->des[0]->encrypt($plaintext);
|
return $this->des[0]->encrypt($plaintext);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($this->use_inline_crypt) {
|
||||||
|
$inline = $this->inline_crypt;
|
||||||
|
return $inline('encrypt', $this, $plaintext);
|
||||||
|
}
|
||||||
|
|
||||||
$des = $this->des;
|
$des = $this->des;
|
||||||
|
|
||||||
$buffer = &$this->enbuffer;
|
$buffer = &$this->enbuffer;
|
||||||
@ -612,7 +460,7 @@ class Crypt_TripleDES {
|
|||||||
$key = $des[2]->_processBlock($key, CRYPT_DES_ENCRYPT);
|
$key = $des[2]->_processBlock($key, CRYPT_DES_ENCRYPT);
|
||||||
$buffer['encrypted'].= $key;
|
$buffer['encrypted'].= $key;
|
||||||
}
|
}
|
||||||
$key = $this->_string_shift($buffer['encrypted'], 8);
|
$key = $this->_string_shift($buffer['encrypted']);
|
||||||
$ciphertext.= $block ^ $key;
|
$ciphertext.= $block ^ $key;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -676,7 +524,7 @@ class Crypt_TripleDES {
|
|||||||
$xor = $des[2]->_processBlock($xor, CRYPT_DES_ENCRYPT);
|
$xor = $des[2]->_processBlock($xor, CRYPT_DES_ENCRYPT);
|
||||||
$buffer['xor'].= $xor;
|
$buffer['xor'].= $xor;
|
||||||
}
|
}
|
||||||
$key = $this->_string_shift($buffer['xor'], 8);
|
$key = $this->_string_shift($buffer['xor']);
|
||||||
$ciphertext.= $block ^ $key;
|
$ciphertext.= $block ^ $key;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -780,6 +628,11 @@ class Crypt_TripleDES {
|
|||||||
return $this->paddable ? $this->_unpad($plaintext) : $plaintext;
|
return $this->paddable ? $this->_unpad($plaintext) : $plaintext;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($this->use_inline_crypt) {
|
||||||
|
$inline = $this->inline_crypt;
|
||||||
|
return $inline('decrypt', $this, $ciphertext);
|
||||||
|
}
|
||||||
|
|
||||||
$des = $this->des;
|
$des = $this->des;
|
||||||
|
|
||||||
$buffer = &$this->debuffer;
|
$buffer = &$this->debuffer;
|
||||||
@ -821,7 +674,7 @@ class Crypt_TripleDES {
|
|||||||
$key = $des[2]->_processBlock($key, CRYPT_DES_ENCRYPT);
|
$key = $des[2]->_processBlock($key, CRYPT_DES_ENCRYPT);
|
||||||
$buffer['ciphertext'].= $key;
|
$buffer['ciphertext'].= $key;
|
||||||
}
|
}
|
||||||
$key = $this->_string_shift($buffer['ciphertext'], 8);
|
$key = $this->_string_shift($buffer['ciphertext']);
|
||||||
$plaintext.= $block ^ $key;
|
$plaintext.= $block ^ $key;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -890,7 +743,7 @@ class Crypt_TripleDES {
|
|||||||
$xor = $des[2]->_processBlock($xor, CRYPT_DES_ENCRYPT);
|
$xor = $des[2]->_processBlock($xor, CRYPT_DES_ENCRYPT);
|
||||||
$buffer['xor'].= $xor;
|
$buffer['xor'].= $xor;
|
||||||
}
|
}
|
||||||
$key = $this->_string_shift($buffer['xor'], 8);
|
$key = $this->_string_shift($buffer['xor']);
|
||||||
$plaintext.= $block ^ $key;
|
$plaintext.= $block ^ $key;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -984,106 +837,6 @@ class Crypt_TripleDES {
|
|||||||
$this->des[2]->disableContinuousBuffer();
|
$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:
|
// vim: ts=4:sw=4:et:
|
||||||
|
Loading…
Reference in New Issue
Block a user