private void InvShiftRows(ref State_t state) { uint temp; // Rotate first row 1 columns to right temp = state.state_t[3, 1]; state.state_t[3, 1] = state.state_t[2, 1]; state.state_t[2, 1] = state.state_t[1, 1]; state.state_t[1, 1] = state.state_t[0, 1]; state.state_t[0, 1] = temp; // Rotate second row 2 columns to right temp = state.state_t[0, 2]; state.state_t[0, 2] = state.state_t[2, 2]; state.state_t[2, 2] = temp; temp = state.state_t[1, 2]; state.state_t[1, 2] = state.state_t[3, 2]; state.state_t[3, 2] = temp; // Rotate third row 3 columns to right temp = state.state_t[0, 3]; state.state_t[0, 3] = state.state_t[1, 3]; state.state_t[1, 3] = state.state_t[2, 3]; state.state_t[2, 3] = state.state_t[3, 3]; state.state_t[3, 3] = temp; }
// The SubBytes Function Substitutes the values in the // state matrix with values in an S-box. private void InvSubBytes(ref State_t state) { uint i, j; for (i = 0; i < 4; ++i) { for (j = 0; j < 4; ++j) { state.state_t[j, i] = getSBoxInvert(state.state_t[j, i] & 0xff); } } }
// The SubBytes Function Substitutes the values in the // state matrix with values in an S-box. private void SubBytes(ref State_t state) { uint i, j; for (i = 0; i < 4; ++i) { for (j = 0; j < 4; ++j) { state.state_t[j, i] = getSBoxValue(state.state_t[j, i] & 0xff); // added "& 0xff" } } }
// This function adds the round key to state. // The round key is added to the state by an XOR function. private void AddRoundKey(uint round, ref State_t state, ref uint[] RoundKey) { uint i, j; for (i = 0; i < 4; ++i) { for (j = 0; j < 4; ++j) { state.state_t[i, j] ^= RoundKey[(round * Nb * 4) + (i * Nb) + j]; } } }
// MixColumns function mixes the columns of the state matrix private void MixColumns(ref State_t state) { uint i; uint Tmp, Tm, t; for (i = 0; i < 4; ++i) { t = state.state_t[i, 0]; Tmp = state.state_t[i, 0] ^ state.state_t[i, 1] ^ state.state_t[i, 2] ^ state.state_t[i, 3]; Tm = state.state_t[i, 0] ^ state.state_t[i, 1]; Tm = xtime(Tm); state.state_t[i, 0] ^= Tm ^ Tmp; Tm = state.state_t[i, 1] ^ state.state_t[i, 2]; Tm = xtime(Tm); state.state_t[i, 1] ^= Tm ^ Tmp; Tm = state.state_t[i, 2] ^ state.state_t[i, 3]; Tm = xtime(Tm); state.state_t[i, 2] ^= Tm ^ Tmp; Tm = state.state_t[i, 3] ^ t; Tm = xtime(Tm); state.state_t[i, 3] ^= Tm ^ Tmp; } }
// MixColumns function mixes the columns of the state matrix. // The method used to multiply may be difficult to understand for the inexperienced. // Please use the references to gain more information. private void InvMixColumns(ref State_t state) { int i; uint a, b, c, d; for (i = 0; i < 4; ++i) { a = state.state_t[i, 0]; b = state.state_t[i, 1]; c = state.state_t[i, 2]; d = state.state_t[i, 3]; state.state_t[i, 0] = Multiply(a, 0x0e) ^ Multiply(b, 0x0b) ^ Multiply(c, 0x0d) ^ Multiply(d, 0x09); state.state_t[i, 1] = Multiply(a, 0x09) ^ Multiply(b, 0x0e) ^ Multiply(c, 0x0b) ^ Multiply(d, 0x0d); state.state_t[i, 2] = Multiply(a, 0x0d) ^ Multiply(b, 0x09) ^ Multiply(c, 0x0e) ^ Multiply(d, 0x0b); state.state_t[i, 3] = Multiply(a, 0x0b) ^ Multiply(b, 0x0d) ^ Multiply(c, 0x09) ^ Multiply(d, 0x0e); } }
public void InvCipher(ref State_t state, ref uint[] RoundKey) { uint round = 0; // Add the First round key to the state before starting the rounds. AddRoundKey(Nr, ref state, ref RoundKey); // There will be Nr rounds. // The first Nr-1 rounds are identical. // These Nr-1 rounds are executed in the loop below. for (round = (Nr - 1); round > 0; --round) { InvShiftRows(ref state); InvSubBytes(ref state); AddRoundKey(round, ref state, ref RoundKey); InvMixColumns(ref state); } // The last round is given below. // The MixColumns function is not here in the last round. InvShiftRows(ref state); InvSubBytes(ref state); AddRoundKey(0, ref state, ref RoundKey); }
// Cipher is the main function that encrypts the PlainText. private void Cipher(ref State_t state, ref uint[] RoundKey) { uint round = 0; // Add the First round key to the state before starting the rounds. AddRoundKey(0, ref state, ref RoundKey); // There will be Nr rounds. // The first Nr-1 rounds are identical. // These Nr-1 rounds are executed in the loop below. for (round = 1; round < Nr; ++round) { SubBytes(ref state); ShiftRows(ref state); MixColumns(ref state); AddRoundKey(round, ref state, ref RoundKey); } // The last round is given below. // The MixColumns function is not here in the last round. SubBytes(ref state); ShiftRows(ref state); AddRoundKey(Nr, ref state, ref RoundKey); }