AESFastDecryptionEngine constructor

AESFastDecryptionEngine(
  1. 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);
}