VeilNet

Post-Quantum Cryptography

Every connection between anchors uses post-quantum cryptography, and every payload is encrypted a second time, end to end.

Cipher Suites

Anchors use ML-DSA for signatures and ML-KEM for key exchange, both post-quantum algorithms. A cipher suite fixes the strength of each. Each tree uses one suite, and every key in the tree uses it:

SuiteSignaturesKey encapsulationEncryptionTLS key exchangeNIST category
0x01, the defaultML-DSA-87ML-KEM-1024AES-256-GCMSecP384r1MLKEM10245
0x02ML-DSA-65ML-KEM-768AES-256-GCMX25519MLKEM7683

The suite is chosen once, when the root of the tree is created. Every sub-realm and every anchor in the tree uses the same suite, and an anchor refuses a peer in another suite.

The default is NIST category 5, the highest level, because an identity cannot be reissued. The cost is size: category 5 keys, signatures and certificates are larger than at category 3.

Post-Quantum Coverage

Every security property of a connection is post-quantum, except the TLS certificate's own signature:

PropertyAlgorithmPost-quantum
IdentityAn AnchorID is a hash of an ML-DSA public key. Claiming one means breaking ML-DSAYes
Confidentiality, including of traffic recorded todayTLS 1.3 with a hybrid ML-KEM key exchange, and a second, end-to-end layer with ML-KEM and AES-256-GCMYes
AuthenticationML-DSA signatures bind the identity to the TLS certificate and to the sessionYes
The TLS certificate's own signatureEd25519, on a key made for one connection. It only proves possession of that key during the handshakeNo

The certificate key is classical by choice. It is made for one connection and discarded afterwards, and no security property rests on it alone. An attacker who could forge Ed25519 signatures still could not produce the ML-DSA signatures that bind the identity to the session.

Fig. 01 — What the identity rests on
IDENTITY KEY · ML-DSA-87the anchor itselfSIGNS THE CERTIFICATE KEY'S HASHCERTIFICATE KEY · ED25519short-lived, never storedCERTIFICATEVERIFY · CLASSICALML-DSA PROOF, AFTEROVER THE EXPORTER,CHAIN AND TAINTSTHIS CONNECTIONusable once both proofs verify

Ed25519 only proves possession of the certificate key inside one handshake. The identity depends on the two ML-DSA links: the signature that binds the certificate key, and the proof over this session's TLS exporter.

The TLS handshake offers only the hybrid ML-KEM key exchange, so post-quantum key exchange is required, not just preferred. This protects against harvest-now-decrypt-later attacks, in which traffic recorded today is decrypted later. A peer that cannot use it fails the handshake.

Encryption Layers

Traffic is encrypted twice. Each hop between two anchors is encrypted, and the whole route is also encrypted end to end, as a separate layer:

LayerBetweenKey exchangeCipher
Hop by hopEach pair of anchors on the route, relays includedTLS 1.3 over QUIC, with the hybrid ML-KEM key exchangeAES-GCM or ChaCha20-Poly1305, as the two ends agree
End to endThe two endpoints onlyML-KEM-1024AES-256-GCM, always
Fig. 02 — Two layers, sealed separately
END TO END · ML-KEM-1024 + AES-256-GCM · ONE SEAL, A TO BHOP 1 · TLS 1.3HOP 2 · TLS 1.3HOP 3 · TLS 1.3ARELAYHOP KEYS ONLYRELAYHOP KEYS ONLYBEACH HOP: QUIC, TLS 1.3, HYBRID ML-KEM KEY EXCHANGE · OPENED AND SEALED AGAIN AT EACH ANCHOR
Swipe to see the full chart

Each hop's encryption ends at the next anchor, relays included. The end-to-end seal does not: A seals each frame for B, and only B can open it. A relay holds the keys for its own hops, but nothing that opens the frame.

  • A relay cannot read the traffic. The end-to-end layer stays intact across every hop, so a relay never holds a key that opens it.
  • A relay cannot see the route. Each relay learns only the next hop, and nothing about where the traffic started.
  • A relay cannot get genuine traffic refused by sending forged frames. The receiver checks each frame before it records it as seen.

Key Lifetimes

Each kind of key has its own lifetime:

KeyLifetimeWhat it means for you
Identity, ML-DSANever rotatedA new key is a new anchor
Key exchange, ML-KEMReplaced every ten minutesForward secrecy for each ten-minute period. A stolen current key exposes only the sessions opened in that period
TLS certificate, Ed25519Made for a connection and never storedNothing to manage
Connection tagRotates every hourClocks may differ by up to an hour. Two hours of difference always fails
TLS sessionsNever resumedEvery connection proves its certificate key again

Checking the Key Exchange

Each new connection is logged with the key exchange it used. To confirm post-quantum key exchange on a machine you run, read it from that log line.

You cannot confirm it by probing an anchor from outside, because an anchor does not answer strangers.

0 of 2 done
  1. Linux
    $ sudo journalctl -u conflux --no-pager | grep "a peer connected"
    … msg="a peer connected" peer=i46dpakhug direction=outbound group=SecP384r1MLKEM1024
    macOS and FreeBSD
    $ grep "a peer connected" /var/log/conflux.log
    Windows, PowerShell as Administrator
    > Select-String -Path "C:\ProgramData\conflux\logs\conflux.log" -Pattern "a peer connected"

AES Hardware Acceleration

The end-to-end layer always uses AES-256-GCM. It runs fastest on processors that accelerate it: AES-NI with PCLMULQDQ on amd64, or the AES and PMULL extensions on arm64. Every 64-bit ARM application processor since about 2014 has these extensions.

To check a Linux machine, run:

$ grep -m1 -o -w -e aes -e pclmulqdq -e pmull /proc/cpuinfo

On amd64, the output should include both aes and pclmulqdq. On arm64, it should include aes and pmull. A virtual machine can hide a flag that its host has, so run the check inside the guest.