Sharing an approach we’ve been building and would like scrutiny on. It’s aimed at the narrow but real problem of migrating the signature layer of on-chain / agent identity to post-quantum, and it leans on recomputation rather than trust.
The problem. Shor breaks the ECDSA/Schnorr signatures under most of Web3 and most AI-attestation identity. Hashes survive (Grover only halves them). The usual reflex “add a post-quantum signature alongside the classical one” doesn’t actually close it: a forger who derives the classical key just omits the extra signature. A second signature is opt-in from the verifier’s side, and a forger opts out.
The approach. Bind, don’t append. Publish an anchored key-binding this classical key → this post-quantum key before any break, and enforce a consumer cutoff:
-
An action proven anchored before the cutoff admits classical-only (the back catalog is never retroactively invalidated).
-
An action anchored at/after the cutoff must carry a valid PQ companion under the binding in force at that action’s anchor time, else it’s rejected.
The forger’s omission now fails closed: after the cutoff, “no valid companion” is a reject, not a shrug.
Why anchor-time, not signature-time. Authority is judged by an action’s on-chain anchor time, never by when a claimed signature says it was made. A compromised key can backdate a signature; it can’t backdate an on-chain anchor. The trustworthy quantity is the one the operator can’t reshape after the fact.
Why recompute, not trust. Every binding is content-addressed and re-derivable from public data in the browser, the classical proof-of-possession is the anchoring transaction itself (sent by the classical key), so the on-chain record is the proof, not a second signature to forge around. Nothing here asks you to trust a server; you re-run it.
What’s live (two implementations, two NIST families). The profile pq_key_binding.v0 is carried by two independent implementations converging on one byte-compatible content-address through canonicalization alone: ML-DSA-65 (FIPS 204, lattice) and SLH-DSA-SHA2-192s (FIPS 205, hash-based). {algorithm} is a field, not a fork.
The two-family choice is a resilience hedge, not decoration. In 2026, cryptanalysis from Anthropic cut HAWK-256’s estimated key-recovery cost from 2^64 to 2^38; the HAWK submission team then withdrew it from NIST’s additional-signatures process (it had been in that process since the 2023 on-ramp). Refs: Anthropic research · withdrawal stated verbatim on NIST’s round-3 additional-signatures page (“The submission team has withdrawn HAWK…”).
Scope matters, and it’s structural, for two independent reasons the result doesn’t reach the finalized standards. HAWK is a hash-and-sign scheme in the Falcon lineage built on the Lattice Isomorphism Problem, and the n/2+1 reduction runs through that LIP structure specifically; ML-DSA is Fiat-Shamir over MLWE/MSIS a different problem and a different construction. HAWK was a candidate, deployed nowhere; the finalized FIPS standards ML-KEM, ML-DSA, SLH-DSA are untouched. The lesson we build on is structural: pair a finalized standard with a second scheme from a different cryptographic family. A cryptanalytic break that depends specifically on lattice structure does not directly transfer to the hash-based lane. SLH-DSA rests on different security assumptions, so weakening one family need not invalidate the other; the independently anchored recompute record remains available for verification.
Both bindings recompute cold, in-browser, from two different origins; a cutoff enforcer runs the migration rule and reproduces a set of pinned conformance vectors. One honest note on evidence class: the ML-DSA side is two independent verifiers, but the SLH-DSA side is a single implementation (both panels vendor the same @noble/post-quantum), so it’s verified twice by the same code and rather than launder that into a green, an independent reviewer’s standing UNVERIFIABLE verdict keeps it visibly single-impl. Three parties, per-lane independence stated honestly, not four claimed. Per-agent keys are epoch-anchored and sign a companion on every action, with the anchor-time cutoff enforcer currently in shadow, it records the verdict, doesn’t yet reject, until companion coverage is proven.
Recovery, the in-progress next layer (scrutiny welcome). Be explicit about maturity, because the two halves aren’t at the same stage: pq_key_binding.v0 above is live, multi-implementation, and cold-verified; the recovery layer below is a runnable reference model — executable and blind-diffable via conformance vectors, but not yet live-wired. Concretely: the per-agent key rotation and revocation primitives are deployed in our gateway (owner-authorized, anchor-time resolved); the recovery-class taxonomy on top of them, which lets an auditor tell which kind of transition happened, is specified and vectored, with agent_terminal and seed_epoch_rotation pre-implementation. Please don’t read the classes as already shipped.
A key-binding scheme is only survivable past a single incident if an auditor can independently tell what kind of authority transition happened. We specify three anchored classes as falsifiable claims a third party recomputes, each judged only against its declared class, so a record that fails its predicate is rejected, never silently relabeled as a neighbour:
Which key governs an artifact is resolved by the artifact’s anchor time, and the same rule carries rotation and revocation, forward-acting, never retroactive:
The two hardest points, and how we resolved them:
(1) A terminal/kill statement has to forbid future bindings, not merely describe the present absence of one. So terminality is a standing binding-path constraint (fail-closed), split by intent: a deliberate retirement is absolute; a defensive incident-kill is liftable only by a valid fleet seed-rotation, never by a per-agent path, or the compromised key could resurrect itself.
(2) The authority for replacing a compromised root secret can’t reduce to that secret. The fleet seed-rotation is anchored on the classical deployer key, proven by its own transaction (not a separable signature), and deployer-key compromise is stated as explicitly out-of-scope. Same shape as anchor-time-over-signature-time: the authority for undoing something can’t reduce to the thing being undone.
One honest boundary, stated up front. The fleet seed-recovery is the single place this profile is not fully public-recompute: the new keys derive from a secret seed, so a third party can’t re-derive them. The public guarantee is deployer-authorization (the anchor tx is sent by the deployer key) + the anchored Merkle root of the new keys; the derivation itself is operator-attested. This is deliberate, not a gap we haven’t closed, commit-then-reveal doesn’t apply (the seed is a standing secret for every key, so revealing it to prove honesty would leak every private key), leaving exactly two options: operator-attested (v0, here) or a ZK proof of correct derivation that never reveals the seed (v1+). We name it plainly rather than imply the recovery is publicly recomputable when it isn’t.
Links (all recomputable):
-
Live dual-family bindings, recompute in your browser : https://ai.verticecriativo.pt/quantum
-
Cutoff enforcer + selftests (live gateway) : https://gateway.ensub.org/pq/enforce/selftest
-
Conformance vectors (neutral repo) :
pq_key_binding.v0: https://github.com/trustless-ai/recompute-kit/tree/main/conformance/pq-key-binding-v0 · recovery classes: https://github.com/trustless-ai/recompute-kit/tree/main/conformance/pq-recovery-classes-v0
Not claiming “quantum-proof.” The claim is precise: the recompute layer rests on hashes (the primitive that survives), and the signature layer migrates by a binding + cutoff you can verify yourself. Feedback on the cutoff semantics, the anchor-time choice, and especially the recovery/authority model very welcome. (Sharing this as a discussion ahead of a possible ERC in the agent-identity family, filing deferred pending scrutiny + the recovery implementation.)
Co-authored : @TMerlini / vertice.eth (SLH-DSA attestor lane, live gateway enforcement, per-agent + recovery layers, reference impl), @babyblueviper1 (ML-DSA implementation + verifier, blind-diffs), @pipavlo82 (failure-class + authority-domain design, conformance vectors), and @blockbird (independent verification, the standing UNVERIFIABLE lane, spec findings, on-chain anchor decode).




