Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BIP 322: Explain various signature intents, add TODOs #1347

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 33 additions & 4 deletions bip-0322.mediawiki
Original file line number Diff line number Diff line change
Expand Up @@ -17,22 +17,32 @@ A standard for interoperable signed messages based on the Bitcoin Script format,

== Motivation ==

The current message signing standard only works for P2PKH (1...) invoice addresses. We propose to extend and generalize the standard by using a Bitcoin Script based approach. This ensures that any coins, no matter what script they are controlled by, can in-principle be signed for. For easy interoperability with existing signing hardware, we also define a signature message format which resembles a Bitcoin transaction (except that it contains an invalid input, so it cannot be spent on any real network).
TODO: Proof of sender

The current message signing standard only works for P2PKH (1...) invoice addresses, and only proves the intended recipient of an invoice address agrees to the message.
We propose to extend and generalize the standard by using a Bitcoin Script based approach.
This ensures that any coins, no matter what script they are controlled by, can in-principle be signed for.
For easy interoperability with existing signing hardware, we also define a signature message format which resembles a Bitcoin transaction (except that it contains an invalid input, so it cannot be spent on any real network).

Additionally, the current message signature format uses ECDSA signatures which do not commit to the public key, meaning that they do not actually prove knowledge of any secret keys. (Indeed, valid signatures can be tweaked by 3rd parties to become valid signatures on certain related keys.)

There appears to also be a desire to prove funds availability.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this sentence needed?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Motivation for a new message signing standard that does something the current one does not.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe something less ambiguous like "Proving fund availability is a also a useful feature with practical use cases."

Ultimately 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. No signmessage protocol can fix these limitations.
However, this proposal offers a way to prove that the message itself was signed by someone who does control an amount of bitcoins.

== Types of Signatures ==

This BIP specifies three formats for signing messages: ''legacy'', ''simple'' and ''full''. Additionally, a variant of the ''full'' format can be used to demonstrate control over a set of UTXOs.
This BIP specifies three formats for signing messages: ''legacy'', ''simple'' and ''full''. Additionally, a variant of the ''full'' format can be used to demonstrate control over an amount of bitcoins, represented by a set of UTXOs.

=== Legacy ===

New proofs should use the new format for all invoice address formats, including P2PKH.

The legacy format MAY be used, but must be restricted to the legacy P2PKH invoice address format.

It can only prove a message is signed by the intended recipient of the given invoice address.
Notably, it does not prove any control of bitcoins or having had sent any transactions.

=== Simple ===

A ''simple'' signature consists of a witness stack, consensus encoded as a vector of vectors of bytes, and base64-encoded. Validators should construct <code>to_spend</code> and <code>to_sign</code> as defined below, with default values for all fields except that
Expand All @@ -43,6 +53,8 @@ A ''simple'' signature consists of a witness stack, consensus encoded as a vecto

and then proceed as they would for a full signature.

It also only can prove the message is signed by the intended recipient of the given invoice address, and cannot prove any control of bitcoins or having had sent any transactions.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
It also only can prove the message is signed by the intended recipient of the given invoice address, and cannot prove any control of bitcoins or having had sent any transactions.
Furthermore, it can only prove the message is signed by the intended recipient of the given invoice address, and cannot prove any control of bitcoins or having had sent any transactions.


=== Full ===

Full signatures follow an analogous specification to the BIP-325 challenges and solutions used by Signet.
Expand Down Expand Up @@ -76,16 +88,33 @@ The <code>to_sign</code> transaction is:

A full signature consists of the base64-encoding of the <code>to_sign</code> transaction in standard network serialisation once it has been signed.

This signature, as-is, only proves a message is signed by the intended recipient of the given invoice address which creates the <code>message_challenge</code> script.
It does not prove any control of bitcoins or having had sent any transactions.

TODO: How does this interact with as-of-yet-unspecified "Silent Transactions"?
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This isn't "future work", but a matter of compatibility, which BIPs should address.


TODO: Some invalid opcode to allow only in various proof types?
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems like it should be too trivial to put off as "future work". IMO.

Copy link
Contributor

@ZenulAbidin ZenulAbidin Aug 9, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@luke-jr Here's a solution at least for the Silent Transactions. Since they can't decide which address formats they will use for it (there is a lot of to-and-fro between taproot and segwit), and all such address formats can be represented in the Simple format anyway, just write in this BIP that Silent Transactions can use the Simple format to sign their messages, and the scriptPubKey/scriptSig/Witness will all be the same.

[Why do we need an invalid opcode to redefine in the first place, I thought invalid opcodes in the script are supposed to make the verifier return an inconclusive status.]

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Making an invalid opcode valid would be useful to provide a separate Tapscript that is valid only for signing messages, but not actual spending.

Copy link

@rxgrant rxgrant Aug 10, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If someone wants to hide the specific allocation of outgoing value among tapscript outputs, then it would already be possible to create a branch that spends the UTXO to an OP_RETURN. Since BIP322-signature-txs cannot be spent, there's no downside to signing that branch.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note that we can also redefine the meaning of OP_CHECKSIG in the context of message signing and verifying to hash the virtual transaction that is derived from the message i.e. to_spend. Bitcointalk source


TODO: A way for the initial signer to delegate to another scriptPubKey; needed for better privacy and CoinJoin/Lightning compatibility
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Putting this off to a future standard would compromise the privacy benefits.


=== Full (Proof of Funds) ===

A signer may construct a proof of funds, demonstrating control of a set of UTXOs, by constructing a full signature as above, with the following modifications.
A signer may construct a proof of funds, demonstrating ownership of an amount of bitcoins, by constructing a full signature as above, with the following modifications.

* <code>message_challenge</code> is unused and shall be set to <code>OP_TRUE</code>
* Similarly, <code>message_signature</code> is then empty.
* All outputs that the signer wishes to demonstrate control of are included as additional inputs of <code>to_sign</code>, and their witness and scriptSig data should be set as though these outputs were actually being spent.
* <code>vout[0].nValue</code> should be set to the desired amount of bitcoins to prove ownership of.
* The signer must select UTXOs with values sum to at least the desired proof amount, and include them as additional inputs of <code>to_sign</code>. Their witness and scriptSig data should be set as though these outputs were actually being spent.

Unlike an ordinary signature, validators of a proof of funds need access to the current UTXO set, to learn that the claimed inputs exist on the blockchain, and to learn their scriptPubKeys.

This signature proves only that the message is signed by someone who owns the specified (in nValue) amount of bitcoins.
It does not prove anything about the transactions or recipients thereof when the UTXOs were created;
it does not prove control or ownership of the specific UTXOs;
Comment on lines +111 to +113
Copy link
Member

@achow101 achow101 Jul 28, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lines 111 and 113 seem contradictory.

Since the signature is over specific UTXOs, if the signature proves that the signer owns the specified amount, that implies that the signer owns those UTXOs, or at least has the ability to spend them as they have to provide valid scriptSigs and witnesses. If the signature does not prove that the signer has the ability to spend those specific UTXOs, then I don't see how the signature proves that they own the specified amount of Bitcoin.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

eg, MtGox should produce these signatures for their users, while still keeping funds mingled in separate hot/cold wallets. The hot UTXOs might be spent by any unrelated user, but in the meantime serve as proof of an available sum for another user. Two separate users might have proofs for different actual balances yet technically sign using the same UTXO(s).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should it say that the signature proves control over the UTXOs, but does not prove ownership or unique control?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It doesn't prove control over the UTXOs, though, that's the point. It shows (perhaps not proves absolutely) ownership.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I consider myself pretty knowledgeable, and you've been saying this for many years (about signmessage), and to be honest I've never fully understood what you mean.

My understanding is that signing a message (or a transaction) proves control over a UTXO, with the following caveats:

  • it may not have been you who did the signing (e.g. you are a Gox user and Gox did the sig)
  • it may not have been recent (Gox did it 10 years ago and since then has run into some trouble ... although I suppose you could include a recent headline and/or a challerger-provided nonce to help with this)
  • even if it's recent, it is obsolete as soon as it's created (ok, you signed 1 second ago but your signing device caught fire at the same time)
  • it may not indicate unique control (Gox may be signing with the same UTXOs for multiple users)
  • it may not indicate general-purpose signing ability (maybe your hardware wallet will only sign messages, or only sign BIP322 provably-invalid transactions, etc., and won't actually sign real transactions)

Does this match your understanding? The word "ownership" feels nebulous to me and I'm not sure what you mean by it.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Whether or not the script has been satisfied is meaningful. How that is tied to a claim is meaning constructed outside the Bitcoin blockchain, by the parties that choose to use BIP322-signatures. Unlike txs stored in the blockchain, these signatures don't prevent double spending their associated claims.

Some people may agree that the ability to satisfy the script at one moment is still valuable, because they know the constraints of their L2 problem domain.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ALL of this is outside the blockchain.

If a signature doesn't indicate a purpose, then the parties can't agree on a purpose, because one of them probably won't be able to produce a signature at all.

Copy link

@rxgrant rxgrant Aug 11, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Other metadata used to indicate the purpose can wrap the signature.

One approach to this, with well defined structure for wrapping signatures, is the W3C Verifiable Credential Data Model, which is very specific about what a claim is: https://www.w3.org/TR/vc-data-model/#claims

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can't even produce the signature until this purpose is defined...

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

None of this is new. Signatures go like this:

protocol indicating purpose, perhaps just words
--- begin signature ---
signature(protocol indicating purpose, perhaps just words)

In the case of the example I offered, the protocol indicating purpose is quite sophisticated. I belive it's a compelling example that allows you no room to try to derail BIP322 on the grounds that all that meaning needs to be defined inside BIP322.

P.S. This argument has moved beyond the proposed patch that started these replies, which I'm not arguing for or against, so I'll move on.

and it does not prove anything about who may send a transaction consuming the UTXOs in the future.

TODO: Maybe the stripped transactions & merkle branches for each UTXO should be included so that it's sufficient to only have block headers? But more full nodes is better... so maybe not.

== Detailed Specification ==

For all signature types, except legacy, the <code>to_spend</code> and <code>to_sign</code> transactions must be valid transactions which pass all consensus checks, except of course that the output with prevout <code>000...000:FFFFFFFF</code> does not exist.
Expand Down