From: Hans Stringuer <hans.stringuer@gmail.com>
To: Bitcoin Development Mailing List <bitcoindev@googlegroups.com>
Subject: Re: [bitcoindev] BIP Draft Post-Quantum Address Format (bc1z) using ML-DSA-65
Date: Fri, 13 Nov 2026 09:25:18 -0800 (PST) [thread overview]
Message-ID: <23d3f227-fb57-4ad3-8dab-438d2bd6e651n@googlegroups.com> (raw)
In-Reply-To: <CAAa3hFN+z1KGRkU_8JLmQ_1cXMZEYHO-0370Q_REv_MB2ci9Og@mail.gmail.com>
[-- Attachment #1.1: Type: text/plain, Size: 6326 bytes --]
Hi Zeeshan, all,
Thank you, both points are right, and they are now part of a substantially
revised draft (v0.2):
https://github.com/Zaenus/btc-safe/blob/main/docs/bip/0001-pq-address-format.md
> I think this is definitely useful **before** a CRQC exists.
Agreed. The Motivation section now spells out why waiting fails. Soft
forks take years from proposal to activation, and migration is limited
by block space: a 1-in/1-out move from P2WPKH to the new output type is
486 WU, so every 10 million UTXOs needs roughly 1,200 completely full
blocks. A safe destination has to exist well before the threat does.
> I think it'd be useful to highlight that unlike a P2WPKH address, the
> address remains quantum-resistant even after its public key and
> signatures are revealed.
Yes. My comparison with P2WPKH undersold the design. The hash commitment
only keeps outputs small (34 bytes instead of ~1,955); it is not what
provides security. Unlike P2WPKH, the output stays safe while a spend
waits in the mempool, after it has been spent, and under address reuse
(still bad for privacy, of course). The draft now says this explicitly.
Corrections to my original post
-------------------------------
Several things in my first message were wrong, and I want to correct them
on the list:
1. Witness version 2 / bc1z: version 2 is used by BIP-360 (P2MR). The
proposal now uses witness version 3, so addresses start with bc1r
(tb1r on testnet).
2. "Similar to how P2WPKH works": misleading, see above.
3. "~6.9 million BTC (~$586B)": I replaced this with the figure cited in
BIP-361 (more than 34% of all bitcoin had an exposed public key as of
March 2026) and dropped the dollar value.
4. The signature aggregation claim ("~33KB to ~2KB for 10 signatures")
is withdrawn. The prototype was a mock that could be forged, and the
approach was unsound anyway: pairing-based SNARKs such as Groth16 are
themselves broken by a CRQC, and consensus cannot depend on a trusted
setup. Aggregation is now out of scope; a short research note
explains what a sound approach would need.
5. The reference implementation produced bech32 rather than bech32m
checksums for the new witness version, so BIP-350 wallets would have
rejected its addresses. That is fixed and tested against the BIP-350
vectors. It also generated mainnet addresses by default; it now
defaults to testnet, since these outputs are anyone-can-spend until a
soft fork activates.
What changed in the design
--------------------------
key_blob = key_type || pubkey (0x01 = ML-DSA-65)
commitment = TaggedHash("PQKeyCommit", key_blob)
scriptPubKey = OP_3 <32-byte commitment>
witness = <signature[||hash_type]> <key_blob> [annex]
sighash = TaggedHash("PQSighash", 0x00 || SigMsg(hash_type, 0))
verify = ML-DSA.Verify(pk, sighash, sig, ctx="bitcoin:pq:tx")
- Key type byte: the key blob is always the last witness element, and
undefined key types succeed (like OP_SUCCESS). ML-DSA-44, SLH-DSA,
FN-DSA or a hybrid type can then be added by later soft forks without
spending another witness version.
- The signature message is BIP-341's SigMsg, unchanged, under a new tag.
It commits to all input amounts and scriptPubKeys, which BIP-143 does
not.
- FIPS 204 context strings separate transaction signatures from
off-chain message signatures.
- The draft now has full spending rules, relay policy, size figures, and
a rationale section comparing this with P2MR (BIP-360), hybrid keys,
ML-DSA-44, SLH-DSA and FN-DSA.
- Test vectors (docs/bip/0001-test-vectors.json) cover keys and
derivation, all seven hash types, and 32 valid and invalid spends. The
signatures come from an independent ML-DSA implementation, and the
sighash code also passes the official BIP-341 vectors.
Size: an ML-DSA-65 input is 5,433 WU (~1,358 vB), about 736 per block. A
1-in/2-out transaction is about 1,455 vB.
Status of my original questions
-------------------------------
1. Address format: revised as above (witness v3, bech32m, tagged-hash
commitment with a key type byte).
2. ML-DSA-65 vs. smaller parameters: still open, and I would value
opinions. ML-DSA-44 inputs are 28% smaller (3,904 WU); ML-DSA-65
gives more margin against future lattice cryptanalysis. Should a
hybrid secp256k1 + ML-DSA key type also exist from day one?
3. Deployment: no activation mechanism proposed yet. Bitcoin Core
benchmarks of ML-DSA-65 verification come first.
4. Migration: the reference tools classify addresses by exposure
(Taproot and spent-from addresses count as exposed) and derive
recoverable destinations from a BIP-39 seed. BIP-361 covers the
policy side.
5. Before a CRQC: yes, per Zeeshan's reply and the reasoning above.
Detailed technical discussion is also happening on Delving Bitcoin:
https://delvingbitcoin.org/t/bip-draft-witness-version-3-ml-dsa-65-post-quantum-key-path-spending/
Full list of changes:
https://github.com/Zaenus/btc-safe/blob/main/CHANGELOG.md
Thanks again for the review.
Best regards,
Hans
https://github.com/Zaenus
Em sexta-feira, 13 de novembro de 2026 às 13:28:40 UTC-3, Zeeshan Ali Khan
escreveu:
> Hi Hans,
>
> > 5. Whether the community sees value in pursuing this before a CRQC exists
>
> I can't speak for others but I think this is definitely useful
> **before** a CRQC exists. It'd be too late for the 6.9 million BTC you
> mentioned when there is CRQC. :)
>
> > revealing the full public key only at spend time in the witness —
> similar to how P2WPKH works today.
>
> I think it'd be useful to highlight that unlike a P2WPKH address, the
> address remains quantum-resistant even after its public key and
> signatures are revealed.
>
> --
> Regards,
>
> Zeeshan Ali Khan
>
--
You received this message because you are subscribed to the Google Groups "Bitcoin Development Mailing List" group.
To unsubscribe from this group and stop receiving emails from it, send an email to bitcoindev+unsubscribe@googlegroups.com.
To view this discussion visit https://groups.google.com/d/msgid/bitcoindev/23d3f227-fb57-4ad3-8dab-438d2bd6e651n%40googlegroups.com.
[-- Attachment #1.2: Type: text/html, Size: 7442 bytes --]
next prev parent reply other threads:[~2026-11-13 17:26 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-11-12 17:25 [bitcoindev] BIP Draft Post-Quantum Address Format (bc1z) using ML-DSA-65 Hans Stringuer
2026-11-13 12:18 ` [bitcoindev] " Hans Stringuer
2026-11-13 15:49 ` [bitcoindev] " Zeeshan Ali Khan
2026-11-13 17:25 ` Hans Stringuer [this message]
2026-11-13 20:16 ` Murch
2026-11-13 20:29 ` Hans Stringuer
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=23d3f227-fb57-4ad3-8dab-438d2bd6e651n@googlegroups.com \
--to=hans.stringuer@gmail.com \
--cc=bitcoindev@googlegroups.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox