u/JimmeJJ

Critique of a hybrid identity scheme: Ed25519 today + truncated commitment to Falcon/Dilithium for post-quantum migration

Critique of a hybrid identity scheme: Ed25519 today + truncated commitment to Falcon/Dilithium for post-quantum migration

I'm designing the identity scheme for hashiverse, an open-source peer-to-peer twitter/x replacement that I want to remain robust against a future quantum adversary, without paying the size cost of shipping full PQ public keys today. I'd appreciate a teardown to find flaws before I'm stuck with it in deployed code.

The scheme

At identity creation, the user generates three keypairs locally (based on a long keyphrase or some other locally generated entropy):

  • Ed25519 (classical signing).
  • ML-DSA-44 (Dilithium, FIPS 204).
  • Falcon-512 (FN-DSA, FIPS 205).

The public identity, called ClientId, is:

ClientId = {
    verification_key:  <Ed25519 public key, 32 bytes>
    pq_commitment:     <16 bytes Blake3(Falcon512_pubkey)[..16]
                        || 16 bytes Blake3(MLDSA44_pubkey)[..16]>
    id:                Blake3(verification_key || pq_commitment)
}

Public identity material is 64 bytes (verification_key + pq_commitment), plus a 32-byte derived id used for routing.

The full PQ public keys (~897 B Falcon-512, ~1312 B ML-DSA-44) are NOT shipped or published today. The user holds them privately. Today, every signed artefact in the network is signed with Ed25519 only; the PQ private keys sit unused.

The future-proofing claim

If Ed25519 becomes practically forgeable (e.g. a CRQC capable of solving discrete log on Curve25519), the network performs a coordinated migration:

  1. Each user reveals their Falcon-512 public key.
  2. Verifiers check the revealed key against the user's 16-byte Falcon commitment.
  3. Subsequent signatures must be Falcon-512.
  4. If Falcon is also subsequently broken (e.g. a structural attack on NTRU lattices), fall through to ML-DSA, verified against the user's own committed 16 bytes.

Cost today: 32 bytes per identity for the commitment, versus ~2,200 bytes for shipping both PQ public keys directly.

Specific concerns I'd appreciate critique on

  1. Truncated commitment security. Each PQ public key is committed via the first 16 bytes (128 bits) of Blake3. Classical pre-image security is ~2^(128,) which I read as acceptable. Under Grover it drops to ~2^(64,) which feels uncomfortably close to feasible by the time a CRQC actually exists. Is 16 bytes enough, or should I expand to 32 bytes per algorithm?
  2. Multi-target attack scaling. With N visible identities, a quantum attacker willing to forge any one of them (rather than a specific target) needs roughly 2^(64) / sqrt(N) work under Grover for a pre-image. For N around 2^(20,) that's around 2^(54) work. At what scale does this stop being theoretical?
  3. Transition window vulnerability. Between the day a CRQC becomes practical and the day the network completes migration to PQ verification, all existing Ed25519-secured identities are forgeable. There's no automatic switchover; some governance step has to happen. Are there cleaner designs that let verification be "the latest still-unbroken algorithm in the committed set" without requiring a coordinated fork?
  4. Independence of the two PQ commitments. Falcon and Dilithium are committed independently. If only Falcon is broken (e.g. as a function of its specific lattice structure), I want verification to fall back to Dilithium. Is this fall-back-to-the-next-algo pattern sound, or does the independence of commitments hide a subtlety I'm missing?
  5. Identity immutability. Once created, the ClientId is permanent. No rotation, no algorithm swap, no cross-signed succession. A "please follow me on my new identity" social protocol is documented as future work but not built. If a user's Ed25519 private key is compromised today (pre-quantum), they have no in-protocol recovery and must abandon the identity. Is permanent identity defensible as a design choice, or is this a fundamental design wart?
  6. Pre-release primitive. I'm using the ml-dsa Rust crate at version 0.1.0-rc.7. The crate authors note that generated keys may change before v1.0. Any identities I let users create now risk invalidating their Dilithium commitment when the crate stabilises. Practical concern, or am I overthinking the lifecycle?

I'd value any teardowns. The scheme isn't deployed at scale yet, so a critical flaw caught now is still cheap to fix.

Code: https://github.com/hashiverse/hashiverse, specifically hashiverse-rust/hashiverse-lib/src/tools/keys_post_quantum.rs and client_id.rs.

u/JimmeJJ — 2 days ago