mirror of
https://github.com/phpseclib/phpseclib.git
synced 2024-12-24 02:55:30 +00:00
SymmetricCiphers: don't cache "hi-optimized code"
Also add a new engine - ENGINE_EVAL. Previously ENGINE_INTERNAL had three different modes - a "hi-optimized" version, a "lo-optimized" version and a version that didn't depend on create_function and there wasn't a way to really isolate these modes and test them individually.
This commit is contained in:
parent
2a1177b256
commit
d34a911402
@ -478,113 +478,82 @@ class Blowfish extends BlockCipher
|
||||
*/
|
||||
protected function setupInlineCrypt()
|
||||
{
|
||||
$lambda_functions =& self::getLambdaFunctions();
|
||||
|
||||
// We create max. 10 hi-optimized code for memory reason. Means: For each $key one ultra fast inline-crypt function.
|
||||
// (Currently, for Blowfish, one generated $lambda_function cost on php5.5@32bit ~100kb unfreeable mem and ~180kb on php5.5@64bit)
|
||||
// After that, we'll still create very fast optimized code but not the hi-ultimative code, for each $mode one.
|
||||
$gen_hi_opt_code = (bool)(count($lambda_functions) < 10);
|
||||
|
||||
// Generation of a unique hash for our generated code
|
||||
$code_hash = "Crypt_Blowfish, {$this->mode}";
|
||||
if ($gen_hi_opt_code) {
|
||||
$code_hash = str_pad($code_hash, 32) . $this->hashInlineCryptFunction($this->key);
|
||||
}
|
||||
|
||||
if (!isset($lambda_functions[$code_hash])) {
|
||||
switch (true) {
|
||||
case $gen_hi_opt_code:
|
||||
$p = $this->bctx['p'];
|
||||
$init_crypt = '
|
||||
static $sb_0, $sb_1, $sb_2, $sb_3;
|
||||
if (!$sb_0) {
|
||||
$sb_0 = $this->bctx["sb"][0];
|
||||
$sb_1 = $this->bctx["sb"][1];
|
||||
$sb_2 = $this->bctx["sb"][2];
|
||||
$sb_3 = $this->bctx["sb"][3];
|
||||
}
|
||||
';
|
||||
break;
|
||||
default:
|
||||
$p = [];
|
||||
for ($i = 0; $i < 18; ++$i) {
|
||||
$p[] = '$p_' . $i;
|
||||
}
|
||||
$init_crypt = '
|
||||
list($sb_0, $sb_1, $sb_2, $sb_3) = $this->bctx["sb"];
|
||||
list(' . implode(',', $p) . ') = $this->bctx["p"];
|
||||
|
||||
';
|
||||
$p = $this->bctx['p'];
|
||||
$init_crypt = '
|
||||
static $sb_0, $sb_1, $sb_2, $sb_3;
|
||||
if (!$sb_0) {
|
||||
$sb_0 = $this->bctx["sb"][0];
|
||||
$sb_1 = $this->bctx["sb"][1];
|
||||
$sb_2 = $this->bctx["sb"][2];
|
||||
$sb_3 = $this->bctx["sb"][3];
|
||||
}
|
||||
';
|
||||
|
||||
// Generating encrypt code:
|
||||
$encrypt_block = '
|
||||
$in = unpack("N*", $in);
|
||||
$l = $in[1];
|
||||
$r = $in[2];
|
||||
';
|
||||
for ($i = 0; $i < 16; $i+= 2) {
|
||||
$encrypt_block.= '
|
||||
$l^= ' . $p[$i] . ';
|
||||
$r^= ($sb_0[$l >> 24 & 0xff] +
|
||||
$sb_1[$l >> 16 & 0xff] ^
|
||||
$sb_2[$l >> 8 & 0xff]) +
|
||||
$sb_3[$l & 0xff];
|
||||
|
||||
$r^= ' . $p[$i + 1] . ';
|
||||
$l^= ($sb_0[$r >> 24 & 0xff] +
|
||||
$sb_1[$r >> 16 & 0xff] ^
|
||||
$sb_2[$r >> 8 & 0xff]) +
|
||||
$sb_3[$r & 0xff];
|
||||
';
|
||||
}
|
||||
// Generating encrypt code:
|
||||
$encrypt_block = '
|
||||
$in = unpack("N*", $in);
|
||||
$l = $in[1];
|
||||
$r = $in[2];
|
||||
';
|
||||
for ($i = 0; $i < 16; $i+= 2) {
|
||||
$encrypt_block.= '
|
||||
$in = pack("N*",
|
||||
$r ^ ' . $p[17] . ',
|
||||
$l ^ ' . $p[16] . '
|
||||
);
|
||||
$l^= ' . $p[$i] . ';
|
||||
$r^= ($sb_0[$l >> 24 & 0xff] +
|
||||
$sb_1[$l >> 16 & 0xff] ^
|
||||
$sb_2[$l >> 8 & 0xff]) +
|
||||
$sb_3[$l & 0xff];
|
||||
|
||||
$r^= ' . $p[$i + 1] . ';
|
||||
$l^= ($sb_0[$r >> 24 & 0xff] +
|
||||
$sb_1[$r >> 16 & 0xff] ^
|
||||
$sb_2[$r >> 8 & 0xff]) +
|
||||
$sb_3[$r & 0xff];
|
||||
';
|
||||
|
||||
// Generating decrypt code:
|
||||
$decrypt_block = '
|
||||
$in = unpack("N*", $in);
|
||||
$l = $in[1];
|
||||
$r = $in[2];
|
||||
';
|
||||
|
||||
for ($i = 17; $i > 2; $i-= 2) {
|
||||
$decrypt_block.= '
|
||||
$l^= ' . $p[$i] . ';
|
||||
$r^= ($sb_0[$l >> 24 & 0xff] +
|
||||
$sb_1[$l >> 16 & 0xff] ^
|
||||
$sb_2[$l >> 8 & 0xff]) +
|
||||
$sb_3[$l & 0xff];
|
||||
|
||||
$r^= ' . $p[$i - 1] . ';
|
||||
$l^= ($sb_0[$r >> 24 & 0xff] +
|
||||
$sb_1[$r >> 16 & 0xff] ^
|
||||
$sb_2[$r >> 8 & 0xff]) +
|
||||
$sb_3[$r & 0xff];
|
||||
';
|
||||
}
|
||||
|
||||
$decrypt_block.= '
|
||||
$in = pack("N*",
|
||||
$r ^ ' . $p[0] . ',
|
||||
$l ^ ' . $p[1] . '
|
||||
);
|
||||
';
|
||||
|
||||
$lambda_functions[$code_hash] = $this->createInlineCryptFunction(
|
||||
[
|
||||
'init_crypt' => $init_crypt,
|
||||
'init_encrypt' => '',
|
||||
'init_decrypt' => '',
|
||||
'encrypt_block' => $encrypt_block,
|
||||
'decrypt_block' => $decrypt_block
|
||||
]
|
||||
);
|
||||
}
|
||||
$this->inline_crypt = \Closure::bind($lambda_functions[$code_hash], $this, $this->getClassContext());
|
||||
$encrypt_block.= '
|
||||
$in = pack("N*",
|
||||
$r ^ ' . $p[17] . ',
|
||||
$l ^ ' . $p[16] . '
|
||||
);
|
||||
';
|
||||
// Generating decrypt code:
|
||||
$decrypt_block = '
|
||||
$in = unpack("N*", $in);
|
||||
$l = $in[1];
|
||||
$r = $in[2];
|
||||
';
|
||||
|
||||
for ($i = 17; $i > 2; $i-= 2) {
|
||||
$decrypt_block.= '
|
||||
$l^= ' . $p[$i] . ';
|
||||
$r^= ($sb_0[$l >> 24 & 0xff] +
|
||||
$sb_1[$l >> 16 & 0xff] ^
|
||||
$sb_2[$l >> 8 & 0xff]) +
|
||||
$sb_3[$l & 0xff];
|
||||
|
||||
$r^= ' . $p[$i - 1] . ';
|
||||
$l^= ($sb_0[$r >> 24 & 0xff] +
|
||||
$sb_1[$r >> 16 & 0xff] ^
|
||||
$sb_2[$r >> 8 & 0xff]) +
|
||||
$sb_3[$r & 0xff];
|
||||
';
|
||||
}
|
||||
|
||||
$decrypt_block.= '
|
||||
$in = pack("N*",
|
||||
$r ^ ' . $p[0] . ',
|
||||
$l ^ ' . $p[1] . '
|
||||
);
|
||||
';
|
||||
|
||||
$this->inline_crypt = $this->createInlineCryptFunction(
|
||||
[
|
||||
'init_crypt' => $init_crypt,
|
||||
'init_encrypt' => '',
|
||||
'init_decrypt' => '',
|
||||
'encrypt_block' => $encrypt_block,
|
||||
'decrypt_block' => $decrypt_block
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -92,15 +92,6 @@ abstract class SymmetricKey
|
||||
const MODE_STREAM = 5;
|
||||
/**#@-*/
|
||||
|
||||
/**
|
||||
* Whirlpool available flag
|
||||
*
|
||||
* @see \phpseclib\Crypt\Common\SymmetricKey::_hashInlineCryptFunction()
|
||||
* @var bool
|
||||
* @access private
|
||||
*/
|
||||
private static $WHIRLPOOL_AVAILABLE;
|
||||
|
||||
/**#@+
|
||||
* @access private
|
||||
* @see \phpseclib\Crypt\Common\SymmetricKey::__construct()
|
||||
@ -110,13 +101,17 @@ abstract class SymmetricKey
|
||||
*/
|
||||
const ENGINE_INTERNAL = 1;
|
||||
/**
|
||||
* Base value for the mcrypt implementation $engine switch
|
||||
* Base value for the eval() implementation $engine switch
|
||||
*/
|
||||
const ENGINE_MCRYPT = 2;
|
||||
const ENGINE_EVAL = 2;
|
||||
/**
|
||||
* Base value for the mcrypt implementation $engine switch
|
||||
*/
|
||||
const ENGINE_OPENSSL = 3;
|
||||
const ENGINE_MCRYPT = 3;
|
||||
/**
|
||||
* Base value for the mcrypt implementation $engine switch
|
||||
*/
|
||||
const ENGINE_OPENSSL = 4;
|
||||
/**#@-*/
|
||||
|
||||
/**
|
||||
@ -480,11 +475,6 @@ abstract class SymmetricKey
|
||||
}
|
||||
|
||||
$this->mode = $mode;
|
||||
|
||||
// Determining whether inline crypting can be used by the cipher
|
||||
if ($this->use_inline_crypt !== false) {
|
||||
$this->use_inline_crypt = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -982,7 +972,7 @@ abstract class SymmetricKey
|
||||
$this->setup();
|
||||
$this->changed = false;
|
||||
}
|
||||
if ($this->use_inline_crypt) {
|
||||
if ($this->engine === self::ENGINE_EVAL) {
|
||||
$inline = $this->inline_crypt;
|
||||
return $inline('encrypt', $plaintext);
|
||||
}
|
||||
@ -1266,7 +1256,7 @@ abstract class SymmetricKey
|
||||
$this->setup();
|
||||
$this->changed = false;
|
||||
}
|
||||
if ($this->use_inline_crypt) {
|
||||
if ($this->engine === self::ENGINE_EVAL) {
|
||||
$inline = $this->inline_crypt;
|
||||
return $inline('decrypt', $ciphertext);
|
||||
}
|
||||
@ -1696,9 +1686,7 @@ abstract class SymmetricKey
|
||||
}
|
||||
$this->openssl_emulate_ctr = false;
|
||||
$result = $this->cipher_name_openssl &&
|
||||
extension_loaded('openssl') &&
|
||||
// PHP 5.3.0 - 5.3.2 did not let you set IV's
|
||||
version_compare(PHP_VERSION, '5.3.3', '>=');
|
||||
extension_loaded('openssl');
|
||||
if (!$result) {
|
||||
return false;
|
||||
}
|
||||
@ -1721,6 +1709,8 @@ abstract class SymmetricKey
|
||||
return $this->cipher_name_mcrypt &&
|
||||
extension_loaded('mcrypt') &&
|
||||
in_array($this->cipher_name_mcrypt, @mcrypt_list_algorithms());
|
||||
case self::ENGINE_EVAL:
|
||||
return method_exists($this, 'setupInlineCrypt');
|
||||
case self::ENGINE_INTERNAL:
|
||||
return true;
|
||||
}
|
||||
@ -1737,7 +1727,9 @@ abstract class SymmetricKey
|
||||
*
|
||||
* - \phpseclib\Crypt\Common\SymmetricKey::ENGINE_MCRYPT [fast]
|
||||
*
|
||||
* - \phpseclib\Crypt\Common\SymmetricKey::ENGINE_INTERNAL [slow]
|
||||
* - \phpseclib\Crypt\Common\SymmetricKey::ENGINE_EVAL [slow]
|
||||
*
|
||||
* - \phpseclib\Crypt\Common\SymmetricKey::ENGINE_INTERNAL [slowest]
|
||||
*
|
||||
* If the preferred crypt engine is not available the fastest available one will be used
|
||||
*
|
||||
@ -1751,6 +1743,7 @@ abstract class SymmetricKey
|
||||
//case self::ENGINE_OPENSSL;
|
||||
case self::ENGINE_MCRYPT:
|
||||
case self::ENGINE_INTERNAL:
|
||||
case self::ENGINE_EVAL:
|
||||
$this->preferredEngine = $engine;
|
||||
break;
|
||||
default:
|
||||
@ -1784,7 +1777,8 @@ abstract class SymmetricKey
|
||||
$candidateEngines = [
|
||||
$this->preferredEngine,
|
||||
self::ENGINE_OPENSSL,
|
||||
self::ENGINE_MCRYPT
|
||||
self::ENGINE_MCRYPT,
|
||||
self::ENGINE_EVAL
|
||||
];
|
||||
foreach ($candidateEngines as $engine) {
|
||||
if ($this->isValidEngine($engine)) {
|
||||
@ -1876,7 +1870,7 @@ abstract class SymmetricKey
|
||||
$this->clearBuffers();
|
||||
$this->setupKey();
|
||||
|
||||
if ($this->use_inline_crypt) {
|
||||
if ($this->engine === self::ENGINE_EVAL) {
|
||||
$this->setupInlineCrypt();
|
||||
}
|
||||
}
|
||||
@ -2064,9 +2058,7 @@ abstract class SymmetricKey
|
||||
*
|
||||
* _setupInlineCrypt() would be called only if:
|
||||
*
|
||||
* - $engine == self::ENGINE_INTERNAL and
|
||||
*
|
||||
* - $use_inline_crypt === true
|
||||
* - $this->engine === self::ENGINE_EVAL
|
||||
*
|
||||
* - each time on _setup(), after(!) _setupKey()
|
||||
*
|
||||
@ -2114,16 +2106,7 @@ abstract class SymmetricKey
|
||||
* @access private
|
||||
* @internal If a Crypt_* class providing inline crypting it must extend _setupInlineCrypt()
|
||||
*/
|
||||
protected function setupInlineCrypt()
|
||||
{
|
||||
// If, for any reason, an extending \phpseclib\Crypt\Common\SymmetricKey() \phpseclib\Crypt\* class
|
||||
// not using inline crypting then it must be ensured that: $this->use_inline_crypt = false
|
||||
// ie in the class var declaration of $use_inline_crypt in general for the \phpseclib\Crypt\* class,
|
||||
// in the constructor at object instance-time
|
||||
// or, if it's runtime-specific, at runtime
|
||||
|
||||
$this->use_inline_crypt = false;
|
||||
}
|
||||
//protected function setupInlineCrypt();
|
||||
|
||||
/**
|
||||
* Creates the performance-optimized function for en/decrypt()
|
||||
@ -2586,63 +2569,7 @@ abstract class SymmetricKey
|
||||
|
||||
eval('$func = function ($_action, $_text) { ' . $init_crypt . 'if ($_action == "encrypt") { ' . $encrypt . ' } else { ' . $decrypt . ' }};');
|
||||
|
||||
return $func;
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds the lambda_functions table (classwide)
|
||||
*
|
||||
* Each name of the lambda function, created from
|
||||
* _setupInlineCrypt() && _createInlineCryptFunction()
|
||||
* is stored, classwide (!), here for reusing.
|
||||
*
|
||||
* The string-based index of $function is a classwide
|
||||
* unique value representing, at least, the $mode of
|
||||
* operation (or more... depends of the optimizing level)
|
||||
* for which $mode the lambda function was created.
|
||||
*
|
||||
* @access private
|
||||
* @return array &$functions
|
||||
*/
|
||||
protected function &getLambdaFunctions()
|
||||
{
|
||||
static $functions = [];
|
||||
return $functions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a digest from $bytes
|
||||
*
|
||||
* @see self::setupInlineCrypt()
|
||||
* @access private
|
||||
* @param $bytes
|
||||
* @return string
|
||||
*/
|
||||
protected function hashInlineCryptFunction($bytes)
|
||||
{
|
||||
if (!isset(self::$WHIRLPOOL_AVAILABLE)) {
|
||||
self::$WHIRLPOOL_AVAILABLE = extension_loaded('hash') && in_array('whirlpool', hash_algos());
|
||||
}
|
||||
|
||||
$result = '';
|
||||
$hash = $bytes;
|
||||
|
||||
switch (true) {
|
||||
case self::$WHIRLPOOL_AVAILABLE:
|
||||
foreach (str_split($bytes, 64) as $t) {
|
||||
$hash = hash('whirlpool', $hash, true);
|
||||
$result .= $t ^ $hash;
|
||||
}
|
||||
return $result . hash('whirlpool', $hash, true);
|
||||
default:
|
||||
$len = strlen($bytes);
|
||||
for ($i = 0; $i < $len; $i+=20) {
|
||||
$t = substr($bytes, $i, 20);
|
||||
$hash = sha1($hash, true);
|
||||
$result .= $t ^ $hash;
|
||||
}
|
||||
return $result . sha1($hash, true);
|
||||
}
|
||||
return \Closure::bind($func, $this, $this->getClassContext());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1301,155 +1301,108 @@ class DES extends BlockCipher
|
||||
*/
|
||||
protected function setupInlineCrypt()
|
||||
{
|
||||
$lambda_functions =& self::getLambdaFunctions();
|
||||
|
||||
// Engine configuration for:
|
||||
// - DES ($des_rounds == 1) or
|
||||
// - 3DES ($des_rounds == 3)
|
||||
$des_rounds = $this->des_rounds;
|
||||
|
||||
// We create max. 10 hi-optimized code for memory reason. Means: For each $key one ultra fast inline-crypt function.
|
||||
// (Currently, for DES, one generated $lambda_function cost on php5.5@32bit ~135kb unfreeable mem and ~230kb on php5.5@64bit)
|
||||
// (Currently, for TripleDES, one generated $lambda_function cost on php5.5@32bit ~240kb unfreeable mem and ~340kb on php5.5@64bit)
|
||||
// After that, we'll still create very fast optimized code but not the hi-ultimative code, for each $mode one
|
||||
$gen_hi_opt_code = (bool)( count($lambda_functions) < 10 );
|
||||
|
||||
// Generation of a unique hash for our generated code
|
||||
$code_hash = "Crypt_DES, $des_rounds, {$this->mode}";
|
||||
if ($gen_hi_opt_code) {
|
||||
// For hi-optimized code, we create for each combination of
|
||||
// $mode, $des_rounds and $this->key its own encrypt/decrypt function.
|
||||
// After max 10 hi-optimized functions, we create generic
|
||||
// (still very fast.. but not ultra) functions for each $mode/$des_rounds
|
||||
// Currently 2 * 5 generic functions will be then max. possible.
|
||||
$code_hash = str_pad($code_hash, 32) . $this->hashInlineCryptFunction($this->key);
|
||||
}
|
||||
|
||||
// Is there a re-usable $lambda_functions in there? If not, we have to create it.
|
||||
if (!isset($lambda_functions[$code_hash])) {
|
||||
// Init code for both, encrypt and decrypt.
|
||||
$init_crypt = 'static $sbox1, $sbox2, $sbox3, $sbox4, $sbox5, $sbox6, $sbox7, $sbox8, $shuffleip, $shuffleinvip;
|
||||
if (!$sbox1) {
|
||||
$sbox1 = array_map("intval", $this->sbox1);
|
||||
$sbox2 = array_map("intval", $this->sbox2);
|
||||
$sbox3 = array_map("intval", $this->sbox3);
|
||||
$sbox4 = array_map("intval", $this->sbox4);
|
||||
$sbox5 = array_map("intval", $this->sbox5);
|
||||
$sbox6 = array_map("intval", $this->sbox6);
|
||||
$sbox7 = array_map("intval", $this->sbox7);
|
||||
$sbox8 = array_map("intval", $this->sbox8);'
|
||||
/* Merge $shuffle with $[inv]ipmap */ . '
|
||||
for ($i = 0; $i < 256; ++$i) {
|
||||
$shuffleip[] = $this->shuffle[$this->ipmap[$i]];
|
||||
$shuffleinvip[] = $this->shuffle[$this->invipmap[$i]];
|
||||
}
|
||||
$init_crypt = 'static $sbox1, $sbox2, $sbox3, $sbox4, $sbox5, $sbox6, $sbox7, $sbox8, $shuffleip, $shuffleinvip;
|
||||
if (!$sbox1) {
|
||||
$sbox1 = array_map("intval", $this->sbox1);
|
||||
$sbox2 = array_map("intval", $this->sbox2);
|
||||
$sbox3 = array_map("intval", $this->sbox3);
|
||||
$sbox4 = array_map("intval", $this->sbox4);
|
||||
$sbox5 = array_map("intval", $this->sbox5);
|
||||
$sbox6 = array_map("intval", $this->sbox6);
|
||||
$sbox7 = array_map("intval", $this->sbox7);
|
||||
$sbox8 = array_map("intval", $this->sbox8);'
|
||||
/* Merge $shuffle with $[inv]ipmap */ . '
|
||||
for ($i = 0; $i < 256; ++$i) {
|
||||
$shuffleip[] = $this->shuffle[$this->ipmap[$i]];
|
||||
$shuffleinvip[] = $this->shuffle[$this->invipmap[$i]];
|
||||
}
|
||||
}
|
||||
';
|
||||
|
||||
$k = [
|
||||
self::ENCRYPT => $this->keys[self::ENCRYPT],
|
||||
self::DECRYPT => $this->keys[self::DECRYPT]
|
||||
];
|
||||
$init_encrypt = '';
|
||||
$init_decrypt = '';
|
||||
|
||||
// Creating code for en- and decryption.
|
||||
$crypt_block = [];
|
||||
foreach ([self::ENCRYPT, self::DECRYPT] as $c) {
|
||||
/* Do the initial IP permutation. */
|
||||
$crypt_block[$c] = '
|
||||
$in = unpack("N*", $in);
|
||||
$l = $in[1];
|
||||
$r = $in[2];
|
||||
$in = unpack("N*",
|
||||
($shuffleip[ $r & 0xFF] & "\x80\x80\x80\x80\x80\x80\x80\x80") |
|
||||
($shuffleip[($r >> 8) & 0xFF] & "\x40\x40\x40\x40\x40\x40\x40\x40") |
|
||||
($shuffleip[($r >> 16) & 0xFF] & "\x20\x20\x20\x20\x20\x20\x20\x20") |
|
||||
($shuffleip[($r >> 24) & 0xFF] & "\x10\x10\x10\x10\x10\x10\x10\x10") |
|
||||
($shuffleip[ $l & 0xFF] & "\x08\x08\x08\x08\x08\x08\x08\x08") |
|
||||
($shuffleip[($l >> 8) & 0xFF] & "\x04\x04\x04\x04\x04\x04\x04\x04") |
|
||||
($shuffleip[($l >> 16) & 0xFF] & "\x02\x02\x02\x02\x02\x02\x02\x02") |
|
||||
($shuffleip[($l >> 24) & 0xFF] & "\x01\x01\x01\x01\x01\x01\x01\x01")
|
||||
);
|
||||
' . /* Extract L0 and R0 */ '
|
||||
$l = $in[1];
|
||||
$r = $in[2];
|
||||
';
|
||||
|
||||
switch (true) {
|
||||
case $gen_hi_opt_code:
|
||||
// In Hi-optimized code mode, we use our [3]DES key schedule as hardcoded integers.
|
||||
// No futher initialisation of the $keys schedule is necessary.
|
||||
// That is the extra performance boost.
|
||||
$k = [
|
||||
self::ENCRYPT => $this->keys[self::ENCRYPT],
|
||||
self::DECRYPT => $this->keys[self::DECRYPT]
|
||||
];
|
||||
$init_encrypt = '';
|
||||
$init_decrypt = '';
|
||||
break;
|
||||
default:
|
||||
// In generic optimized code mode, we have to use, as the best compromise [currently],
|
||||
// our key schedule as $ke/$kd arrays. (with hardcoded indexes...)
|
||||
$k = [
|
||||
self::ENCRYPT => [],
|
||||
self::DECRYPT => []
|
||||
];
|
||||
for ($i = 0, $c = count($this->keys[self::ENCRYPT]); $i < $c; ++$i) {
|
||||
$k[self::ENCRYPT][$i] = '$ke[' . $i . ']';
|
||||
$k[self::DECRYPT][$i] = '$kd[' . $i . ']';
|
||||
}
|
||||
$init_encrypt = '$ke = $this->keys[self::ENCRYPT];';
|
||||
$init_decrypt = '$kd = $this->keys[self::DECRYPT];';
|
||||
break;
|
||||
}
|
||||
$l = '$l';
|
||||
$r = '$r';
|
||||
|
||||
// Creating code for en- and decryption.
|
||||
$crypt_block = [];
|
||||
foreach ([self::ENCRYPT, self::DECRYPT] as $c) {
|
||||
/* Do the initial IP permutation. */
|
||||
$crypt_block[$c] = '
|
||||
$in = unpack("N*", $in);
|
||||
$l = $in[1];
|
||||
$r = $in[2];
|
||||
$in = unpack("N*",
|
||||
($shuffleip[ $r & 0xFF] & "\x80\x80\x80\x80\x80\x80\x80\x80") |
|
||||
($shuffleip[($r >> 8) & 0xFF] & "\x40\x40\x40\x40\x40\x40\x40\x40") |
|
||||
($shuffleip[($r >> 16) & 0xFF] & "\x20\x20\x20\x20\x20\x20\x20\x20") |
|
||||
($shuffleip[($r >> 24) & 0xFF] & "\x10\x10\x10\x10\x10\x10\x10\x10") |
|
||||
($shuffleip[ $l & 0xFF] & "\x08\x08\x08\x08\x08\x08\x08\x08") |
|
||||
($shuffleip[($l >> 8) & 0xFF] & "\x04\x04\x04\x04\x04\x04\x04\x04") |
|
||||
($shuffleip[($l >> 16) & 0xFF] & "\x02\x02\x02\x02\x02\x02\x02\x02") |
|
||||
($shuffleip[($l >> 24) & 0xFF] & "\x01\x01\x01\x01\x01\x01\x01\x01")
|
||||
);
|
||||
' . /* Extract L0 and R0 */ '
|
||||
$l = $in[1];
|
||||
$r = $in[2];
|
||||
';
|
||||
// Perform DES or 3DES.
|
||||
for ($ki = -1, $des_round = 0; $des_round < $des_rounds; ++$des_round) {
|
||||
// Perform the 16 steps.
|
||||
for ($i = 0; $i < 16; ++$i) {
|
||||
// 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.
|
||||
$crypt_block[$c].= '
|
||||
$b1 = ((' . $r . ' >> 3) & 0x1FFFFFFF) ^ (' . $r . ' << 29) ^ ' . $k[$c][++$ki] . ';
|
||||
$b2 = ((' . $r . ' >> 31) & 0x00000001) ^ (' . $r . ' << 1) ^ ' . $k[$c][++$ki] . ';' .
|
||||
/* S-box indexing. */
|
||||
$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 . ';
|
||||
';
|
||||
// end of "the Feistel (F) function"
|
||||
|
||||
$l = '$l';
|
||||
$r = '$r';
|
||||
|
||||
// Perform DES or 3DES.
|
||||
for ($ki = -1, $des_round = 0; $des_round < $des_rounds; ++$des_round) {
|
||||
// Perform the 16 steps.
|
||||
for ($i = 0; $i < 16; ++$i) {
|
||||
// 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.
|
||||
$crypt_block[$c].= '
|
||||
$b1 = ((' . $r . ' >> 3) & 0x1FFFFFFF) ^ (' . $r . ' << 29) ^ ' . $k[$c][++$ki] . ';
|
||||
$b2 = ((' . $r . ' >> 31) & 0x00000001) ^ (' . $r . ' << 1) ^ ' . $k[$c][++$ki] . ';' .
|
||||
/* S-box indexing. */
|
||||
$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 . ';
|
||||
';
|
||||
// end of "the Feistel (F) function"
|
||||
|
||||
// swap L & R
|
||||
list($l, $r) = [$r, $l];
|
||||
}
|
||||
// swap L & R
|
||||
list($l, $r) = [$r, $l];
|
||||
}
|
||||
|
||||
// Perform the inverse IP permutation.
|
||||
$crypt_block[$c].= '$in =
|
||||
($shuffleinvip[($l >> 24) & 0xFF] & "\x80\x80\x80\x80\x80\x80\x80\x80") |
|
||||
($shuffleinvip[($r >> 24) & 0xFF] & "\x40\x40\x40\x40\x40\x40\x40\x40") |
|
||||
($shuffleinvip[($l >> 16) & 0xFF] & "\x20\x20\x20\x20\x20\x20\x20\x20") |
|
||||
($shuffleinvip[($r >> 16) & 0xFF] & "\x10\x10\x10\x10\x10\x10\x10\x10") |
|
||||
($shuffleinvip[($l >> 8) & 0xFF] & "\x08\x08\x08\x08\x08\x08\x08\x08") |
|
||||
($shuffleinvip[($r >> 8) & 0xFF] & "\x04\x04\x04\x04\x04\x04\x04\x04") |
|
||||
($shuffleinvip[ $l & 0xFF] & "\x02\x02\x02\x02\x02\x02\x02\x02") |
|
||||
($shuffleinvip[ $r & 0xFF] & "\x01\x01\x01\x01\x01\x01\x01\x01");
|
||||
';
|
||||
list($l, $r) = [$r, $l];
|
||||
}
|
||||
|
||||
// Creates the inline-crypt function
|
||||
$lambda_functions[$code_hash] = $this->createInlineCryptFunction(
|
||||
[
|
||||
'init_crypt' => $init_crypt,
|
||||
'init_encrypt' => $init_encrypt,
|
||||
'init_decrypt' => $init_decrypt,
|
||||
'encrypt_block' => $crypt_block[self::ENCRYPT],
|
||||
'decrypt_block' => $crypt_block[self::DECRYPT]
|
||||
]
|
||||
);
|
||||
// Perform the inverse IP permutation.
|
||||
$crypt_block[$c].= '$in =
|
||||
($shuffleinvip[($l >> 24) & 0xFF] & "\x80\x80\x80\x80\x80\x80\x80\x80") |
|
||||
($shuffleinvip[($r >> 24) & 0xFF] & "\x40\x40\x40\x40\x40\x40\x40\x40") |
|
||||
($shuffleinvip[($l >> 16) & 0xFF] & "\x20\x20\x20\x20\x20\x20\x20\x20") |
|
||||
($shuffleinvip[($r >> 16) & 0xFF] & "\x10\x10\x10\x10\x10\x10\x10\x10") |
|
||||
($shuffleinvip[($l >> 8) & 0xFF] & "\x08\x08\x08\x08\x08\x08\x08\x08") |
|
||||
($shuffleinvip[($r >> 8) & 0xFF] & "\x04\x04\x04\x04\x04\x04\x04\x04") |
|
||||
($shuffleinvip[ $l & 0xFF] & "\x02\x02\x02\x02\x02\x02\x02\x02") |
|
||||
($shuffleinvip[ $r & 0xFF] & "\x01\x01\x01\x01\x01\x01\x01\x01");
|
||||
';
|
||||
}
|
||||
|
||||
// Set the inline-crypt function as callback in: $this->inline_crypt
|
||||
$this->inline_crypt = \Closure::bind($lambda_functions[$code_hash], $this, $this->getClassContext());
|
||||
// Creates the inline-crypt function
|
||||
$this->inline_crypt = $this->createInlineCryptFunction(
|
||||
[
|
||||
'init_crypt' => $init_crypt,
|
||||
'init_encrypt' => $init_encrypt,
|
||||
'init_decrypt' => $init_decrypt,
|
||||
'encrypt_block' => $crypt_block[self::ENCRYPT],
|
||||
'decrypt_block' => $crypt_block[self::DECRYPT]
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -578,132 +578,103 @@ class RC2 extends BlockCipher
|
||||
*/
|
||||
protected function setupInlineCrypt()
|
||||
{
|
||||
$lambda_functions =& self::getLambdaFunctions();
|
||||
// Init code for both, encrypt and decrypt.
|
||||
$init_crypt = '$keys = $this->keys;';
|
||||
|
||||
// The first 10 generated $lambda_functions will use the $keys hardcoded as integers
|
||||
// for the mixing rounds, for better inline crypt performance [~20% faster].
|
||||
// But for memory reason we have to limit those ultra-optimized $lambda_functions to an amount of 10.
|
||||
// (Currently, for Crypt_RC2, one generated $lambda_function cost on php5.5@32bit ~60kb unfreeable mem and ~100kb on php5.5@64bit)
|
||||
$gen_hi_opt_code = (bool)(count($lambda_functions) < 10);
|
||||
$keys = $this->keys;
|
||||
|
||||
// Generation of a unique hash for our generated code
|
||||
$code_hash = "Crypt_RC2, {$this->mode}";
|
||||
if ($gen_hi_opt_code) {
|
||||
$code_hash = str_pad($code_hash, 32) . $this->hashInlineCryptFunction($this->key);
|
||||
}
|
||||
// $in is the current 8 bytes block which has to be en/decrypt
|
||||
$encrypt_block = $decrypt_block = '
|
||||
$in = unpack("v4", $in);
|
||||
$r0 = $in[1];
|
||||
$r1 = $in[2];
|
||||
$r2 = $in[3];
|
||||
$r3 = $in[4];
|
||||
';
|
||||
|
||||
// Is there a re-usable $lambda_functions in there?
|
||||
// If not, we have to create it.
|
||||
if (!isset($lambda_functions[$code_hash])) {
|
||||
// Init code for both, encrypt and decrypt.
|
||||
$init_crypt = '$keys = $this->keys;';
|
||||
// Create code for encryption.
|
||||
$limit = 20;
|
||||
$actions = [$limit => 44, 44 => 64];
|
||||
$j = 0;
|
||||
|
||||
switch (true) {
|
||||
case $gen_hi_opt_code:
|
||||
$keys = $this->keys;
|
||||
default:
|
||||
$keys = [];
|
||||
foreach ($this->keys as $k => $v) {
|
||||
$keys[$k] = '$keys[' . $k . ']';
|
||||
}
|
||||
}
|
||||
for (;;) {
|
||||
// Mixing round.
|
||||
$encrypt_block .= '
|
||||
$r0 = (($r0 + ' . $keys[$j++] . ' +
|
||||
((($r1 ^ $r2) & $r3) ^ $r1)) & 0xFFFF) << 1;
|
||||
$r0 |= $r0 >> 16;
|
||||
$r1 = (($r1 + ' . $keys[$j++] . ' +
|
||||
((($r2 ^ $r3) & $r0) ^ $r2)) & 0xFFFF) << 2;
|
||||
$r1 |= $r1 >> 16;
|
||||
$r2 = (($r2 + ' . $keys[$j++] . ' +
|
||||
((($r3 ^ $r0) & $r1) ^ $r3)) & 0xFFFF) << 3;
|
||||
$r2 |= $r2 >> 16;
|
||||
$r3 = (($r3 + ' . $keys[$j++] . ' +
|
||||
((($r0 ^ $r1) & $r2) ^ $r0)) & 0xFFFF) << 5;
|
||||
$r3 |= $r3 >> 16;';
|
||||
|
||||
// $in is the current 8 bytes block which has to be en/decrypt
|
||||
$encrypt_block = $decrypt_block = '
|
||||
$in = unpack("v4", $in);
|
||||
$r0 = $in[1];
|
||||
$r1 = $in[2];
|
||||
$r2 = $in[3];
|
||||
$r3 = $in[4];
|
||||
';
|
||||
if ($j === $limit) {
|
||||
if ($limit === 64) {
|
||||
break;
|
||||
}
|
||||
|
||||
// Create code for encryption.
|
||||
$limit = 20;
|
||||
$actions = [$limit => 44, 44 => 64];
|
||||
$j = 0;
|
||||
|
||||
for (;;) {
|
||||
// Mixing round.
|
||||
// Mashing round.
|
||||
$encrypt_block .= '
|
||||
$r0 = (($r0 + ' . $keys[$j++] . ' +
|
||||
((($r1 ^ $r2) & $r3) ^ $r1)) & 0xFFFF) << 1;
|
||||
$r0 |= $r0 >> 16;
|
||||
$r1 = (($r1 + ' . $keys[$j++] . ' +
|
||||
((($r2 ^ $r3) & $r0) ^ $r2)) & 0xFFFF) << 2;
|
||||
$r1 |= $r1 >> 16;
|
||||
$r2 = (($r2 + ' . $keys[$j++] . ' +
|
||||
((($r3 ^ $r0) & $r1) ^ $r3)) & 0xFFFF) << 3;
|
||||
$r2 |= $r2 >> 16;
|
||||
$r3 = (($r3 + ' . $keys[$j++] . ' +
|
||||
((($r0 ^ $r1) & $r2) ^ $r0)) & 0xFFFF) << 5;
|
||||
$r3 |= $r3 >> 16;';
|
||||
|
||||
if ($j === $limit) {
|
||||
if ($limit === 64) {
|
||||
break;
|
||||
}
|
||||
|
||||
// Mashing round.
|
||||
$encrypt_block .= '
|
||||
$r0 += $keys[$r3 & 0x3F];
|
||||
$r1 += $keys[$r0 & 0x3F];
|
||||
$r2 += $keys[$r1 & 0x3F];
|
||||
$r3 += $keys[$r2 & 0x3F];';
|
||||
$limit = $actions[$limit];
|
||||
}
|
||||
$r0 += $keys[$r3 & 0x3F];
|
||||
$r1 += $keys[$r0 & 0x3F];
|
||||
$r2 += $keys[$r1 & 0x3F];
|
||||
$r3 += $keys[$r2 & 0x3F];';
|
||||
$limit = $actions[$limit];
|
||||
}
|
||||
}
|
||||
|
||||
$encrypt_block .= '$in = pack("v4", $r0, $r1, $r2, $r3);';
|
||||
$encrypt_block .= '$in = pack("v4", $r0, $r1, $r2, $r3);';
|
||||
|
||||
// Create code for decryption.
|
||||
$limit = 44;
|
||||
$actions = [$limit => 20, 20 => 0];
|
||||
$j = 64;
|
||||
// Create code for decryption.
|
||||
$limit = 44;
|
||||
$actions = [$limit => 20, 20 => 0];
|
||||
$j = 64;
|
||||
|
||||
for (;;) {
|
||||
// R-mixing round.
|
||||
for (;;) {
|
||||
// R-mixing round.
|
||||
$decrypt_block .= '
|
||||
$r3 = ($r3 | ($r3 << 16)) >> 5;
|
||||
$r3 = ($r3 - ' . $keys[--$j] . ' -
|
||||
((($r0 ^ $r1) & $r2) ^ $r0)) & 0xFFFF;
|
||||
$r2 = ($r2 | ($r2 << 16)) >> 3;
|
||||
$r2 = ($r2 - ' . $keys[--$j] . ' -
|
||||
((($r3 ^ $r0) & $r1) ^ $r3)) & 0xFFFF;
|
||||
$r1 = ($r1 | ($r1 << 16)) >> 2;
|
||||
$r1 = ($r1 - ' . $keys[--$j] . ' -
|
||||
((($r2 ^ $r3) & $r0) ^ $r2)) & 0xFFFF;
|
||||
$r0 = ($r0 | ($r0 << 16)) >> 1;
|
||||
$r0 = ($r0 - ' . $keys[--$j] . ' -
|
||||
((($r1 ^ $r2) & $r3) ^ $r1)) & 0xFFFF;';
|
||||
|
||||
if ($j === $limit) {
|
||||
if ($limit === 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
// R-mashing round.
|
||||
$decrypt_block .= '
|
||||
$r3 = ($r3 | ($r3 << 16)) >> 5;
|
||||
$r3 = ($r3 - ' . $keys[--$j] . ' -
|
||||
((($r0 ^ $r1) & $r2) ^ $r0)) & 0xFFFF;
|
||||
$r2 = ($r2 | ($r2 << 16)) >> 3;
|
||||
$r2 = ($r2 - ' . $keys[--$j] . ' -
|
||||
((($r3 ^ $r0) & $r1) ^ $r3)) & 0xFFFF;
|
||||
$r1 = ($r1 | ($r1 << 16)) >> 2;
|
||||
$r1 = ($r1 - ' . $keys[--$j] . ' -
|
||||
((($r2 ^ $r3) & $r0) ^ $r2)) & 0xFFFF;
|
||||
$r0 = ($r0 | ($r0 << 16)) >> 1;
|
||||
$r0 = ($r0 - ' . $keys[--$j] . ' -
|
||||
((($r1 ^ $r2) & $r3) ^ $r1)) & 0xFFFF;';
|
||||
|
||||
if ($j === $limit) {
|
||||
if ($limit === 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
// R-mashing round.
|
||||
$decrypt_block .= '
|
||||
$r3 = ($r3 - $keys[$r2 & 0x3F]) & 0xFFFF;
|
||||
$r2 = ($r2 - $keys[$r1 & 0x3F]) & 0xFFFF;
|
||||
$r1 = ($r1 - $keys[$r0 & 0x3F]) & 0xFFFF;
|
||||
$r0 = ($r0 - $keys[$r3 & 0x3F]) & 0xFFFF;';
|
||||
$limit = $actions[$limit];
|
||||
}
|
||||
$r3 = ($r3 - $keys[$r2 & 0x3F]) & 0xFFFF;
|
||||
$r2 = ($r2 - $keys[$r1 & 0x3F]) & 0xFFFF;
|
||||
$r1 = ($r1 - $keys[$r0 & 0x3F]) & 0xFFFF;
|
||||
$r0 = ($r0 - $keys[$r3 & 0x3F]) & 0xFFFF;';
|
||||
$limit = $actions[$limit];
|
||||
}
|
||||
|
||||
$decrypt_block .= '$in = pack("v4", $r0, $r1, $r2, $r3);';
|
||||
|
||||
// Creates the inline-crypt function
|
||||
$lambda_functions[$code_hash] = $this->createInlineCryptFunction(
|
||||
[
|
||||
'init_crypt' => $init_crypt,
|
||||
'encrypt_block' => $encrypt_block,
|
||||
'decrypt_block' => $decrypt_block
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
// Set the inline-crypt function as callback in: $this->inline_crypt
|
||||
$this->inline_crypt = \Closure::bind($lambda_functions[$code_hash], $this, $this->getClassContext());
|
||||
$decrypt_block .= '$in = pack("v4", $r0, $r1, $r2, $r3);';
|
||||
|
||||
// Creates the inline-crypt function
|
||||
$this->inline_crypt = $this->createInlineCryptFunction(
|
||||
[
|
||||
'init_crypt' => $init_crypt,
|
||||
'encrypt_block' => $encrypt_block,
|
||||
'decrypt_block' => $decrypt_block
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -811,170 +811,137 @@ class Rijndael extends BlockCipher
|
||||
*/
|
||||
protected function setupInlineCrypt()
|
||||
{
|
||||
// Note: _setupInlineCrypt() will be called only if $this->changed === true
|
||||
// So here we are'nt under the same heavy timing-stress as we are in _de/encryptBlock() or de/encrypt().
|
||||
// However...the here generated function- $code, stored as php callback in $this->inline_crypt, must work as fast as even possible.
|
||||
$w = $this->w;
|
||||
$dw = $this->dw;
|
||||
$init_encrypt = '';
|
||||
$init_decrypt = '';
|
||||
|
||||
$lambda_functions =& self::getLambdaFunctions();
|
||||
$Nr = $this->Nr;
|
||||
$Nb = $this->Nb;
|
||||
$c = $this->c;
|
||||
|
||||
// We create max. 10 hi-optimized code for memory reason. Means: For each $key one ultra fast inline-crypt function.
|
||||
// (Currently, for Crypt_Rijndael/AES, one generated $lambda_function cost on php5.5@32bit ~80kb unfreeable mem and ~130kb on php5.5@64bit)
|
||||
// After that, we'll still create very fast optimized code but not the hi-ultimative code, for each $mode one.
|
||||
$gen_hi_opt_code = (bool)(count($lambda_functions) < 10);
|
||||
// Generating encrypt code:
|
||||
$init_encrypt.= '
|
||||
static $tables;
|
||||
if (empty($tables)) {
|
||||
$tables = &$this->getTables();
|
||||
}
|
||||
$t0 = $tables[0];
|
||||
$t1 = $tables[1];
|
||||
$t2 = $tables[2];
|
||||
$t3 = $tables[3];
|
||||
$sbox = $tables[4];
|
||||
';
|
||||
|
||||
// Generation of a uniqe hash for our generated code
|
||||
$code_hash = "Crypt_Rijndael, {$this->mode}, {$this->Nr}, {$this->Nb}";
|
||||
if ($gen_hi_opt_code) {
|
||||
$code_hash = str_pad($code_hash, 32) . $this->hashInlineCryptFunction($this->key);
|
||||
$s = 'e';
|
||||
$e = 's';
|
||||
$wc = $Nb - 1;
|
||||
|
||||
// Preround: addRoundKey
|
||||
$encrypt_block = '$in = unpack("N*", $in);'."\n";
|
||||
for ($i = 0; $i < $Nb; ++$i) {
|
||||
$encrypt_block .= '$s'.$i.' = $in['.($i + 1).'] ^ '.$w[++$wc].";\n";
|
||||
}
|
||||
|
||||
if (!isset($lambda_functions[$code_hash])) {
|
||||
switch (true) {
|
||||
case $gen_hi_opt_code:
|
||||
// The hi-optimized $lambda_functions will use the key-words hardcoded for better performance.
|
||||
$w = $this->w;
|
||||
$dw = $this->dw;
|
||||
$init_encrypt = '';
|
||||
$init_decrypt = '';
|
||||
break;
|
||||
default:
|
||||
for ($i = 0, $cw = count($this->w); $i < $cw; ++$i) {
|
||||
$w[] = '$w[' . $i . ']';
|
||||
$dw[] = '$dw[' . $i . ']';
|
||||
}
|
||||
$init_encrypt = '$w = $this->w;';
|
||||
$init_decrypt = '$dw = $this->dw;';
|
||||
}
|
||||
|
||||
$Nr = $this->Nr;
|
||||
$Nb = $this->Nb;
|
||||
$c = $this->c;
|
||||
|
||||
// Generating encrypt code:
|
||||
$init_encrypt.= '
|
||||
static $tables;
|
||||
if (empty($tables)) {
|
||||
$tables = &$this->getTables();
|
||||
}
|
||||
$t0 = $tables[0];
|
||||
$t1 = $tables[1];
|
||||
$t2 = $tables[2];
|
||||
$t3 = $tables[3];
|
||||
$sbox = $tables[4];
|
||||
';
|
||||
|
||||
$s = 'e';
|
||||
$e = 's';
|
||||
$wc = $Nb - 1;
|
||||
|
||||
// Preround: addRoundKey
|
||||
$encrypt_block = '$in = unpack("N*", $in);'."\n";
|
||||
for ($i = 0; $i < $Nb; ++$i) {
|
||||
$encrypt_block .= '$s'.$i.' = $in['.($i + 1).'] ^ '.$w[++$wc].";\n";
|
||||
}
|
||||
|
||||
// Mainrounds: shiftRows + subWord + mixColumns + addRoundKey
|
||||
for ($round = 1; $round < $Nr; ++$round) {
|
||||
list($s, $e) = [$e, $s];
|
||||
for ($i = 0; $i < $Nb; ++$i) {
|
||||
$encrypt_block.=
|
||||
'$'.$e.$i.' =
|
||||
$t0[($'.$s.$i .' >> 24) & 0xff] ^
|
||||
$t1[($'.$s.(($i + $c[1]) % $Nb).' >> 16) & 0xff] ^
|
||||
$t2[($'.$s.(($i + $c[2]) % $Nb).' >> 8) & 0xff] ^
|
||||
$t3[ $'.$s.(($i + $c[3]) % $Nb).' & 0xff] ^
|
||||
'.$w[++$wc].";\n";
|
||||
}
|
||||
}
|
||||
|
||||
// Finalround: subWord + shiftRows + addRoundKey
|
||||
// Mainrounds: shiftRows + subWord + mixColumns + addRoundKey
|
||||
for ($round = 1; $round < $Nr; ++$round) {
|
||||
list($s, $e) = [$e, $s];
|
||||
for ($i = 0; $i < $Nb; ++$i) {
|
||||
$encrypt_block.=
|
||||
'$'.$e.$i.' =
|
||||
$sbox[ $'.$e.$i.' & 0xff] |
|
||||
($sbox[($'.$e.$i.' >> 8) & 0xff] << 8) |
|
||||
($sbox[($'.$e.$i.' >> 16) & 0xff] << 16) |
|
||||
($sbox[($'.$e.$i.' >> 24) & 0xff] << 24);'."\n";
|
||||
$t0[($'.$s.$i .' >> 24) & 0xff] ^
|
||||
$t1[($'.$s.(($i + $c[1]) % $Nb).' >> 16) & 0xff] ^
|
||||
$t2[($'.$s.(($i + $c[2]) % $Nb).' >> 8) & 0xff] ^
|
||||
$t3[ $'.$s.(($i + $c[3]) % $Nb).' & 0xff] ^
|
||||
'.$w[++$wc].";\n";
|
||||
}
|
||||
$encrypt_block .= '$in = pack("N*"'."\n";
|
||||
for ($i = 0; $i < $Nb; ++$i) {
|
||||
$encrypt_block.= ',
|
||||
($'.$e.$i .' & '.((int)0xFF000000).') ^
|
||||
($'.$e.(($i + $c[1]) % $Nb).' & 0x00FF0000 ) ^
|
||||
($'.$e.(($i + $c[2]) % $Nb).' & 0x0000FF00 ) ^
|
||||
($'.$e.(($i + $c[3]) % $Nb).' & 0x000000FF ) ^
|
||||
'.$w[$i]."\n";
|
||||
}
|
||||
|
||||
// Finalround: subWord + shiftRows + addRoundKey
|
||||
for ($i = 0; $i < $Nb; ++$i) {
|
||||
$encrypt_block.=
|
||||
'$'.$e.$i.' =
|
||||
$sbox[ $'.$e.$i.' & 0xff] |
|
||||
($sbox[($'.$e.$i.' >> 8) & 0xff] << 8) |
|
||||
($sbox[($'.$e.$i.' >> 16) & 0xff] << 16) |
|
||||
($sbox[($'.$e.$i.' >> 24) & 0xff] << 24);'."\n";
|
||||
}
|
||||
$encrypt_block .= '$in = pack("N*"'."\n";
|
||||
for ($i = 0; $i < $Nb; ++$i) {
|
||||
$encrypt_block.= ',
|
||||
($'.$e.$i .' & '.((int)0xFF000000).') ^
|
||||
($'.$e.(($i + $c[1]) % $Nb).' & 0x00FF0000 ) ^
|
||||
($'.$e.(($i + $c[2]) % $Nb).' & 0x0000FF00 ) ^
|
||||
($'.$e.(($i + $c[3]) % $Nb).' & 0x000000FF ) ^
|
||||
'.$w[$i]."\n";
|
||||
}
|
||||
$encrypt_block .= ');';
|
||||
|
||||
// Generating decrypt code:
|
||||
$init_decrypt.= '
|
||||
static $invtables;
|
||||
if (empty($invtables)) {
|
||||
$invtables = &$this->getInvTables();
|
||||
}
|
||||
$encrypt_block .= ');';
|
||||
$dt0 = $invtables[0];
|
||||
$dt1 = $invtables[1];
|
||||
$dt2 = $invtables[2];
|
||||
$dt3 = $invtables[3];
|
||||
$isbox = $invtables[4];
|
||||
';
|
||||
|
||||
// Generating decrypt code:
|
||||
$init_decrypt.= '
|
||||
static $invtables;
|
||||
if (empty($invtables)) {
|
||||
$invtables = &$this->getInvTables();
|
||||
}
|
||||
$dt0 = $invtables[0];
|
||||
$dt1 = $invtables[1];
|
||||
$dt2 = $invtables[2];
|
||||
$dt3 = $invtables[3];
|
||||
$isbox = $invtables[4];
|
||||
';
|
||||
$s = 'e';
|
||||
$e = 's';
|
||||
$wc = $Nb - 1;
|
||||
|
||||
$s = 'e';
|
||||
$e = 's';
|
||||
$wc = $Nb - 1;
|
||||
// Preround: addRoundKey
|
||||
$decrypt_block = '$in = unpack("N*", $in);'."\n";
|
||||
for ($i = 0; $i < $Nb; ++$i) {
|
||||
$decrypt_block .= '$s'.$i.' = $in['.($i + 1).'] ^ '.$dw[++$wc].';'."\n";
|
||||
}
|
||||
|
||||
// Preround: addRoundKey
|
||||
$decrypt_block = '$in = unpack("N*", $in);'."\n";
|
||||
for ($i = 0; $i < $Nb; ++$i) {
|
||||
$decrypt_block .= '$s'.$i.' = $in['.($i + 1).'] ^ '.$dw[++$wc].';'."\n";
|
||||
}
|
||||
|
||||
// Mainrounds: shiftRows + subWord + mixColumns + addRoundKey
|
||||
for ($round = 1; $round < $Nr; ++$round) {
|
||||
list($s, $e) = [$e, $s];
|
||||
for ($i = 0; $i < $Nb; ++$i) {
|
||||
$decrypt_block.=
|
||||
'$'.$e.$i.' =
|
||||
$dt0[($'.$s.$i .' >> 24) & 0xff] ^
|
||||
$dt1[($'.$s.(($Nb + $i - $c[1]) % $Nb).' >> 16) & 0xff] ^
|
||||
$dt2[($'.$s.(($Nb + $i - $c[2]) % $Nb).' >> 8) & 0xff] ^
|
||||
$dt3[ $'.$s.(($Nb + $i - $c[3]) % $Nb).' & 0xff] ^
|
||||
'.$dw[++$wc].";\n";
|
||||
}
|
||||
}
|
||||
|
||||
// Finalround: subWord + shiftRows + addRoundKey
|
||||
// Mainrounds: shiftRows + subWord + mixColumns + addRoundKey
|
||||
for ($round = 1; $round < $Nr; ++$round) {
|
||||
list($s, $e) = [$e, $s];
|
||||
for ($i = 0; $i < $Nb; ++$i) {
|
||||
$decrypt_block.=
|
||||
'$'.$e.$i.' =
|
||||
$isbox[ $'.$e.$i.' & 0xff] |
|
||||
($isbox[($'.$e.$i.' >> 8) & 0xff] << 8) |
|
||||
($isbox[($'.$e.$i.' >> 16) & 0xff] << 16) |
|
||||
($isbox[($'.$e.$i.' >> 24) & 0xff] << 24);'."\n";
|
||||
$dt0[($'.$s.$i .' >> 24) & 0xff] ^
|
||||
$dt1[($'.$s.(($Nb + $i - $c[1]) % $Nb).' >> 16) & 0xff] ^
|
||||
$dt2[($'.$s.(($Nb + $i - $c[2]) % $Nb).' >> 8) & 0xff] ^
|
||||
$dt3[ $'.$s.(($Nb + $i - $c[3]) % $Nb).' & 0xff] ^
|
||||
'.$dw[++$wc].";\n";
|
||||
}
|
||||
$decrypt_block .= '$in = pack("N*"'."\n";
|
||||
for ($i = 0; $i < $Nb; ++$i) {
|
||||
$decrypt_block.= ',
|
||||
($'.$e.$i. ' & '.((int)0xFF000000).') ^
|
||||
($'.$e.(($Nb + $i - $c[1]) % $Nb).' & 0x00FF0000 ) ^
|
||||
($'.$e.(($Nb + $i - $c[2]) % $Nb).' & 0x0000FF00 ) ^
|
||||
($'.$e.(($Nb + $i - $c[3]) % $Nb).' & 0x000000FF ) ^
|
||||
'.$dw[$i]."\n";
|
||||
}
|
||||
$decrypt_block .= ');';
|
||||
|
||||
$lambda_functions[$code_hash] = $this->createInlineCryptFunction(
|
||||
[
|
||||
'init_crypt' => '',
|
||||
'init_encrypt' => $init_encrypt,
|
||||
'init_decrypt' => $init_decrypt,
|
||||
'encrypt_block' => $encrypt_block,
|
||||
'decrypt_block' => $decrypt_block
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
$this->inline_crypt = \Closure::bind($lambda_functions[$code_hash], $this, $this->getClassContext());
|
||||
// Finalround: subWord + shiftRows + addRoundKey
|
||||
for ($i = 0; $i < $Nb; ++$i) {
|
||||
$decrypt_block.=
|
||||
'$'.$e.$i.' =
|
||||
$isbox[ $'.$e.$i.' & 0xff] |
|
||||
($isbox[($'.$e.$i.' >> 8) & 0xff] << 8) |
|
||||
($isbox[($'.$e.$i.' >> 16) & 0xff] << 16) |
|
||||
($isbox[($'.$e.$i.' >> 24) & 0xff] << 24);'."\n";
|
||||
}
|
||||
$decrypt_block .= '$in = pack("N*"'."\n";
|
||||
for ($i = 0; $i < $Nb; ++$i) {
|
||||
$decrypt_block.= ',
|
||||
($'.$e.$i. ' & '.((int)0xFF000000).') ^
|
||||
($'.$e.(($Nb + $i - $c[1]) % $Nb).' & 0x00FF0000 ) ^
|
||||
($'.$e.(($Nb + $i - $c[2]) % $Nb).' & 0x0000FF00 ) ^
|
||||
($'.$e.(($Nb + $i - $c[3]) % $Nb).' & 0x000000FF ) ^
|
||||
'.$dw[$i]."\n";
|
||||
}
|
||||
$decrypt_block .= ');';
|
||||
|
||||
$this->inline_crypt = $this->createInlineCryptFunction(
|
||||
[
|
||||
'init_crypt' => '',
|
||||
'init_encrypt' => $init_encrypt,
|
||||
'init_decrypt' => $init_decrypt,
|
||||
'encrypt_block' => $encrypt_block,
|
||||
'decrypt_block' => $decrypt_block
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -707,142 +707,111 @@ class Twofish extends BlockCipher
|
||||
*/
|
||||
protected function setupInlineCrypt()
|
||||
{
|
||||
$lambda_functions =& self::getLambdaFunctions();
|
||||
|
||||
// Max. 10 Ultra-Hi-optimized inline-crypt functions. After that, we'll (still) create very fast code, but not the ultimate fast one.
|
||||
// (Currently, for Crypt_Twofish, one generated $lambda_function cost on php5.5@32bit ~140kb unfreeable mem and ~240kb on php5.5@64bit)
|
||||
$gen_hi_opt_code = (bool)(count($lambda_functions) < 10);
|
||||
|
||||
// Generation of a unique hash for our generated code
|
||||
$code_hash = "Crypt_Twofish, {$this->mode}";
|
||||
if ($gen_hi_opt_code) {
|
||||
$code_hash = str_pad($code_hash, 32) . $this->hashInlineCryptFunction($this->key);
|
||||
}
|
||||
|
||||
if (!isset($lambda_functions[$code_hash])) {
|
||||
switch (true) {
|
||||
case $gen_hi_opt_code:
|
||||
$K = $this->K;
|
||||
$init_crypt = '
|
||||
static $S0, $S1, $S2, $S3;
|
||||
if (!$S0) {
|
||||
for ($i = 0; $i < 256; ++$i) {
|
||||
$S0[] = (int)$this->S0[$i];
|
||||
$S1[] = (int)$this->S1[$i];
|
||||
$S2[] = (int)$this->S2[$i];
|
||||
$S3[] = (int)$this->S3[$i];
|
||||
}
|
||||
}
|
||||
';
|
||||
break;
|
||||
default:
|
||||
$K = [];
|
||||
for ($i = 0; $i < 40; ++$i) {
|
||||
$K[] = '$K_' . $i;
|
||||
}
|
||||
$init_crypt = '
|
||||
$S0 = $this->S0;
|
||||
$S1 = $this->S1;
|
||||
$S2 = $this->S2;
|
||||
$S3 = $this->S3;
|
||||
list(' . implode(',', $K) . ') = $this->K;
|
||||
';
|
||||
$K = $this->K;
|
||||
$init_crypt = '
|
||||
static $S0, $S1, $S2, $S3;
|
||||
if (!$S0) {
|
||||
for ($i = 0; $i < 256; ++$i) {
|
||||
$S0[] = (int)$this->S0[$i];
|
||||
$S1[] = (int)$this->S1[$i];
|
||||
$S2[] = (int)$this->S2[$i];
|
||||
$S3[] = (int)$this->S3[$i];
|
||||
}
|
||||
}
|
||||
';
|
||||
|
||||
// Generating encrypt code:
|
||||
$encrypt_block = '
|
||||
$in = unpack("V4", $in);
|
||||
$R0 = '.$K[0].' ^ $in[1];
|
||||
$R1 = '.$K[1].' ^ $in[2];
|
||||
$R2 = '.$K[2].' ^ $in[3];
|
||||
$R3 = '.$K[3].' ^ $in[4];
|
||||
';
|
||||
for ($ki = 7, $i = 0; $i < 8; ++$i) {
|
||||
$encrypt_block.= '
|
||||
$t0 = $S0[ $R0 & 0xff] ^
|
||||
$S1[($R0 >> 8) & 0xff] ^
|
||||
$S2[($R0 >> 16) & 0xff] ^
|
||||
$S3[($R0 >> 24) & 0xff];
|
||||
$t1 = $S0[($R1 >> 24) & 0xff] ^
|
||||
$S1[ $R1 & 0xff] ^
|
||||
$S2[($R1 >> 8) & 0xff] ^
|
||||
$S3[($R1 >> 16) & 0xff];
|
||||
$R2^= ($t0 + $t1 + '.$K[++$ki].');
|
||||
$R2 = ($R2 >> 1 & 0x7fffffff) | ($R2 << 31);
|
||||
$R3 = ((($R3 >> 31) & 1) | ($R3 << 1)) ^ ($t0 + ($t1 << 1) + '.$K[++$ki].');
|
||||
|
||||
$t0 = $S0[ $R2 & 0xff] ^
|
||||
$S1[($R2 >> 8) & 0xff] ^
|
||||
$S2[($R2 >> 16) & 0xff] ^
|
||||
$S3[($R2 >> 24) & 0xff];
|
||||
$t1 = $S0[($R3 >> 24) & 0xff] ^
|
||||
$S1[ $R3 & 0xff] ^
|
||||
$S2[($R3 >> 8) & 0xff] ^
|
||||
$S3[($R3 >> 16) & 0xff];
|
||||
$R0^= ($t0 + $t1 + '.$K[++$ki].');
|
||||
$R0 = ($R0 >> 1 & 0x7fffffff) | ($R0 << 31);
|
||||
$R1 = ((($R1 >> 31) & 1) | ($R1 << 1)) ^ ($t0 + ($t1 << 1) + '.$K[++$ki].');
|
||||
';
|
||||
}
|
||||
// Generating encrypt code:
|
||||
$encrypt_block = '
|
||||
$in = unpack("V4", $in);
|
||||
$R0 = '.$K[0].' ^ $in[1];
|
||||
$R1 = '.$K[1].' ^ $in[2];
|
||||
$R2 = '.$K[2].' ^ $in[3];
|
||||
$R3 = '.$K[3].' ^ $in[4];
|
||||
';
|
||||
for ($ki = 7, $i = 0; $i < 8; ++$i) {
|
||||
$encrypt_block.= '
|
||||
$in = pack("V4", '.$K[4].' ^ $R2,
|
||||
'.$K[5].' ^ $R3,
|
||||
'.$K[6].' ^ $R0,
|
||||
'.$K[7].' ^ $R1);
|
||||
';
|
||||
$t0 = $S0[ $R0 & 0xff] ^
|
||||
$S1[($R0 >> 8) & 0xff] ^
|
||||
$S2[($R0 >> 16) & 0xff] ^
|
||||
$S3[($R0 >> 24) & 0xff];
|
||||
$t1 = $S0[($R1 >> 24) & 0xff] ^
|
||||
$S1[ $R1 & 0xff] ^
|
||||
$S2[($R1 >> 8) & 0xff] ^
|
||||
$S3[($R1 >> 16) & 0xff];
|
||||
$R2^= ($t0 + $t1 + '.$K[++$ki].');
|
||||
$R2 = ($R2 >> 1 & 0x7fffffff) | ($R2 << 31);
|
||||
$R3 = ((($R3 >> 31) & 1) | ($R3 << 1)) ^ ($t0 + ($t1 << 1) + '.$K[++$ki].');
|
||||
|
||||
// Generating decrypt code:
|
||||
$decrypt_block = '
|
||||
$in = unpack("V4", $in);
|
||||
$R0 = '.$K[4].' ^ $in[1];
|
||||
$R1 = '.$K[5].' ^ $in[2];
|
||||
$R2 = '.$K[6].' ^ $in[3];
|
||||
$R3 = '.$K[7].' ^ $in[4];
|
||||
$t0 = $S0[ $R2 & 0xff] ^
|
||||
$S1[($R2 >> 8) & 0xff] ^
|
||||
$S2[($R2 >> 16) & 0xff] ^
|
||||
$S3[($R2 >> 24) & 0xff];
|
||||
$t1 = $S0[($R3 >> 24) & 0xff] ^
|
||||
$S1[ $R3 & 0xff] ^
|
||||
$S2[($R3 >> 8) & 0xff] ^
|
||||
$S3[($R3 >> 16) & 0xff];
|
||||
$R0^= ($t0 + $t1 + '.$K[++$ki].');
|
||||
$R0 = ($R0 >> 1 & 0x7fffffff) | ($R0 << 31);
|
||||
$R1 = ((($R1 >> 31) & 1) | ($R1 << 1)) ^ ($t0 + ($t1 << 1) + '.$K[++$ki].');
|
||||
';
|
||||
for ($ki = 40, $i = 0; $i < 8; ++$i) {
|
||||
$decrypt_block.= '
|
||||
$t0 = $S0[$R0 & 0xff] ^
|
||||
$S1[$R0 >> 8 & 0xff] ^
|
||||
$S2[$R0 >> 16 & 0xff] ^
|
||||
$S3[$R0 >> 24 & 0xff];
|
||||
$t1 = $S0[$R1 >> 24 & 0xff] ^
|
||||
$S1[$R1 & 0xff] ^
|
||||
$S2[$R1 >> 8 & 0xff] ^
|
||||
$S3[$R1 >> 16 & 0xff];
|
||||
$R3^= $t0 + ($t1 << 1) + '.$K[--$ki].';
|
||||
$R3 = $R3 >> 1 & 0x7fffffff | $R3 << 31;
|
||||
$R2 = ($R2 >> 31 & 0x1 | $R2 << 1) ^ ($t0 + $t1 + '.$K[--$ki].');
|
||||
|
||||
$t0 = $S0[$R2 & 0xff] ^
|
||||
$S1[$R2 >> 8 & 0xff] ^
|
||||
$S2[$R2 >> 16 & 0xff] ^
|
||||
$S3[$R2 >> 24 & 0xff];
|
||||
$t1 = $S0[$R3 >> 24 & 0xff] ^
|
||||
$S1[$R3 & 0xff] ^
|
||||
$S2[$R3 >> 8 & 0xff] ^
|
||||
$S3[$R3 >> 16 & 0xff];
|
||||
$R1^= $t0 + ($t1 << 1) + '.$K[--$ki].';
|
||||
$R1 = $R1 >> 1 & 0x7fffffff | $R1 << 31;
|
||||
$R0 = ($R0 >> 31 & 0x1 | $R0 << 1) ^ ($t0 + $t1 + '.$K[--$ki].');
|
||||
';
|
||||
}
|
||||
$decrypt_block.= '
|
||||
$in = pack("V4", '.$K[0].' ^ $R2,
|
||||
'.$K[1].' ^ $R3,
|
||||
'.$K[2].' ^ $R0,
|
||||
'.$K[3].' ^ $R1);
|
||||
';
|
||||
|
||||
$lambda_functions[$code_hash] = $this->createInlineCryptFunction(
|
||||
[
|
||||
'init_crypt' => $init_crypt,
|
||||
'init_encrypt' => '',
|
||||
'init_decrypt' => '',
|
||||
'encrypt_block' => $encrypt_block,
|
||||
'decrypt_block' => $decrypt_block
|
||||
]
|
||||
);
|
||||
}
|
||||
$this->inline_crypt = \Closure::bind($lambda_functions[$code_hash], $this, $this->getClassContext());
|
||||
$encrypt_block.= '
|
||||
$in = pack("V4", '.$K[4].' ^ $R2,
|
||||
'.$K[5].' ^ $R3,
|
||||
'.$K[6].' ^ $R0,
|
||||
'.$K[7].' ^ $R1);
|
||||
';
|
||||
|
||||
// Generating decrypt code:
|
||||
$decrypt_block = '
|
||||
$in = unpack("V4", $in);
|
||||
$R0 = '.$K[4].' ^ $in[1];
|
||||
$R1 = '.$K[5].' ^ $in[2];
|
||||
$R2 = '.$K[6].' ^ $in[3];
|
||||
$R3 = '.$K[7].' ^ $in[4];
|
||||
';
|
||||
for ($ki = 40, $i = 0; $i < 8; ++$i) {
|
||||
$decrypt_block.= '
|
||||
$t0 = $S0[$R0 & 0xff] ^
|
||||
$S1[$R0 >> 8 & 0xff] ^
|
||||
$S2[$R0 >> 16 & 0xff] ^
|
||||
$S3[$R0 >> 24 & 0xff];
|
||||
$t1 = $S0[$R1 >> 24 & 0xff] ^
|
||||
$S1[$R1 & 0xff] ^
|
||||
$S2[$R1 >> 8 & 0xff] ^
|
||||
$S3[$R1 >> 16 & 0xff];
|
||||
$R3^= $t0 + ($t1 << 1) + '.$K[--$ki].';
|
||||
$R3 = $R3 >> 1 & 0x7fffffff | $R3 << 31;
|
||||
$R2 = ($R2 >> 31 & 0x1 | $R2 << 1) ^ ($t0 + $t1 + '.$K[--$ki].');
|
||||
|
||||
$t0 = $S0[$R2 & 0xff] ^
|
||||
$S1[$R2 >> 8 & 0xff] ^
|
||||
$S2[$R2 >> 16 & 0xff] ^
|
||||
$S3[$R2 >> 24 & 0xff];
|
||||
$t1 = $S0[$R3 >> 24 & 0xff] ^
|
||||
$S1[$R3 & 0xff] ^
|
||||
$S2[$R3 >> 8 & 0xff] ^
|
||||
$S3[$R3 >> 16 & 0xff];
|
||||
$R1^= $t0 + ($t1 << 1) + '.$K[--$ki].';
|
||||
$R1 = $R1 >> 1 & 0x7fffffff | $R1 << 31;
|
||||
$R0 = ($R0 >> 31 & 0x1 | $R0 << 1) ^ ($t0 + $t1 + '.$K[--$ki].');
|
||||
';
|
||||
}
|
||||
$decrypt_block.= '
|
||||
$in = pack("V4", '.$K[0].' ^ $R2,
|
||||
'.$K[1].' ^ $R3,
|
||||
'.$K[2].' ^ $R0,
|
||||
'.$K[3].' ^ $R1);
|
||||
';
|
||||
|
||||
$this->inline_crypt = $this->createInlineCryptFunction(
|
||||
[
|
||||
'init_crypt' => $init_crypt,
|
||||
'init_encrypt' => '',
|
||||
'init_decrypt' => '',
|
||||
'encrypt_block' => $encrypt_block,
|
||||
'decrypt_block' => $decrypt_block
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
16
tests/Unit/Crypt/AES/EvalTest.php
Normal file
16
tests/Unit/Crypt/AES/EvalTest.php
Normal file
@ -0,0 +1,16 @@
|
||||
<?php
|
||||
/**
|
||||
* @author Andreas Fischer <bantu@phpbb.com>
|
||||
* @copyright 2013 Andreas Fischer
|
||||
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
||||
*/
|
||||
|
||||
use phpseclib\Crypt\Common\BlockCipher;
|
||||
|
||||
class Unit_Crypt_AES_EvalTest extends Unit_Crypt_AES_TestCase
|
||||
{
|
||||
protected function setUp()
|
||||
{
|
||||
$this->engine = BlockCipher::ENGINE_EVAL;
|
||||
}
|
||||
}
|
@ -14,6 +14,7 @@ class Unit_Crypt_BlowfishTest extends PhpseclibTestCase
|
||||
{
|
||||
$engines = array(
|
||||
BlockCipher::ENGINE_INTERNAL => 'internal',
|
||||
BlockCipher::ENGINE_EVAL => 'eval',
|
||||
BlockCipher::ENGINE_MCRYPT => 'mcrypt',
|
||||
BlockCipher::ENGINE_OPENSSL => 'OpenSSL',
|
||||
);
|
||||
|
@ -12,6 +12,7 @@ class Unit_Crypt_RC2Test extends PhpseclibTestCase
|
||||
{
|
||||
var $engines = array(
|
||||
BlockCipher::ENGINE_INTERNAL => 'internal',
|
||||
BlockCipher::ENGINE_EVAL => 'eval',
|
||||
BlockCipher::ENGINE_MCRYPT => 'mcrypt',
|
||||
BlockCipher::ENGINE_OPENSSL => 'OpenSSL',
|
||||
);
|
||||
|
@ -12,6 +12,7 @@ class Unit_Crypt_TripleDESTest extends PhpseclibTestCase
|
||||
{
|
||||
var $engines = array(
|
||||
BlockCipher::ENGINE_INTERNAL => 'internal',
|
||||
BlockCipher::ENGINE_EVAL => 'eval',
|
||||
BlockCipher::ENGINE_MCRYPT => 'mcrypt',
|
||||
BlockCipher::ENGINE_OPENSSL => 'OpenSSL',
|
||||
);
|
||||
|
@ -14,6 +14,7 @@ class Unit_Crypt_TwofishTest extends PhpseclibTestCase
|
||||
{
|
||||
$engines = array(
|
||||
BlockCipher::ENGINE_INTERNAL => 'internal',
|
||||
BlockCipher::ENGINE_EVAL => 'eval',
|
||||
BlockCipher::ENGINE_MCRYPT => 'mcrypt',
|
||||
BlockCipher::ENGINE_OPENSSL => 'OpenSSL',
|
||||
);
|
||||
|
Loading…
Reference in New Issue
Block a user