Skip to content

SSH

Terminal window
pqdoctor ssh github.com
pqdoctor ssh git.example.com:2222
pqdoctor ssh ssh://git@example.org:7999 --json # the user name is dropped

pqdoctor sends its identification (SSH-2.0-pqdoctor_<version>), reads the server’s identification and its KEXINIT (the algorithms it offers), and hangs up. It never sends a KEXINIT of its own, never does a key exchange, and never logs in.

Method
mlkem768x25519-sha256 ML-KEM hybrid. OpenSSH 9.9 added it, 10.0 made it the default
mlkem768nistp256-sha256 ML-KEM hybrid with P-256
mlkem1024nistp384-sha384 The only one that meets CNSA 2.0
sntrup761x25519-sha512 (+ @openssh.com) Streamlined NTRU Prime hybrid. OpenSSH’s default from 9.0 to 9.9

Kyber drafts and sntrup4591761… count as “draft only”.

pqdoctor ssh github.com · 2026-10-15
✔ ssh github.com:22 (140.82.114.4)
Post-quantum: offers mlkem768x25519-sha256, sntrup761x25519-sha512, sntrup761x25519-sha512@openssh.com
The server offers a hybrid post-quantum key exchange. A client that also has one (OpenSSH 9.0+) uses it.
server: 1f08b963 strict kex: yes
! Not CNSA 2.0: that needs ML-KEM-1024 (mlkem1024nistp384-sha384). X25519 and P-256 hybrids are fine for everyone else.
Offered (server's order)
kex mlkem768x25519-sha256, sntrup761x25519-sha512, sntrup761x25519-sha512@openssh.com, curve25519-sha256, curve25519-sha256@libssh.org, ecdh-sha2-nistp256, ecdh-sha2-nistp384, ecdh-sha2-nistp521, diffie-hellman-group-exchange-sha256
host key ssh-ed25519, ecdsa-sha2-nistp256, rsa-sha2-512, rsa-sha2-256, ssh-rsa
ciphers chacha20-poly1305@openssh.com, aes256-gcm@openssh.com, aes128-gcm@openssh.com, aes256-ctr, aes192-ctr, aes128-ctr
macs hmac-sha2-512-etm@openssh.com, hmac-sha2-256-etm@openssh.com, hmac-sha2-512, hmac-sha2-256
Code Means
ssh-mlkem Offers an ML-KEM hybrid
ssh-sntrup-only Post-quantum, but only sntrup761, not ML-KEM (the NIST standard). OpenSSH 9.9+ offers ML-KEM as well
ssh-draft-only Only draft methods
ssh-kex-config OpenSSH 9.0+ supports a PQ method, but the server’s KexAlgorithms leaves it out
ssh-old-openssh OpenSSH older than 9.0
ssh-no-pq Not OpenSSH, and no PQ method offered
connect-failed Couldn’t connect

OpenSSH 9.0 or newer with PQ left out. pqdoctor prints a KexAlgorithms line with the PQ methods this version has (ML-KEM from 9.9, sntrup761 from 9.0), in front of the methods the server offers now:

Terminal window
# /etc/ssh/sshd_config (or a file in sshd_config.d/)
KexAlgorithms mlkem768x25519-sha256,sntrup761x25519-sha512,sntrup761x25519-sha512@openssh.com,curve25519-sha256,ecdh-sha2-nistp256
# then
sudo sshd -t && sudo systemctl reload ssh # 'sshd' on some systems

Older OpenSSH. Upgrade to OpenSSH 10.0 or later. It offers mlkem768x25519-sha256 first by default, with no config change.

Not OpenSSH. Check its release notes for mlkem768x25519-sha256 or sntrup761x25519-sha512 and enable it. If it has neither, put OpenSSH 10 in front.

With no known host keys, this stops right after the key exchange, before any key is offered:

Terminal window
ssh -vv -o BatchMode=yes -o StrictHostKeyChecking=yes -o UserKnownHostsFile=/dev/null -o GlobalKnownHostsFile=/dev/null github.com 2>&1 | grep -E 'kex: algorithm|KEX algorithms'

On 2026-10-15, github.com and gitlab.com were checked with pqdoctor and with OpenSSH 10.0p2 (ssh -vv). The servers’ offered lists were the same in both, apart from marker names (ext-info-*, kex-strict-*) that pqdoctor leaves out. Both servers negotiated mlkem768x25519-sha256.

Exit status: 0 post-quantum, 1 not, 2 unreachable.

No post-quantum host key (signature) algorithm is standard for SSH yet. pqdoctor flags names from drafts and OQS-OpenSSH that the server offers in its host key list — anything with mldsa, ml-dsa, slh-dsa, sphincs, falcon or dilithium in it — in pqHostKey, marks them “(draft)” on screen, and warns to keep a classical host key too. They don’t change the verdict, which is about the key exchange.