I am having trouble porting some code originally written in Borland Delphi
to PHP. The Delphi code expects certain behavior on integer overflows that I
can only duplicate on some PHP systems. For example:
$BB = -2181087916;
$AA = (int)$BB;
$AA = intval($BB);
On some systems, $AA will be int(-2147483648), however, on most systems, $AA
will be int(2113879380), which is the same value truncated at 32 bits. It is
this latter behavior that I need to properly port the Delphi code.
Can someone suggest a way to do this that is consistent on all platforms?
For reference, I am attaching the Delphi code and my PHP port.
Thanks...
--Bruce
{quick (block) mixer routine}
procedure MixBlock(const Matrix : T128bit; var Block; Encrypt : Boolean);
const
CKeyBox : array [False..True, 0..3, 0..2] of LongInt =
(((0, 3, 1), (2, 1, 3), (1, 0, 2), (3, 2, 0)),
((3, 2, 0), (1, 0, 2), (2, 1, 3), (0, 3, 1)));
var
Blocks : array [0..1] of LongInt absolute Block;
Work : LongInt;
Right : LongInt;
Left : LongInt;
R : LongInt;
AA, BB : LongInt;
CC, DD : LongInt;
begin
Right := Blocks[0];
Left := Blocks[1];
for R := 0 to 3 do begin
{transform the right side}
AA := Right;
BB := Matrix[CKeyBox[Encrypt, R, 0]];
CC := Matrix[CKeyBox[Encrypt, R, 1]];
DD := Matrix[CKeyBox[Encrypt, R, 2]];
AA := AA + DD; DD := DD + AA; AA := AA xor (AA shr 7);
BB := BB + AA; AA := AA + BB; BB := BB xor (BB shl 13);
CC := CC + BB; BB := BB + CC; CC := CC xor (CC shr 17);
DD := DD + CC; CC := CC + DD; DD := DD xor (DD shl 9);
AA := AA + DD; DD := DD + AA; AA := AA xor (AA shr 3);
BB := BB + AA; BB := BB xor (BB shl 7);
CC := CC + BB;
CC := CC xor (DD shr 15);
DD := DD + CC;
DD := DD xor (DD shl 11);
Work := Left xor DD;
Left := Right;
Right := Work;
end;
Blocks[0] := Left;
Blocks[1] := Right;
end;
Here is my PHP port:
<?php
function zeroFill($a, $b)
{
$z = hexdec(80000000);
if ($z & $a)
{
$a >>= 1;
$a &= (~ $z);
$a |= 0x40000000;
$a >>= ($b-1);
}
else
{
$a >>= $b;
}
return $a;
}
function MixBlock($AKey, &$ACode, $Encrypt)
{
$CKeyBox = array(array(3, 2, 0), array(1, 0, 2), array(2, 1, 3), array(0,
3, 1));
$Right = $ACode[0];
$Left = $ACode[1];
for ($R=0; $R<=3; $R++)
{
$AA = $Right;
if ($Encrypt)
{
$BB = $AKey[$CKeyBox[$R][0]];
$CC = $AKey[$CKeyBox[$R][1]];
$DD = $AKey[$CKeyBox[$R][2]];
}
else
{
$BB = $AKey[$CKeyBox[3-$R][0]];
$CC = $AKey[$CKeyBox[3-$R][1]];
$DD = $AKey[$CKeyBox[3-$R][2]];
}
$AA = (int)$AA + (int)$DD;
$DD = (int)$DD + (int)$AA;
$AA = (int)$AA ^ zeroFill($AA, 7);
$BB = (int)$BB + (int)$AA;
$AA = (int)$AA + (int)$BB;
$BB = (int)$BB ^ ((int)$BB << 13);
$CC = (int)$CC + (int)$BB; $BB = (int)$BB + (int)$CC;
$CC = (int)$CC ^ zeroFill($CC, 17);
$DD = (int)$DD + (int)$CC; $CC = (int)$CC + (int)$DD;
$DD = (int)$DD ^ ((int)$DD << 9);
$AA = (int)$AA + (int)$DD; $DD = (int)$DD + (int)$AA;
$AA = (int)$AA ^ zeroFill($AA, 3);
$BB = (int)$BB + (int)$AA;
$BB = (int)$BB ^ (int)((int)$BB << 7);
$CC = (int)$CC + (int)$BB;
$CC = (int)$CC ^ zeroFill($DD, 15);
$DD = (int)$DD + (int)$CC;
$DD = (int)$DD ^ (int)((int)$DD << 11);
$Work = $Left ^ $DD;
$Left = $Right;
$Right = $Work;
}
$ACode[0] = $Left;
$ACode[1] = $Right;
}
?>