newMacSink method
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);
}