I'm having problems with an algorithm I'm doing to decrypt data. The is problems every time that I try to run an overflow error happened in line:
uint sum=(numberOfRounds*Delta);
The file I'm reading just has the array in hexadecimal: 3D 00 01 12 02 CC F8 FD 33 3B 44 01 00 92 00 03 03 00 CB 44 6D 38 01 12 00 24 D6 23 02 04 E9 65 F7 44 00 00 00 00 00 5B D2 D6 ED 3A 81 03 DD 00 00 00 00 00 00 AC 87 B0 51 0F 27 01 00 D9
The code is bellow:
private const int EncryptedDataBlockSizeInBytes = 4;
private static readonly uint[] Key = new uint[] { 0xA50DADD1, 0xFEAD1276, 0x03948029, 0x49493095 };
private const uint Delta = 0x9E3779B9;
public static int headersize = 13;
public static int crcsize = 1;
public static byte[] Decrypt(byte[] data, int offset, int count, uint[] key)
{
if (count % EncryptedDataBlockSizeInBytes != 0)
{
throw new ArgumentException("The count of the data to be decrypted must be divisible by 4.");
}
// Convert the byte array into a uint array
uint[] dataInUints = ConvertBytesToUints(data, offset, count);
uint numberOfRounds = (uint)(6 + (52 / dataInUints.Length));
uint n = (uint)(dataInUints.Length - 1);
uint sum = numberOfRounds * Delta;
uint y = dataInUints[0];
do
{
uint e = (sum >> 2) & 3;
uint z;
for (uint i = n; i > 0; i--)
{
z = dataInUints[i - 1];
dataInUints[i] -= XxteaMx(z, y, e, sum, key, i);
y = dataInUints[i];
}
z = dataInUints[n];
dataInUints[0] -= XxteaMx(z, y, e, sum, key, 0);
y = dataInUints[0];
sum -= Delta;
}
while (sum != 0);
// Convert the decrypted data back into a byte array and return the result
return ConvertUintsToBytes(dataInUints);
}
private static uint XxteaMx(uint z, uint y, uint e, uint sum, uint[] key, uint i)
{
return (((((z) >> 5) ^ ((y) << 2)) + (((y) >> 3) ^ ((z) << 4))) ^ (((sum) ^ y) + ((key)[((i) & 3U) ^ (e)] ^ (z))));
}
private static uint[] ConvertBytesToUints(byte[] data, int offset, int count)
{
uint[] result = new uint[count / 4];
// Run through the data and create the uints from
// the array of bytes
for (int i = offset, j = 0; i < offset + count; i += 4, j++)
{
result[j] = ((uint)data[i + 3] << 24) | ((uint)data[i + 2] << 16) | ((uint)data[i + 1] << 8) | (data[i]);
}
// Return the array of uints
return result;
}
private static byte[] ConvertUintsToBytes(uint[] data)
{
byte[] result = new byte[data.Length * 4];
// Run through the data and create the bytes from
// the array of uints
for (int i = 0, j = 0; i < data.Length; i++, j += 4)
{
result[j] = (byte)(data[i]);
result[j + 1] = (byte)(data[i] >> 8);
result[j + 2] = (byte)(data[i] >> 16);
result[j + 3] = (byte)(data[i] >> 24);
}
// Return the array of bytes
return result;
}
void Button1Click(object sender, EventArgs e)
{
FileStream file = new FileStream("arquivobin.dat", FileMode.Open);
BinaryReader br = new BinaryReader(file);
byte[] data = new byte[br.BaseStream.Length];
data = br.ReadBytes((int)br.BaseStream.Length);
string s = "";
richTextBox1.Text = "My binary file data:" + "\n";
for(int i =0; i< data.Length; i++){
s = data[i].ToString();
richTextBox1.Text += s + " ";
}
richTextBox1.Text += "\n\n\n" ;
richTextBox1.Text += "My HEADER:" + "\n";
for (int i = 0; i < headersize; i++)
{
s = data[i].ToString();
richTextBox1.Text += s + " ";
}
richTextBox1.Text += "\n\n\n";
richTextBox1.Text += "My payload:" + "\n";
for(int i = headersize; i < data.Length - crcsize; i++){
s = data[i].ToString();
richTextBox1.Text += s + " ";
}
richTextBox1.Text += "\n\n\n";
richTextBox1.Text += "My CheckSum:" + "\n";
s = printhex(data[data.Length - crcsize]);
richTextBox1.Text += s;
int offset = headersize;
int count = data.Length - crcsize - headersize;
byte[] result = Decrypt(data, headersize, count, Key);
richTextBox1.Text += "\n\n\n";
richTextBox1.Text += "My Decrypted:" + "\n";
for (int i = headersize; i < data.Length - crcsize; i++)
{
s = result[i].ToString();
richTextBox1.Text += s + " ";
}
file.Close();
}
}
If I'm reading your code right... that line will always overflow insofar as
numberOfRoundsis greater than 1.uintin C# is just an alias foruint32as such withDeltabeing so large (the most significant bit is 1) the calculation will always overflow when you multiplyDeltaagainst anything. However If I'm reading your code correctly that calculation is supposed to be an addition instead of the multiplication it currently is, if that is not correct I would suggest changingsumto beinguint64.