コード例 #1
0
ファイル: blowfish.php プロジェクト: Toxatoxa/Sample-Code
    /**
     * Creates performance-optimized function for de/encrypt(), storing it in $this->inline_crypt
     *
     * @access private
     */
    function inline_crypt_setup()
    {
        /*{{{*/
        $lambda_functions =& Crypt_Blowfish::get_lambda_functions();
        $block_size = 8;
        $mode = $this->mode;
        $code_hash = "{$mode}";
        if (!isset($lambda_functions[$code_hash])) {
            $init_cryptBlock = '

                extract($self->bctx["p"],  EXTR_PREFIX_ALL, "p");

                extract($self->bctx["sb"], EXTR_PREFIX_ALL, "sb");

            ';
            // Generating encrypt code:
            $_encryptBlock = '

                $in = unpack("N*", $in);

                $l = $in[1];

                $r = $in[2];

            ';
            for ($i = 0; $i < 16; $i += 2) {
                $_encryptBlock .= '

                    $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];

                ';
            }
            $_encryptBlock .= '

                $in = pack("N*", $r ^ $p_17, $l ^ $p_16);

            ';
            // Generating decrypt code:
            $_decryptBlock = '

                $in = unpack("N*", $in);

                $l = $in[1];

                $r = $in[2];

            ';
            for ($i = 17; $i > 2; $i -= 2) {
                $_decryptBlock .= '

                    $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];

                ';
            }
            $_decryptBlock .= '

                $in = pack("N*", $r ^ $p_0, $l ^ $p_1);

            ';
            // Generating mode of operation code:
            switch ($mode) {
                case CRYPT_BLOWFISH_MODE_ECB:
                    $encrypt = '

                        $ciphertext = "";

                        $text = $self->_pad($text);

                        $plaintext_len = strlen($text);



                        for ($i = 0; $i < $plaintext_len; $i+= ' . $block_size . ') {

                            $in = substr($text, $i, ' . $block_size . ');

                            ' . $_encryptBlock . '

                            $ciphertext.= $in;

                        }

                        return $ciphertext;

                        ';
                    $decrypt = '

                        $plaintext = "";

                        $text = str_pad($text, strlen($text) + (' . $block_size . ' - strlen($text) % ' . $block_size . ') % ' . $block_size . ', chr(0));

                        $ciphertext_len = strlen($text);



                        for ($i = 0; $i < $ciphertext_len; $i+= ' . $block_size . ') {

                            $in = substr($text, $i, ' . $block_size . ');

                            ' . $_decryptBlock . '

                            $plaintext.= $in;

                        }



                        return $self->_unpad($plaintext);

                        ';
                    break;
                case CRYPT_BLOWFISH_MODE_CBC:
                    $encrypt = '

                        $ciphertext = "";

                        $text = $self->_pad($text);

                        $plaintext_len = strlen($text);



                        $in = $self->encryptIV;



                        for ($i = 0; $i < $plaintext_len; $i+= ' . $block_size . ') {

                            $in = substr($text, $i, ' . $block_size . ') ^ $in;

                            ' . $_encryptBlock . '

                            $ciphertext.= $in;

                        }



                        if ($self->continuousBuffer) {

                            $self->encryptIV = $in;

                        }



                        return $ciphertext;

                        ';
                    $decrypt = '

                        $plaintext = "";

                        $text = str_pad($text, strlen($text) + (' . $block_size . ' - strlen($text) % ' . $block_size . ') % ' . $block_size . ', chr(0));

                        $ciphertext_len = strlen($text);



                        $iv = $self->decryptIV;



                        for ($i = 0; $i < $ciphertext_len; $i+= ' . $block_size . ') {

                            $in = $block = substr($text, $i, ' . $block_size . ');

                            ' . $_decryptBlock . '

                            $plaintext.= $in ^ $iv;

                            $iv = $block;

                        }



                        if ($self->continuousBuffer) {

                            $self->decryptIV = $iv;

                        }



                        return $self->_unpad($plaintext);

                        ';
                    break;
                case CRYPT_BLOWFISH_MODE_CTR:
                    $encrypt = '

                        $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);

                                    ' . $_encryptBlock . '

                                    $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);

                                ' . $_encryptBlock . '

                                $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 = '

                        $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);

                                    ' . $_encryptBlock . '

                                    $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);

                                ' . $_encryptBlock . '

                                $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_BLOWFISH_MODE_CFB:
                    $encrypt = '

                        $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;

                            ' . $_encryptBlock . ';

                            $iv = $in ^ substr($text, $i, ' . $block_size . ');

                            $ciphertext.= $iv;

                            $len-= ' . $block_size . ';

                            $i+= ' . $block_size . ';

                        }

                        if ($len) {

                            $in = $iv;

                            ' . $_encryptBlock . '

                            $iv = $in;

                            $block = $iv ^ substr($text, $i);

                            $iv = substr_replace($iv, $block, 0, $len);

                            $ciphertext.= $block;

                            $pos = $len;

                        }

                        return $ciphertext;

                    ';
                    $decrypt = '

                        $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;

                            ' . $_encryptBlock . '

                            $iv = $in;

                            $cb = substr($text, $i, ' . $block_size . ');

                            $plaintext.= $iv ^ $cb;

                            $iv = $cb;

                            $len-= ' . $block_size . ';

                            $i+= ' . $block_size . ';

                        }

                        if ($len) {

                            $in = $iv;

                            ' . $_encryptBlock . '

                            $iv = $in;

                            $plaintext.= $iv ^ substr($text, $i);

                            $iv = substr_replace($iv, substr($text, $i), 0, $len);

                            $pos = $len;

                        }



                        return $plaintext;

                        ';
                    break;
                case CRYPT_BLOWFISH_MODE_OFB:
                    $encrypt = '

                        $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;

                                    ' . $_encryptBlock . '

                                    $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;

                                ' . $_encryptBlock . '

                                $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 = '

                        $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;

                                    ' . $_encryptBlock . '

                                    $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;

                                ' . $_encryptBlock . '

                                $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;
            }
            $fnc_head = '$action, &$self, $text';
            $fnc_body = $init_cryptBlock . 'if ($action == "encrypt") { ' . $encrypt . ' } else { ' . $decrypt . ' }';
            if (function_exists('create_function') && is_callable('create_function')) {
                $lambda_functions[$code_hash] = create_function($fnc_head, $fnc_body);
            } else {
                eval('function ' . ($lambda_functions[$code_hash] = 'f' . md5(microtime())) . '(' . $fnc_head . ') { ' . $fnc_body . ' }');
            }
        }
        $this->inline_crypt = $lambda_functions[$code_hash];
    }