6 && $i % $Nk == 4)
{
$tmp = SubWord($tmp);
}
$w[$i] = dechex(hexdec($w[$i-$Nk]) ^ hexdec($tmp));
//echo " w[i-Nk]: " . $w[$i-$Nk] . " w[i]: $w[$i]
";
}
return $w;
}
function SubWord($val)
{
global $sbox;
$res = "";
for ($i = 0; $i < strlen($val); $i+=2)
{
$res .= $sbox[hexdec($val[$i])][hexdec($val[$i+1])];
}
//echo " SubWord: $res";
return $res;
}
function RotWord($val)
{
$res = substr($val, 2, 6);
$res .= substr($val, 0, 2);
//echo " RotWord: $res";
return $res;
}
function AddRoundKey($state, $w, $j)
{
global $Nb;
$res = array();
for ($i = 0; $i < count($state); $i++)
{
for ($k = 0; $k < count($state[$i]); $k++)
{
$cmp[$k] = dechex(hexdec(substr($w[$j*$Nb+$k], $i*2, 2)) ^ hexdec($state[$i][$k]));
if (strlen($cmp[$k]) < 2) $cmp[$k] = "0" . $cmp[$k];
}
$res[] = $cmp;
}
echo "AddRoundKey: " . print_r($res);
return $res;
}
function partition($var, $size)
{
$res = array();
for ($i = 0; $i < strlen($var); $i += $size)
{
$res[$i/$size] = substr($var, $i, $size);
}
return $res;
}
function SubBytes($state)
{
$res = array();
foreach ($state as $s)
{
$res[] = partition(SubWord(implode("", $s)), 2);
}
echo "SubBytes: " . print_r($res);
return $res;
}
function ShiftRows($state)
{
for ($i = 0; $i < count($state); $i++)
{
for ($j = 0; $j < $i; $j++)
{
$tmp = array_shift($state[$i]);
$state[$i][3] = $tmp;
}
}
echo "ShiftRows: " . print_r($state);
return $state;
}
/* Taken/Modified from wikipedia.org */
function gmix_column($r) {
/* The array 'a' is simply a copy of the input array 'r'
* The array 'b' is each element of the array 'a' multiplied by 2
* in Rijndael's Galois field
* a[n] ^ b[n] is element n multiplied by 3 in Rijndael's Galois field */
for($c=0;$c<4;$c++) {
$a[$c] = $r[$c];
$h = $r[$c] & hexdec("80"); /* hi bit */
$b[$c] = $r[$c] << 1;
if($h == hexdec("80"))
$b[$c] ^= hexdec("1b"); /* Rijndael's Galois field */
}
$r[0] = $b[0] ^ $a[3] ^ $a[2] ^ $b[1] ^ $a[1]; /* 2 * a0 + a3 + a2 + 3 * a1 */
$r[1] = $b[1] ^ $a[0] ^ $a[3] ^ $b[2] ^ $a[2]; /* 2 * a1 + a0 + a3 + 3 * a2 */
$r[2] = $b[2] ^ $a[1] ^ $a[0] ^ $b[3] ^ $a[3]; /* 2 * a2 + a1 + a0 + 3 * a3 */
$r[3] = $b[3] ^ $a[2] ^ $a[1] ^ $b[0] ^ $a[0]; /* 2 * a3 + a2 + a1 + 3 * a0 */
return $r;
}
function MixColumns($state)
{
$mcmat = array(
array( "02", "03", "01", "01"),
array( "01", "02", "03", "01"),
array( "01", "01", "02", "03"),
array( "03", "01", "01", "02"));
$res = array();
for ($i = 0; $i < count($state); $i++)
{
$r[0] = hexdec($state[0][$i]);
$r[1] = hexdec($state[1][$i]);
$r[2] = hexdec($state[2][$i]);
$r[3] = hexdec($state[3][$i]);
$r = gmix_column($r);
$res[0][$i] = dechex($r[0]);
$res[1][$i] = dechex($r[1]);
$res[2][$i] = dechex($r[2]);
$res[3][$i] = dechex($r[3]);
}
//For some reason sometimes we get prepended 1's, clean those out.
for ($i = 0; $i < count($res); $i++)
{
for ($j = 0; $j < count($res[$j]); $j++)
{
if (strlen($res[$i][$j]) == 3)
{
$res[$i][$j] = substr($res[$i][$j], 1, 2);
}
}
}
echo "MixColumns: " . print_r($res);
return $res;
}
function AES($in, $key)
{
global $Nr, $Nb;
//Make the State into the array of strings..
$state = array();
for ($i = 0; $i < strlen($in)/8; $i++)
{
$state[$i][0] = substr($in, 0+$i*2, 2);
$state[$i][1] = substr($in, 8+$i*2, 2);
$state[$i][2] = substr($in, 16+$i*2, 2);
$state[$i][3] = substr($in, 24+$i*2, 2);
}
echo "
Current State " . print_r($state) . "m"; $w = KeyExpansion($key); $state = AddRoundKey($state, $w, 0); for ($i = 0; $i < $Nr-1; $i++) { $state = SubBytes($state); $state = ShiftRows($state); $state = MixColumns($state); $state = AddRoundKey($state, $w, $i+1); } $state = SubBytes($state); $state = ShiftRows($state); $state = AddRoundKey($state, $w, $Nr); return $state; } ?> 2b7e151628aed2a6abf7158809cf4f3c