Beispiel #1
0
 /**
  * Creates the subkeys $_mkey (the masking key) and
  * $_rkey (the rotate key) which are 16 bytes each. These are
  * created from the original key. The original key is null
  * padded up to 16 bytes and expanded to 32 bytes. It is then
  * split in half to create $_mkey and $_rkey
  *
  * @return void
  */
 private function createSubKeys()
 {
     $x = $this->key();
     $z = "";
     // init to 16 bytes
     $skey = array();
     // the max length of the key is 16 bytes, however if it is
     // less, pad it with null to get ito to 16 bytes
     if ($this->keySize() < self::BYTES_KEY_MAX) {
         $x = str_pad($x, self::BYTES_KEY_MAX, "", STR_PAD_RIGHT);
     }
     /*
      * NOW FOR THE UGLY PART, THIS IS TAKEN FROM PAGE 3-4 OF
      * http://tools.ietf.org/html/rfc2144
      */
     // two loops, each loop does 16 bytes for a total of 32 bytes
     for ($i = 0; $i < 2; ++$i) {
         // z0z1z2z3 = x0x1x2x3 ^ S5[xD] ^ S6[xF] ^ S7[xC] ^ S8[xE] ^ S7[x8]
         $tmp = substr($x, 0x0, 4);
         $tmp = parent::dec2Str(parent::uInt32(parent::str2Dec($tmp) ^ self::$_s5[ord($x[0xd])] ^ self::$_s6[ord($x[0xf])] ^ self::$_s7[ord($x[0xc])] ^ self::$_s8[ord($x[0xe])] ^ self::$_s7[ord($x[0x8])]), 4);
         $z = substr_replace($z, $tmp, 0x0, 4);
         //print "Z0: ".parent::str2Hex($z)." (".strlen($z).")\n";
         // z4z5z6z7 = x8x9xAxB ^ S5[z0] ^ S6[z2] ^ S7[z1] ^ S8[z3] ^ S8[xA]
         $tmp = substr($x, 0x8, 4);
         $tmp = parent::dec2Str(parent::uInt32(parent::str2Dec($tmp) ^ self::$_s5[ord($z[0x0])] ^ self::$_s6[ord($z[0x2])] ^ self::$_s7[ord($z[0x1])] ^ self::$_s8[ord($z[0x3])] ^ self::$_s8[ord($x[0xa])]), 4);
         $z = substr_replace($z, $tmp, 0x4, 4);
         // z8z9zAzB = xCxDxExF ^ S5[z7] ^ S6[z6] ^ S7[z5] ^ S8[z4] ^ S5[x9]
         $tmp = substr($x, 0xc, 4);
         $tmp = parent::dec2Str(parent::uInt32(parent::str2Dec($tmp) ^ self::$_s5[ord($z[0x7])] ^ self::$_s6[ord($z[0x6])] ^ self::$_s7[ord($z[0x5])] ^ self::$_s8[ord($z[0x4])] ^ self::$_s5[ord($x[0x9])]), 4);
         $z = substr_replace($z, $tmp, 0x8, 4);
         // zCzDzEzF = x4x5x6x7 ^ S5[zA] ^ S6[z9] ^ S7[zB] ^ S8[z8] ^ S6[xB]
         $tmp = substr($x, 0x4, 4);
         $tmp = parent::dec2Str(parent::uInt32(parent::str2Dec($tmp) ^ self::$_s5[ord($z[0xa])] ^ self::$_s6[ord($z[0x9])] ^ self::$_s7[ord($z[0xb])] ^ self::$_s8[ord($z[0x8])] ^ self::$_s6[ord($x[0xb])]), 4);
         $z = substr_replace($z, $tmp, 0xc, 4);
         //print "Z: ".parent::str2Hex($z)." (".strlen($z).")\n";
         // K1  = S5[z8] ^ S6[z9] ^ S7[z7] ^ S8[z6] ^ S5[z2]
         $skey[] = parent::uInt32(self::$_s5[ord($z[0x8])] ^ self::$_s6[ord($z[0x9])] ^ self::$_s7[ord($z[0x7])] ^ self::$_s8[ord($z[0x6])] ^ self::$_s5[ord($z[0x2])]);
         // K2  = S5[zA] ^ S6[zB] ^ S7[z5] ^ S8[z4] ^ S6[z6]
         $skey[] = parent::uInt32(self::$_s5[ord($z[0xa])] ^ self::$_s6[ord($z[0xb])] ^ self::$_s7[ord($z[0x5])] ^ self::$_s8[ord($z[0x4])] ^ self::$_s6[ord($z[0x6])]);
         // K3  = S5[zC] ^ S6[zD] ^ S7[z3] ^ S8[z2] ^ S7[z9]
         $skey[] = parent::uInt32(self::$_s5[ord($z[0xc])] ^ self::$_s6[ord($z[0xd])] ^ self::$_s7[ord($z[0x3])] ^ self::$_s8[ord($z[0x2])] ^ self::$_s7[ord($z[0x9])]);
         // K4  = S5[zE] ^ S6[zF] ^ S7[z1] ^ S8[z0] ^ S8[zC]
         $skey[] = parent::uInt32(self::$_s5[ord($z[0xe])] ^ self::$_s6[ord($z[0xf])] ^ self::$_s7[ord($z[0x1])] ^ self::$_s8[ord($z[0x0])] ^ self::$_s8[ord($z[0xc])]);
         // x0x1x2x3 = z8z9zAzB ^ S5[z5] ^ S6[z7] ^ S7[z4] ^ S8[z6] ^ S7[z0]
         $tmp = substr($z, 0x8, 4);
         $tmp = parent::dec2Str(parent::uInt32(parent::str2Dec($tmp) ^ self::$_s5[ord($z[0x5])] ^ self::$_s6[ord($z[0x7])] ^ self::$_s7[ord($z[0x4])] ^ self::$_s8[ord($z[0x6])] ^ self::$_s7[ord($z[0x0])]), 4);
         $x = substr_replace($x, $tmp, 0x0, 4);
         // x4x5x6x7 = z0z1z2z3 ^ S5[x0] ^ S6[x2] ^ S7[x1] ^ S8[x3] ^ S8[z2]
         $tmp = substr($z, 0x0, 4);
         $tmp = parent::dec2Str(parent::uInt32(parent::str2Dec($tmp) ^ self::$_s5[ord($x[0x0])] ^ self::$_s6[ord($x[0x2])] ^ self::$_s7[ord($x[0x1])] ^ self::$_s8[ord($x[0x3])] ^ self::$_s8[ord($z[0x2])]), 4);
         $x = substr_replace($x, $tmp, 0x4, 4);
         // x8x9xAxB = z4z5z6z7 ^ S5[x7] ^ S6[x6] ^ S7[x5] ^ S8[x4] ^ S5[z1]
         $tmp = substr($z, 0x4, 4);
         $tmp = parent::dec2Str(parent::uInt32(parent::str2Dec($tmp) ^ self::$_s5[ord($x[0x7])] ^ self::$_s6[ord($x[0x6])] ^ self::$_s7[ord($x[0x5])] ^ self::$_s8[ord($x[0x4])] ^ self::$_s5[ord($z[0x1])]), 4);
         $x = substr_replace($x, $tmp, 0x8, 4);
         // xCxDxExF = zCzDzEzF ^ S5[xA] ^ S6[x9] ^ S7[xB] ^ S8[x8] ^ S6[z3]
         $tmp = substr($z, 0xc, 4);
         $tmp = parent::dec2Str(parent::uInt32(parent::str2Dec($tmp) ^ self::$_s5[ord($x[0xa])] ^ self::$_s6[ord($x[0x9])] ^ self::$_s7[ord($x[0xb])] ^ self::$_s8[ord($x[0x8])] ^ self::$_s6[ord($z[0x3])]), 4);
         $x = substr_replace($x, $tmp, 0xc, 4);
         // K5  = S5[x3] ^ S6[x2] ^ S7[xC] ^ S8[xD] ^ S5[x8]
         $skey[] = parent::uInt32(self::$_s5[ord($x[0x3])] ^ self::$_s6[ord($x[0x2])] ^ self::$_s7[ord($x[0xc])] ^ self::$_s8[ord($x[0xd])] ^ self::$_s5[ord($x[0x8])]);
         // K6  = S5[x1] ^ S6[x0] ^ S7[xE] ^ S8[xF] ^ S6[xD]
         $skey[] = parent::uInt32(self::$_s5[ord($x[0x1])] ^ self::$_s6[ord($x[0x0])] ^ self::$_s7[ord($x[0xe])] ^ self::$_s8[ord($x[0xf])] ^ self::$_s6[ord($x[0xd])]);
         // K7  = S5[x7] ^ S6[x6] ^ S7[x8] ^ S8[x9] ^ S7[x3]
         $skey[] = parent::uInt32(self::$_s5[ord($x[0x7])] ^ self::$_s6[ord($x[0x6])] ^ self::$_s7[ord($x[0x8])] ^ self::$_s8[ord($x[0x9])] ^ self::$_s7[ord($x[0x3])]);
         // K8  = S5[x5] ^ S6[x4] ^ S7[xA] ^ S8[xB] ^ S8[x7]
         $skey[] = parent::uInt32(self::$_s5[ord($x[0x5])] ^ self::$_s6[ord($x[0x4])] ^ self::$_s7[ord($x[0xa])] ^ self::$_s8[ord($x[0xb])] ^ self::$_s8[ord($x[0x7])]);
         // z0z1z2z3 = x0x1x2x3 ^ S5[xD] ^ S6[xF] ^ S7[xC] ^ S8[xE] ^ S7[x8]
         $tmp = substr($x, 0x0, 4);
         $tmp = parent::dec2Str(parent::uInt32(parent::str2Dec($tmp) ^ self::$_s5[ord($x[0xd])] ^ self::$_s6[ord($x[0xf])] ^ self::$_s7[ord($x[0xc])] ^ self::$_s8[ord($x[0xe])] ^ self::$_s7[ord($x[0x8])]), 4);
         $z = substr_replace($z, $tmp, 0x0, 4);
         // z4z5z6z7 = x8x9xAxB ^ S5[z0] ^ S6[z2] ^ S7[z1] ^ S8[z3] ^ S8[xA]
         $tmp = substr($x, 0x8, 4);
         $tmp = parent::dec2Str(parent::uInt32(parent::str2Dec($tmp) ^ self::$_s5[ord($z[0x0])] ^ self::$_s6[ord($z[0x2])] ^ self::$_s7[ord($z[0x1])] ^ self::$_s8[ord($z[0x3])] ^ self::$_s8[ord($x[0xa])]), 4);
         $z = substr_replace($z, $tmp, 0x4, 4);
         // z8z9zAzB = xCxDxExF ^ S5[z7] ^ S6[z6] ^ S7[z5] ^ S8[z4] ^ S5[x9]
         $tmp = substr($x, 0xc, 4);
         $tmp = parent::dec2Str(parent::uInt32(parent::str2Dec($tmp) ^ self::$_s5[ord($z[0x7])] ^ self::$_s6[ord($z[0x6])] ^ self::$_s7[ord($z[0x5])] ^ self::$_s8[ord($z[0x4])] ^ self::$_s5[ord($x[0x9])]), 4);
         $z = substr_replace($z, $tmp, 0x8, 4);
         // zCzDzEzF = x4x5x6x7 ^ S5[zA] ^ S6[z9] ^ S7[zB] ^ S8[z8] ^ S6[xB]
         $tmp = substr($x, 0x4, 4);
         $tmp = parent::dec2Str(parent::uInt32(parent::str2Dec($tmp) ^ self::$_s5[ord($z[0xa])] ^ self::$_s6[ord($z[0x9])] ^ self::$_s7[ord($z[0xb])] ^ self::$_s8[ord($z[0x8])] ^ self::$_s6[ord($x[0xb])]), 4);
         $z = substr_replace($z, $tmp, 0xc, 4);
         // K9  = S5[z3] ^ S6[z2] ^ S7[zC] ^ S8[zD] ^ S5[z9]
         $skey[] = parent::uInt32(self::$_s5[ord($z[0x3])] ^ self::$_s6[ord($z[0x2])] ^ self::$_s7[ord($z[0xc])] ^ self::$_s8[ord($z[0xd])] ^ self::$_s5[ord($z[0x9])]);
         // K10 = S5[z1] ^ S6[z0] ^ S7[zE] ^ S8[zF] ^ S6[zC]
         $skey[] = parent::uInt32(self::$_s5[ord($z[0x1])] ^ self::$_s6[ord($z[0x0])] ^ self::$_s7[ord($z[0xe])] ^ self::$_s8[ord($z[0xf])] ^ self::$_s6[ord($z[0xc])]);
         // K11 = S5[z7] ^ S6[z6] ^ S7[z8] ^ S8[z9] ^ S7[z2]
         $skey[] = parent::uInt32(self::$_s5[ord($z[0x7])] ^ self::$_s6[ord($z[0x6])] ^ self::$_s7[ord($z[0x8])] ^ self::$_s8[ord($z[0x9])] ^ self::$_s7[ord($z[0x2])]);
         // K12 = S5[z5] ^ S6[z4] ^ S7[zA] ^ S8[zB] ^ S8[z6]
         $skey[] = parent::uInt32(self::$_s5[ord($z[0x5])] ^ self::$_s6[ord($z[0x4])] ^ self::$_s7[ord($z[0xa])] ^ self::$_s8[ord($z[0xb])] ^ self::$_s8[ord($z[0x6])]);
         // x0x1x2x3 = z8z9zAzB ^ S5[z5] ^ S6[z7] ^ S7[z4] ^ S8[z6] ^ S7[z0]
         $tmp = substr($z, 0x8, 4);
         $tmp = parent::dec2Str(parent::uInt32(parent::str2Dec($tmp) ^ self::$_s5[ord($z[0x5])] ^ self::$_s6[ord($z[0x7])] ^ self::$_s7[ord($z[0x4])] ^ self::$_s8[ord($z[0x6])] ^ self::$_s7[ord($z[0x0])]), 4);
         $x = substr_replace($x, $tmp, 0x0, 4);
         // x4x5x6x7 = z0z1z2z3 ^ S5[x0] ^ S6[x2] ^ S7[x1] ^ S8[x3] ^ S8[z2]
         $tmp = substr($z, 0x0, 4);
         $tmp = parent::dec2Str(parent::uInt32(parent::str2Dec($tmp) ^ self::$_s5[ord($x[0x0])] ^ self::$_s6[ord($x[0x2])] ^ self::$_s7[ord($x[0x1])] ^ self::$_s8[ord($x[0x3])] ^ self::$_s8[ord($z[0x2])]), 4);
         $x = substr_replace($x, $tmp, 0x4, 4);
         // x8x9xAxB = z4z5z6z7 ^ S5[x7] ^ S6[x6] ^ S7[x5] ^ S8[x4] ^ S5[z1]
         $tmp = substr($z, 0x4, 4);
         $tmp = parent::dec2Str(parent::uInt32(parent::str2Dec($tmp) ^ self::$_s5[ord($x[0x7])] ^ self::$_s6[ord($x[0x6])] ^ self::$_s7[ord($x[0x5])] ^ self::$_s8[ord($x[0x4])] ^ self::$_s5[ord($z[0x1])]), 4);
         $x = substr_replace($x, $tmp, 0x8, 4);
         // xCxDxExF = zCzDzEzF ^ S5[xA] ^ S6[x9] ^ S7[xB] ^ S8[x8] ^ S6[z3]
         $tmp = substr($z, 0xc, 4);
         $tmp = parent::dec2Str(parent::uInt32(parent::str2Dec($tmp) ^ self::$_s5[ord($x[0xa])] ^ self::$_s6[ord($x[0x9])] ^ self::$_s7[ord($x[0xb])] ^ self::$_s8[ord($x[0x8])] ^ self::$_s6[ord($z[0x3])]), 4);
         $x = substr_replace($x, $tmp, 0xc, 4);
         // K13 = S5[x8] ^ S6[x9] ^ S7[x7] ^ S8[x6] ^ S5[x3]
         $skey[] = parent::uInt32(self::$_s5[ord($x[0x8])] ^ self::$_s6[ord($x[0x9])] ^ self::$_s7[ord($x[0x7])] ^ self::$_s8[ord($x[0x6])] ^ self::$_s5[ord($x[0x3])]);
         // K14 = S5[xA] ^ S6[xB] ^ S7[x5] ^ S8[x4] ^ S6[x7]
         $skey[] = parent::uInt32(self::$_s5[ord($x[0xa])] ^ self::$_s6[ord($x[0xb])] ^ self::$_s7[ord($x[0x5])] ^ self::$_s8[ord($x[0x4])] ^ self::$_s6[ord($x[0x7])]);
         // K15 = S5[xC] ^ S6[xD] ^ S7[x3] ^ S8[x2] ^ S7[x8]
         $skey[] = parent::uInt32(self::$_s5[ord($x[0xc])] ^ self::$_s6[ord($x[0xd])] ^ self::$_s7[ord($x[0x3])] ^ self::$_s8[ord($x[0x2])] ^ self::$_s7[ord($x[0x8])]);
         // K16 = S5[xE] ^ S6[xF] ^ S7[x1] ^ S8[x0] ^ S8[xD]
         $skey[] = parent::uInt32(self::$_s5[ord($x[0xe])] ^ self::$_s6[ord($x[0xf])] ^ self::$_s7[ord($x[0x1])] ^ self::$_s8[ord($x[0x0])] ^ self::$_s8[ord($x[0xd])]);
     }
     // create the 16 byte masking and rotate subkeys
     $this->_mkey = array_slice($skey, 0, 16);
     $this->_rkey = array_slice($skey, 16, 16);
     // $_rkey only uses the least significant 5 bits
     $this->_rkey = array_map(function ($v) {
         return $v &= 31;
     }, $this->_rkey);
     // there is 4kb in the s5 - s8 sboxes, which are not needed after we
     // create the subkeys, so free up the memory. unset() doesn't work here
     for ($i = 5; $i <= 8; ++$i) {
         self::${"_s{$i}"} = null;
     }
 }
Beispiel #2
0
 /**
  * The same alorigthm is used for both Encryption, and Decryption
  *
  * @param string $data A 96 bit block of data
  * @return boolean Returns true
  */
 private function threeway(&$data)
 {
     // first split $data into three 32 bit parts
     $data = str_split($data, 4);
     $data = array_map("parent::str2Dec", $data);
     // split the key into three 32 bit parts
     $key = str_split($this->key(), 4);
     $key = array_map("parent::str2Dec", $key);
     // determine which round constant to use
     if ($this->operation() == parent::ENCRYPT) {
         $rcon = self::$_rcon_enc;
     } else {
         $rcon = self::$_rcon_dec;
     }
     if ($this->operation() == parent::DECRYPT) {
         $this->theta($key);
         $this->invertBits($key);
         $this->invertBits($data);
     }
     // 3Way uses 11 rounds
     for ($i = 0; $i < self::ROUNDS; ++$i) {
         $data[0] = parent::uInt32($data[0] ^ $key[0] ^ $rcon[$i] << 16);
         $data[1] = parent::uInt32($data[1] ^ $key[1]);
         $data[2] = parent::uInt32($data[2] ^ $key[2] ^ $rcon[$i]);
         $this->rho($data);
     }
     $data[0] = parent::uInt32($data[0] ^ $key[0] ^ $rcon[self::ROUNDS] << 16);
     $data[1] = parent::uInt32($data[1] ^ $key[1]);
     $data[2] = parent::uInt32($data[2] ^ $key[2] ^ $rcon[self::ROUNDS]);
     $this->theta($data);
     if ($this->operation() == parent::DECRYPT) {
         $this->invertBits($data);
     }
     // assemble the three 32 bit parts back to a 96 bit string
     $data = parent::dec2Str($data[0], 4) . parent::dec2Str($data[1], 4) . parent::dec2Str($data[2], 4);
     return true;
 }
Beispiel #3
0
 /**
  * CAST-256 F3 function
  *
  * @param $d integer The the data input
  * @param $m integer The 32 bit masking key
  * @param $r integer The round number
  * @return integer The value after the F3 calculation
  */
 private function f3($d, $m, $r)
 {
     $n = parent::uInt32($m - $d);
     $n = parent::uInt32(parent::rotBitsLeft32($n, $r));
     $n = parent::dec2Str($n, 4);
     return parent::uInt32((self::$_s1[ord($n[0])] + self::$_s2[ord($n[1])] ^ self::$_s3[ord($n[2])]) - self::$_s4[ord($n[3])]);
 }
Beispiel #4
0
 /**
  * The same alorigthm is used for both Encryption, and Decryption
  *
  * @param string $data A 64 bit block of data
  * @return boolean Returns true
  */
 private function blowfish(&$data)
 {
     // divide the data into into two 32 bit halves
     $xl = parent::str2Dec(substr($data, 0, 4));
     $xr = parent::str2Dec(substr($data, 4, 4));
     for ($i = 0; $i < 16; ++$i) {
         if ($this->operation() == parent::ENCRYPT) {
             $xl ^= self::$_p[$i];
         } else {
             $xl ^= self::$_p[17 - $i];
         }
         // perform F() on the left half, and XOR with the right half
         $xr = $this->F($xl) ^ $xr;
         // swap $xl and $xr
         $tmp = $xr;
         $xr = $xl;
         $xl = $tmp;
     }
     // swap $xl and $xr after the 16th round to undo the last swap
     $tmp = $xl;
     $xl = $xr;
     $xr = $tmp;
     // XOR the final two elements of $_p
     if ($this->operation() == parent::ENCRYPT) {
         $xr ^= self::$_p[16];
         $xl = $xl ^ self::$_p[17];
     } else {
         $xr ^= self::$_p[1];
         $xl ^= self::$_p[0];
     }
     // recombine the two halves, force them to be 4 bytes each
     $data = parent::dec2Str($xl, 4) . parent::dec2Str($xr, 4);
     return true;
 }