Demystifying AES Key Expansion: A Deep Dive into Secure Cryptography
In the world of cryptography, AES (Advanced Encryption Standard) stands tall as one of the most widely used encryption algorithms, trusted for its robust security features. At the heart of AES lies a critical process known as key expansion, which plays a pivotal role in generating the round keys used for encryption and decryption. In this blog post, we will delve into the intricacies of AES key expansion, unraveling its significance and exploring the mechanisms behind it.
Understanding AES Encryption
Before delving into key expansion, let's grasp the fundamentals of AES encryption briefly. AES operates on fixed block sizes of 128 bits, with key lengths of 128, 192, or 256 bits. It employs a substitution-permutation network (SPN) structure, dividing the encryption process into several rounds. Each round consists of four main operations: SubBytes, ShiftRows, MixColumns, and AddRoundKey.
The Role of Key Expansion
Key expansion is the process of transforming a relatively short key into a larger set of round keys, which are used in each round of the AES encryption and decryption process. This expansion ensures that the encryption algorithm remains secure and resistant to various cryptographic attacks, such as brute force and differential cryptanalysis.
The Key Expansion Algorithm Process with Algorithm Source Code
import 'dart:io';
import 'list_data.dart';
var rConColumn = [];
var round;
Data data = Data();
void main() {
round = 03;
var currentRoundHexKey = [
['47', '40', 'A3', '4C'],
['37', 'D4', '70', '9F'],
['94', 'E4', '3A', '42'],
['ED', 'A5', 'AE', 'BC'],
];
int keyRowCount = currentRoundHexKey.length; //total row in current Round key
int keyColumnCount =
currentRoundHexKey[0].length; //total column in current Round key
var sBoxProcessingColumn = []; //currently working column before Sbox
var afterSBoxProcessingColumn = []; //after processing sbox column
var nxtRoundHexKey = []; //next Round key or final result
int n = keyColumnCount - 1;
//loop for finding column before processing sbox
for (int i = 0; i < keyRowCount;) {
i++;
if (i == keyColumnCount) {
i = 0;
sBoxProcessingColumn.add(currentRoundHexKey[i][n]);
break;
}
sBoxProcessingColumn.add(currentRoundHexKey[i][n]);
}
//loop for finding column after processing sbox
for (int i = 0; i < sBoxProcessingColumn.length; i++) {
String firstChar = sBoxProcessingColumn[i].substring(0, 1);
String secondChar = sBoxProcessingColumn[i].substring(1);
int row = int.parse(firstChar, radix: 16);
int colmn = int.parse(secondChar, radix: 16);
String value = data.s_Box[row][colmn];
afterSBoxProcessingColumn.add(value);
}
rConTableValue(round);
String? result;
for (int i = 0; i < keyRowCount; i++) {
nxtRoundHexKey.add([]);
}
//loop for xor operation
for (int i = 0; i < keyColumnCount; i++) {
if (i == 0) {
for (int j = 0; j < keyRowCount; j++) {
String result1 =
xorHex(afterSBoxProcessingColumn[j], currentRoundHexKey[j][i]);
result = xorHex(result1, rConColumn[j]);
nxtRoundHexKey[i].add(result);
}
} else {
for (int j = 0; j < keyRowCount; j++) {
result = xorHex(nxtRoundHexKey[i - 1][j], currentRoundHexKey[j][i]);
nxtRoundHexKey[i].add(result);
}
}
}
//Next Round Key Output
print('Round ${round + 1} AES Key : ');
for (int i = 0; i < keyRowCount; i++) {
for (int j = 0; j < keyColumnCount; j++) {
stdout.write('${nxtRoundHexKey[j][i]} ');
}
print('');
}
}
//function for complete rcon table
void rConTableValue(int round) {
rConColumn.add(data.rCon_table[round]);
rConColumn.add('00');
rConColumn.add('00');
rConColumn.add('00');
}
//function for Xor operation between two string
String xorHex(String hex1, String hex2) {
int int1 = int.parse(hex1, radix: 16);
int int2 = int.parse(hex2, radix: 16);
int result = int1 ^ int2;
String hexResult =
result.toRadixString(16); // Convert result back to hexadecimal
return hexResult.toUpperCase();
}
class Data{
var rCon_table = [
'01', '02', '04', '08', '10', '20', '40', '80', '1B', '36', '6C', 'D8', 'AB', '4D'
];
var s_Box = [
[
"63", "7C", "77", "7B", "F2", "6B", "6F", "C5", "30", "01", "67", "2B", "FE", "D7", "AB", "76",
],
[
"CA", "82", "C9", "7D", "FA", "59", "47", "F0", "AD", "D4", "A2", "AF", "9C", "A4", "72", "C0",
],
[
"B7", "FD", "93", "26", "36", "3F", "F7", "CC", "34", "A5", "E5", "F1", "71", "D8", "31", "15",
],
[
"04", "C7", "23", "C3", "18", "96", "05", "9A", "07", "12", "80", "E2", "EB", "27", "B2", "75",
],
[
"09", "83", "2C", "1A", "1B", "6E", "5A", "A0", "52", "3B", "D6", "B3", "29", "E3", "2F", "84",
],
[
"53", "D1", "00", "ED", "20", "FC", "B1", "5B", "6A", "CB", "BE", "39", "4A", "4C", "58", "CF",
],
[
"D0", "EF", "AA", "FB", "43", "4D", "33", "85", "45", "F9", "02", "7F", "50", "3C", "9F", "A8",
],
[
"51", "A3", "40", "8F", "92", "9D", "38", "F5", "BC", "B6", "DA", "21", "10", "FF", "F3", "D2",
],
[
"CD", "0C", "13", "EC", "5F", "97", "44", "17", "C4", "A7", "7E", "3D", "64", "5D", "19", "73",
],
[
"60", "81", "4F", "DC", "22", "2A", "90", "88", "46", "EE", "B8", "14", "DE", "5E", "0B", "DB",
],
[
"E0", "32", "3A", "0A", "49", "06", "24", "5C", "C2", "D3", "AC", "62", "91", "95", "E4", "79",
],
[
"E7", "C8", "37", "6D", "8D", "D5", "4E", "A9", "6C", "56", "F4", "EA", "65", "7A", "AE", "08",
],
[
"BA", "78", "25", "2E", "1C", "A6", "B4", "C6", "E8", "DD", "74", "1F", "4B", "BD", "8B", "8A",
],
[
"70", "3E", "B5", "66", "48", "03", "F6", "0E", "61", "35", "57", "B9", "86", "C1", "1D", "9E",
],
[
"E1", "F8", "98", "11", "69", "D9", "8E", "94", "9B", "1E", "87", "E9", "CE", "55", "28", "DF",
],
[
"8C", "A1", "89", "0D", "BF", "E6", "42", "68", "41", "99", "2D", "0F", "B0", "54", "BB", "16",
],
];
}
Subscribe to my newsletter
Read articles from Md Shamim Ahamed directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
Md Shamim Ahamed
Md Shamim Ahamed
As a budding Flutter Android developer, I am passionate and adaptable Flutter developer with robust problem-solving skills. Experienced in cross-platform mobile app development and proficient in UI/UX design. Collaborative by nature, I am passionate about crafting efficient and user-friendly solutions.