private void DecryptBlock(
uint[,] KW)
{
int r;
uint r0, r1, r2, r3;
C0 ^= KW[ROUNDS, 0];
C1 ^= KW[ROUNDS, 1];
C2 ^= KW[ROUNDS, 2];
C3 ^= KW[ROUNDS, 3];
for (r = ROUNDS - 1; r > 1;)
{
r0 = Tinv0[C0 & 255] ^ Shift(Tinv0[(C3 >> 8) & 255], 24) ^ Shift(Tinv0[(C2 >> 16) & 255], 16) ^
Shift(Tinv0[(C1 >> 24) & 255], 8) ^ KW[r, 0];
r1 = Tinv0[C1 & 255] ^ Shift(Tinv0[(C0 >> 8) & 255], 24) ^ Shift(Tinv0[(C3 >> 16) & 255], 16) ^
Shift(Tinv0[(C2 >> 24) & 255], 8) ^ KW[r, 1];
r2 = Tinv0[C2 & 255] ^ Shift(Tinv0[(C1 >> 8) & 255], 24) ^ Shift(Tinv0[(C0 >> 16) & 255], 16) ^
Shift(Tinv0[(C3 >> 24) & 255], 8) ^ KW[r, 2];
r3 = Tinv0[C3 & 255] ^ Shift(Tinv0[(C2 >> 8) & 255], 24) ^ Shift(Tinv0[(C1 >> 16) & 255], 16) ^
Shift(Tinv0[(C0 >> 24) & 255], 8) ^ KW[r--, 3];
C0 = Tinv0[r0 & 255] ^ Shift(Tinv0[(r3 >> 8) & 255], 24) ^ Shift(Tinv0[(r2 >> 16) & 255], 16) ^
Shift(Tinv0[(r1 >> 24) & 255], 8) ^ KW[r, 0];
C1 = Tinv0[r1 & 255] ^ Shift(Tinv0[(r0 >> 8) & 255], 24) ^ Shift(Tinv0[(r3 >> 16) & 255], 16) ^
Shift(Tinv0[(r2 >> 24) & 255], 8) ^ KW[r, 1];
C2 = Tinv0[r2 & 255] ^ Shift(Tinv0[(r1 >> 8) & 255], 24) ^ Shift(Tinv0[(r0 >> 16) & 255], 16) ^
Shift(Tinv0[(r3 >> 24) & 255], 8) ^ KW[r, 2];
C3 = Tinv0[r3 & 255] ^ Shift(Tinv0[(r2 >> 8) & 255], 24) ^ Shift(Tinv0[(r1 >> 16) & 255], 16) ^
Shift(Tinv0[(r0 >> 24) & 255], 8) ^ KW[r--, 3];
}
r0 = Tinv0[C0 & 255] ^ Shift(Tinv0[(C3 >> 8) & 255], 24) ^ Shift(Tinv0[(C2 >> 16) & 255], 16) ^
Shift(Tinv0[(C1 >> 24) & 255], 8) ^ KW[r, 0];
r1 = Tinv0[C1 & 255] ^ Shift(Tinv0[(C0 >> 8) & 255], 24) ^ Shift(Tinv0[(C3 >> 16) & 255], 16) ^
Shift(Tinv0[(C2 >> 24) & 255], 8) ^ KW[r, 1];
r2 = Tinv0[C2 & 255] ^ Shift(Tinv0[(C1 >> 8) & 255], 24) ^ Shift(Tinv0[(C0 >> 16) & 255], 16) ^
Shift(Tinv0[(C3 >> 24) & 255], 8) ^ KW[r, 2];
r3 = Tinv0[C3 & 255] ^ Shift(Tinv0[(C2 >> 8) & 255], 24) ^ Shift(Tinv0[(C1 >> 16) & 255], 16) ^
Shift(Tinv0[(C0 >> 24) & 255], 8) ^ KW[r, 3];
// the final round's table is a simple function of Si so we don't use a whole other four tables for it
C0 = Si[r0 & 255] ^ (((uint)Si[(r3 >> 8) & 255]) << 8) ^ (((uint)Si[(r2 >> 16) & 255]) << 16) ^
(((uint)Si[(r1 >> 24) & 255]) << 24) ^ KW[0, 0];
C1 = Si[r1 & 255] ^ (((uint)Si[(r0 >> 8) & 255]) << 8) ^ (((uint)Si[(r3 >> 16) & 255]) << 16) ^
(((uint)Si[(r2 >> 24) & 255]) << 24) ^ KW[0, 1];
C2 = Si[r2 & 255] ^ (((uint)Si[(r1 >> 8) & 255]) << 8) ^ (((uint)Si[(r0 >> 16) & 255]) << 16) ^
(((uint)Si[(r3 >> 24) & 255]) << 24) ^ KW[0, 2];
C3 = Si[r3 & 255] ^ (((uint)Si[(r2 >> 8) & 255]) << 8) ^ (((uint)Si[(r1 >> 16) & 255]) << 16) ^
(((uint)Si[(r0 >> 24) & 255]) << 24) ^ KW[0, 3];
}