encryptSync method

SecretBox encryptSync(
  1. List<int> clearText, {
  2. required SecretKeyData secretKeyData,
  3. List<int>? nonce,
  4. List<int> aad = const <int>[],
  5. int keyStreamIndex = 0,
})

Implementation

SecretBox encryptSync(
  List<int> clearText, {
  required SecretKeyData secretKeyData,
  List<int>? nonce,
  List<int> aad = const <int>[],
  int keyStreamIndex = 0,
}) {
  final actualSecretKeyLength = secretKeyData.bytes.length;
  final expectedSecretKeyLength = secretKeyLength;
  if (actualSecretKeyLength != expectedSecretKeyLength) {
    throw ArgumentError.value(
      secretKeyData,
      'secretKeyData',
      'Expected $secretKeyLength bytes, got $actualSecretKeyLength bytes',
    );
  }
  if (keyStreamIndex < 0 || keyStreamIndex >= 0x10000000) {
    throw ArgumentError.value(keyStreamIndex, 'keyStreamIndex');
  }
  nonce ??= newNonce();
  final expandedKey = aesExpandKeyForEncrypting(secretKeyData);

  // `h` = AES(zero_block, key)
  final h = Uint32List(4);
  aesEncryptBlock(h, 0, h, 0, expandedKey);
  h[0] = _uint32ChangeEndian(h[0]);
  h[1] = _uint32ChangeEndian(h[1]);
  h[2] = _uint32ChangeEndian(h[2]);
  h[3] = _uint32ChangeEndian(h[3]);

  // Calculate initial nonce
  var stateBytes = _nonceToBlock(h: h, nonce: nonce);
  var state = Uint32List.view(stateBytes.buffer);

  // Memorize the state of the first block for calculating MAC later.
  final stateOfFirstBlock = Uint32List.fromList(state);

  // Increment nonce
  bytesIncrementBigEndian(stateBytes, 1 + (keyStreamIndex ~/ 16));

  // Allocate space for output bytes + 128 bit hash
  final blockCount = (keyStreamIndex % 16 + clearText.length + 15) ~/ 16;
  final keyStream = Uint32List((blockCount + 1) * 4);

  // For each block
  for (var i = 0; i < keyStream.length; i += 4) {
    // Encrypt state.
    aesEncryptBlock(keyStream, i, state, 0, expandedKey);

    // Increment state.
    bytesIncrementBigEndian(stateBytes, 1);
  }

  // cipherText = keyStream[start, end] ^ clearText
  final cipherText = Uint8List.view(
    keyStream.buffer,
    keyStream.offsetInBytes + keyStreamIndex % 16,
    clearText.length,
  );
  for (var i = 0; i < clearText.length; i++) {
    cipherText[i] ^= clearText[i];
  }

  // Calculate MAC
  final mac = const DartGcm()._calculateMacSync(
    cipherText,
    aad: aad,
    expandedKey: expandedKey,
    h: h,
    precounterBlock: stateOfFirstBlock,
  );

  return SecretBox(cipherText, nonce: nonce, mac: mac);
}