예제 #1
0
    /**
     * Creates performance-optimized function for de/encrypt(), storing it in $this->inline_crypt
     *
     * @param optional Integer $des_rounds (1 = DES[default], 3 = TribleDES)
     * @access private
     */
    function inline_crypt_setup($des_rounds = 1)
    {
        $lambda_functions =& Crypt_DES::get_lambda_functions();
        $block_size = 8;
        $mode = $this->mode;
        $code_hash = "{$mode},{$des_rounds}";
        if (!isset($lambda_functions[$code_hash])) {
            // Generating encrypt code:
            $ki = -1;
            $init_cryptBlock = '
                $shuffle  = $self->shuffle;
                $invipmap = $self->invipmap;
                $ipmap = $self->ipmap;
                $sbox1 = $self->sbox1;
                $sbox2 = $self->sbox2;
                $sbox3 = $self->sbox3;
                $sbox4 = $self->sbox4;
                $sbox5 = $self->sbox5;
                $sbox6 = $self->sbox6;
                $sbox7 = $self->sbox7;
                $sbox8 = $self->sbox8;
            ';
            $_cryptBlock = '$in = unpack("N*", $in);' . "\n";
            // Do the initial IP permutation.
            $_cryptBlock .= '
                $l  = $in[1];
                $r  = $in[2];
                $in = unpack("N*",
                    ($shuffle[$ipmap[ $r        & 0xFF]] & "\\x80\\x80\\x80\\x80\\x80\\x80\\x80\\x80") |
                    ($shuffle[$ipmap[($r >>  8) & 0xFF]] & "\\x40\\x40\\x40\\x40\\x40\\x40\\x40\\x40") |
                    ($shuffle[$ipmap[($r >> 16) & 0xFF]] & "\\x20\\x20\\x20\\x20\\x20\\x20\\x20\\x20") |
                    ($shuffle[$ipmap[($r >> 24) & 0xFF]] & "\\x10\\x10\\x10\\x10\\x10\\x10\\x10\\x10") |
                    ($shuffle[$ipmap[ $l        & 0xFF]] & "\\x08\\x08\\x08\\x08\\x08\\x08\\x08\\x08") |
                    ($shuffle[$ipmap[($l >>  8) & 0xFF]] & "\\x04\\x04\\x04\\x04\\x04\\x04\\x04\\x04") |
                    ($shuffle[$ipmap[($l >> 16) & 0xFF]] & "\\x02\\x02\\x02\\x02\\x02\\x02\\x02\\x02") |
                    ($shuffle[$ipmap[($l >> 24) & 0xFF]] & "\\x01\\x01\\x01\\x01\\x01\\x01\\x01\\x01")
                );

                ' . '' . '
                $l = $in[1];
                $r = $in[2];
            ';
            $l = 'l';
            $r = 'r';
            for ($des_round = 0; $des_round < $des_rounds; ++$des_round) {
                // Perform the 16 steps.
                // 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.
                for ($i = 0; $i < 8; ++$i) {
                    $_cryptBlock .= '
                        $b1 = (($' . $r . ' >>  3) & 0x1FFFFFFF)  ^ ($' . $r . ' << 29) ^ $k_' . ++$ki . ';
                        $b2 = (($' . $r . ' >> 31) & 0x00000001)  ^ ($' . $r . ' <<  1) ^ $k_' . ++$ki . ';
                        $' . $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 . ';

                        $b1 = (($' . $l . ' >>  3) & 0x1FFFFFFF)  ^ ($' . $l . ' << 29) ^ $k_' . ++$ki . ';
                        $b2 = (($' . $l . ' >> 31) & 0x00000001)  ^ ($' . $l . ' <<  1) ^ $k_' . ++$ki . ';
                        $' . $r . '  = $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] ^ $' . $r . ';
                    ';
                }
                // Last step should not permute L & R.
                $t = $l;
                $l = $r;
                $r = $t;
            }
            // Perform the inverse IP permutation.
            $_cryptBlock .= '$in = (
                    ($shuffle[$invipmap[($' . $r . ' >> 24) & 0xFF]] & "\\x80\\x80\\x80\\x80\\x80\\x80\\x80\\x80") |
                    ($shuffle[$invipmap[($' . $l . ' >> 24) & 0xFF]] & "\\x40\\x40\\x40\\x40\\x40\\x40\\x40\\x40") |
                    ($shuffle[$invipmap[($' . $r . ' >> 16) & 0xFF]] & "\\x20\\x20\\x20\\x20\\x20\\x20\\x20\\x20") |
                    ($shuffle[$invipmap[($' . $l . ' >> 16) & 0xFF]] & "\\x10\\x10\\x10\\x10\\x10\\x10\\x10\\x10") |
                    ($shuffle[$invipmap[($' . $r . ' >>  8) & 0xFF]] & "\\x08\\x08\\x08\\x08\\x08\\x08\\x08\\x08") |
                    ($shuffle[$invipmap[($' . $l . ' >>  8) & 0xFF]] & "\\x04\\x04\\x04\\x04\\x04\\x04\\x04\\x04") |
                    ($shuffle[$invipmap[ $' . $r . '        & 0xFF]] & "\\x02\\x02\\x02\\x02\\x02\\x02\\x02\\x02") |
                    ($shuffle[$invipmap[ $' . $l . '        & 0xFF]] & "\\x01\\x01\\x01\\x01\\x01\\x01\\x01\\x01")
                );
            ';
            // Generating mode of operation code:
            switch ($mode) {
                case CRYPT_DES_MODE_ECB:
                    $encrypt = $init_cryptBlock . '
                        extract($self->keys[CRYPT_DES_ENCRYPT_1DIM],  EXTR_PREFIX_ALL, "k");
                        $ciphertext = "";
                        $plaintext_len = strlen($text);

                        for ($i = 0; $i < $plaintext_len; $i+= ' . $block_size . ') {
                            $in = substr($text, $i, ' . $block_size . ');
                            ' . $_cryptBlock . '
                            $ciphertext.= $in;
                        }
                       
                        return $ciphertext;
                        ';
                    $decrypt = $init_cryptBlock . '
                        extract($self->keys[CRYPT_DES_DECRYPT_1DIM],  EXTR_PREFIX_ALL, "k");
                        $plaintext = "";
                        $ciphertext_len = strlen($text);

                        for ($i = 0; $i < $ciphertext_len; $i+= ' . $block_size . ') {
                            $in = substr($text, $i, ' . $block_size . ');
                            ' . $_cryptBlock . '
                            $plaintext.= $in;
                        }

                        return $self->_unpad($plaintext);
                        ';
                    break;
                case CRYPT_DES_MODE_CBC:
                    $encrypt = $init_cryptBlock . '
                        extract($self->keys[CRYPT_DES_ENCRYPT_1DIM],  EXTR_PREFIX_ALL, "k");
                        $ciphertext = "";
                        $plaintext_len = strlen($text);

                        $in = $self->encryptIV;

                        for ($i = 0; $i < $plaintext_len; $i+= ' . $block_size . ') {
                            $in = substr($text, $i, ' . $block_size . ') ^ $in;
                            ' . $_cryptBlock . '
                            $ciphertext.= $in;
                        }

                        if ($self->continuousBuffer) {
                            $self->encryptIV = $in;
                        }

                        return $ciphertext;
                        ';
                    $decrypt = $init_cryptBlock . '
                        extract($self->keys[CRYPT_DES_DECRYPT_1DIM],  EXTR_PREFIX_ALL, "k");
                        $plaintext = "";
                        $ciphertext_len = strlen($text);

                        $iv = $self->decryptIV;

                        for ($i = 0; $i < $ciphertext_len; $i+= ' . $block_size . ') {
                            $in = $block = substr($text, $i, ' . $block_size . ');
                            ' . $_cryptBlock . '
                            $plaintext.= $in ^ $iv;
                            $iv = $block;
                        }

                        if ($self->continuousBuffer) {
                            $self->decryptIV = $iv;
                        }

                        return $self->_unpad($plaintext);
                        ';
                    break;
                case CRYPT_DES_MODE_CTR:
                    $encrypt = $init_cryptBlock . '
                        extract($self->keys[CRYPT_DES_ENCRYPT_1DIM],  EXTR_PREFIX_ALL, "k");
                        $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);
                                    ' . $_cryptBlock . '
                                    $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);
                                ' . $_cryptBlock . '
                                $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 = $init_cryptBlock . '
                        extract($self->keys[CRYPT_DES_ENCRYPT_1DIM],  EXTR_PREFIX_ALL, "k");
                        $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);
                                    ' . $_cryptBlock . '
                                    $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);
                                ' . $_cryptBlock . '
                                $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_DES_MODE_CFB:
                    $encrypt = $init_cryptBlock . '
                        extract($self->keys[CRYPT_DES_ENCRYPT_1DIM],  EXTR_PREFIX_ALL, "k");
                        $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;
                            ' . $_cryptBlock . ';
                            $iv = $in ^ substr($text, $i, ' . $block_size . ');
                            $ciphertext.= $iv;
                            $len-= ' . $block_size . ';
                            $i+= ' . $block_size . ';
                        }
                        if ($len) {
                            $in = $iv;
                            ' . $_cryptBlock . '
                            $iv = $in;
                            $block = $iv ^ substr($text, $i);
                            $iv = substr_replace($iv, $block, 0, $len);
                            $ciphertext.= $block;
                            $pos = $len;
                        }
                        return $ciphertext;
                    ';
                    $decrypt = $init_cryptBlock . '
                        extract($self->keys[CRYPT_DES_ENCRYPT_1DIM],  EXTR_PREFIX_ALL, "k");
                        $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;
                            ' . $_cryptBlock . '
                            $iv = $in;
                            $cb = substr($text, $i, ' . $block_size . ');
                            $plaintext.= $iv ^ $cb;
                            $iv = $cb;
                            $len-= ' . $block_size . ';
                            $i+= ' . $block_size . ';
                        }
                        if ($len) {
                            $in = $iv;
                            ' . $_cryptBlock . '
                            $iv = $in;
                            $plaintext.= $iv ^ substr($text, $i);
                            $iv = substr_replace($iv, substr($text, $i), 0, $len);
                            $pos = $len;
                        }

                        return $plaintext;
                        ';
                    break;
                case CRYPT_DES_MODE_OFB:
                    $encrypt = $init_cryptBlock . '
                        extract($self->keys[CRYPT_DES_ENCRYPT_1DIM],  EXTR_PREFIX_ALL, "k");
                        $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;
                                    ' . $_cryptBlock . '
                                    $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;
                                ' . $_cryptBlock . '
                                $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 = $init_cryptBlock . '
                        extract($self->keys[CRYPT_DES_ENCRYPT_1DIM],  EXTR_PREFIX_ALL, "k");
                        $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;
                                    ' . $_cryptBlock . '
                                    $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;
                                ' . $_cryptBlock . '
                                $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;
            }
            $lambda_functions[$code_hash] = create_function('$action, &$self, $text', 'if ($action == "encrypt") { ' . $encrypt . ' } else { ' . $decrypt . ' }');
        }
        $this->inline_crypt = $lambda_functions[$code_hash];
    }
예제 #2
0
    function inline_crypt_setup($des_rounds = 1)
    {
        $lambda_functions =& Crypt_DES::get_lambda_functions();
        $block_size = 8;
        $mode = $this->mode;

        $code_hash = "$mode,$des_rounds";

        if (!isset($lambda_functions[$code_hash])) {
                        $ki = -1;
            $init_cryptBlock = '
                $shuffle  = $self->shuffle;
                $invipmap = $self->invipmap;
                $ipmap = $self->ipmap;
                $sbox1 = $self->sbox1;
                $sbox2 = $self->sbox2;
                $sbox3 = $self->sbox3;
                $sbox4 = $self->sbox4;
                $sbox5 = $self->sbox5;
                $sbox6 = $self->sbox6;
                $sbox7 = $self->sbox7;
                $sbox8 = $self->sbox8;
            ';

            $_cryptBlock = '$in = unpack("N*", $in);'."\n";
                        $_cryptBlock .= '
                $l  = $in[1];
                $r  = $in[2];
                $in = unpack("N*",
                    ($shuffle[$ipmap[ $r        & 0xFF]] & "\x80\x80\x80\x80\x80\x80\x80\x80") |
                    ($shuffle[$ipmap[($r >>  8) & 0xFF]] & "\x40\x40\x40\x40\x40\x40\x40\x40") |
                    ($shuffle[$ipmap[($r >> 16) & 0xFF]] & "\x20\x20\x20\x20\x20\x20\x20\x20") |
                    ($shuffle[$ipmap[($r >> 24) & 0xFF]] & "\x10\x10\x10\x10\x10\x10\x10\x10") |
                    ($shuffle[$ipmap[ $l        & 0xFF]] & "\x08\x08\x08\x08\x08\x08\x08\x08") |
                    ($shuffle[$ipmap[($l >>  8) & 0xFF]] & "\x04\x04\x04\x04\x04\x04\x04\x04") |
                    ($shuffle[$ipmap[($l >> 16) & 0xFF]] & "\x02\x02\x02\x02\x02\x02\x02\x02") |
                    ($shuffle[$ipmap[($l >> 24) & 0xFF]] & "\x01\x01\x01\x01\x01\x01\x01\x01")
                );

                '.''  .'
                $l = $in[1];
                $r = $in[2];
            ';

            $l = 'l';
            $r = 'r';
            for ($des_round = 0; $des_round < $des_rounds; ++$des_round) {
                                                                                for ($i = 0; $i < 8; ++$i) {
                    $_cryptBlock .= '
                        $b1 = (($' . $r . ' >>  3) & 0x1FFFFFFF)  ^ ($' . $r . ' << 29) ^ $k_'.(++$ki).';
                        $b2 = (($' . $r . ' >> 31) & 0x00000001)  ^ ($' . $r . ' <<  1) ^ $k_'.(++$ki).';
                        $' . $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 . ';

                        $b1 = (($' . $l . ' >>  3) & 0x1FFFFFFF)  ^ ($' . $l . ' << 29) ^ $k_'.(++$ki).';
                        $b2 = (($' . $l . ' >> 31) & 0x00000001)  ^ ($' . $l . ' <<  1) ^ $k_'.(++$ki).';
                        $' . $r . '  = $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] ^ $' . $r . ';
                    ';
                }

                                $t = $l;
                $l = $r;
                $r = $t;
            }

                        $_cryptBlock .= '$in = (
                    ($shuffle[$invipmap[($' . $r . ' >> 24) & 0xFF]] & "\x80\x80\x80\x80\x80\x80\x80\x80") |
                    ($shuffle[$invipmap[($' . $l . ' >> 24) & 0xFF]] & "\x40\x40\x40\x40\x40\x40\x40\x40") |
                    ($shuffle[$invipmap[($' . $r . ' >> 16) & 0xFF]] & "\x20\x20\x20\x20\x20\x20\x20\x20") |
                    ($shuffle[$invipmap[($' . $l . ' >> 16) & 0xFF]] & "\x10\x10\x10\x10\x10\x10\x10\x10") |
                    ($shuffle[$invipmap[($' . $r . ' >>  8) & 0xFF]] & "\x08\x08\x08\x08\x08\x08\x08\x08") |
                    ($shuffle[$invipmap[($' . $l . ' >>  8) & 0xFF]] & "\x04\x04\x04\x04\x04\x04\x04\x04") |
                    ($shuffle[$invipmap[ $' . $r . '        & 0xFF]] & "\x02\x02\x02\x02\x02\x02\x02\x02") |
                    ($shuffle[$invipmap[ $' . $l . '        & 0xFF]] & "\x01\x01\x01\x01\x01\x01\x01\x01")
                );
            ';

                        switch ($mode) {
                case CRYPT_DES_MODE_ECB:
                    $encrypt = $init_cryptBlock . '
                        extract($self->keys[CRYPT_DES_ENCRYPT_1DIM],  EXTR_PREFIX_ALL, "k");
                        $ciphertext = "";
                        $plaintext_len = strlen($text);

                        for ($i = 0; $i < $plaintext_len; $i+= '.$block_size.') {
                            $in = substr($text, $i, '.$block_size.');
                            '.$_cryptBlock.'
                            $ciphertext.= $in;
                        }

                        return $ciphertext;
                        ';

                    $decrypt = $init_cryptBlock . '
                        extract($self->keys[CRYPT_DES_DECRYPT_1DIM],  EXTR_PREFIX_ALL, "k");
                        $plaintext = "";
                        $ciphertext_len = strlen($text);

                        for ($i = 0; $i < $ciphertext_len; $i+= '.$block_size.') {
                            $in = substr($text, $i, '.$block_size.');
                            '.$_cryptBlock.'
                            $plaintext.= $in;
                        }

                        return $self->_unpad($plaintext);
                        ';
                    break;
                case CRYPT_DES_MODE_CBC:
                    $encrypt = $init_cryptBlock . '
                        extract($self->keys[CRYPT_DES_ENCRYPT_1DIM],  EXTR_PREFIX_ALL, "k");
                        $ciphertext = "";
                        $plaintext_len = strlen($text);

                        $in = $self->encryptIV;

                        for ($i = 0; $i < $plaintext_len; $i+= '.$block_size.') {
                            $in = substr($text, $i, '.$block_size.') ^ $in;
                            '.$_cryptBlock.'
                            $ciphertext.= $in;
                        }

                        if ($self->continuousBuffer) {
                            $self->encryptIV = $in;
                        }

                        return $ciphertext;
                        ';

                    $decrypt = $init_cryptBlock . '
                        extract($self->keys[CRYPT_DES_DECRYPT_1DIM],  EXTR_PREFIX_ALL, "k");
                        $plaintext = "";
                        $ciphertext_len = strlen($text);

                        $iv = $self->decryptIV;

                        for ($i = 0; $i < $ciphertext_len; $i+= '.$block_size.') {
                            $in = $block = substr($text, $i, '.$block_size.');
                            '.$_cryptBlock.'
                            $plaintext.= $in ^ $iv;
                            $iv = $block;
                        }

                        if ($self->continuousBuffer) {
                            $self->decryptIV = $iv;
                        }

                        return $self->_unpad($plaintext);
                        ';
                    break;
                case CRYPT_DES_MODE_CTR:
                    $encrypt = $init_cryptBlock . '
                        extract($self->keys[CRYPT_DES_ENCRYPT_1DIM],  EXTR_PREFIX_ALL, "k");
                        $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);
                                    '.$_cryptBlock.'
                                    $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);
                                '.$_cryptBlock.'
                                $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 = $init_cryptBlock . '
                        extract($self->keys[CRYPT_DES_ENCRYPT_1DIM],  EXTR_PREFIX_ALL, "k");
                        $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);
                                    '.$_cryptBlock.'
                                    $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);
                                '.$_cryptBlock.'
                                $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_DES_MODE_CFB:
                    $encrypt = $init_cryptBlock . '
                        extract($self->keys[CRYPT_DES_ENCRYPT_1DIM],  EXTR_PREFIX_ALL, "k");
                        $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;
                            '.$_cryptBlock.';
                            $iv = $in ^ substr($text, $i, '.$block_size.');
                            $ciphertext.= $iv;
                            $len-= '.$block_size.';
                            $i+= '.$block_size.';
                        }
                        if ($len) {
                            $in = $iv;
                            '.$_cryptBlock.'
                            $iv = $in;
                            $block = $iv ^ substr($text, $i);
                            $iv = substr_replace($iv, $block, 0, $len);
                            $ciphertext.= $block;
                            $pos = $len;
                        }
                        return $ciphertext;
                    ';

                    $decrypt = $init_cryptBlock . '
                        extract($self->keys[CRYPT_DES_ENCRYPT_1DIM],  EXTR_PREFIX_ALL, "k");
                        $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;
                            '.$_cryptBlock.'
                            $iv = $in;
                            $cb = substr($text, $i, '.$block_size.');
                            $plaintext.= $iv ^ $cb;
                            $iv = $cb;
                            $len-= '.$block_size.';
                            $i+= '.$block_size.';
                        }
                        if ($len) {
                            $in = $iv;
                            '.$_cryptBlock.'
                            $iv = $in;
                            $plaintext.= $iv ^ substr($text, $i);
                            $iv = substr_replace($iv, substr($text, $i), 0, $len);
                            $pos = $len;
                        }

                        return $plaintext;
                        ';
                    break;
                case CRYPT_DES_MODE_OFB:
                    $encrypt = $init_cryptBlock . '
                        extract($self->keys[CRYPT_DES_ENCRYPT_1DIM],  EXTR_PREFIX_ALL, "k");
                        $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;
                                    '.$_cryptBlock.'
                                    $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;
                                '.$_cryptBlock.'
                                $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 = $init_cryptBlock . '
                        extract($self->keys[CRYPT_DES_ENCRYPT_1DIM],  EXTR_PREFIX_ALL, "k");
                        $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;
                                    '.$_cryptBlock.'
                                    $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;
                                '.$_cryptBlock.'
                                $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;
            }
            $lambda_functions[$code_hash] = create_function('$action, &$self, $text', 'if ($action == "encrypt") { '.$encrypt.' } else { '.$decrypt.' }');
        }
        $this->inline_crypt = $lambda_functions[$code_hash];
    }
예제 #3
0
 public function inline_crypt_setup($des_rounds)
 {
     $lambda_functions =& Crypt_DES::get_lambda_functions();
     $block_size = 8;
     $mode = $this->mode;
     $code_hash = "{$mode},{$des_rounds}";
     if (!$lambda_functions[$code_hash]) {
         $ki = -1;
         $init_cryptBlock = "\n                \$shuffle  = \$self->shuffle;\n                \$invipmap = \$self->invipmap;\n                \$ipmap = \$self->ipmap;\n                \$sbox1 = \$self->sbox1;\n                \$sbox2 = \$self->sbox2;\n                \$sbox3 = \$self->sbox3;\n                \$sbox4 = \$self->sbox4;\n                \$sbox5 = \$self->sbox5;\n                \$sbox6 = \$self->sbox6;\n                \$sbox7 = \$self->sbox7;\n                \$sbox8 = \$self->sbox8;\n            ";
         $_cryptBlock = "\$in = unpack(\"N*\", \$in);\n";
         $_cryptBlock .= "\n                \$l  = \$in[1];\n                \$r  = \$in[2];\n                \$in = unpack(\"N*\",\n                    (\$shuffle[\$ipmap[ \$r        & 0xFF]] & \"\\x80\\x80\\x80\\x80\\x80\\x80\\x80\\x80\") |\n                    (\$shuffle[\$ipmap[(\$r >>  8) & 0xFF]] & \"\\x40\\x40\\x40\\x40\\x40\\x40\\x40\\x40\") |\n                    (\$shuffle[\$ipmap[(\$r >> 16) & 0xFF]] & \"\\x20\\x20\\x20\\x20\\x20\\x20\\x20\\x20\") |\n                    (\$shuffle[\$ipmap[(\$r >> 24) & 0xFF]] & \"\\x10\\x10\\x10\\x10\\x10\\x10\\x10\\x10\") |\n                    (\$shuffle[\$ipmap[ \$l        & 0xFF]] & \"\\x08\\x08\\x08\\x08\\x08\\x08\\x08\\x08\") |\n                    (\$shuffle[\$ipmap[(\$l >>  8) & 0xFF]] & \"\\x04\\x04\\x04\\x04\\x04\\x04\\x04\\x04\") |\n                    (\$shuffle[\$ipmap[(\$l >> 16) & 0xFF]] & \"\\x02\\x02\\x02\\x02\\x02\\x02\\x02\\x02\") |\n                    (\$shuffle[\$ipmap[(\$l >> 24) & 0xFF]] & \"\\x01\\x01\\x01\\x01\\x01\\x01\\x01\\x01\")\n                );\n\n                \n                \$l = \$in[1];\n                \$r = \$in[2];\n            ";
         $l = "l";
         $r = "r";
         for ($des_round = 0; $des_round < $des_rounds; ++$des_round) {
             for ($i = 0; $i < 8; ++$i) {
                 $_cryptBlock .= "\n                        \$b1 = ((\$" . $r . " >>  3) & 0x1FFFFFFF)  ^ (\$" . $r . " << 29) ^ \$k_" . ++$ki . ";\n                        \$b2 = ((\$" . $r . " >> 31) & 0x00000001)  ^ (\$" . $r . " <<  1) ^ \$k_" . ++$ki . ";\n                        \$" . $l . "  = \$sbox1[(\$b1 >> 24) & 0x3F] ^ \$sbox2[(\$b2 >> 24) & 0x3F] ^\n                              \$sbox3[(\$b1 >> 16) & 0x3F] ^ \$sbox4[(\$b2 >> 16) & 0x3F] ^\n                              \$sbox5[(\$b1 >>  8) & 0x3F] ^ \$sbox6[(\$b2 >>  8) & 0x3F] ^\n                              \$sbox7[ \$b1        & 0x3F] ^ \$sbox8[ \$b2        & 0x3F] ^ \$" . $l . ";\n\n                        \$b1 = ((\$" . $l . " >>  3) & 0x1FFFFFFF)  ^ (\$" . $l . " << 29) ^ \$k_" . ++$ki . ";\n                        \$b2 = ((\$" . $l . " >> 31) & 0x00000001)  ^ (\$" . $l . " <<  1) ^ \$k_" . ++$ki . ";\n                        \$" . $r . "  = \$sbox1[(\$b1 >> 24) & 0x3F] ^ \$sbox2[(\$b2 >> 24) & 0x3F] ^\n                              \$sbox3[(\$b1 >> 16) & 0x3F] ^ \$sbox4[(\$b2 >> 16) & 0x3F] ^\n                              \$sbox5[(\$b1 >>  8) & 0x3F] ^ \$sbox6[(\$b2 >>  8) & 0x3F] ^\n                              \$sbox7[ \$b1        & 0x3F] ^ \$sbox8[ \$b2        & 0x3F] ^ \$" . $r . ";\n                    ";
             }
             $t = $l;
             $l = $r;
             $r = $t;
         }
         $_cryptBlock .= "\$in = (\n                    (\$shuffle[\$invipmap[(\$" . $r . " >> 24) & 0xFF]] & \"\\x80\\x80\\x80\\x80\\x80\\x80\\x80\\x80\") |\n                    (\$shuffle[\$invipmap[(\$" . $l . " >> 24) & 0xFF]] & \"\\x40\\x40\\x40\\x40\\x40\\x40\\x40\\x40\") |\n                    (\$shuffle[\$invipmap[(\$" . $r . " >> 16) & 0xFF]] & \"\\x20\\x20\\x20\\x20\\x20\\x20\\x20\\x20\") |\n                    (\$shuffle[\$invipmap[(\$" . $l . " >> 16) & 0xFF]] & \"\\x10\\x10\\x10\\x10\\x10\\x10\\x10\\x10\") |\n                    (\$shuffle[\$invipmap[(\$" . $r . " >>  8) & 0xFF]] & \"\\x08\\x08\\x08\\x08\\x08\\x08\\x08\\x08\") |\n                    (\$shuffle[\$invipmap[(\$" . $l . " >>  8) & 0xFF]] & \"\\x04\\x04\\x04\\x04\\x04\\x04\\x04\\x04\") |\n                    (\$shuffle[\$invipmap[ \$" . $r . "        & 0xFF]] & \"\\x02\\x02\\x02\\x02\\x02\\x02\\x02\\x02\") |\n                    (\$shuffle[\$invipmap[ \$" . $l . "        & 0xFF]] & \"\\x01\\x01\\x01\\x01\\x01\\x01\\x01\\x01\")\n                );\n            ";
         switch ($mode) {
             case CRYPT_DES_MODE_ECB:
                 $encrypt = $init_cryptBlock . "\n                        extract(\$self->keys[CRYPT_DES_ENCRYPT_1DIM],  EXTR_PREFIX_ALL, \"k\");\n                        \$ciphertext = \"\";\n                        \$plaintext_len = strlen(\$text);\n\n                        for (\$i = 0; \$i < \$plaintext_len; \$i+= " . $block_size . ") {\n                            \$in = substr(\$text, \$i, " . $block_size . ");\n                            " . $_cryptBlock . "\n                            \$ciphertext.= \$in;\n                        }\n                       \n                        return \$ciphertext;\n                        ";
                 $decrypt = $init_cryptBlock . "\n                        extract(\$self->keys[CRYPT_DES_DECRYPT_1DIM],  EXTR_PREFIX_ALL, \"k\");\n                        \$plaintext = \"\";\n                        \$ciphertext_len = strlen(\$text);\n\n                        for (\$i = 0; \$i < \$ciphertext_len; \$i+= " . $block_size . ") {\n                            \$in = substr(\$text, \$i, " . $block_size . ");\n                            " . $_cryptBlock . "\n                            \$plaintext.= \$in;\n                        }\n\n                        return \$self->_unpad(\$plaintext);\n                        ";
                 break;
             case CRYPT_DES_MODE_CBC:
                 $encrypt = $init_cryptBlock . "\n                        extract(\$self->keys[CRYPT_DES_ENCRYPT_1DIM],  EXTR_PREFIX_ALL, \"k\");\n                        \$ciphertext = \"\";\n                        \$plaintext_len = strlen(\$text);\n\n                        \$in = \$self->encryptIV;\n\n                        for (\$i = 0; \$i < \$plaintext_len; \$i+= " . $block_size . ") {\n                            \$in = substr(\$text, \$i, " . $block_size . ") ^ \$in;\n                            " . $_cryptBlock . "\n                            \$ciphertext.= \$in;\n                        }\n\n                        if (\$self->continuousBuffer) {\n                            \$self->encryptIV = \$in;\n                        }\n\n                        return \$ciphertext;\n                        ";
                 $decrypt = $init_cryptBlock . "\n                        extract(\$self->keys[CRYPT_DES_DECRYPT_1DIM],  EXTR_PREFIX_ALL, \"k\");\n                        \$plaintext = \"\";\n                        \$ciphertext_len = strlen(\$text);\n\n                        \$iv = \$self->decryptIV;\n\n                        for (\$i = 0; \$i < \$ciphertext_len; \$i+= " . $block_size . ") {\n                            \$in = \$block = substr(\$text, \$i, " . $block_size . ");\n                            " . $_cryptBlock . "\n                            \$plaintext.= \$in ^ \$iv;\n                            \$iv = \$block;\n                        }\n\n                        if (\$self->continuousBuffer) {\n                            \$self->decryptIV = \$iv;\n                        }\n\n                        return \$self->_unpad(\$plaintext);\n                        ";
                 break;
             case CRYPT_DES_MODE_CTR:
                 $encrypt = $init_cryptBlock . "\n                        extract(\$self->keys[CRYPT_DES_ENCRYPT_1DIM],  EXTR_PREFIX_ALL, \"k\");\n                        \$ciphertext = \"\";\n                        \$plaintext_len = strlen(\$text);\n                        \$xor = \$self->encryptIV;\n                        \$buffer = &\$self->enbuffer;\n\n                        if (strlen(\$buffer[\"encrypted\"])) {\n                            for (\$i = 0; \$i < \$plaintext_len; \$i+= " . $block_size . ") {\n                                \$block = substr(\$text, \$i, " . $block_size . ");\n                                if (strlen(\$block) > strlen(\$buffer[\"encrypted\"])) {\n                                    \$in = \$self->_generate_xor(\$xor);\n                                    " . $_cryptBlock . "\n                                    \$buffer[\"encrypted\"].= \$in;\n                                }\n                                \$key = \$self->_string_shift(\$buffer[\"encrypted\"]);\n                                \$ciphertext.= \$block ^ \$key;\n                            }\n                        } else {\n                            for (\$i = 0; \$i < \$plaintext_len; \$i+= " . $block_size . ") {\n                                \$block = substr(\$text, \$i, " . $block_size . ");\n                                \$in = \$self->_generate_xor(\$xor);\n                                " . $_cryptBlock . "\n                                \$key = \$in;\n                                \$ciphertext.= \$block ^ \$key;\n                            }\n                        }\n                        if (\$self->continuousBuffer) {\n                            \$self->encryptIV = \$xor;\n                            if (\$start = \$plaintext_len % " . $block_size . ") {\n                                \$buffer[\"encrypted\"] = substr(\$key, \$start) . \$buffer[\"encrypted\"];\n                            }\n                        }\n\n                        return \$ciphertext;\n                    ";
                 $decrypt = $init_cryptBlock . "\n                        extract(\$self->keys[CRYPT_DES_ENCRYPT_1DIM],  EXTR_PREFIX_ALL, \"k\");\n                        \$plaintext = \"\";\n                        \$ciphertext_len = strlen(\$text);\n                        \$xor = \$self->decryptIV;\n                        \$buffer = &\$self->debuffer;\n\n                        if (strlen(\$buffer[\"ciphertext\"])) {\n                            for (\$i = 0; \$i < \$ciphertext_len; \$i+= " . $block_size . ") {\n                                \$block = substr(\$text, \$i, " . $block_size . ");\n                                if (strlen(\$block) > strlen(\$buffer[\"ciphertext\"])) {\n                                    \$in = \$self->_generate_xor(\$xor);\n                                    " . $_cryptBlock . "\n                                    \$buffer[\"ciphertext\"].= \$in;\n                                }\n                                \$key = \$self->_string_shift(\$buffer[\"ciphertext\"]);\n                                \$plaintext.= \$block ^ \$key;\n                            }\n                        } else {\n                            for (\$i = 0; \$i < \$ciphertext_len; \$i+= " . $block_size . ") {\n                                \$block = substr(\$text, \$i, " . $block_size . ");\n                                \$in = \$self->_generate_xor(\$xor);\n                                " . $_cryptBlock . "\n                                \$key = \$in;\n                                \$plaintext.= \$block ^ \$key;\n                            }\n                        }\n                        if (\$self->continuousBuffer) {\n                            \$self->decryptIV = \$xor;\n                            if (\$start = \$ciphertext_len % " . $block_size . ") {\n                                \$buffer[\"ciphertext\"] = substr(\$key, \$start) . \$buffer[\"ciphertext\"];\n                            }\n                        }\n                       \n                        return \$plaintext;\n                        ";
                 break;
             case CRYPT_DES_MODE_CFB:
                 $encrypt = $init_cryptBlock . "\n                        extract(\$self->keys[CRYPT_DES_ENCRYPT_1DIM],  EXTR_PREFIX_ALL, \"k\");\n                        \$ciphertext = \"\";\n                        \$buffer = &\$self->enbuffer;\n\n                        if (\$self->continuousBuffer) {\n                            \$iv = &\$self->encryptIV;\n                            \$pos = &\$buffer[\"pos\"];\n                        } else {\n                            \$iv = \$self->encryptIV;\n                            \$pos = 0;\n                        }\n                        \$len = strlen(\$text);\n                        \$i = 0;\n                        if (\$pos) {\n                            \$orig_pos = \$pos;\n                            \$max = " . $block_size . " - \$pos;\n                            if (\$len >= \$max) {\n                                \$i = \$max;\n                                \$len-= \$max;\n                                \$pos = 0;\n                            } else {\n                                \$i = \$len;\n                                \$pos+= \$len;\n                                \$len = 0;\n                            }\n                            \$ciphertext = substr(\$iv, \$orig_pos) ^ \$text;\n                            \$iv = substr_replace(\$iv, \$ciphertext, \$orig_pos, \$i);\n                        }\n                        while (\$len >= " . $block_size . ") {\n                            \$in = \$iv;\n                            " . $_cryptBlock . ";\n                            \$iv = \$in ^ substr(\$text, \$i, " . $block_size . ");\n                            \$ciphertext.= \$iv;\n                            \$len-= " . $block_size . ";\n                            \$i+= " . $block_size . ";\n                        }\n                        if (\$len) {\n                            \$in = \$iv;\n                            " . $_cryptBlock . "\n                            \$iv = \$in;\n                            \$block = \$iv ^ substr(\$text, \$i);\n                            \$iv = substr_replace(\$iv, \$block, 0, \$len);\n                            \$ciphertext.= \$block;\n                            \$pos = \$len;\n                        }\n                        return \$ciphertext;\n                    ";
                 $decrypt = $init_cryptBlock . "\n                        extract(\$self->keys[CRYPT_DES_ENCRYPT_1DIM],  EXTR_PREFIX_ALL, \"k\");\n                        \$plaintext = \"\";\n                        \$buffer = &\$self->debuffer;\n\n                        if (\$self->continuousBuffer) {\n                            \$iv = &\$self->decryptIV;\n                            \$pos = &\$buffer[\"pos\"];\n                        } else {\n                            \$iv = \$self->decryptIV;\n                            \$pos = 0;\n                        }\n                        \$len = strlen(\$text);\n                        \$i = 0;\n                        if (\$pos) {\n                            \$orig_pos = \$pos;\n                            \$max = " . $block_size . " - \$pos;\n                            if (\$len >= \$max) {\n                                \$i = \$max;\n                                \$len-= \$max;\n                                \$pos = 0;\n                            } else {\n                                \$i = \$len;\n                                \$pos+= \$len;\n                                \$len = 0;\n                            }\n                            \$plaintext = substr(\$iv, \$orig_pos) ^ \$text;\n                            \$iv = substr_replace(\$iv, substr(\$text, 0, \$i), \$orig_pos, \$i);\n                        }\n                        while (\$len >= " . $block_size . ") {\n                            \$in = \$iv;\n                            " . $_cryptBlock . "\n                            \$iv = \$in;\n                            \$cb = substr(\$text, \$i, " . $block_size . ");\n                            \$plaintext.= \$iv ^ \$cb;\n                            \$iv = \$cb;\n                            \$len-= " . $block_size . ";\n                            \$i+= " . $block_size . ";\n                        }\n                        if (\$len) {\n                            \$in = \$iv;\n                            " . $_cryptBlock . "\n                            \$iv = \$in;\n                            \$plaintext.= \$iv ^ substr(\$text, \$i);\n                            \$iv = substr_replace(\$iv, substr(\$text, \$i), 0, \$len);\n                            \$pos = \$len;\n                        }\n\n                        return \$plaintext;\n                        ";
                 break;
             case CRYPT_DES_MODE_OFB:
                 $encrypt = $init_cryptBlock . "\n                        extract(\$self->keys[CRYPT_DES_ENCRYPT_1DIM],  EXTR_PREFIX_ALL, \"k\");\n                        \$ciphertext = \"\";\n                        \$plaintext_len = strlen(\$text);\n                        \$xor = \$self->encryptIV;\n                        \$buffer = &\$self->enbuffer;\n\n                        if (strlen(\$buffer[\"xor\"])) {\n                            for (\$i = 0; \$i < \$plaintext_len; \$i+= " . $block_size . ") {\n                                \$block = substr(\$text, \$i, " . $block_size . ");\n                                if (strlen(\$block) > strlen(\$buffer[\"xor\"])) {\n                                    \$in = \$xor;\n                                    " . $_cryptBlock . "\n                                    \$xor = \$in;\n                                    \$buffer[\"xor\"].= \$xor;\n                                }\n                                \$key = \$self->_string_shift(\$buffer[\"xor\"]);\n                                \$ciphertext.= \$block ^ \$key;\n                            }\n                        } else {\n                            for (\$i = 0; \$i < \$plaintext_len; \$i+= " . $block_size . ") {\n                                \$in = \$xor;\n                                " . $_cryptBlock . "\n                                \$xor = \$in;\n                                \$ciphertext.= substr(\$text, \$i, " . $block_size . ") ^ \$xor;\n                            }\n                            \$key = \$xor;\n                        }\n                        if (\$self->continuousBuffer) {\n                            \$self->encryptIV = \$xor;\n                            if (\$start = \$plaintext_len % " . $block_size . ") {\n                                 \$buffer[\"xor\"] = substr(\$key, \$start) . \$buffer[\"xor\"];\n                            }\n                        }\n                        return \$ciphertext;\n                        ";
                 $decrypt = $init_cryptBlock . "\n                        extract(\$self->keys[CRYPT_DES_ENCRYPT_1DIM],  EXTR_PREFIX_ALL, \"k\");\n                        \$plaintext = \"\";\n                        \$ciphertext_len = strlen(\$text);\n                        \$xor = \$self->decryptIV;\n                        \$buffer = &\$self->debuffer;\n\n                        if (strlen(\$buffer[\"xor\"])) {\n                            for (\$i = 0; \$i < \$ciphertext_len; \$i+= " . $block_size . ") {\n                                \$block = substr(\$text, \$i, " . $block_size . ");\n                                if (strlen(\$block) > strlen(\$buffer[\"xor\"])) {\n                                    \$in = \$xor;\n                                    " . $_cryptBlock . "\n                                    \$xor = \$in;\n                                    \$buffer[\"xor\"].= \$xor;\n                                }\n                                \$key = \$self->_string_shift(\$buffer[\"xor\"]);\n                                \$plaintext.= \$block ^ \$key;\n                            }\n                        } else {\n                            for (\$i = 0; \$i < \$ciphertext_len; \$i+= " . $block_size . ") {\n                                \$in = \$xor;\n                                " . $_cryptBlock . "\n                                \$xor = \$in;\n                                \$plaintext.= substr(\$text, \$i, " . $block_size . ") ^ \$xor;\n                            }\n                            \$key = \$xor;\n                        }\n                        if (\$self->continuousBuffer) {\n                            \$self->decryptIV = \$xor;\n                            if (\$start = \$ciphertext_len % " . $block_size . ") {\n                                 \$buffer[\"xor\"] = substr(\$key, \$start) . \$buffer[\"xor\"];\n                            }\n                        }\n                        return \$plaintext;\n                        ";
                 break;
         }
         $lambda_functions[$code_hash] = create_function("\$action, &\$self, \$text", "if (\$action == \"encrypt\") { " . $encrypt . " } else { " . $decrypt . " }");
     }
     $this->inline_crypt = $lambda_functions[$code_hash];
 }