deriveKeyBytes static method
Derives a key using scrypt with custom parameters
password - The password to derive the key from
salt - The salt to use for key derivation
N - CPU/memory cost parameter (must be power of 2, >= 2)
r - Block size parameter (typically 8)
p - Parallelization parameter (typically 1)
dkLen - Length of derived key in bytes
Returns a Future
Implementation
static Future<Uint8List> deriveKeyBytes(
String password,
String salt, {
int N = _defaultN,
int r = _defaultR,
int p = _defaultP,
int dkLen = _defaultDkLen,
}) async {
// Validate parameters
if (N < 2 || (N & (N - 1)) != 0) {
throw ArgumentError('N must be a power of 2 and >= 2');
}
if (r < 1) throw ArgumentError('r must be >= 1');
if (p < 1) throw ArgumentError('p must be >= 1');
if (dkLen < 1) throw ArgumentError('dkLen must be >= 1');
// Convert password and salt to bytes
final pwd = Uint8List.fromList(password.codeUnits);
final saltBytes = Uint8List.fromList(salt.codeUnits);
// Step 1: Generate B = PBKDF2(password, salt, 1, p * 128 * r)
final B = await _pbkdf2(pwd, saltBytes, 1, p * 128 * r);
// Step 2: Generate B' = ROMix(B, N)
final bPrime = await _romix(B, N, r);
// Step 3: Generate DK = PBKDF2(password, salt + B', 1, dkLen)
// CRITICAL FIX: Use original salt combined with bPrime for final derivation
final finalSalt = Uint8List.fromList([...saltBytes, ...bPrime]);
final dK = await _pbkdf2(pwd, finalSalt, 1, dkLen);
return dK;
}