deriveKeyBytes static method

Future<Uint8List> deriveKeyBytes(
  1. String password,
  2. String salt, {
  3. int N = _defaultN,
  4. int r = _defaultR,
  5. int p = _defaultP,
  6. int dkLen = _defaultDkLen,
})

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;
}