private byte[] ProcessDecrypt(byte[] byteInput, string password) { if (password.Length != blockSize) { throw new Exception("Password is not 128bit long"); } var result = new List <byte>(); //We will divide the byteInput into Block of 16 chars var blockIteration = (int)Math.Ceiling((byteInput.Length * 1.0) / blockSize); var currentByteBlock = new byte[4, 4]; var cbcBlock = new byte[4, 4]; BlockFill(cbcBlock, 0); var substitute = new Substitution(); var addKey = new AddKey(substitute, password); var mixColumn = new MixColumns(); var shiftRow = new ShiftRow(); for (var blockCount = 0; blockCount < blockIteration; blockCount++) { var blockStart = blockCount * blockSize; var cipherCBC = new byte[4, 4]; //COnvert to a blockArray of 4x4 for (int i = 0; i < 4; i++) { for (int j = 0; j < 4; j++) { currentByteBlock[j, i] = byteInput[blockStart + i * 4 + j]; cipherCBC[j, i] = currentByteBlock[j, i]; } } LogEngine.LogBytes(currentByteBlock, "Current Block"); addKey.AddRoundKey(Nr, currentByteBlock); shiftRow.InvByteShift(currentByteBlock); substitute.InvByteSub(currentByteBlock); for (int rnd = Nr - 1; rnd > 0; rnd--) { addKey.AddRoundKey(rnd, currentByteBlock); mixColumn.InvApplyColumn(currentByteBlock); shiftRow.InvByteShift(currentByteBlock); substitute.InvByteSub(currentByteBlock); } addKey.AddRoundKey(0, currentByteBlock); for (int i = 0; i < 4; i++) { for (int j = 0; j < 4; j++) { result.Add((byte)(cbcBlock[j, i] ^ currentByteBlock[j, i])); } } //Copy this stage Cypher as next stage CBC BlockCopy(cipherCBC, cbcBlock); } addKey.Dispose(); return(result.ToArray()); }