Browse docs · Security
Get started
Concepts
Guides
Security
Reference
Docs / Security
Cryptography
Every algorithm PastKeys uses, what it protects, and which parts are post-quantum. Credentials are sealed with hybrid X25519 + ML-KEM-768.
PastKeys seals every credential with post-quantum hybrid encryption. This page lists every algorithm we use, what it protects, and which parts are post-quantum today.
Why post-quantum now
A sealed credential is long-lived ciphertext that the control plane stores. That makes it a target for harvest now, decrypt later: copy the blob today, then decrypt it once a large quantum computer exists. Key exchange with X25519 alone would fall to that attack, and for a product whose promise is "we can't read your secrets," a delayed break of every stored credential is the worst case.
So the key exchange is a hybrid of X25519 and ML-KEM-768, the NIST post-quantum standard (FIPS 203). Both shared secrets feed the key derivation, so a blob stays sealed unless both algorithms are broken. That covers a quantum break of X25519 and any undiscovered flaw in the newer ML-KEM. NIST and the IETF recommend this hybrid approach for the transition period.
How a credential is sealed
- You run
broker sealon a trusted machine, or the broker seals it. Either way it uses the broker's hybrid public key. - A fresh X25519 key pair is made for this one seal, and an ML-KEM-768 encapsulation produces a second shared secret.
- HKDF-SHA256 combines both secrets. Its salt binds the whole transcript: the ephemeral key, the ML-KEM ciphertext, and the broker's identity.
- AES-256-GCM encrypts the token. The transcript is also bound as additional data, so a blob can't be re-pointed at another broker.
- Only the broker's private key opens it. A wrong key or any tampering returns an error, never plaintext.
The exact wire format is in the whitepaper.
Every algorithm we use
| Protects | Algorithm | Quantum status |
|---|---|---|
| Credential key exchange | X25519 + ML-KEM-768 (FIPS 203) | Post-quantum |
| Credential encryption | AES-256-GCM | Quantum-resistant (256-bit key) |
| Key derivation | HKDF-SHA256 | Quantum-resistant |
| Broker TLS (when the broker serves TLS) | TLS 1.3 with X25519MLKEM768 key exchange, Go's default | Post-quantum with clients that support it |
| Audit log integrity | SHA-256 hash chain | Quantum-resistant |
| Audit log signatures | Ed25519, optional | Classical. Moving to ML-DSA (FIPS 204) once it is in the Go standard library |
| Agent identity tokens | RS256/384/512, PS256, ES256/384, chosen by your identity provider | Classical. Tokens are short-lived and single use |
| Password storage | Argon2id (64 MiB, t=3, p=2) | Memory-hard, quantum-resistant |
| Stored API and broker tokens | SHA-256 hash, constant-time comparison | Quantum-resistant |
Why some parts are still classical
Harvest now, decrypt later threatens encrypted data that is stored. Signatures and identity tokens face a different risk: forging one needs a quantum computer at the moment it is checked, and identity tokens expire in minutes. So encryption is where post-quantum protection matters first, and that is where it ships today. Audit signatures move to ML-DSA once it lands in the Go standard library, and identity-token algorithms follow your identity provider.
Implementation
- Go standard library only:
crypto/mlkem,crypto/ecdh,crypto/hkdf,crypto/cipher, plus Argon2id fromgolang.org/x/crypto. No custom algorithms. - Secrets and tokens are compared in constant time.
- Every check fails closed. A parse error, a wrong key, or a bad signature means deny.
- Credentials sealed in the original X25519-only format still open, so rotating to a hybrid key never strands a credential.
See the zero-access model for who can see what.