Skip to content

Conversation

@lucasqueiroz23
Copy link

@lucasqueiroz23 lucasqueiroz23 commented Oct 29, 2025

This implements mlkem768x25519-sha256 according to the following draft: https://datatracker.ietf.org/doc/html/draft-ietf-sshm-mlkem-hybrid-kex-03.html#name-mlkem768x25519-sha256

This is a Post-Quantum/Traditional hybrid key exchange algorithm. Basically, this means that we use both a traditional key exchange mechanism and a post-quantum one to generate a shared secret.

Post-Quantum algorithms are those that should not break in face of a quantum computer attack. This one is hybrid because even if mlkem proves to break from a traditional computer attack, curve25519 will serve as a fallback.

Also, OpenSSH v10.0+ uses this same algorithm as default (https://www.openssh.org/pq.html).

This implementation is limited to node 24.7.0+, because that's when node got mlkem support on its crypto API.

Relevant document:
https://nvlpubs.nist.gov/nistpubs/fips/nist.fips.203.pdf

@mscdex
Copy link
Owner

mscdex commented Oct 29, 2025

All of the unrelated (code style) changes need to be reverted. Additionally for the new changes, make sure it at least passes the linting (npm run lint).

@mscdex
Copy link
Owner

mscdex commented Oct 29, 2025

We also need at least one test that connects the client and server using the new algorithm to at least make sure that works.

Unfortunately OpenSSH 9.6 is currently the latest version on Gitub Actions' ubuntu-latest, so there is no way to test with the OpenSSH client in CI.

@lucasqueiroz23
Copy link
Author

All of the unrelated (code style) changes need to be reverted. Additionally for the new changes, make sure it at least passes the linting (npm run lint).

Done! Didn't notice that, my text editor made these changes automatically.

We also need at least one test that connects the client and server using the new algorithm to at least make sure that works.

Unfortunately OpenSSH 9.6 is currently the latest version on Gitub Actions' ubuntu-latest, so there is no way to test with the OpenSSH client in CI.

Ok, I'll be working on it tomorrow.

@lucasqueiroz23
Copy link
Author

@mscdex In order to test with OpenSSH, I created a branch on my fork (https://github.com/lucasqueiroz23/ssh2/tree/mlkem-tests) that creates two docker containers: one that'll run an OpenSSH10.1 server and another that'll run some scripts that use ssh2.js client and server implementations. Since I won't open a PR for that branch, I updated its README to describe its usage. I dockerized it so you could easily test it as well, if you want to.

Basically, we'll have a script that'll run a ssh2.js client (which accepts mlkem as kex) that connects to the openssh10.1 server, another that runs a ssh2.js server (that accepts mlkem as kex) and connects an openssh10.1 client to it and an ssh2.js server and a client that will both accept mlkem and connect to each other.

It took some time, but I think it was worth it.

Here's the output:
image

If I add the debug feature on each test, we can see that the handshake works fine for each of them:

image image image

I also added some integration tests on test/test-misc-client-server.js. I think the most interesting one checks if client and server computed the same K_PQ and K_CL values.

@lucasqueiroz23
Copy link
Author

@mscdex Suggestions applied!

@lucasqueiroz23 lucasqueiroz23 requested a review from mscdex October 30, 2025 15:41
@lucasqueiroz23 lucasqueiroz23 requested a review from mscdex October 30, 2025 18:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants