encrypt method

  1. @override
List<int> encrypt(
  1. List<int> nonce,
  2. List<int> plaintext, {
  3. List<int>? associatedData,
  4. List<int>? dst,
})
override

Encrypts data using the Galois/Counter Mode (GCM) with associated data (AEAD).

This method encrypts data using the GCM mode, providing authenticated encryption with associated data (AEAD). It uses a nonce and associated data for encryption, and generates an authentication tag to ensure data integrity.

Parameters:

  • nonce: The nonce value used for encryption, must have a length equal to the GCM nonce length (12 bytes).
  • plaintext: The data to be encrypted.
  • associatedData: (Optional) Additional data that is authenticated but not encrypted.
  • dst: (Optional) The destination for the encrypted data and authentication tag. If not provided, a new List<int> is created.

Returns:

  • The encrypted data with the appended authentication tag.

Throws:

  • ArgumentException if the provided nonce has an incorrect length or if the destination size is incorrect.

Note: This method performs GCM encryption by combining nonce, plaintext, and optional associated data, and generating an authentication tag for data integrity verification.

Implementation

@override
List<int> encrypt(List<int> nonce, List<int> plaintext,
    {List<int>? associatedData, List<int>? dst}) {
  if (nonce.length != nonceLength) {
    throw const ArgumentException("GCM: incorrect nonce length");
  }

  final blockSize = _cipher.blockSize;

  final resultLength = plaintext.length + tagLength;
  List<int> result = dst ?? List<int>.filled(resultLength, 0);
  if (result.length != resultLength) {
    throw const ArgumentException("GCM: incorrect destination length");
  }

  final counter = List<int>.filled(blockSize, 0);
  counter.setAll(0, nonce);

  counter[blockSize - 1] = 1;

  final tagMask = List<int>.filled(blockSize, 0);
  _cipher.encryptBlock(counter, tagMask);

  counter[blockSize - 1] = 2;

  final ctr = CTR(_cipher, counter);
  ctr.streamXOR(plaintext, result);
  ctr.clean();
  final calculatedTag = List<int>.filled(tagLength, 0);
  final cipherText = result.sublist(0, result.length - tagLength);

  _authenticate(calculatedTag, tagMask, cipherText, associatedData);
  result.setRange(result.length - tagLength, result.length, calculatedTag);
  zero(counter);
  zero(tagMask);
  return result;
}