A data point that may be useful here: I maintain a small 2014 scrypt chain (Blazecoin, UTXO, Bitcoin Core 28 based), and in September we deployed a post-quantum output type on mainnet. It's not Bitcoin, and some of our choices only work because the chain is small, but the measured numbers carry over.
What we built: a hash-committed output (32-byte hash of the key blob) spent with an ML-DSA-44 (FIPS 204) signature through a new opcode. It's a single scheme with no ECDSA hybrid, and a versioned algorithm ID so ML-DSA-65/87 or SLH-DSA can be added later without a new address format.
Sizes and speed, measured: | ECDSA P2PKH | ML-DSA-44 |
| Input size | 148 B | 3,782 B |
| Inputs per 1 MB (no witness discount) | ~6,700 | ~264 |
| Inputs per 100 KB standard tx | ~670 | 26 |
| Verify, one core (managed code) | 254 µs | 132 µs |
Verification is not the bottleneck. A full block of ML-DSA-44 inputs verifies in about 35 ms. Bytes are what bind: a 25x cut in inputs per block. On Bitcoin a witness discount would soften that, but it is still the main cost.
Why not SLH-DSA first: SLH-DSA-SHA2-128s has the most conservative assumptions, but signatures are ~7.9 KB and signing took ~835 ms each in our tests (a 12-input transaction took 10 s to sign). We reserved it as the fallback if lattices break. Falcon is smaller but FIPS 206 isn't final, and its floating-point signing is a known implementation hazard.
On P2MR: the hash commitment protects against long exposure, but a script leaf that still ends in a classical signature only moves exposure from "first spend" to "first spend of that leaf". Our chain has no tapscript, so we did the signature scheme first. For Bitcoin, I'd read that as an argument for P2MR and a post-quantum opcode arriving close together.
Consensus cost: a 1,312-byte public key and a 2,420-byte signature can't be pushed under the 520-byte element limit. We relaxed it only for inputs spending the new template, which made it a hard fork for us (our chain has no segwit). In a new tapscript leaf version that would be a soft fork.
What doesn't carry over: the rollout. We picked the activation height with about a day's notice, which is only possible when one operator runs most of the hashrate. And the hard part remains migration: coins on reused or spent-from addresses stay exposed until their owners move them. That's a holder-behaviour problem no output type solves.
I'm happy to share the benchmark details or the signature-digest design if that's useful for this thread.