Esempio n. 1
0
function des($key, $message, $encrypt, $mode, $iv)
{
    //declaring this locally speeds things up a bit
    $spfunction1 = array(0x1010400, 0, 0x10000, 0x1010404, 0x1010004, 0x10404, 0x4, 0x10000, 0x400, 0x1010400, 0x1010404, 0x400, 0x1000404, 0x1010004, 0x1000000, 0x4, 0x404, 0x1000400, 0x1000400, 0x10400, 0x10400, 0x1010000, 0x1010000, 0x1000404, 0x10004, 0x1000004, 0x1000004, 0x10004, 0, 0x404, 0x10404, 0x1000000, 0x10000, 0x1010404, 0x4, 0x1010000, 0x1010400, 0x1000000, 0x1000000, 0x400, 0x1010004, 0x10000, 0x10400, 0x1000004, 0x400, 0x4, 0x1000404, 0x10404, 0x1010404, 0x10004, 0x1010000, 0x1000404, 0x1000004, 0x404, 0x10404, 0x1010400, 0x404, 0x1000400, 0x1000400, 0, 0x10004, 0x10400, 0, 0x1010004);
    $spfunction2 = array(-0x7fef7fe0, -0x7fff8000, 0x8000, 0x108020, 0x100000, 0x20, -0x7fefffe0, -0x7fff7fe0, -0x7fffffe0, -0x7fef7fe0, -0x7fef8000, -0x80000000, -0x7fff8000, 0x100000, 0x20, -0x7fefffe0, 0x108000, 0x100020, -0x7fff7fe0, 0, -0x80000000, 0x8000, 0x108020, -0x7ff00000, 0x100020, -0x7fffffe0, 0, 0x108000, 0x8020, -0x7fef8000, -0x7ff00000, 0x8020, 0, 0x108020, -0x7fefffe0, 0x100000, -0x7fff7fe0, -0x7ff00000, -0x7fef8000, 0x8000, -0x7ff00000, -0x7fff8000, 0x20, -0x7fef7fe0, 0x108020, 0x20, 0x8000, -0x80000000, 0x8020, -0x7fef8000, 0x100000, -0x7fffffe0, 0x100020, -0x7fff7fe0, -0x7fffffe0, 0x100020, 0x108000, 0, -0x7fff8000, 0x8020, -0x80000000, -0x7fefffe0, -0x7fef7fe0, 0x108000);
    $spfunction3 = array(0x208, 0x8020200, 0, 0x8020008, 0x8000200, 0, 0x20208, 0x8000200, 0x20008, 0x8000008, 0x8000008, 0x20000, 0x8020208, 0x20008, 0x8020000, 0x208, 0x8000000, 0x8, 0x8020200, 0x200, 0x20200, 0x8020000, 0x8020008, 0x20208, 0x8000208, 0x20200, 0x20000, 0x8000208, 0x8, 0x8020208, 0x200, 0x8000000, 0x8020200, 0x8000000, 0x20008, 0x208, 0x20000, 0x8020200, 0x8000200, 0, 0x200, 0x20008, 0x8020208, 0x8000200, 0x8000008, 0x200, 0, 0x8020008, 0x8000208, 0x20000, 0x8000000, 0x8020208, 0x8, 0x20208, 0x20200, 0x8000008, 0x8020000, 0x8000208, 0x208, 0x8020000, 0x20208, 0x8, 0x8020008, 0x20200);
    $spfunction4 = array(0x802001, 0x2081, 0x2081, 0x80, 0x802080, 0x800081, 0x800001, 0x2001, 0, 0x802000, 0x802000, 0x802081, 0x81, 0, 0x800080, 0x800001, 0x1, 0x2000, 0x800000, 0x802001, 0x80, 0x800000, 0x2001, 0x2080, 0x800081, 0x1, 0x2080, 0x800080, 0x2000, 0x802080, 0x802081, 0x81, 0x800080, 0x800001, 0x802000, 0x802081, 0x81, 0, 0, 0x802000, 0x2080, 0x800080, 0x800081, 0x1, 0x802001, 0x2081, 0x2081, 0x80, 0x802081, 0x81, 0x1, 0x2000, 0x800001, 0x2001, 0x802080, 0x800081, 0x2001, 0x2080, 0x800000, 0x802001, 0x80, 0x800000, 0x2000, 0x802080);
    $spfunction5 = array(0x100, 0x2080100, 0x2080000, 0x42000100, 0x80000, 0x100, 0x40000000, 0x2080000, 0x40080100, 0x80000, 0x2000100, 0x40080100, 0x42000100, 0x42080000, 0x80100, 0x40000000, 0x2000000, 0x40080000, 0x40080000, 0, 0x40000100, 0x42080100, 0x42080100, 0x2000100, 0x42080000, 0x40000100, 0, 0x42000000, 0x2080100, 0x2000000, 0x42000000, 0x80100, 0x80000, 0x42000100, 0x100, 0x2000000, 0x40000000, 0x2080000, 0x42000100, 0x40080100, 0x2000100, 0x40000000, 0x42080000, 0x2080100, 0x40080100, 0x100, 0x2000000, 0x42080000, 0x42080100, 0x80100, 0x42000000, 0x42080100, 0x2080000, 0, 0x40080000, 0x42000000, 0x80100, 0x2000100, 0x40000100, 0x80000, 0, 0x40080000, 0x2080100, 0x40000100);
    $spfunction6 = array(0x20000010, 0x20400000, 0x4000, 0x20404010, 0x20400000, 0x10, 0x20404010, 0x400000, 0x20004000, 0x404010, 0x400000, 0x20000010, 0x400010, 0x20004000, 0x20000000, 0x4010, 0, 0x400010, 0x20004010, 0x4000, 0x404000, 0x20004010, 0x10, 0x20400010, 0x20400010, 0, 0x404010, 0x20404000, 0x4010, 0x404000, 0x20404000, 0x20000000, 0x20004000, 0x10, 0x20400010, 0x404000, 0x20404010, 0x400000, 0x4010, 0x20000010, 0x400000, 0x20004000, 0x20000000, 0x4010, 0x20000010, 0x20404010, 0x404000, 0x20400000, 0x404010, 0x20404000, 0, 0x20400010, 0x10, 0x4000, 0x20400000, 0x404010, 0x4000, 0x400010, 0x20004010, 0, 0x20404000, 0x20000000, 0x400010, 0x20004010);
    $spfunction7 = array(0x200000, 0x4200002, 0x4000802, 0, 0x800, 0x4000802, 0x200802, 0x4200800, 0x4200802, 0x200000, 0, 0x4000002, 0x2, 0x4000000, 0x4200002, 0x802, 0x4000800, 0x200802, 0x200002, 0x4000800, 0x4000002, 0x4200000, 0x4200800, 0x200002, 0x4200000, 0x800, 0x802, 0x4200802, 0x200800, 0x2, 0x4000000, 0x200800, 0x4000000, 0x200800, 0x200000, 0x4000802, 0x4000802, 0x4200002, 0x4200002, 0x2, 0x200002, 0x4000000, 0x4000800, 0x200000, 0x4200800, 0x802, 0x200802, 0x4200800, 0x802, 0x4000002, 0x4200802, 0x4200000, 0x200800, 0, 0x2, 0x4200802, 0, 0x200802, 0x4200000, 0x800, 0x4000002, 0x4000800, 0x800, 0x200002);
    $spfunction8 = array(0x10001040, 0x1000, 0x40000, 0x10041040, 0x10000000, 0x10001040, 0x40, 0x10000000, 0x40040, 0x10040000, 0x10041040, 0x41000, 0x10041000, 0x41040, 0x1000, 0x40, 0x10040000, 0x10000040, 0x10001000, 0x1040, 0x41000, 0x40040, 0x10040040, 0x10041000, 0x1040, 0, 0, 0x10040040, 0x10000040, 0x10001000, 0x41040, 0x40000, 0x41040, 0x40000, 0x10041000, 0x1000, 0x40, 0x10040040, 0x1000, 0x41040, 0x10001000, 0x40, 0x10000040, 0x10040000, 0x10040040, 0x10000000, 0x40000, 0x10001040, 0, 0x10041040, 0x40040, 0x10000040, 0x10040000, 0x10001000, 0x10001040, 0, 0x10041040, 0x41000, 0x41000, 0x1040, 0x1040, 0x40040, 0x10000000, 0x10041000);
    $masks = array(4294967295, 2147483647, 1073741823, 536870911, 268435455, 134217727, 67108863, 33554431, 16777215, 8388607, 4194303, 2097151, 1048575, 524287, 262143, 131071, 65535, 32767, 16383, 8191, 4095, 2047, 1023, 511, 255, 127, 63, 31, 15, 7, 3, 1, 0);
    //create the 16 or 48 subkeys we will need
    $keys = des_createKeys($key);
    $m = 0;
    $len = strlen($message);
    $chunk = 0;
    //set up the loops for single and triple des
    $iterations = count($keys) == 32 ? 3 : 9;
    //single or triple des
    if ($iterations == 3) {
        $looping = $encrypt ? array(0, 32, 2) : array(30, -2, -2);
    } else {
        $looping = $encrypt ? array(0, 32, 2, 62, 30, -2, 64, 96, 2) : array(94, 62, -2, 32, 64, 2, 30, -2, -2);
    }
    $message .= chr(0) . chr(0) . chr(0) . chr(0) . chr(0) . chr(0) . chr(0) . chr(0);
    //pad the message out with null bytes
    //store the result here
    $result = "";
    $tempresult = "";
    if ($mode == 1) {
        //CBC mode
        $cbcleft = ord($iv[$m++]) << 24 | ord($iv[$m++]) << 16 | ord($iv[$m++]) << 8 | ord($iv[$m++]);
        $cbcright = ord($iv[$m++]) << 24 | ord($iv[$m++]) << 16 | ord($iv[$m++]) << 8 | ord($iv[$m++]);
        $m = 0;
    }
    //loop through each 64 bit chunk of the message
    while ($m < $len) {
        $left = ord($message[$m++]) << 24 | ord($message[$m++]) << 16 | ord($message[$m++]) << 8 | ord($message[$m++]);
        $right = ord($message[$m++]) << 24 | ord($message[$m++]) << 16 | ord($message[$m++]) << 8 | ord($message[$m++]);
        //for Cipher Block Chaining mode, xor the message with the previous result
        if ($mode == 1) {
            if ($encrypt) {
                $left ^= $cbcleft;
                $right ^= $cbcright;
            } else {
                $cbcleft2 = $cbcleft;
                $cbcright2 = $cbcright;
                $cbcleft = $left;
                $cbcright = $right;
            }
        }
        //first each 64 but chunk of the message must be permuted according to IP
        $temp = ($left >> 4 & $masks[4] ^ $right) & 0xf0f0f0f;
        $right ^= $temp;
        $left ^= $temp << 4;
        $temp = ($left >> 16 & $masks[16] ^ $right) & 0xffff;
        $right ^= $temp;
        $left ^= $temp << 16;
        $temp = ($right >> 2 & $masks[2] ^ $left) & 0x33333333;
        $left ^= $temp;
        $right ^= $temp << 2;
        $temp = ($right >> 8 & $masks[8] ^ $left) & 0xff00ff;
        $left ^= $temp;
        $right ^= $temp << 8;
        $temp = ($left >> 1 & $masks[1] ^ $right) & 0x55555555;
        $right ^= $temp;
        $left ^= $temp << 1;
        $left = $left << 1 | $left >> 31 & $masks[31];
        $right = $right << 1 | $right >> 31 & $masks[31];
        //do this either 1 or 3 times for each chunk of the message
        for ($j = 0; $j < $iterations; $j += 3) {
            $endloop = $looping[$j + 1];
            $loopinc = $looping[$j + 2];
            //now go through and perform the encryption or decryption
            for ($i = $looping[$j]; $i != $endloop; $i += $loopinc) {
                //for efficiency
                $right1 = $right ^ $keys[$i];
                $right2 = ($right >> 4 & $masks[4] | $right << 28) ^ $keys[$i + 1];
                //the result is attained by passing these bytes through the S selection functions
                $temp = $left;
                $left = $right;
                $right = $temp ^ ($spfunction2[$right1 >> 24 & $masks[24] & 0x3f] | $spfunction4[$right1 >> 16 & $masks[16] & 0x3f] | $spfunction6[$right1 >> 8 & $masks[8] & 0x3f] | $spfunction8[$right1 & 0x3f] | $spfunction1[$right2 >> 24 & $masks[24] & 0x3f] | $spfunction3[$right2 >> 16 & $masks[16] & 0x3f] | $spfunction5[$right2 >> 8 & $masks[8] & 0x3f] | $spfunction7[$right2 & 0x3f]);
            }
            $temp = $left;
            $left = $right;
            $right = $temp;
            //unreverse left and right
        }
        //for either 1 or 3 iterations
        //move then each one bit to the right
        $left = $left >> 1 & $masks[1] | $left << 31;
        $right = $right >> 1 & $masks[1] | $right << 31;
        //now perform IP-1, which is IP in the opposite direction
        $temp = ($left >> 1 & $masks[1] ^ $right) & 0x55555555;
        $right ^= $temp;
        $left ^= $temp << 1;
        $temp = ($right >> 8 & $masks[8] ^ $left) & 0xff00ff;
        $left ^= $temp;
        $right ^= $temp << 8;
        $temp = ($right >> 2 & $masks[2] ^ $left) & 0x33333333;
        $left ^= $temp;
        $right ^= $temp << 2;
        $temp = ($left >> 16 & $masks[16] ^ $right) & 0xffff;
        $right ^= $temp;
        $left ^= $temp << 16;
        $temp = ($left >> 4 & $masks[4] ^ $right) & 0xf0f0f0f;
        $right ^= $temp;
        $left ^= $temp << 4;
        //for Cipher Block Chaining mode, xor the message with the previous result
        if ($mode == 1) {
            if ($encrypt) {
                $cbcleft = $left;
                $cbcright = $right;
            } else {
                $left ^= $cbcleft2;
                $right ^= $cbcright2;
            }
        }
        $tempresult .= chr($left >> 24 & $masks[24]) . chr($left >> 16 & $masks[16] & 0xff) . chr($left >> 8 & $masks[8] & 0xff) . chr($left & 0xff) . chr($right >> 24 & $masks[24]) . chr($right >> 16 & $masks[16] & 0xff) . chr($right >> 8 & $masks[8] & 0xff) . chr($right & 0xff);
        $chunk += 8;
        if ($chunk == 512) {
            $result .= $tempresult;
            $tempresult = "";
            $chunk = 0;
        }
    }
    //for every 8 characters, or 64 bits in the message
    //return the result as an array
    return $result . $tempresult;
}
Esempio n. 2
0
function des($message, $key, $encrypt, $mode, $iv)
{
    $spfunction1 = array(0x1010400, 0, 0x10000, 0x1010404, 0x1010004, 0x10404, 0x4, 0x10000, 0x400, 0x1010400, 0x1010404, 0x400, 0x1000404, 0x1010004, 0x1000000, 0x4, 0x404, 0x1000400, 0x1000400, 0x10400, 0x10400, 0x1010000, 0x1010000, 0x1000404, 0x10004, 0x1000004, 0x1000004, 0x10004, 0, 0x404, 0x10404, 0x1000000, 0x10000, 0x1010404, 0x4, 0x1010000, 0x1010400, 0x1000000, 0x1000000, 0x400, 0x1010004, 0x10000, 0x10400, 0x1000004, 0x400, 0x4, 0x1000404, 0x10404, 0x1010404, 0x10004, 0x1010000, 0x1000404, 0x1000004, 0x404, 0x10404, 0x1010400, 0x404, 0x1000400, 0x1000400, 0, 0x10004, 0x10400, 0, 0x1010004);
    $spfunction2 = array(-0x7fef7fe0, -0x7fff8000, 0x8000, 0x108020, 0x100000, 0x20, -0x7fefffe0, -0x7fff7fe0, -0x7fffffe0, -0x7fef7fe0, -0x7fef8000, -0x80000000, -0x7fff8000, 0x100000, 0x20, -0x7fefffe0, 0x108000, 0x100020, -0x7fff7fe0, 0, -0x80000000, 0x8000, 0x108020, -0x7ff00000, 0x100020, -0x7fffffe0, 0, 0x108000, 0x8020, -0x7fef8000, -0x7ff00000, 0x8020, 0, 0x108020, -0x7fefffe0, 0x100000, -0x7fff7fe0, -0x7ff00000, -0x7fef8000, 0x8000, -0x7ff00000, -0x7fff8000, 0x20, -0x7fef7fe0, 0x108020, 0x20, 0x8000, -0x80000000, 0x8020, -0x7fef8000, 0x100000, -0x7fffffe0, 0x100020, -0x7fff7fe0, -0x7fffffe0, 0x100020, 0x108000, 0, -0x7fff8000, 0x8020, -0x80000000, -0x7fefffe0, -0x7fef7fe0, 0x108000);
    $spfunction3 = array(0x208, 0x8020200, 0, 0x8020008, 0x8000200, 0, 0x20208, 0x8000200, 0x20008, 0x8000008, 0x8000008, 0x20000, 0x8020208, 0x20008, 0x8020000, 0x208, 0x8000000, 0x8, 0x8020200, 0x200, 0x20200, 0x8020000, 0x8020008, 0x20208, 0x8000208, 0x20200, 0x20000, 0x8000208, 0x8, 0x8020208, 0x200, 0x8000000, 0x8020200, 0x8000000, 0x20008, 0x208, 0x20000, 0x8020200, 0x8000200, 0, 0x200, 0x20008, 0x8020208, 0x8000200, 0x8000008, 0x200, 0, 0x8020008, 0x8000208, 0x20000, 0x8000000, 0x8020208, 0x8, 0x20208, 0x20200, 0x8000008, 0x8020000, 0x8000208, 0x208, 0x8020000, 0x20208, 0x8, 0x8020008, 0x20200);
    $spfunction4 = array(0x802001, 0x2081, 0x2081, 0x80, 0x802080, 0x800081, 0x800001, 0x2001, 0, 0x802000, 0x802000, 0x802081, 0x81, 0, 0x800080, 0x800001, 0x1, 0x2000, 0x800000, 0x802001, 0x80, 0x800000, 0x2001, 0x2080, 0x800081, 0x1, 0x2080, 0x800080, 0x2000, 0x802080, 0x802081, 0x81, 0x800080, 0x800001, 0x802000, 0x802081, 0x81, 0, 0, 0x802000, 0x2080, 0x800080, 0x800081, 0x1, 0x802001, 0x2081, 0x2081, 0x80, 0x802081, 0x81, 0x1, 0x2000, 0x800001, 0x2001, 0x802080, 0x800081, 0x2001, 0x2080, 0x800000, 0x802001, 0x80, 0x800000, 0x2000, 0x802080);
    $spfunction5 = array(0x100, 0x2080100, 0x2080000, 0x42000100, 0x80000, 0x100, 0x40000000, 0x2080000, 0x40080100, 0x80000, 0x2000100, 0x40080100, 0x42000100, 0x42080000, 0x80100, 0x40000000, 0x2000000, 0x40080000, 0x40080000, 0, 0x40000100, 0x42080100, 0x42080100, 0x2000100, 0x42080000, 0x40000100, 0, 0x42000000, 0x2080100, 0x2000000, 0x42000000, 0x80100, 0x80000, 0x42000100, 0x100, 0x2000000, 0x40000000, 0x2080000, 0x42000100, 0x40080100, 0x2000100, 0x40000000, 0x42080000, 0x2080100, 0x40080100, 0x100, 0x2000000, 0x42080000, 0x42080100, 0x80100, 0x42000000, 0x42080100, 0x2080000, 0, 0x40080000, 0x42000000, 0x80100, 0x2000100, 0x40000100, 0x80000, 0, 0x40080000, 0x2080100, 0x40000100);
    $spfunction6 = array(0x20000010, 0x20400000, 0x4000, 0x20404010, 0x20400000, 0x10, 0x20404010, 0x400000, 0x20004000, 0x404010, 0x400000, 0x20000010, 0x400010, 0x20004000, 0x20000000, 0x4010, 0, 0x400010, 0x20004010, 0x4000, 0x404000, 0x20004010, 0x10, 0x20400010, 0x20400010, 0, 0x404010, 0x20404000, 0x4010, 0x404000, 0x20404000, 0x20000000, 0x20004000, 0x10, 0x20400010, 0x404000, 0x20404010, 0x400000, 0x4010, 0x20000010, 0x400000, 0x20004000, 0x20000000, 0x4010, 0x20000010, 0x20404010, 0x404000, 0x20400000, 0x404010, 0x20404000, 0, 0x20400010, 0x10, 0x4000, 0x20400000, 0x404010, 0x4000, 0x400010, 0x20004010, 0, 0x20404000, 0x20000000, 0x400010, 0x20004010);
    $spfunction7 = array(0x200000, 0x4200002, 0x4000802, 0, 0x800, 0x4000802, 0x200802, 0x4200800, 0x4200802, 0x200000, 0, 0x4000002, 0x2, 0x4000000, 0x4200002, 0x802, 0x4000800, 0x200802, 0x200002, 0x4000800, 0x4000002, 0x4200000, 0x4200800, 0x200002, 0x4200000, 0x800, 0x802, 0x4200802, 0x200800, 0x2, 0x4000000, 0x200800, 0x4000000, 0x200800, 0x200000, 0x4000802, 0x4000802, 0x4200002, 0x4200002, 0x2, 0x200002, 0x4000000, 0x4000800, 0x200000, 0x4200800, 0x802, 0x200802, 0x4200800, 0x802, 0x4000002, 0x4200802, 0x4200000, 0x200800, 0, 0x2, 0x4200802, 0, 0x200802, 0x4200000, 0x800, 0x4000002, 0x4000800, 0x800, 0x200002);
    $spfunction8 = array(0x10001040, 0x1000, 0x40000, 0x10041040, 0x10000000, 0x10001040, 0x40, 0x10000000, 0x40040, 0x10040000, 0x10041040, 0x41000, 0x10041000, 0x41040, 0x1000, 0x40, 0x10040000, 0x10000040, 0x10001000, 0x1040, 0x41000, 0x40040, 0x10040040, 0x10041000, 0x1040, 0, 0, 0x10040040, 0x10000040, 0x10001000, 0x41040, 0x40000, 0x41040, 0x40000, 0x10041000, 0x1000, 0x40, 0x10040040, 0x1000, 0x41040, 0x10001000, 0x40, 0x10000040, 0x10040000, 0x10040040, 0x10000000, 0x40000, 0x10001040, 0, 0x10041040, 0x40040, 0x10000040, 0x10040000, 0x10001000, 0x10001040, 0, 0x10041040, 0x41000, 0x41000, 0x1040, 0x1040, 0x40040, 0x10000000, 0x10041000);
    $masks = array(4294967295, 2147483647, 1073741823, 536870911, 268435455, 134217727, 67108863, 33554431, 16777215, 8388607, 4194303, 2097151, 1048575, 524287, 262143, 131071, 65535, 32767, 16383, 8191, 4095, 2047, 1023, 511, 255, 127, 63, 31, 15, 7, 3, 1, 0);
    $keys = des_createKeys($key);
    $m = 0;
    $len = strlen($message);
    $chunk = 0;
    $iterations = count($keys) == 32 ? 3 : 9;
    if ($iterations == 3) {
        $looping = $encrypt ? array(0, 32, 2) : array(30, -2, -2);
    } else {
        $looping = $encrypt ? array(0, 32, 2, 62, 30, -2, 64, 96, 2) : array(94, 62, -2, 32, 64, 2, 30, -2, -2);
    }
    $message .= chr(0) . chr(0) . chr(0) . chr(0) . chr(0) . chr(0) . chr(0) . chr(0);
    //pad the message out with null bytes
    $result = "";
    $tempresult = "";
    if ($mode == 1) {
        $cbcleft = ord($iv[$m++]) << 24 | ord($iv[$m++]) << 16 | ord($iv[$m++]) << 8 | ord($iv[$m++]);
        $cbcright = ord($iv[$m++]) << 24 | ord($iv[$m++]) << 16 | ord($iv[$m++]) << 8 | ord($iv[$m++]);
        $m = 0;
    }
    while ($m < $len) {
        $left = ord($message[$m++]) << 24 | ord($message[$m++]) << 16 | ord($message[$m++]) << 8 | ord($message[$m++]);
        $right = ord($message[$m++]) << 24 | ord($message[$m++]) << 16 | ord($message[$m++]) << 8 | ord($message[$m++]);
        if ($mode == 1) {
            if ($encrypt) {
                $left ^= $cbcleft;
                $right ^= $cbcright;
            } else {
                $cbcleft2 = $cbcleft;
                $cbcright2 = $cbcright;
                $cbcleft = $left;
                $cbcright = $right;
            }
        }
        $temp = ($left >> 4 & $masks[4] ^ $right) & 0xf0f0f0f;
        $right ^= $temp;
        $left ^= $temp << 4;
        $temp = ($left >> 16 & $masks[16] ^ $right) & 0xffff;
        $right ^= $temp;
        $left ^= $temp << 16;
        $temp = ($right >> 2 & $masks[2] ^ $left) & 0x33333333;
        $left ^= $temp;
        $right ^= $temp << 2;
        $temp = ($right >> 8 & $masks[8] ^ $left) & 0xff00ff;
        $left ^= $temp;
        $right ^= $temp << 8;
        $temp = ($left >> 1 & $masks[1] ^ $right) & 0x55555555;
        $right ^= $temp;
        $left ^= $temp << 1;
        $left = $left << 1 | $left >> 31 & $masks[31];
        $right = $right << 1 | $right >> 31 & $masks[31];
        for ($j = 0; $j < $iterations; $j += 3) {
            $endloop = $looping[$j + 1];
            $loopinc = $looping[$j + 2];
            for ($i = $looping[$j]; $i != $endloop; $i += $loopinc) {
                $right1 = $right ^ $keys[$i];
                $right2 = ($right >> 4 & $masks[4] | $right << 28) ^ $keys[$i + 1];
                $temp = $left;
                $left = $right;
                $right = $temp ^ ($spfunction2[$right1 >> 24 & $masks[24] & 0x3f] | $spfunction4[$right1 >> 16 & $masks[16] & 0x3f] | $spfunction6[$right1 >> 8 & $masks[8] & 0x3f] | $spfunction8[$right1 & 0x3f] | $spfunction1[$right2 >> 24 & $masks[24] & 0x3f] | $spfunction3[$right2 >> 16 & $masks[16] & 0x3f] | $spfunction5[$right2 >> 8 & $masks[8] & 0x3f] | $spfunction7[$right2 & 0x3f]);
            }
            $temp = $left;
            $left = $right;
            $right = $temp;
        }
        $left = $left >> 1 & $masks[1] | $left << 31;
        $right = $right >> 1 & $masks[1] | $right << 31;
        $temp = ($left >> 1 & $masks[1] ^ $right) & 0x55555555;
        $right ^= $temp;
        $left ^= $temp << 1;
        $temp = ($right >> 8 & $masks[8] ^ $left) & 0xff00ff;
        $left ^= $temp;
        $right ^= $temp << 8;
        $temp = ($right >> 2 & $masks[2] ^ $left) & 0x33333333;
        $left ^= $temp;
        $right ^= $temp << 2;
        $temp = ($left >> 16 & $masks[16] ^ $right) & 0xffff;
        $right ^= $temp;
        $left ^= $temp << 16;
        $temp = ($left >> 4 & $masks[4] ^ $right) & 0xf0f0f0f;
        $right ^= $temp;
        $left ^= $temp << 4;
        if ($mode == 1) {
            if ($encrypt) {
                $cbcleft = $left;
                $cbcright = $right;
            } else {
                $left ^= $cbcleft2;
                $right ^= $cbcright2;
            }
        }
        $tempresult .= chr($left >> 24 & $masks[24]) . chr($left >> 16 & $masks[16] & 0xff) . chr($left >> 8 & $masks[8] & 0xff) . chr($left & 0xff) . chr($right >> 24 & $masks[24]) . chr($right >> 16 & $masks[16] & 0xff) . chr($right >> 8 & $masks[8] & 0xff) . chr($right & 0xff);
        $chunk += 8;
        if ($chunk == 512) {
            $result .= $tempresult;
            $tempresult = "";
            $chunk = 0;
        }
    }
    return $result . $tempresult;
}