private void SetKey(byte[] key)
{
int[] k32e = new int[MAX_KEY_BITS/64]; // 4
int[] k32o = new int[MAX_KEY_BITS/64]; // 4
int[] sBoxKeys = new int[MAX_KEY_BITS/64]; // 4
gSubKeys = new int[TOTAL_SUBKEYS];
if (k64Cnt < 1)
{
throw new ArgumentException("Key size less than 64 bits");
}
if (k64Cnt > 4)
{
throw new ArgumentException("Key size larger than 256 bits");
}
/*
* k64Cnt is the number of 8 byte blocks (64 chunks)
* that are in the input key. The input key is a
* maximum of 32 bytes ( 256 bits ), so the range
* for k64Cnt is 1..4
*/
for (int i=0,p=0; i<k64Cnt ; i++)
{
p = i* 8;
k32e[i] = BytesTo32Bits(key, p);
k32o[i] = BytesTo32Bits(key, p+4);
sBoxKeys[k64Cnt-1-i] = RS_MDS_Encode(k32e[i], k32o[i]);
}
int q,A,B;
for (int i=0; i < TOTAL_SUBKEYS / 2 ; i++)
{
q = i*SK_STEP;
A = F32(q, k32e);
B = F32(q+SK_BUMP, k32o);
B = B << 8 | (int)((uint)B >> 24);
A += B;
gSubKeys[i*2] = A;
A += B;
gSubKeys[i*2 + 1] = A << SK_ROTL | (int)((uint)A >> (32-SK_ROTL));
}
/*
* fully expand the table for speed
*/
int k0 = sBoxKeys[0];
int k1 = sBoxKeys[1];
int k2 = sBoxKeys[2];
int k3 = sBoxKeys[3];
int b0, b1, b2, b3;
gSBox = new int[4*MAX_KEY_BITS];
for (int i=0; i<MAX_KEY_BITS; i++)
{
b0 = b1 = b2 = b3 = i;
switch (k64Cnt & 3)
{
case 1:
gSBox[i*2] = gMDS0[(P[P_01,b0] & 0xff) ^ M_b0(k0)];
gSBox[i*2+1] = gMDS1[(P[P_11,b1] & 0xff) ^ M_b1(k0)];
gSBox[i*2+0x200] = gMDS2[(P[P_21,b2] & 0xff) ^ M_b2(k0)];
gSBox[i*2+0x201] = gMDS3[(P[P_31,b3] & 0xff) ^ M_b3(k0)];
break;
case 0: // 256 bits of key
b0 = (P[P_04,b0] & 0xff) ^ M_b0(k3);
b1 = (P[P_14,b1] & 0xff) ^ M_b1(k3);
b2 = (P[P_24,b2] & 0xff) ^ M_b2(k3);
b3 = (P[P_34,b3] & 0xff) ^ M_b3(k3);
// fall through, having pre-processed b[0]..b[3] with k32[3]
goto case 3;
case 3: // 192 bits of key
b0 = (P[P_03,b0] & 0xff) ^ M_b0(k2);
b1 = (P[P_13,b1] & 0xff) ^ M_b1(k2);
b2 = (P[P_23,b2] & 0xff) ^ M_b2(k2);
b3 = (P[P_33,b3] & 0xff) ^ M_b3(k2);
// fall through, having pre-processed b[0]..b[3] with k32[2]
goto case 2;
case 2: // 128 bits of key
gSBox[i * 2] = gMDS0[(P[P_01, (P[P_02, b0] & 0xff) ^ M_b0(k1)] & 0xff) ^ M_b0(k0)];
gSBox[i*2+1] = gMDS1[(P[P_11,(P[P_12,b1] & 0xff) ^ M_b1(k1)] & 0xff) ^ M_b1(k0)];
gSBox[i*2+0x200] = gMDS2[(P[P_21,(P[P_22,b2] & 0xff) ^ M_b2(k1)] & 0xff) ^ M_b2(k0)];
gSBox[i * 2 + 0x201] = gMDS3[(P[P_31, (P[P_32, b3] & 0xff) ^ M_b3(k1)] & 0xff) ^ M_b3(k0)];
break;
}
}
/*
* the function exits having setup the gSBox with the
* input key material.
*/
}