// The InvSubBytes Function Substitutes the values in the // state matrix with values in an InvSbox static void InvSubBytes(byte[,] state) { for (byte col = 0; col < Nb; ++col) { state[0, col] = Boxes.getInvSBoxValue(state[0, col]); state[1, col] = Boxes.getInvSBoxValue(state[1, col]); state[2, col] = Boxes.getInvSBoxValue(state[2, col]); state[3, col] = Boxes.getInvSBoxValue(state[3, col]); } }//end SubBytes()
//------------------------------------------------------------------------------------------------------- // This function produces Nb*(Nr+1) round keys. The round keys are used in each round to decrypt the states. static void KeyExpansion(byte[,] RoundKey, byte[] Key) { byte i, j, k; byte[] tempa = new byte[4]; // Used for the column/row operations // The first round key is the key itself. for (i = 0; i < Nk; ++i) { RoundKey[0, i] = Key[(i * 4) + 0]; RoundKey[1, i] = Key[(i * 4) + 1]; RoundKey[2, i] = Key[(i * 4) + 2]; RoundKey[3, i] = Key[(i * 4) + 3]; } //------------------------------------------- // All other round keys are found from the previous round keys. for (i = Nk; i < (Nr + 1) * Nb; ++i)//each column !!!!!!!!! { { //k = (byte)((i - 1) * 4);//every 4 column tempa[0] = RoundKey[0, i - 1]; tempa[1] = RoundKey[1, i - 1]; tempa[2] = RoundKey[2, i - 1]; tempa[3] = RoundKey[3, i - 1]; } if (i % Nk == 0) { // This function shifts the 4 bytes in a word to the left once. // [a0,a1,a2,a3] becomes [a1,a2,a3,a0] // Function RotWord() { byte temp = tempa[0]; tempa[0] = tempa[1]; tempa[1] = tempa[2]; tempa[2] = tempa[3]; tempa[3] = temp; } // SubWord() is a function that takes a four-byte input word and // applies the S-box to each of the four bytes to produce an output word. // Function Subword() { tempa[0] = Boxes.getSBoxValue(tempa[0]); tempa[1] = Boxes.getSBoxValue(tempa[1]); tempa[2] = Boxes.getSBoxValue(tempa[2]); tempa[3] = Boxes.getSBoxValue(tempa[3]); } // Function Xor: W(i-nk) ^ W(i-1) ^ Rcon(i/nk-1) { tempa[0] = (byte)(RoundKey[0, i - Nk] ^ tempa[0] ^ Rcon[i / Nk]); tempa[1] = (byte)(RoundKey[1, i - Nk] ^ tempa[1]); tempa[2] = (byte)(RoundKey[2, i - Nk] ^ tempa[2]); tempa[3] = (byte)(RoundKey[3, i - Nk] ^ tempa[3]); } } else { tempa[0] = (byte)(RoundKey[0, i - 1] ^ RoundKey[0, i - Nk]); tempa[1] = (byte)(RoundKey[1, i - 1] ^ RoundKey[1, i - Nk]); tempa[2] = (byte)(RoundKey[2, i - 1] ^ RoundKey[2, i - Nk]); tempa[3] = (byte)(RoundKey[3, i - 1] ^ RoundKey[3, i - Nk]); } //assigment { RoundKey[0, i] = tempa[0]; RoundKey[1, i] = tempa[1]; RoundKey[2, i] = tempa[2]; RoundKey[3, i] = tempa[3]; } } }