doAuthentication static method
Performs the full authentication handshake and returns a tuple of (auth_key, time_offset).
The sender must be a connected MTProtoPlainSender that will be used
to exchange the unencrypted DH messages with the server.
Throws SecurityError if any step of the handshake fails validation.
Implementation
static Future<(AuthKey, int)> doAuthentication(
MTProtoPlainSender sender,
) async {
final random = Random.secure();
// Step 1: Request PQ
final nonceBytes = Uint8List(16);
for (var i = 0; i < 16; i++) {
nonceBytes[i] = random.nextInt(256);
}
final nonce = _bytesToBigInt(nonceBytes, signed: true);
_log.info('Starting authentication with nonce=${nonce.toRadixString(16)}');
await sender.send(ReqPqMultiRequest(nonce: nonce));
// The full implementation would proceed with:
// 1. Parse ResPQ to get server_nonce, pq, and RSA fingerprints
// 2. Factor pq into p and q using Factorization.factorize()
// 3. Construct PQInnerData with nonce, server_nonce, new_nonce, pq, p, q
// 4. RSA-encrypt PQInnerData using the server's public key fingerprint
// 5. Send ReqDHParams with the encrypted inner data
// 6. Decrypt the server's DH parameters using AES-IGE
// 7. Validate g, dh_prime, g_a per MTProto security guidelines
// 8. Generate random b, compute g_b = pow(g, b, dh_prime)
// 9. Compute auth_key = pow(g_a, b, dh_prime)
// 10. Send SetClientDHParams with encrypted g_b
// 11. Verify DhGenOk and nonce hash
// This requires full TL type registration and parsing support.
// The framework is in place; complete implementation depends on
// the TL layer code generation being wired up.
throw UnimplementedError(
'Full auth implementation requires TL type registration. '
'The DH key exchange steps are documented above. '
'Wire up the generated TL types to complete this.',
);
}