/** * Setup the performance-optimized function for de/encrypt() * * @see Crypt_Base::_setupInlineCrypt() * @access private */ function _setupInlineCrypt() { $lambda_functions =& Crypt_Twofish::_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 uniqe 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)$self->S0[$i]; $S1[] = (int)$self->S1[$i]; $S2[] = (int)$self->S2[$i]; $S3[] = (int)$self->S3[$i]; } } '; break; default: $K = array(); for ($i = 0; $i < 40; ++$i) { $K[] = '$K_' . $i; } $init_crypt = ' $S0 = $self->S0; $S1 = $self->S1; $S2 = $self->S2; $S3 = $self->S3; list(' . implode(',', $K) . ') = $self->K; '; } // 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] . '); '; } $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); '; $lambda_functions[$code_hash] = $this->_createInlineCryptFunction(array('init_crypt' => $init_crypt, 'init_encrypt' => '', 'init_decrypt' => '', 'encrypt_block' => $encrypt_block, 'decrypt_block' => $decrypt_block)); } $this->inline_crypt = $lambda_functions[$code_hash]; }