Bitcoin Development Mailinglist
 help / color / mirror / Atom feed
From: "'duncan0k' via Bitcoin Development Mailing List" <bitcoindev@googlegroups.com>
To: bitcoindev@googlegroups.com
Subject: [bitcoindev] Standardizing public key exposure classification for existing outputs
Date: Fri, 4 Sep 2026 19:10:58 +0000	[thread overview]
Message-ID: <010001a06dd4cdd9-b8082042-8750-4e9a-917e-2053c919e4c4-000000@email.amazonses.com> (raw)

Hi all,

I would like to gauge interest in a specification that defines how to
classify an existing Bitcoin output by whether the public key needed to
spend it has already been published on-chain.

The gap: BIP 360 gives us an output type whose key stays off-chain
until a script-path spend, and BIP 361 proposes a phased sunset of
legacy signature verification. Both assume the ecosystem can answer
"which existing outputs are exposed?" -- but no BIP specifies how that
question is answered.

Why this is a practical problem: published estimates of the exposed
supply currently range from roughly 25% to over 34%. As far as I can
tell the spread is definitional, not measurement error. Recurring
disagreements:

- Is a P2TR output exposed at rest? Its 32-byte output key is a public
  key, and solving its discrete log yields a working key-path spend
  regardless of how the internal key was chosen -- a NUMS internal key
  does not help, since consensus never checks how Q was constructed.

- Is a spent-from P2PKH address that still holds a balance "exposed at
  rest" or "exposed on spend"? To an adversary these are the same
  situation, but tools label them differently.

- What should a classifier report for a P2SH/P2WSH output whose script
  has never been revealed?

- What about keys disclosed off-chain -- xpubs handed to service
  providers, or spends of the corresponding output on a 2017 fork?

If BIP 361 or something like it advances, "is this output
legacy-vulnerable" becomes a question asked at scale by wallets,
explorers and custodians, with money attached. Users consulting two
tools should not get two answers about the same coins.

What the draft does: it specifies four levels -- EXPOSED_AT_REST,
EXPOSED_ON_SPEND, NOT_EXPOSED, UNDETERMINED -- a per-output-type
assignment table, and a fail-closed rule: where data is insufficient
to distinguish two levels, the more-exposed level must be assigned.
Two points I would particularly like feedback on:

1. Disclosure mechanism does not change the level. A reused,
   spent-from script that retains a balance is EXPOSED_AT_REST, the
   same as P2PK. I think separating these invites the reading that
   reused addresses are safer than P2PK, which is false. Some existing
   tools (including an earlier iteration of my own) do separate them.

2. UNDETERMINED is mandatory for unrecognized output types, rather
   than defaulting them to unexposed. Any classifier predating a
   future output type will encounter outputs it cannot reason about,
   and reporting those as safe asserts a property it has not
   established.

The draft also specifies a constant-time floor: if a script's
confirmed spent-output count is greater than zero, a spend has
occurred, and for every type except P2MR that publishes the material
the script commits to. This is what prevents a truncated history scan
from producing a false NOT_EXPOSED -- without it, every implementation
independently decides what to report when it runs out of scan budget,
and the divergence reappears at the engineering layer. (The one
over-approximation -- a revealed script that requires no signature --
errs in the conservative direction, which the fail-closed rule
permits; see the v0.2.0 changelog.)

Explicitly out of scope: risk scoring. Turning exposure into a number
requires weighing balance, dormancy and CRQC timelines, none of which
are observable on-chain and all of which are contested. The draft
stops at the observable so that the numbers people compute on top of
it are at least computed over the same facts.

Draft, reference implementation and test vectors:
https://github.com/duncan0k/pubkey-exposure-classification

I posted this to Delving Bitcoin a couple of days ago and am
cross-posting here for wider review:
https://delvingbitcoin.org/t/standardizing-an-exposure-classification-for-existing-outputs-pre-bip/2866

Before I invest further: is this something the list considers worth
specifying, or is it better left to each implementation? I am also
interested in whether anyone has prior art I have missed -- I could
not find a canonical definition, but this is the kind of thing that
gets rediscovered.

duncan0k

-- 
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/010001a06dd4cdd9-b8082042-8750-4e9a-917e-2053c919e4c4-000000%40email.amazonses.com.


             reply	other threads:[~2026-09-04 19:25 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-09-04 19:10 'duncan0k' via Bitcoin Development Mailing List [this message]
2026-09-07 20:53 ` [bitcoindev] Standardizing public key exposure classification for existing outputs 'conduition' via Bitcoin Development Mailing List
2026-09-08  3:53   ` 'duncan0k' via Bitcoin Development Mailing List
2026-09-14 21:04 ` 'duncan0k' via Bitcoin Development Mailing List
2026-09-18 10:38 ` 'duncan0k' via Bitcoin Development Mailing List

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=010001a06dd4cdd9-b8082042-8750-4e9a-917e-2053c919e4c4-000000@email.amazonses.com \
    --to=bitcoindev@googlegroups.com \
    --cc=duncan0k@cipherscope.io \
    /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