mirror of
https://github.com/phpseclib/phpseclib.git
synced 2024-12-26 11:37:33 +00:00
- speed up BigInteger.php
- added support for more public / private key formats (thanks, m4rc!) git-svn-id: http://phpseclib.svn.sourceforge.net/svnroot/phpseclib/trunk@91 21d32557-59b3-4da0-833f-c5933fad653e
This commit is contained in:
parent
d574a6770e
commit
748983a824
@ -62,7 +62,7 @@
|
||||
* @author Jim Wigginton <terrafrost@php.net>
|
||||
* @copyright MMIX Jim Wigginton
|
||||
* @license http://www.gnu.org/licenses/lgpl.txt
|
||||
* @version $Id: RSA.php,v 1.10 2010-01-29 06:21:16 terrafrost Exp $
|
||||
* @version $Id: RSA.php,v 1.11 2010-02-26 03:40:25 terrafrost Exp $
|
||||
* @link http://phpseclib.sourceforge.net
|
||||
*/
|
||||
|
||||
@ -767,35 +767,80 @@ class Crypt_RSA {
|
||||
implementation are part of the standard, as well.
|
||||
|
||||
* OpenSSL is the de facto standard. It's utilized by OpenSSH and other projects */
|
||||
if (preg_match('#DEK-Info: DES-EDE3-CBC,(.+)#', $key, $matches)) {
|
||||
$iv = pack('H*', trim($matches[1]));
|
||||
if (preg_match('#DEK-Info: (.+),(.+)#', $key, $matches)) {
|
||||
$iv = pack('H*', trim($matches[2]));
|
||||
$symkey = pack('H*', md5($this->password . $iv)); // symkey is short for symmetric key
|
||||
$symkey.= substr(pack('H*', md5($symkey . $this->password . $iv)), 0, 8);
|
||||
$ciphertext = base64_decode(preg_replace('#.+(\r|\n|\r\n)\1|[\r\n]|-.+-#s', '', $key));
|
||||
$ciphertext = preg_replace('#.+(\r|\n|\r\n)\1|[\r\n]|-.+-#s', '', $key);
|
||||
$ciphertext = preg_match('#^[a-zA-Z\d/+]*={0,2}$#', $ciphertext) ? base64_decode($ciphertext) : false;
|
||||
if ($ciphertext === false) {
|
||||
return false;
|
||||
$ciphertext = $key;
|
||||
}
|
||||
if (!class_exists('Crypt_TripleDES')) {
|
||||
require_once('Crypt/TripleDES.php');
|
||||
switch ($matches[1]) {
|
||||
case 'DES-EDE3-CBC':
|
||||
if (!class_exists('Crypt_TripleDES')) {
|
||||
require_once('Crypt/TripleDES.php');
|
||||
}
|
||||
$crypto = new Crypt_TripleDES();
|
||||
break;
|
||||
case 'DES-CBC':
|
||||
if (!class_exists('Crypt_DES')) {
|
||||
require_once('Crypt/DES.php');
|
||||
}
|
||||
$crypto = new Crypt_DES();
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
$des = new Crypt_TripleDES();
|
||||
$des->setKey($symkey);
|
||||
$des->setIV($iv);
|
||||
$key = $des->decrypt($ciphertext);
|
||||
$crypto->setKey($symkey);
|
||||
$crypto->setIV($iv);
|
||||
$decoded = $crypto->decrypt($ciphertext);
|
||||
} else {
|
||||
$key = base64_decode(preg_replace('#-.+-|[\r\n]#', '', $key));
|
||||
$decoded = preg_replace('#-.+-|[\r\n]#', '', $key);
|
||||
$decoded = preg_match('#^[a-zA-Z\d/+]*={0,2}$#', $decoded) ? base64_decode($decoded) : false;
|
||||
}
|
||||
|
||||
if ($key === false) {
|
||||
if ($decoded !== false) {
|
||||
$key = $decoded;
|
||||
}
|
||||
|
||||
$components = array();
|
||||
|
||||
if (ord($this->_string_shift($key)) != CRYPT_RSA_ASN1_SEQUENCE) {
|
||||
return false;
|
||||
}
|
||||
if ($this->_decodeLength($key) != strlen($key)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$private = false;
|
||||
$components = array();
|
||||
$tag = ord($this->_string_shift($key));
|
||||
if ($tag == CRYPT_RSA_ASN1_SEQUENCE) {
|
||||
/* intended for keys for which OpenSSL's asn1parse returns the following:
|
||||
|
||||
0:d=0 hl=4 l= 290 cons: SEQUENCE
|
||||
4:d=1 hl=2 l= 13 cons: SEQUENCE
|
||||
6:d=2 hl=2 l= 9 prim: OBJECT :rsaEncryption
|
||||
17:d=2 hl=2 l= 0 prim: NULL
|
||||
19:d=1 hl=4 l= 271 prim: BIT STRING */
|
||||
$this->_string_shift($key, $this->_decodeLength($key));
|
||||
$this->_string_shift($key); // skip over the BIT STRING tag
|
||||
$this->_decodeLength($key); // skip over the BIT STRING length
|
||||
// "The initial octet shall encode, as an unsigned binary integer wtih bit 1 as the least significant bit, the number of
|
||||
// unused bits in teh final subsequent octet. The number shall be in the range zero to seven."
|
||||
// -- http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf (section 8.6.2.2)
|
||||
$this->_string_shift($key);
|
||||
if (ord($this->_string_shift($key)) != CRYPT_RSA_ASN1_SEQUENCE) {
|
||||
return false;
|
||||
}
|
||||
if ($this->_decodeLength($key) != strlen($key)) {
|
||||
return false;
|
||||
}
|
||||
$tag = ord($this->_string_shift($key));
|
||||
}
|
||||
if ($tag != CRYPT_RSA_ASN1_INTEGER) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->_string_shift($key); // skip over CRYPT_RSA_ASN1_SEQUENCE
|
||||
$this->_decodeLength($key); // skip over the length of the above sequence
|
||||
$this->_string_shift($key); // skip over CRYPT_RSA_ASN1_INTEGER
|
||||
$length = $this->_decodeLength($key);
|
||||
$temp = $this->_string_shift($key, $length);
|
||||
if (strlen($temp) != 1 || ord($temp) > 2) {
|
||||
@ -806,7 +851,9 @@ class Crypt_RSA {
|
||||
|
||||
return $components;
|
||||
}
|
||||
$this->_string_shift($key); // skip over CRYPT_RSA_ASN1_INTEGER
|
||||
if (ord($this->_string_shift($key)) != CRYPT_RSA_ASN1_INTEGER) {
|
||||
return false;
|
||||
}
|
||||
$length = $this->_decodeLength($key);
|
||||
$components['modulus'] = new Math_BigInteger($this->_string_shift($key, $length), -256);
|
||||
$this->_string_shift($key);
|
||||
@ -831,10 +878,14 @@ class Crypt_RSA {
|
||||
$length = $this->_decodeLength($key);
|
||||
$components['coefficients'] = array(2 => new Math_BigInteger($this->_string_shift($key, $length), -256));
|
||||
if (!empty($key)) {
|
||||
$key = substr($key, 1); // skip over CRYPT_RSA_ASN1_SEQUENCE
|
||||
if (ord($this->_string_shift($key)) != CRYPT_RSA_ASN1_INTEGER) {
|
||||
return false;
|
||||
}
|
||||
$this->_decodeLength($key);
|
||||
while (!empty($key)) {
|
||||
$key = substr($key, 1); // skip over CRYPT_RSA_ASN1_SEQUENCE
|
||||
if (ord($this->_string_shift($key)) != CRYPT_RSA_ASN1_SEQUENCE) {
|
||||
return false;
|
||||
}
|
||||
$this->_decodeLength($key);
|
||||
$key = substr($key, 1);
|
||||
$length = $this->_decodeLength($key);
|
||||
@ -855,13 +906,25 @@ class Crypt_RSA {
|
||||
return false;
|
||||
}
|
||||
|
||||
$components = array();
|
||||
extract(unpack('Nlength', $this->_string_shift($key, 4)));
|
||||
$components['modulus'] = new Math_BigInteger($this->_string_shift($key, $length), -256);
|
||||
extract(unpack('Nlength', $this->_string_shift($key, 4)));
|
||||
$components['publicExponent'] = new Math_BigInteger($this->_string_shift($key, $length), -256);
|
||||
$cleanup = substr($key, 0, 11) == "\0\0\0\7ssh-rsa";
|
||||
|
||||
return $components;
|
||||
extract(unpack('Nlength', $this->_string_shift($key, 4)));
|
||||
$publicExponent = new Math_BigInteger($this->_string_shift($key, $length), -256);
|
||||
extract(unpack('Nlength', $this->_string_shift($key, 4)));
|
||||
$modulus = new Math_BigInteger($this->_string_shift($key, $length), -256);
|
||||
|
||||
if ($cleanup && strlen($key)) {
|
||||
extract(unpack('Nlength', $this->_string_shift($key, 4)));
|
||||
return array(
|
||||
'modulus' => new Math_BigInteger($this->_string_shift($key, $length), -256),
|
||||
'publicExponent' => $modulus
|
||||
);
|
||||
} else {
|
||||
return array(
|
||||
'modulus' => $modulus,
|
||||
'publicExponent' => $publicExponent
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -47,7 +47,7 @@
|
||||
* @author Jim Wigginton <terrafrost@php.net>
|
||||
* @copyright MMVII Jim Wigginton
|
||||
* @license http://www.gnu.org/licenses/lgpl.txt
|
||||
* @version $Id: TripleDES.php,v 1.12 2010-02-09 06:10:26 terrafrost Exp $
|
||||
* @version $Id: TripleDES.php,v 1.13 2010-02-26 03:40:25 terrafrost Exp $
|
||||
* @link http://phpseclib.sourceforge.net
|
||||
*/
|
||||
|
||||
@ -284,7 +284,7 @@ class Crypt_TripleDES {
|
||||
$key = str_pad($key, 24, chr(0));
|
||||
// if $key is between 64 and 128-bits, use the first 64-bits as the last, per this:
|
||||
// http://php.net/function.mcrypt-encrypt#47973
|
||||
$key = $length <= 16 ? substr_replace($key, substr($key, 0, 8), 16) : substr($key, 0, 24);
|
||||
//$key = $length <= 16 ? substr_replace($key, substr($key, 0, 8), 16) : substr($key, 0, 24);
|
||||
}
|
||||
$this->key = $key;
|
||||
switch (true) {
|
||||
@ -386,7 +386,7 @@ class Crypt_TripleDES {
|
||||
$ciphertext = mcrypt_generic($this->enmcrypt, $plaintext);
|
||||
|
||||
if (!$this->continuousBuffer) {
|
||||
mcrypt_generic_init($this->enmcrypt, $this->keys, $this->encryptIV);
|
||||
mcrypt_generic_init($this->enmcrypt, $this->key, $this->encryptIV);
|
||||
}
|
||||
|
||||
return $ciphertext;
|
||||
@ -477,7 +477,7 @@ class Crypt_TripleDES {
|
||||
$plaintext = mdecrypt_generic($this->demcrypt, $ciphertext);
|
||||
|
||||
if (!$this->continuousBuffer) {
|
||||
mcrypt_generic_init($this->demcrypt, $this->keys, $this->decryptIV);
|
||||
mcrypt_generic_init($this->demcrypt, $this->key, $this->decryptIV);
|
||||
}
|
||||
|
||||
return $this->mode != 'ctr' ? $this->_unpad($plaintext) : $plaintext;
|
||||
|
@ -67,7 +67,7 @@
|
||||
* @author Jim Wigginton <terrafrost@php.net>
|
||||
* @copyright MMVI Jim Wigginton
|
||||
* @license http://www.gnu.org/licenses/lgpl.txt
|
||||
* @version $Id: BigInteger.php,v 1.29 2010-02-21 07:45:31 terrafrost Exp $
|
||||
* @version $Id: BigInteger.php,v 1.30 2010-02-26 03:40:26 terrafrost Exp $
|
||||
* @link http://pear.php.net/package/Math_BigInteger
|
||||
*/
|
||||
|
||||
@ -860,7 +860,7 @@ class Math_BigInteger {
|
||||
$carry = $sum >= MATH_BIGINTEGER_MAX_DIGIT52; // eg. floor($sum / 2**52); only possible values (in any base) are 0 and 1
|
||||
$sum = $carry ? $sum - MATH_BIGINTEGER_MAX_DIGIT52 : $sum;
|
||||
|
||||
$temp = floor($sum / 0x4000000);
|
||||
$temp = (int) ($sum / 0x4000000);
|
||||
|
||||
$value[$i] = $sum - 0x4000000 * $temp; // eg. a faster alternative to fmod($sum, 0x4000000)
|
||||
$value[$j] = $temp;
|
||||
@ -996,7 +996,7 @@ class Math_BigInteger {
|
||||
$carry = $sum < 0; // eg. floor($sum / 2**52); only possible values (in any base) are 0 and 1
|
||||
$sum = $carry ? $sum + MATH_BIGINTEGER_MAX_DIGIT52 : $sum;
|
||||
|
||||
$temp = floor($sum / 0x4000000);
|
||||
$temp = (int) ($sum / 0x4000000);
|
||||
|
||||
$x_value[$i] = $sum - 0x4000000 * $temp;
|
||||
$x_value[$j] = $temp;
|
||||
@ -1144,7 +1144,7 @@ class Math_BigInteger {
|
||||
|
||||
for ($j = 0; $j < $x_length; ++$j) { // ie. $i = 0
|
||||
$temp = $x_value[$j] * $y_value[0] + $carry; // $product_value[$k] == 0
|
||||
$carry = floor($temp / 0x4000000);
|
||||
$carry = (int) ($temp / 0x4000000);
|
||||
$product_value[$j] = $temp - 0x4000000 * $carry;
|
||||
}
|
||||
|
||||
@ -1157,7 +1157,7 @@ class Math_BigInteger {
|
||||
|
||||
for ($j = 0, $k = $i; $j < $x_length; ++$j, ++$k) {
|
||||
$temp = $product_value[$k] + $x_value[$j] * $y_value[$i] + $carry;
|
||||
$carry = floor($temp / 0x4000000);
|
||||
$carry = (int) ($temp / 0x4000000);
|
||||
$product_value[$k] = $temp - 0x4000000 * $carry;
|
||||
}
|
||||
|
||||
@ -1245,13 +1245,13 @@ class Math_BigInteger {
|
||||
$i2 = $i << 1;
|
||||
|
||||
$temp = $square_value[$i2] + $value[$i] * $value[$i];
|
||||
$carry = floor($temp / 0x4000000);
|
||||
$carry = (int) ($temp / 0x4000000);
|
||||
$square_value[$i2] = $temp - 0x4000000 * $carry;
|
||||
|
||||
// note how we start from $i+1 instead of 0 as we do in multiplication.
|
||||
for ($j = $i + 1, $k = $i2 + 1; $j <= $max_index; ++$j, ++$k) {
|
||||
$temp = $square_value[$k] + 2 * $value[$j] * $value[$i] + $carry;
|
||||
$carry = floor($temp / 0x4000000);
|
||||
$carry = (int) ($temp / 0x4000000);
|
||||
$square_value[$k] = $temp - 0x4000000 * $carry;
|
||||
}
|
||||
|
||||
@ -1449,7 +1449,7 @@ class Math_BigInteger {
|
||||
if ($x_window[0] == $y_window[0]) {
|
||||
$quotient_value[$q_index] = 0x3FFFFFF;
|
||||
} else {
|
||||
$quotient_value[$q_index] = floor(
|
||||
$quotient_value[$q_index] = (int) (
|
||||
($x_window[0] * 0x4000000 + $x_window[1])
|
||||
/
|
||||
$y_window[0]
|
||||
@ -1519,7 +1519,7 @@ class Math_BigInteger {
|
||||
|
||||
for ($i = count($dividend) - 1; $i >= 0; --$i) {
|
||||
$temp = 0x4000000 * $carry + $dividend[$i];
|
||||
$result[$i] = floor($temp / $divisor);
|
||||
$result[$i] = (int) ($temp / $divisor);
|
||||
$carry = $temp - $divisor * $result[$i];
|
||||
}
|
||||
|
||||
@ -2089,7 +2089,7 @@ class Math_BigInteger {
|
||||
|
||||
for ($j = 0; $j < $x_length; ++$j) { // ie. $i = 0, $k = $i
|
||||
$temp = $x_value[$j] * $y_value[0] + $carry; // $product_value[$k] == 0
|
||||
$carry = floor($temp / 0x4000000);
|
||||
$carry = (int) ($temp / 0x4000000);
|
||||
$product_value[$j] = $temp - 0x4000000 * $carry;
|
||||
}
|
||||
|
||||
@ -2105,7 +2105,7 @@ class Math_BigInteger {
|
||||
|
||||
for ($j = 0, $k = $i; $j < $x_length && $k < $stop; ++$j, ++$k) {
|
||||
$temp = $product_value[$k] + $x_value[$j] * $y_value[$i] + $carry;
|
||||
$carry = floor($temp / 0x4000000);
|
||||
$carry = (int) ($temp / 0x4000000);
|
||||
$product_value[$k] = $temp - 0x4000000 * $carry;
|
||||
}
|
||||
|
||||
@ -2154,7 +2154,7 @@ class Math_BigInteger {
|
||||
|
||||
for ($i = 0; $i < $k; ++$i) {
|
||||
$temp = $result[MATH_BIGINTEGER_VALUE][$i] * $cache[MATH_BIGINTEGER_DATA][$key];
|
||||
$temp = $temp - 0x4000000 * floor($temp / 0x4000000);
|
||||
$temp = $temp - 0x4000000 * ((int) ($temp / 0x4000000));
|
||||
$temp = $this->_regularMultiply(array($temp), $n);
|
||||
$temp = array_merge($this->_array_repeat(0, $i), $temp);
|
||||
$result = $this->_add($result[MATH_BIGINTEGER_VALUE], false, $temp, false);
|
||||
@ -2206,9 +2206,9 @@ class Math_BigInteger {
|
||||
$a = array(MATH_BIGINTEGER_VALUE => $this->_array_repeat(0, $n + 1));
|
||||
for ($i = 0; $i < $n; ++$i) {
|
||||
$temp = $a[MATH_BIGINTEGER_VALUE][0] + $x[$i] * $y[0];
|
||||
$temp = $temp - 0x4000000 * floor($temp / 0x4000000);
|
||||
$temp = $temp - 0x4000000 * ((int) ($temp / 0x4000000));
|
||||
$temp = $temp * $cache[MATH_BIGINTEGER_DATA][$key];
|
||||
$temp = $temp - 0x4000000 * floor($temp / 0x4000000);
|
||||
$temp = $temp - 0x4000000 * ((int) ($temp / 0x4000000));
|
||||
$temp = $this->_add($this->_regularMultiply(array($x[$i]), $y), false, $this->_regularMultiply(array($temp), $m), false);
|
||||
$a = $this->_add($a[MATH_BIGINTEGER_VALUE], false, $temp[MATH_BIGINTEGER_VALUE], false);
|
||||
$a[MATH_BIGINTEGER_VALUE] = array_slice($a[MATH_BIGINTEGER_VALUE], 1);
|
||||
@ -3307,7 +3307,7 @@ class Math_BigInteger {
|
||||
return;
|
||||
}
|
||||
|
||||
$num_digits = floor($shift / 26);
|
||||
$num_digits = (int) ($shift / 26);
|
||||
$shift %= 26;
|
||||
$shift = 1 << $shift;
|
||||
|
||||
@ -3315,7 +3315,7 @@ class Math_BigInteger {
|
||||
|
||||
for ($i = 0; $i < count($this->value); ++$i) {
|
||||
$temp = $this->value[$i] * $shift + $carry;
|
||||
$carry = floor($temp / 0x4000000);
|
||||
$carry = (int) ($temp / 0x4000000);
|
||||
$this->value[$i] = $temp - $carry * 0x4000000;
|
||||
}
|
||||
|
||||
@ -3342,7 +3342,7 @@ class Math_BigInteger {
|
||||
return;
|
||||
}
|
||||
|
||||
$num_digits = floor($shift / 26);
|
||||
$num_digits = (int) ($shift / 26);
|
||||
$shift %= 26;
|
||||
$carry_shift = 26 - $shift;
|
||||
$carry_mask = (1 << $shift) - 1;
|
||||
|
Loading…
Reference in New Issue
Block a user