calculateMac method
Future<Mac>
calculateMac(
- List<
int> bytes, { - required SecretKey secretKey,
- List<
int> nonce = const <int>[], - 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 {
final secretKeyForPoly1305 = await _poly1305SecretKeyFromChacha20(
secretKey: secretKey,
nonce: nonce,
);
final sink = await _poly1305.newMacSink(
secretKey: secretKeyForPoly1305,
);
var length = 0;
late ByteData tmpByteData;
late Uint8List tmpUint8List;
if (_useStaticBuffer) {
tmpByteData = _tmpByteData;
tmpUint8List = _tmpUint8List;
} else {
tmpByteData = ByteData(16);
tmpUint8List = Uint8List.view(tmpByteData.buffer);
}
tmpByteData.setUint32(0, 0);
tmpByteData.setUint32(4, 0);
tmpByteData.setUint32(8, 0);
tmpByteData.setUint32(12, 0);
// Add Additional Authenticated Data (AAD)
final aadLength = aad.length;
if (aadLength != 0) {
sink.add(aad);
length += aad.length;
final rem = length % 16;
if (rem != 0) {
// Add padding
final paddingLength = 16 - rem;
sink.add(tmpUint8List.sublist(0, paddingLength));
length += paddingLength;
}
}
// Add cipherText
sink.add(bytes);
length += bytes.length;
final rem = length % 16;
if (rem != 0) {
// Add padding
final paddingLength = 16 - rem;
sink.add(tmpUint8List.sublist(0, paddingLength));
length += paddingLength;
}
// Add 16-byte footer.
// We can't use setUint64() because it's not supported in the browsers.
tmpByteData.setUint32(
0,
uint32mask & aadLength,
Endian.little,
);
tmpByteData.setUint32(
4,
aadLength ~/ (uint32mask + 1),
Endian.little,
);
tmpByteData.setUint32(
8,
uint32mask & bytes.length,
Endian.little,
);
tmpByteData.setUint32(
12,
bytes.length ~/ (uint32mask + 1),
Endian.little,
);
sink.add(tmpUint8List);
// Reset the static buffer.
tmpByteData.setUint32(0, 0);
tmpByteData.setUint32(4, 0);
tmpByteData.setUint32(8, 0);
tmpByteData.setUint32(12, 0);
// Return MAC
sink.close();
return sink.mac();
}