protected override void ECB (byte[] input, byte[] output)
{
// unrolled loop, eliminated mul
R0 = (UInt16) (input [0] | (input [1] << 8));
R1 = (UInt16) (input [2] | (input [3] << 8));
R2 = (UInt16) (input [4] | (input [5] << 8));
R3 = (UInt16) (input [6] | (input [7] << 8));
if (encrypt) {
j = 0;
// inline, but looped, Mix(); Mix(); Mix(); Mix(); Mix();
while (j <= 16) {
R0 += (UInt16) (K[j++] + (R3 & R2) + ((~R3) & R1));
R0 = (UInt16) ((R0 << 1) | (R0 >> 15));
R1 += (UInt16) (K[j++] + (R0 & R3) + ((~R0) & R2));
R1 = (UInt16) ((R1 << 2) | (R1 >> 14));
R2 += (UInt16) (K[j++] + (R1 & R0) + ((~R1) & R3));
R2 = (UInt16) ((R2 << 3) | (R2 >> 13));
R3 += (UInt16) (K[j++] + (R2 & R1) + ((~R2) & R0));
R3 = (UInt16) ((R3 << 5) | (R3 >> 11));
}
// inline Mash(); j == 20
R0 += K [R3 & 63];
R1 += K [R0 & 63];
R2 += K [R1 & 63];
R3 += K [R2 & 63];
// inline, but looped, Mix(); Mix(); Mix(); Mix(); Mix(); Mix();
while (j <= 40) {
R0 += (UInt16) (K[j++] + (R3 & R2) + ((~R3) & R1));
R0 = (UInt16) ((R0 << 1) | (R0 >> 15));
R1 += (UInt16) (K[j++] + (R0 & R3) + ((~R0) & R2));
R1 = (UInt16) ((R1 << 2) | (R1 >> 14));
R2 += (UInt16) (K[j++] + (R1 & R0) + ((~R1) & R3));
R2 = (UInt16) ((R2 << 3) | (R2 >> 13));
R3 += (UInt16) (K[j++] + (R2 & R1) + ((~R2) & R0));
R3 = (UInt16) ((R3 << 5) | (R3 >> 11));
}
// inline Mash(); j == 44
R0 += K [R3 & 63];
R1 += K [R0 & 63];
R2 += K [R1 & 63];
R3 += K [R2 & 63];
// inline, but looped, Mix(); Mix(); Mix(); Mix(); Mix();
while (j < 64) {
R0 += (UInt16) (K[j++] + (R3 & R2) + ((~R3) & R1));
R0 = (UInt16) ((R0 << 1) | (R0 >> 15));
R1 += (UInt16) (K[j++] + (R0 & R3) + ((~R0) & R2));
R1 = (UInt16) ((R1 << 2) | (R1 >> 14));
R2 += (UInt16) (K[j++] + (R1 & R0) + ((~R1) & R3));
R2 = (UInt16) ((R2 << 3) | (R2 >> 13));
R3 += (UInt16) (K[j++] + (R2 & R1) + ((~R2) & R0));
R3 = (UInt16) ((R3 << 5) | (R3 >> 11));
}
}
else {
j = 63;
// inline, but looped, RMix(); RMix(); RMix(); RMix(); RMix();
while (j >= 44) {
R3 = (UInt16) ((R3 >> 5) | (R3 << 11));
R3 -= (UInt16) (K[j--] + (R2 & R1) + ((~R2) & R0));
R2 = (UInt16) ((R2 >> 3) | (R2 << 13));
R2 -= (UInt16) (K[j--] + (R1 & R0) + ((~R1) & R3));
R1 = (UInt16) ((R1 >> 2) | (R1 << 14));
R1 -= (UInt16) (K[j--] + (R0 & R3) + ((~R0) & R2));
R0 = (UInt16) ((R0 >> 1) | (R0 << 15));
R0 -= (UInt16) (K[j--] + (R3 & R2) + ((~R3) & R1));
}
// inline RMash();
R3 -= K [R2 & 63];
R2 -= K [R1 & 63];
R1 -= K [R0 & 63];
R0 -= K [R3 & 63];
// inline, but looped, RMix(); RMix(); RMix(); RMix(); RMix(); RMix();
while (j >= 20) {
R3 = (UInt16) ((R3 >> 5) | (R3 << 11));
R3 -= (UInt16) (K[j--] + (R2 & R1) + ((~R2) & R0));
R2 = (UInt16) ((R2 >> 3) | (R2 << 13));
R2 -= (UInt16) (K[j--] + (R1 & R0) + ((~R1) & R3));
R1 = (UInt16) ((R1 >> 2) | (R1 << 14));
R1 -= (UInt16) (K[j--] + (R0 & R3) + ((~R0) & R2));
R0 = (UInt16) ((R0 >> 1) | (R0 << 15));
R0 -= (UInt16) (K[j--] + (R3 & R2) + ((~R3) & R1));
}
// inline RMash();
R3 -= K [R2 & 63];
R2 -= K [R1 & 63];
R1 -= K [R0 & 63];
R0 -= K [R3 & 63];
// inline, but looped, RMix(); RMix(); RMix(); RMix(); RMix();
while (j >= 0) {
R3 = (UInt16) ((R3 >> 5) | (R3 << 11));
R3 -= (UInt16) (K[j--] + (R2 & R1) + ((~R2) & R0));
R2 = (UInt16) ((R2 >> 3) | (R2 << 13));
R2 -= (UInt16) (K[j--] + (R1 & R0) + ((~R1) & R3));
R1 = (UInt16) ((R1 >> 2) | (R1 << 14));
R1 -= (UInt16) (K[j--] + (R0 & R3) + ((~R0) & R2));
R0 = (UInt16) ((R0 >> 1) | (R0 << 15));
R0 -= (UInt16) (K[j--] + (R3 & R2) + ((~R3) & R1));
}
}
// unrolled loop
output[0] = (byte) R0;
output[1] = (byte) (R0 >> 8);
output[2] = (byte) R1;
output[3] = (byte) (R1 >> 8);
output[4] = (byte) R2;
output[5] = (byte) (R2 >> 8);
output[6] = (byte) R3;
output[7] = (byte) (R3 >> 8);
}