initialize static method

OtpCryptoConfig initialize({
  1. required Uint8List masterKey,
  2. Uint8List? salt,
  3. Uint8List? info,
  4. int protocolVersion = 1,
  5. int windowSeconds = 30,
  6. int verificationSkewWindows = 0,
  7. TimeProvider? timeProvider,
  8. bool forceReinitialize = false,
})

Initializes the global configuration (one-time).

  • masterKey: ≥ 32 bytes shared secret (IKM for HKDF).
  • salt: optional HKDF salt (recommend random, app-wide constant).
  • info: optional HKDF info/context string (protocol-binding).
  • protocolVersion: wire-level version. Current: 1
  • windowSeconds: time window size (default 30).
  • verificationSkewWindows: how many adjacent windows to accept during verification (e.g., 1 means try w-1, w, w+1).
  • timeProvider: custom time provider; if null uses a default.

SECURITY:

  • Use forceReinitialize only for tests or controlled rotation flows.

Implementation

static OtpCryptoConfig initialize({
  required Uint8List masterKey,
  Uint8List? salt,
  Uint8List? info,
  int protocolVersion = 1,
  int windowSeconds = 30,
  int verificationSkewWindows = 0,
  TimeProvider? timeProvider,
  bool forceReinitialize = false,
}) {
  if (_instance != null && !forceReinitialize) {
    throw StateError('OtpCryptoConfig is already initialized. Set forceReinitialize=true to replace (use with caution).');
  }
  if (masterKey.length < 32) {
    throw ArgumentError.value(masterKey.length, 'masterKey.length', 'Must be at least 32 bytes.');
  }
  if (windowSeconds <= 0) {
    throw ArgumentError.value(windowSeconds, 'windowSeconds', 'Must be a positive integer.');
  }
  if (verificationSkewWindows < 0 || verificationSkewWindows > 2) {
    // keeping this small avoids costly re-MAC attempts; tune as needed
    throw ArgumentError.value(verificationSkewWindows, 'verificationSkewWindows', 'Must be between 0 and 2.');
  }

  final cfg = OtpCryptoConfig._(
    protocolVersion: protocolVersion,
    windowSeconds: windowSeconds,
    verificationSkewWindows: verificationSkewWindows,
    masterKey: _copy(masterKey),
    hkdfSalt: salt != null ? _copy(salt) : null,
    hkdfInfo: info != null ? _copy(info) : null,
    timeProvider: timeProvider ?? _DefaultSystemTimeProvider(),
  );
  _instance = cfg;
  return cfg;
}