newMacSink method

  1. @override
Future<MacSink> newMacSink({
  1. required SecretKey secretKey,
  2. List<int> nonce = const <int>[],
  3. List<int> aad = const <int>[],
})
override

Constructs a sink for calculating a Mac.

The parameter secretKey must be non-empty.

The parameter nonce can be const <int>[].

The parameter aad is Associated Authenticated Data (AAD). It can be empty. If it's non-empty and the algorithm does not support AAD, the the method throws ArgumentError.

Example

import 'package:better_cryptography/better_cryptography.dart';

void main() {
  final secretKey = SecretKey([1,2,3]);

  // Create a sink
  final sink = await Hmac.sha256().newMacSink(
    secretKey: secretKey,
  );

  // Add chunks of data
  sink.add([4,5,6]);
  sink.add([7,8]);

  // Close
  sink.close();

  // We now have a MAC
  final mac = await sink.mac();

  print('MAC: ${mac.bytes');
}

Implementation

@override
Future<MacSink> newMacSink({
  required SecretKey secretKey,
  List<int> nonce = const <int>[],
  List<int> aad = const <int>[],
}) async {
  if (aad.isNotEmpty) {
    throw ArgumentError.value(aad, 'aad', 'AAD is not supported');
  }

  final hashAlgorithm = this.hashAlgorithm;
  final blockLength = hashAlgorithm.blockLengthInBytes;

  //
  // secret
  //
  final secretKeyData = await secretKey.extract();
  var hmacKey = secretKeyData.bytes;
  if (hmacKey.isEmpty) {
    throw ArgumentError.value(
      secretKey,
      'secretKey',
      'SecretKey bytes must be non-empty',
    );
  }
  if (hmacKey.length > blockLength) {
    hmacKey = (await hashAlgorithm.hash(hmacKey)).bytes;
  }

  //
  // inner sink
  //
  final innerSink = hashAlgorithm.newHashSink();
  final innerPadding = Uint8List(blockLength);
  _preparePadding(innerPadding, hmacKey, 0x36);
  innerSink.add(innerPadding);

  //
  // outer sink
  //
  final outerSink = hashAlgorithm.newHashSink();
  final outerPadding = Uint8List(blockLength);
  _preparePadding(outerPadding, hmacKey, 0x5c);
  outerSink.add(outerPadding);

  return _HmacSink(innerSink, outerSink);
}