AESFastDecryptionEngine constructor
AESFastDecryptionEngine(
- Uint8List key
Implementation
factory AESFastDecryptionEngine(Uint8List key) {
int KC = (key.lengthInBytes / 4).floor(); // key length in words
if (((KC != 4) && (KC != 6) && (KC != 8)) ||
((KC * 4) != key.lengthInBytes)) {
throw ArgumentError("Key length must be 128/192/256 bits");
}
final int _rounds = KC + 6;
// This is not always true for the generalized Rijndael that allows larger block sizes
final List<List<int>> _workingKey = List.generate(
_rounds + 1, (int i) => List<int>.filled(4, 0)); // 4 words in a block
// Copy the key into the round key array.
var keyView = ByteData.view(key.buffer, key.offsetInBytes, key.length);
for (int i = 0, t = 0; i < key.lengthInBytes; i += 4, t++) {
int value = keyView.getUint32(i, Endian.little);
_workingKey[t >> 2][t & 3] = value;
}
// While not enough round key material calculated calculate new values.
int k = (_rounds + 1) << 2;
for (int i = KC; i < k; i++) {
int temp = _workingKey[(i - 1) >> 2][(i - 1) & 3].toInt();
if ((i % KC) == 0) {
temp = _subWord(_shift(temp, 8)) ^ _rcon[((i / KC) - 1).floor()];
} else if ((KC > 6) && ((i % KC) == 4)) {
temp = _subWord(temp);
}
int value = _workingKey[(i - KC) >> 2][(i - KC) & 3] ^ temp;
_workingKey[i >> 2][i & 3] = value;
}
for (int j = 1; j < _rounds; j++) {
for (int i = 0; i < 4; i++) {
var value = _inv_mcol(_workingKey[j][i].toInt());
_workingKey[j][i] = value;
}
}
return AESFastDecryptionEngine._(_workingKey, _rounds);
}