private int[] GenerateWorkingKey(
byte[] key,
int bits)
{
int x;
int[] xKey = new int[128];
for (int i = 0; i != key.Length; i++)
{
xKey[i] = key[i] & 0xff;
}
// Phase 1: Expand input key to 128 bytes
int len = key.Length;
if (len < 128)
{
int index = 0;
x = xKey[len - 1];
do
{
x = piTable[(x + xKey[index++]) & 255] & 0xff;
xKey[len++] = x;
}
while (len < 128);
}
// Phase 2 - reduce effective key size to "bits"
len = (bits + 7) >> 3;
x = piTable[xKey[128 - len] & (255 >> (7 & -bits))] & 0xff;
xKey[128 - len] = x;
for (int i = 128 - len - 1; i >= 0; i--)
{
x = piTable[x ^ xKey[i + len]] & 0xff;
xKey[i] = x;
}
// Phase 3 - copy to newKey in little-endian order
int[] newKey = new int[64];
for (int i = 0; i != newKey.Length; i++)
{
newKey[i] = (xKey[2 * i] + (xKey[2 * i + 1] << 8));
}
return newKey;
}