Skip to content
CryptoDecentral

Note

A Signature Is Not Proof of Funds: What BIP 322 Message Signing Can and Cannot Show

A Bitcoin signed message shows a key could satisfy one address's script for one text, once. It does not prove identity, current control, holdings or a past payment.

2026-11-13 · self-custody, bip-322, bip-137, message-signing, proof-of-funds, psbt, verify-before-trust, civil-liberties

Listen · 10 min · AI voice

Dark CryptoDecentral hex mesh — a single bronze wax-seal-like hexagon pressed onto a translucent teal sheet, with the cells beneath the sheet left deliberately dim and unlit; no text.

Sooner or later someone asks a self-custodian to "sign a message to prove the wallet is yours." A counterparty wants it before a trade, a service wants it before a withdrawal, an auditor wants it, a stranger in a forum wants it to settle an argument. The request sounds like a clean cryptographic answer to a messy social question.

It is narrower than that. Thesis, stated once: a Bitcoin signed message proves that whoever made it could, at that moment, satisfy the script of one address for one piece of text. It does not prove who they are, that they still can, that they hold any coins now, that they sent any past payment, or that they have shown you everything. The current standard, BIP 322, says most of this in its own motivation section. Read signatures for what they prove and nothing more.

Two standards, one old gap

For years "sign message" in Bitcoin meant the format later written down as BIP 137: a 65-byte compact ECDSA signature with a header byte, from which the verifier recovers a public key and checks that it hashes to the claimed address. The header ranges (27–30, 31–34, 35–38, 39–42) only distinguish P2PKH, compressed P2PKH, nested SegWit and native SegWit single-key addresses. Multisig, scripts and Taproot are outside it. BIP 137's own abstract now points readers to the newer scheme.

BIP 322, the "Generic Signed Message Format", fixes the coverage problem with a trick: express the message as a transaction that can never be mined. The signer builds two virtual transactions:

  • to_spend has a fake input (prevout 000…000:FFFFFFFF, which does not exist) whose scriptSig commits to a tagged hash of the message (sha256_tag(m) with tag BIP0322-signed-message), and one zero-value output locked to the address being proven.
  • to_sign spends that output into a single zero-value OP_RETURN. The "signature" is whatever witness satisfies the address's script.

Because verification just runs the normal script interpreter, any address type can in principle be signed for: single key, multisig, Taproot. The spec defines three formats plus one variant: legacy (BIP 137-style, no prefix, and now restricted to P2PKH), simple (smp, a witness stack), full (ful, the whole to_sign), and the proof of funds variant of full (pof, a finalized PSBT). Since version 1.0.0, every non-legacy signature must carry its prefix. BIP 322 was marked Complete in April 2026; its latest revision, 2.1.0 on 23 October 2026, adds Taproot's upgrade mechanisms to the rules that return inconclusive.

What a valid signature actually proves

BIP 322 is unusually candid. Its motivation says: "no message signing protocol can actually prove control of funds, both because a signature is obsolete as soon as it is created, and because the possessor of a secret key may be willing to sign messages on others' behalf even if it would not sign actual transactions." It adds that the BIP "only addresses the use case where a signer shows they will be able to control funds sent to the invoice address. Proving that a signer sent a prior transaction is not possible using this BIP."

Unpack that into the things people wrongly read into a signature:

  • Not identity. It proves the signer could use a key, not who they are. A key can be shared, stolen, or held by an agent signing for someone else.
  • Not current control. It is a snapshot. Keys get lost, rotated, or compromised the next day.
  • Not ownership of coins. A plain signature is about an address, which may hold nothing. Even the pof variant, which adds real UTXOs as extra inputs, says validators "need access to the current UTXO set" to learn they exist and are unspent; an offline validator can only check the cryptography.
  • Not completeness. The spec is explicit: an attested UTXO list "can also never prove that there do not exist more UTXOs for a certain address," and is not "all UTXOs that exist." A signer chooses what to show.
  • Not proof of payment. Who sent a past transaction is out of scope. Anyone claiming a signature proves "I paid you" is using it for something it was not built to show.

The verifier output reflects this. BIP 322 defines three results, not two: valid at time T and age S, invalid, and inconclusive (the validator could not check the scripts, or they use features reserved for future upgrades). Treating "inconclusive" as "probably fine" defeats the point.

Verify like the spec, not like the screenshot

When someone hands you a signature as evidence, the mechanics of checking it matter more than the claim attached to it.

  1. Get three exact inputs. Address, message, signature. The message is hashed "as-is without length prefix or null terminator," so a changed space or line ending is a different message. Check it in software you run, not a page the other party links.
  2. Read the prefix. smp, ful, pof, or a bare legacy blob. The prefix tells you which claim is even possible. Some verifiers assume smp when the prefix is missing, for backward compatibility; know which one you are running.
  3. Put freshness in the message. A signature over "I control this address" can be replayed forever. A verifier who wants a current answer supplies the text, with a date and a random challenge, so an old signature cannot be recycled.
  4. Check the chain separately for any funds claim. For pof, look up every listed outpoint yourself. Then remember what you still don't know: what else exists, and what happens one block later.

Signing safely is a device question

The sharper risk runs the other way: being asked to sign. A BIP 322 request can arrive as a PSBT (BIP 174), the same container used for real spends, marked with a global field PSBT_GLOBAL_GENERIC_SIGNED_MESSAGE (0x09) that BIP 322 itself defines. BIP 322 lists the checks a signer must run before treating it as a message: the field is set, the first input carries the address's script and spends output 0 of a correctly reconstructed to_spend, and there is exactly one zero-value OP_RETURN output. If any check fails, it is an ordinary PSBT. Only then should the device show "signing message m for address A", not "spending 0 satoshi."

The practical rule follows: if a device cannot show you, on its own screen, the message text and the address it is signing for, you do not know you are signing a message. A request that renders as a transaction with real inputs and outputs is a transaction. This is the same verify-on-device discipline as any PSBT spend, applied to a request that is easy to wave through because "it's only a message."

Support is still uneven, so check rather than assume. Bitcoin Core's first BIP 322 pull request, #24058, was closed unmerged; its author cited the effort of keeping up with wallet changes. A newer one, #36809 ("Support BIP322 simple message signing"), was opened on 9 November 2026 and is open as of this note. It covers only the smp format for native SegWit and Taproot addresses; full signatures and proofs of funds are outside it. Software that offers only the legacy format cannot sign for a multisig or Taproot address at all.

Who this matters for

Anyone asked to prove control of a self-held wallet. Under cross-border transfer rules (often called the travel rule), some service providers ask customers to demonstrate control of their own addresses. On the earlier #24058 thread, one commenter notes that multisig users who could not sign legacy messages were being asked to send dust-sized test payments instead. A standard that covers every script type is a real improvement there, but the proof still means only what BIP 322 says it means.

There is a civil-liberty edge too. A signature over a message naming you is a permanent, verifiable link between that identity and that address, and through it to the address's history. Anyone who gets a copy can check it, and a copy cannot be recalled. Sign the narrowest thing that answers the question, for the narrowest audience, and prefer a fresh address over one with a long trail.

What this is not

This is not a guide to any provider's verification process, a ranking of wallets or signing devices, or legal or compliance advice about what you must disclose to anyone. It does not say signed messages are useless; they are a sound proof of the narrow thing they prove. It is not a proof-of-reserves methodology, and nothing here describes a custody service. It says nothing about prices or trading. It covers Bitcoin only; Monero's payment proofs and view keys are different designs with their own scope. Spec quotes are from bitcoin/bips master (BIP 322 v2.1.0) and pull-request states were checked on 13 November 2026.

The one-line takeaway: a signature proves "this key could sign this text, then"; anything beyond that, identity, balance, completeness, or payment, needs separate evidence.

Related on CryptoDecentral

Further reading (primary)

More on this topic

All notes · Get the Monday radar by email