Hi, I’m working on a PQC key establishment and authentication protocol. Currently it works like this:

  1. Client and server each generate ECDSA and Dilithium identity keys and share them between each other, with usb for example.
  2. Client sends to the server single-use ECDH public key, single-use Kyber public key, timestamp, ECDSA and Dilithium signature of everything before it.
  3. Server verifies the message using clients identity keys, generates 2 secrets, one from ECDH and one from Kyber and then it uses blake3 kdf to derive a key from both secrets. Then it sends response with single-use ECDH public key, Kyber ciphertext, timestamp, ECDSA and Dilithium signature of everything before it.
  4. Client verifies the message using servers identity keys, and generates 2 secrets, one from ECDH and one from Kyber ciphertext and then it uses blake3 kdf to derive a key from both secrets.

Kyber: kyber1024 ECDH: secp256k1 ECDSA: secp256k1

I will use the key for XChaCha20-blake3 aead. I don’t know yet how will I generate and keep track of used/unused nonces.

Building this was interesting and fun, but I want more. How can I improve this key exchange, make it more secure, faster, and smaller? Both messages are huge (6268 bytes), because of Kyber and Dilithium.

Any ideas for what application could be this used?

  • @solrize
    link
    18 months ago

    At step 1, you use a secure wired connection. In that case why not just set up a shared secret key? Drop the fancy PQ and PK stuff altogether and use something like DUKPT if you want forward secrecy.