Skip to content

Cryptographic Details

Jack Lund edited this page Mar 20, 2024 · 4 revisions

Voynich generates session keys via ECDH, which are then authenticated using the secret key of the onion service. More specifically, when Alice connects to Bob's onion service using Voynich:

  • Key Exchange:

    • Alice and Bob each create an ephemeral public/private x25519 key pair
    • Alice sends her ephemeral public key to Bob; Bob sends his to Alice
    • Both generate a shared secret based on their ephemeral private key and the other's public key
    • A shared symmetric key is generated from the shared secret by both using an HKDF to expand the secret
    • Following this, all messages exchanged are serialized to binary, the serialized data is expanded to a full block size with random data, and the resulting blocks are encrypted using the shared key before being sent.
  • Authentication:

    • Before chat messages are exchanged, both users authenticate. A session hash is generated by hashing the concatenation of:
      • Alice's onion service ID
      • Bob's onion service ID
      • Alice's onion service public key
      • Bob's onion service public key
      • The shared secret
    • Alice and Bob then append each of their service IDs to that hash, and sign the result using their onion service private key, and exchange their service IDs and the signature
    • They each then go about validating the signature using the public key of the other

Once the validation is successful, they start their session, encrypting each packet as above.

Note that a given symmetric key is never reused in a different session. Key rotation during a session could also be accomplished by redoing the key exchange at various times during the session. Encryption is done using ChaCha20Poly1305 with AEAD, so messages are authenticated as well.

Clone this wiki locally