Explainer

A Bitcoin signed message proves less than it sounds

BIP 322 lets a Bitcoin address answer a message challenge through the same script rules used for spending. A valid result shows that a script could be satisfied at that moment, but it does not prove identity, continuing control, or ownership of every claimed coin.

6 min readBIPs
A Bitcoin signed message proves less than it sounds

The short answer

A Bitcoin signed message is evidence that someone could satisfy the spending condition behind a particular address for a particular piece of text. It can connect a statement to a key or script without moving bitcoin.

That is useful evidence, but the wording matters. It does not identify the person holding the key. It does not prove they still control it later. It does not prove that every coin associated with a wallet belongs to them. A signature answers a narrow cryptographic question, not every real-world question people attach to the word ownership.

How it actually works

The older message-signing convention grew around legacy pay-to-public-key-hash addresses, the addresses that begin with 1. It signs a specially formatted hash of the message and uses a recoverable ECDSA signature so a verifier can recover a public key and compare its address. BIP 137 documents extensions used by some wallets, but the format depends on address types and does not give arbitrary Bitcoin scripts one common verification model.

BIP 322 takes a different approach. The specification, checked on 22 September 2026, is complete at version 2.0.0. Instead of inventing a separate signature rule for each address form, it builds two virtual transactions and asks whether the address's normal script can be satisfied.

The first virtual transaction is called to_spend. Its input points to an output that does not exist, so it cannot be a real spend on Bitcoin. Its script commits to a tagged hash of the exact message. Its zero-value output carries the script behind the address being tested.

The second is called to_sign. It spends the virtual output and sends zero to OP_RETURN. The signer satisfies its input as if it were spending the address's script. A verifier rebuilds the first transaction from the message and address, checks that the second one spends it, then runs the applicable Bitcoin Script rules.

The message hash uses the tag BIP0322-signed-message. Tagged hashing separates this use from other protocols that also hash text. The virtual transaction shape separates the proof from an actual payment: the missing previous output means the pair is not something that can be broadcast to take coins.

BIP 322 defines several encodings:

  • smp is the compact simple form. It carries a witness stack and applies to native SegWit scripts covered by the specification, including P2WPKH and supported P2WSH and Taproot cases without timelocks.
  • ful carries the full signed to_sign transaction. It can represent more script types and can include locktime or sequence conditions.
  • pof carries a finalized partially signed Bitcoin transaction and can add real unspent outputs as inputs for a proof-of-funds claim.
  • The legacy form remains for backward compatibility with P2PKH addresses, but the specification recommends the new format for new proofs.

Those three-letter prefixes matter. Version 2.0 made the selected format explicit. A verifier may treat an unprefixed older value as the simple form for compatibility, but new software should not make readers guess which rules produced a string.

Verification also has more than a yes or no answer. A verifier can report that the proof is valid with a particular locktime and sequence age, that it is invalid, or that it is inconclusive because the verifier does not understand the script. Treating inconclusive as valid would turn unsupported rules into an acceptance path.

Why it matters

The transaction model lets message signing follow Bitcoin's script model. A native SegWit address, a Taproot address, or a multisignature policy should not need unrelated signature conventions merely because their visible address strings differ. The same script interpreter that answers whether an output could be spent can answer whether its message challenge was satisfied.

This is especially important for multisignature. There may be no single public key whose signature represents the whole policy. A two-of-three script is satisfied by the required combination of signers, not by recovering one key from one signature. The PSBT-based path also gives separate signers a familiar container for coordinating partial signatures.

Proof of funds adds a second question: can the signer satisfy the scripts for a stated set of unspent transaction outputs? The verifier must check the current UTXO set to know whether those outputs still exist and remain unspent. An offline check can validate their scripts but cannot establish their current chain state.

Implementations still matter. A format marked complete is not a promise that every wallet, hardware signer, command-line tool, or website supports every variant. Bitcoin Core's traditional signmessage and verifymessage interface is the legacy model, while the BIP lists separate implementation work for the generic format. Before relying on a proof, check that both ends support the same BIP 322 version and prefix. Do not paste a valuable wallet's seed or private key into a message-signing website to bridge a compatibility gap.

What people get wrong

"The signature proves who wrote the message." It proves access to a signing path, not a civil identity. If two people can use the same wallet, either may be able to produce the proof. A custodian may also sign for an address associated with a customer. Identity needs separate evidence linking the person to the address and the exact message.

"The signature proves permanent ownership." A valid proof describes a moment. The key may later be lost, rotated, shared, or compromised. BIP 322 can express time conditions, but it cannot promise future control.

"A proof of funds shows the whole balance." The signer chooses which outputs to include. The format does not prove that there are no other outputs, and it does not turn a set of addresses into a complete wallet inventory. It also cannot prove that the signer would agree to spend those outputs for the verifier.

"Signing is the same as sending a transaction." No coins move. The virtual input does not exist on Bitcoin, and the output is zero-value OP_RETURN. The construction borrows transaction validation rules without creating a valid network payment.

"Any successful result is interchangeable." Legacy, simple, full, and proof-of-funds values carry different capabilities and encodings. The address, exact message, signature prefix, software version, and verification result belong in the record together. A result copied without that context is hard to audit later.

Where to go next

Read BIP 322 beside the basics of asymmetric cryptography if the difference between signing and encryption is unfamiliar. For implementation work, use the specification's published test vectors rather than inventing a sample by hand. They cover the tagged message hash, virtual transaction identifiers, and simple signatures.

For a real verification request, make the message specific: include the purpose, date, counterparty, and a nonce that should not be reused. Keep the address and signature with the exact UTF-8 message. Then state the conclusion narrowly: the script was satisfied for that message under those verification rules. That sentence is less dramatic than "ownership proved", and much more accurate.

Newsletter

Bitcoin, without the noise

What happened in Bitcoin, what it actually changes, and the sources so you can check us. One issue at a time, straight to your inbox.

  • One email per issue, never a drip campaign
  • No tracking pixels and no shared addresses
  • Unsubscribe from any issue in one click

Get the next issue

One email per issue, no tracking pixels, and unsubscribe from any of them. We do not share your address. Privacy policy