decryptStream method

Stream<List<int>> decryptStream(
  1. Stream<List<int>> stream, {
  2. required SecretKey secretKey,
  3. required List<int> nonce,
  4. required FutureOr<Mac> mac,
  5. List<int> aad = const [],
  6. bool allowUseSameBytes = false,
})

Decrypts a Stream of bytes.

Parameter stream is a stream of chunks of bytes.

Parameter secretKey is the secret key. You can generate a secret key with newSecretKey.

Parameter nonce is the nonce.

You must give mac for message authentication. If authentication fails, the output stream will have a SecretBoxAuthenticationError. For example, if your macAlgorithm is MacAlgorithm.empty, use Mac.empty.

You can use aad to pass Associated Authenticated Data (AAD).

If allowUseSameBytes is true, the method is allowed (but not required) to reduce memory allocations by using the same byte array for input and output. If you use the same byte array for other purposes, this may be unsafe.

The default implementation reads the input stream into a buffer and, after the input stream has been closed, calls decrypt. Subclasses are encouraged to override the default implementation so that the input stream is processed as it is received.

Implementation

Stream<List<int>> decryptStream(
  Stream<List<int>> stream, {
  required SecretKey secretKey,
  required List<int> nonce,
  required FutureOr<Mac> mac,
  List<int> aad = const [],
  bool allowUseSameBytes = false,
}) async* {
  final state = newState();
  await state.initialize(
    isEncrypting: false,
    secretKey: secretKey,
    nonce: nonce,
    aad: aad,
  );
  var countForPausing = 0;
  await for (var chunk in stream) {
    final convertedChunk = state.convertChunkSync(
      chunk,
      possibleBuffer: allowUseSameBytes && chunk is Uint8List ? chunk : null,
    );
    yield (convertedChunk);

    // Pause every now and then to avoid blocking the event loop.
    countForPausing += chunk.length;
    if (countForPausing >= _pauseFrequencyInBytes) {
      await Future.delayed(_pauseDuration);
      countForPausing = 0;
    }
  }
  final lastConvertedBytes = await state.convert(
    _emptyUint8List,
    expectedMac: await mac,
  );
  if (lastConvertedBytes.isNotEmpty) {
    yield (lastConvertedBytes);
  }
  if (state.mac != await mac) {
    throw SecretBoxAuthenticationError();
  }
}