Hybrid post-quantum crypto
Every Ratify signature is a pair: one Ed25519, one ML-DSA-65. Both must verify. This page explains why, what each algorithm is doing, and what threats this defends against.
HybridSignature ─────────────── │ ┌────────┼────────┐ ▼ ▼ ┌─────────────┐ ┌──────────────────┐ │ Ed25519 │ │ ML-DSA-65 │ │ signature │ │ signature │ │ │ │ │ │ RFC 8032 │ │ NIST FIPS 204 │ │ Elliptic │ │ Lattice-based │ │ curve │ │ Module-LWE │ │ │ │ │ │ 64 bytes │ │ ~3309 bytes │ │ fast │ │ ~10x slower │ │ │ │ ~50x larger │ └─────────────┘ └──────────────────┘ │ │ └─────── BOTH ────┘ must verifyThe signing function
Section titled “The signing function”sign_bytes = canonical_json(object, omit: ["signature"])
signature.ed25519 = Ed25519.Sign(sign_bytes, private_key.ed25519)signature.ml_dsa_65 = ML-DSA-65.Sign(sign_bytes, private_key.ml_dsa_65)Both signatures are over the same canonical bytes. The two component keys are unrelated — they share no math, no curve, no seed. The hybrid keypair is the cartesian product of two independent keypairs.
The verifier function
Section titled “The verifier function”Valid(σ, msg, pub) := Ed25519.Verify(msg, σ.ed25519, pub.ed25519) ∧ ML-DSA-65.Verify(msg, σ.ml_dsa_65, pub.ml_dsa_65)Logical AND. Failure in either means the whole signature is rejected. This is the structural property — the hybrid defends against algorithm failure in either component because failure in one cannot mask the other.
Threat model
Section titled “Threat model” Today Post-quantum future ───── ───────────────────
Forge a sig with quantum computer no key access? ✗ Practically ✗ ML-DSA-65 has no infeasible known quantum attack; shorter Ed25519 is broken but doesn't help — the ML-DSA-65 sig still fails
Recover priv key quantum computer from sig alone? ✗ Practically ✗ Same — ML-DSA-65 is infeasible conjectured Q-secure
Forge old archived quantum computer sigs (HND attack)? — N/A ✗ ML-DSA-65 holds. Ed25519 alone would be retroactively forgeable; hybrid mode prevents this.
Algorithm flaw Both algorithms used ↓ discovered in in production with Even if a flaw appears in one of them? decade+ of crypt- ML-DSA-65 (newer, less analysis (Ed25519) battle-tested), Ed25519 and FIPS standard- still verifies. ization (ML-DSA-65, FIPS 204 final August 2024).The structural argument: as long as at least one of (Ed25519, ML-DSA-65) is secure, the hybrid signature is secure. You need both to be broken to forge a bundle. That’s the defense in depth.
”Harvest now, decrypt later” (HND)
Section titled “”Harvest now, decrypt later” (HND)”The specific attack the hybrid mode is designed to prevent:
- An adversary records every Ratify proof bundle that crosses the public internet today, in 2026. They store these archives at low cost.
- Years later, a cryptographically-relevant quantum computer (CRQC) becomes available to the adversary.
- The CRQC can attack Ed25519 (via Shor’s algorithm on the elliptic curve discrete log problem). The adversary can now compute the Ed25519 private key from any 2026 public key they recorded.
- With a forged Ed25519 private key, they can produce Ed25519 signatures over arbitrary 2026-dated payloads. In a non-hybrid system, this means they could retroactively claim any agent was authorized to do anything in 2026.
The hybrid defense: even with the Ed25519 private key, the adversary cannot produce a valid hybrid signature because they don’t have the ML-DSA-65 private key. ML-DSA-65 is lattice-based (Module-LWE) and has no known quantum attack. The forged Ed25519 component verifies in isolation, but the verifier requires both — so the forgery is rejected.
Why specifically Ed25519 + ML-DSA-65?
Section titled “Why specifically Ed25519 + ML-DSA-65?”| Choice | Why |
|---|---|
| Ed25519 (not RSA, not ECDSA) | Faster, smaller signatures, no nonce-reuse pitfall, widely deployed, mature libraries everywhere, RFC 8032 standardized |
| ML-DSA-65 (not Falcon, not Dilithium) | ML-DSA-65 is the FIPS 204 standardized form of Dilithium-3, finalized Aug 2024. Wider tooling support than Falcon. Conservative security level (≈ AES-192). |
| Hybrid pair (not pure PQC) | PQC algorithms are new. ML-DSA-65 has years of cryptanalysis but less than Ed25519. Hybrid mode means a flaw in ML-DSA-65 doesn’t sink us. |
This combination is what CNSA 2.0 (US NSA’s commercial cryptography guidance) and BSI (German federal cyber agency) both recommend for the post-quantum transition period.
Size tradeoff
Section titled “Size tradeoff”Hybrid signatures are larger:
Ed25519 only: 64 bytes per signature ML-DSA-65 only: 3309 bytes per signature Hybrid: 3373 bytes per signature (~50× larger than Ed25519 alone)For a ProofBundle with one delegation, the wire size is roughly:
Cert metadata + scopes + IDs: ~400 bytes (varies by scope count) Issuer public key (hybrid): ~2000 bytes Subject public key (hybrid): ~2000 bytes Delegation signature (hybrid): ~3400 bytes Challenge + challenge_sig: ~3500 bytes
Total wire size: ~11–12 KB per bundleFor a sub-delegated chain at depth 3: ~25–30 KB. The bundles are bigger than OAuth bearer tokens (sub-1KB) but fit easily inside any HTTP request and are negligible compared to a video frame, an LLM completion, or a meeting handshake.
Performance tradeoff
Section titled “Performance tradeoff” Operation Ed25519 ML-DSA-65 Hybrid ───────────────────── ─────── ───────── ─────── Keygen ~50 μs ~120 μs ~170 μs Sign ~50 μs ~400 μs ~450 μs Verify ~150 μs ~250 μs ~400 μs(Measured on a modern x86 CPU. Embedded targets are slower; ML-DSA-65 in particular benefits a lot from vectorization.)
Verification is the hot path in real workloads. Roughly 400 μs per bundle, which means a single CPU core can process ~2500 bundles per second. For Verify’s edge verifier (Cloud Run / edge worker) this is well below saturation.
Source
Section titled “Source”The exact algorithms, key encodings, and signature encodings are normative: SPEC.md §5. Every SDK uses an audited implementation of each primitive:
- Go:
crypto/ed25519(standard library) +pqcrypto/mldsa(Cloudflare CIRCL) - TypeScript:
@noble/ed25519+@noble/post-quantum - Python:
cryptography(PyCA) +pqcrypto - Rust:
ed25519-dalek+pqcrypto-mldsa
Where to next
Section titled “Where to next”- Key custody — where the hybrid private key actually lives
- Conformance suite — how byte-identical hybrid signatures are verified across SDKs
- Delegate, Present, Verify — how the hybrid signature fits into the protocol