generateWorkingKey method
Implementation
List<List<int>> generateWorkingKey(bool forEncryption, KeyParameter params) {
var key = params.key;
var keyLen = key.length;
if (keyLen < 16 || keyLen > 32 || (keyLen & 7) != 0) {
throw ArgumentError('Key length not 128/192/256 bits.');
}
var KC = shiftr32(keyLen, 2);
_ROUNDS = KC +
6; // This is not always true for the generalized Rijndael that allows larger block sizes
var W = List.generate(
_ROUNDS + 1,
(int i) =>
List<int>.filled(4, 0, growable: false)); // 4 words in a block
switch (KC) {
case 4:
var col0 = unpack32(key, 0, Endian.little);
W[0][0] = col0;
var col1 = unpack32(key, 4, Endian.little);
W[0][1] = col1;
var col2 = unpack32(key, 8, Endian.little);
W[0][2] = col2;
var col3 = unpack32(key, 12, Endian.little);
W[0][3] = col3;
for (var i = 1; i <= 10; ++i) {
var colx = _subWord(_shift(col3, 8)) ^ _rcon[i - 1];
col0 ^= colx;
W[i][0] = col0;
col1 ^= col0;
W[i][1] = col1;
col2 ^= col1;
W[i][2] = col2;
col3 ^= col2;
W[i][3] = col3;
}
break;
case 6:
var col0 = unpack32(key, 0, Endian.little);
W[0][0] = col0;
var col1 = unpack32(key, 4, Endian.little);
W[0][1] = col1;
var col2 = unpack32(key, 8, Endian.little);
W[0][2] = col2;
var col3 = unpack32(key, 12, Endian.little);
W[0][3] = col3;
var col4 = unpack32(key, 16, Endian.little);
var col5 = unpack32(key, 20, Endian.little);
int i = 1, rcon = 1, colx;
for (;;) {
W[i][0] = col4;
W[i][1] = col5;
colx = _subWord(_shift(col5, 8)) ^ rcon;
rcon <<= 1;
col0 ^= colx;
W[i][2] = col0;
col1 ^= col0;
W[i][3] = col1;
col2 ^= col1;
W[i + 1][0] = col2;
col3 ^= col2;
W[i + 1][1] = col3;
col4 ^= col3;
W[i + 1][2] = col4;
col5 ^= col4;
W[i + 1][3] = col5;
colx = _subWord(_shift(col5, 8)) ^ rcon;
rcon <<= 1;
col0 ^= colx;
W[i + 2][0] = col0;
col1 ^= col0;
W[i + 2][1] = col1;
col2 ^= col1;
W[i + 2][2] = col2;
col3 ^= col2;
W[i + 2][3] = col3;
if ((i += 3) >= 13) {
break;
}
col4 ^= col3;
col5 ^= col4;
}
break;
case 8:
{
var col0 = unpack32(key, 0, Endian.little);
W[0][0] = col0;
var col1 = unpack32(key, 4, Endian.little);
W[0][1] = col1;
var col2 = unpack32(key, 8, Endian.little);
W[0][2] = col2;
var col3 = unpack32(key, 12, Endian.little);
W[0][3] = col3;
var col4 = unpack32(key, 16, Endian.little);
W[1][0] = col4;
var col5 = unpack32(key, 20, Endian.little);
W[1][1] = col5;
var col6 = unpack32(key, 24, Endian.little);
W[1][2] = col6;
var col7 = unpack32(key, 28, Endian.little);
W[1][3] = col7;
int i = 2, rcon = 1, colx;
for (;;) {
colx = _subWord(_shift(col7, 8)) ^ rcon;
rcon <<= 1;
col0 ^= colx;
W[i][0] = col0;
col1 ^= col0;
W[i][1] = col1;
col2 ^= col1;
W[i][2] = col2;
col3 ^= col2;
W[i][3] = col3;
++i;
if (i >= 15) {
break;
}
colx = _subWord(col3);
col4 ^= colx;
W[i][0] = col4;
col5 ^= col4;
W[i][1] = col5;
col6 ^= col5;
W[i][2] = col6;
col7 ^= col6;
W[i][3] = col7;
++i;
}
break;
}
default:
{
throw StateError('Should never get here');
}
}
if (!forEncryption) {
for (var j = 1; j < _ROUNDS; j++) {
for (var i = 0; i < 4; i++) {
W[j][i] = _invMcol(W[j][i]);
}
}
}
return W;
}