createChallenge method
Creates an authentication challenge to send to the user.
This is the first step in the SRP authentication flow. The server generates an ephemeral key pair and creates a challenge containing the public key, salt, and SRP parameters.
Parameters:
ephemeralServerPrivateKeyBytes
: Optional custom ephemeral private key. If not provided, a random key of optimal length is generated automatically.
Returns: Challenge object containing the server's ephemeral public key (B), salt, generator, safe prime, and hash function choice. Send this to the user to begin authentication.
Security note: The ephemeral private key is stored internally and used later during session key derivation. It is automatically erased after use.
Implementation
Future<Challenge> createChallenge({Uint8List? ephemeralServerPrivateKeyBytes}) async {
ephemeralServerPrivateKeyBytes ??= generateRandomBytes(
deriveOptimalByteLengthForEphemeralKeys(safePrime.bitLength)
);
_ephemeralServerPrivateKey = ephemeralServerPrivateKeyBytes.toBigInt();
// k = H(N,g)
final multiplierParameter = (await _hashRfc5054(
[safePrime.toByteList(), generator.toByteList()]
)).toBigInt();
// B = kv + g^b
final ephemeralServerPublicKeyInt = (multiplierParameter * _verifierKey + generator.modPow(_ephemeralServerPrivateKey!, safePrime)) % safePrime;
_ephemeralServerPublicKey = ephemeralServerPublicKeyInt.toByteList();
final customHashFunction = hashFunctionChoice != null ? null : _hashFunction;
return Challenge.fromServer(
generator: generator,
safePrime: safePrime,
ephemeralServerPublicKey: Uint8List.fromList(_ephemeralServerPublicKey!),
verifierKeySalt: Uint8List.fromList(_salt),
hashFunctionChoice: hashFunctionChoice,
customHashFunction: customHashFunction,
);
}