encrypt method

  1. @override
Future<SecretBox> encrypt(
  1. List<int> clearText, {
  2. required SecretKey secretKey,
  3. List<int>? nonce,
  4. List<int> aad = const <int>[],
  5. int keyStreamIndex = 0,
  6. Uint8List? possibleBuffer,
})

Encrypts bytes and returns SecretBox.

You must give a SecretKey that has the correct length and type.

Optional parameter nonce (also known as "initialization vector", "IV", or "salt") is some sequence of bytes. You can generate a nonce with newNonce. If you don't define it, the cipher will generate a random nonce for you. The nonce must be unique for each encryption with the same secret key. It doesn't have to be secret.

Parameter aad can be used to pass Associated Authenticated Data (AAD). If you pass a non-empty list and the underlying cipher doesn't support AAD, the method will throw ArgumentError.

If possibleBuffer is non-null, the method is allowed (but not required) to write the output to it. The buffer can be the same as clearText. Otherwise the method will allocate memory for the output.

Implementation

@override
Future<SecretBox> encrypt(
  List<int> clearText, {
  required SecretKey secretKey,
  List<int>? nonce,
  List<int> aad = const <int>[],
  int keyStreamIndex = 0,
  Uint8List? possibleBuffer,
}) async {
  if (kIsWeb || !channelPolicy.matches(length: clearText.length)) {
    return await fallback.encrypt(
      clearText,
      secretKey: secretKey,
      nonce: nonce,
      aad: aad,
    );
  }
  nonce ??= newNonce();
  if (nonce.length != nonceLength) {
    throw ArgumentError.value(
      nonce,
      'nonce',
      'Nonce should be $nonceLength bytes long, not ${nonce.length} bytes.',
    );
  }
  final secretKeyBytes = await secretKey.extractBytes();
  if (secretKeyBytes.length != secretKeyLength) {
    throw ArgumentError.value(
      secretKey,
      'secretKey',
      'Secret key should be $secretKeyLength bytes long, not ${secretKeyBytes.length} bytes.',
    );
  }
  final args = [
    asUint8List(clearText),
    asUint8List(secretKeyBytes),
    asUint8List(nonce),
    asUint8List(aad),
  ];
  final size = CryptographyChannelQueue.estimateSize(args);
  final queue = CryptographyChannelQueue.defaultInstance;
  final lock = queue.newLock(size: size);
  await lock.lock();
  List result;
  try {
    result = await dispatchBackgroundEncrypt(args);
  } finally {
    lock.unlock();
  }
  final errorMessage = result[0] as String?;
  if (errorMessage != null) {
    throw StateError('$runtimeType.encrypt failed: $errorMessage');
  }
  final cipherText = result[1] as Uint8List;
  final macBytes = result[2] as Uint8List;

  // Sanity check
  if (cipherText.length != cipherTextLength(clearText.length)) {
    throw StateError(
      '$runtimeType.encrypt sanity check failed: '
      'cipherText.length (${cipherText.length}) != '
      'clearText.length (${clearText.length})',
    );
  }

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