/// <summary> /// Replaces each value in this BitMatrix with the corresponding value in the S-Box. /// </summary> public void subBytes() { for (int ii = 0; ii < SIZE; ii++) { bytes[startValue + ii] = subBox.getByte(bytes[startValue + ii]); } }
/// <summary> /// Creates the full key schedule. /// </summary> /// <param name="key"> The single block key to be expanded. </param> /// <returns> The key schedule </returns> public static BitMatrix[] getKeySchedule(byte[] key) //this works { if (key.Length != BLOCK_LENGTH) { throw new ArgumentException("Error in key schudule generation"); } byte[][] schedule = new byte[BLOCK_LENGTH / WORD_LENGTH * ROUNDS][]; for (int ii = 0; ii < schedule.Length; ii++) { schedule[ii] = new byte[WORD_LENGTH]; //initializes the schedule as an array of 4 byte arrays. This is because //it creates the schedule word by word. } byte[] roundConstants = generateRoundConstants(); //creates the round constants. These are single bytes that are XORed for (int ii = 0; ii < BLOCK_LENGTH; ii++) //with the first byte of the first word of the first { schedule[ii / WORD_LENGTH][ii % WORD_LENGTH] = key[ii]; //gets the words from the key and throws them in the first four slots. } for (int ii = WORD_LENGTH; ii < schedule.Length; ii++) //these are words { if (ii % WORD_LENGTH != 0) //if it is the 2nd, 3rd, or 4th word of the key, it is just the 1st word XORed { //with the equivalent word of the previous block. for (int jj = 0; jj < schedule[ii].Length; jj++) { schedule[ii][jj] = (byte)(schedule[ii - WORD_LENGTH][jj] ^ schedule[ii - 1][jj]); //xor four before with the first word of this key } } else //the 1st word of each key is more difficult. { schedule[ii] = (byte[])schedule[ii - 1].Clone(); //otherwise there will be a reference pass byteRotate(schedule[ii]); //rotate by 1 BYTE not bit for (int jj = 0; jj < schedule[ii].Length; jj++) { schedule[ii][jj] = SUB_TABLE.getByte(schedule[ii][jj]); //subByte the whole box } schedule[ii][0] = (byte)(schedule[ii][0] ^ roundConstants[ii / WORD_LENGTH - 1]); //xor the constants to the top of the words for (int jj = 0; jj < schedule[ii].Length; jj++) //theres a -1 on he round constants because there is no RC for the original 4 word key { schedule[ii][jj] = (byte)(schedule[ii][jj] ^ schedule[ii - WORD_LENGTH][jj]); //mod it with the previous first word. } } } BitMatrix[] sched = new BitMatrix[ROUNDS]; //converts the created key to bit matrices. for (int ii = 0; ii < sched.Length; ii++) //convert the data into bit matrices { sched[ii] = new BitMatrix(GF_TABLE, SUB_TABLE, schedule[WORD_LENGTH * ii], schedule[WORD_LENGTH * ii + 1], schedule[WORD_LENGTH * ii + 2], schedule[WORD_LENGTH * ii + 3]); } return(sched); }