calculateMac method

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

Calculates message authentication code.

The parameter secretKey must be non-empty.

The parameter nonce is optional and rarely required by MAC algorithms. The default value is 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.

Implementation

@override
Future<Mac> calculateMac(
  List<int> bytes, {
  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 secretKeyData = await secretKey.extract();
  var hmacKey = secretKeyData.bytes;
  if (hmacKey.isEmpty) {
    throw ArgumentError.value(
      secretKey,
      'secretKey',
      'Must be non-empty',
    );
  }

  final hashAlgorithm = this.hashAlgorithm;

  final blockLength = hashAlgorithm.blockLengthInBytes;
  if (hmacKey.length > blockLength) {
    hmacKey = (await hashAlgorithm.hash(hmacKey)).bytes;
  }

  // Inner hash
  final innerPadding = Uint8List(blockLength);
  _preparePadding(innerPadding, hmacKey, 0x36);
  final innerInput = Uint8List(innerPadding.length + bytes.length);
  innerInput.setAll(0, innerPadding);
  innerInput.setAll(innerPadding.length, bytes);
  final innerHash = await hashAlgorithm.hash(innerInput);

  // Outer hash
  final outerPadding = Uint8List(blockLength);
  _preparePadding(outerPadding, hmacKey, 0x5c);
  final outerInput = Uint8List(outerPadding.length + innerHash.bytes.length);
  outerInput.setAll(0, outerPadding);
  outerInput.setAll(outerPadding.length, innerHash.bytes);
  final outerHash = await hashAlgorithm.hash(outerInput);

  return Mac(outerHash.bytes);
}