deriveKey method
Generates a new secret key from a secret key and a nonce.
Implementation
@override
Future<SecretKey> deriveKey({
required SecretKey secretKey,
List<int> nonce = const <int>[],
List<int> info = const <int>[],
}) async {
// Calculate a pseudorandom key
final secretKeyBytes = await secretKey.extractBytes();
final nonceAsSecretKey = SecretKey(nonce);
final prkMac = await hmac.calculateMac(
secretKeyBytes,
secretKey: nonceAsSecretKey,
nonce: nonce,
);
final prk = SecretKey(prkMac.bytes);
// T(0)
var bytes = const <int>[];
// T(1), T(2), ...
final hashLength = hmac.hashAlgorithm.hashLengthInBytes;
final n = outputLength ~/ hashLength;
final result = Uint8List(outputLength);
for (var i = 0; i <= n; i++) {
final sink = await hmac.newMacSink(secretKey: prk);
sink.add(bytes);
if (info.isNotEmpty) {
sink.add(info);
}
final added = <int>[0xFF & (1 + i)];
sink.add(added);
sink.close();
final mac = await sink.mac();
bytes = mac.bytes;
final offset = i * hashLength;
if (offset + bytes.length <= result.length) {
result.setAll(offset, bytes);
} else {
result.setAll(offset, bytes.take(result.length - offset));
}
}
return SecretKey(result);
}