wrap static method
Future<K4LocalPw>
wrap(
- K4LocalKey key,
- String password, {
- int memoryCost = defaultMemoryCost,
- int timeCost = defaultTimeCost,
- int parallelism = defaultParallelism,
Implementation
static Future<K4LocalPw> wrap(
K4LocalKey key,
String password, {
int memoryCost = defaultMemoryCost,
int timeCost = defaultTimeCost,
int parallelism = defaultParallelism,
}) async {
if (key.rawBytes.length != K4LocalKey.keyLength) {
throw ArgumentError(
'Key must be exactly ${K4LocalKey.keyLength} bytes',
);
}
if (memoryCost <= 0 || memoryCost % 1024 != 0) {
throw ArgumentError('memoryCost must be a positive multiple of 1024');
}
if (timeCost <= 0) {
throw ArgumentError('timeCost must be positive');
}
if (parallelism <= 0) {
throw ArgumentError('parallelism must be positive');
}
final random = Random.secure();
final salt = _randomBytes(random, saltLength);
final preKey = await _derivePreKey(
password,
salt,
memoryCost,
timeCost,
parallelism,
);
final encKey = _deriveKeyMaterial(preKey, 0xff);
final authKey = _deriveKeyMaterial(preKey, 0xfe);
final nonce = _randomBytes(random, nonceLength);
final encrypted = _encrypt(encKey, nonce, key.rawBytes);
final tag = _calculateTag(
PaserkKey.k4LocalPwPrefix,
salt,
memoryCost,
timeCost,
parallelism,
nonce,
encrypted,
authKey,
);
final payloadLength =
saltLength + 8 + 4 + 4 + nonceLength + encrypted.length + tagLength;
final payload = Uint8List(payloadLength);
var offset = 0;
payload.setAll(offset, salt);
offset += saltLength;
payload.setAll(offset, _uint64ToBytes(memoryCost));
offset += 8;
payload.setAll(offset, _uint32ToBytes(timeCost));
offset += 4;
payload.setAll(offset, _uint32ToBytes(parallelism));
offset += 4;
payload.setAll(offset, nonce);
offset += nonceLength;
payload.setAll(offset, encrypted);
offset += encrypted.length;
payload.setAll(offset, tag);
return K4LocalPw(payload);
}