mirror of
https://github.com/bitcoin/bips.git
synced 2026-05-18 16:59:30 +00:00
BIP-0322: grammar and readability touchup
Co-authored-by: Jon Atack <jon@atack.com>
This commit is contained in:
@@ -22,31 +22,23 @@
|
|||||||
== Abstract ==
|
== Abstract ==
|
||||||
|
|
||||||
A standard for interoperable signed messages based on the Bitcoin Script format, either for proving
|
A standard for interoperable signed messages based on the Bitcoin Script format, either for proving
|
||||||
fund availability, or committing to a message as the intended recipient of funds sent to the invoice
|
availability of funds, or for committing to a message as the intended recipient of funds sent to the
|
||||||
address.
|
invoice address.
|
||||||
|
|
||||||
== Motivation ==
|
== Motivation ==
|
||||||
|
|
||||||
The current message signing standard only works for P2PKH (1...) invoice addresses. We propose to
|
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
|
extend and generalize the standard by using an approach based on Bitcoin Script. This ensures that
|
||||||
coins, no matter what script they are controlled by, can in-principle be signed for. For easy
|
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
|
interoperability with existing signing hardware, we also define a signature message format that
|
||||||
resembles a Bitcoin transaction (except that it contains an invalid input, so it cannot be spent on
|
resembles a Bitcoin transaction (except that it contains an invalid input, so it cannot be spent on
|
||||||
any real network).
|
any real network).
|
||||||
|
|
||||||
The [[#full-proof-of-funds|Proof of Funds]] variant allows demonstrating control
|
Additionally, the current message signature format uses ECDSA signatures that do not commit to the
|
||||||
of a set of UTXOs in addition to the message being signed.
|
|
||||||
The list of UTXOs may or may not be related to the address being signed with (the
|
|
||||||
<code>message_challenge</code>).
|
|
||||||
But in any case, the UTXO list does not aim to prove completeness (e.g. it does NOT mean:
|
|
||||||
"these are all UTXOs that exist for an address") nor that they are unspent (e.g. a
|
|
||||||
validator must consult the blockchain to verify that).
|
|
||||||
|
|
||||||
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
|
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.)
|
signatures can be tweaked by third parties to become valid signatures on certain related keys.)
|
||||||
|
|
||||||
Ultimately no message signing protocol can actually prove control of funds, both because a signature
|
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
|
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 message signing
|
sign messages on others' behalf even if it would not sign actual transactions. No message signing
|
||||||
protocol can fix these limitations.
|
protocol can fix these limitations.
|
||||||
@@ -58,7 +50,7 @@ using this BIP.
|
|||||||
== Terminology ==
|
== Terminology ==
|
||||||
|
|
||||||
In the context of this BIP, whenever the word "signature" or similar is used, it refers to the
|
In the context of this BIP, whenever the word "signature" or similar is used, it refers to the
|
||||||
output of the signing process described below and, depending on the script type of the
|
output of the signing process described below, and, depending on the script type of the
|
||||||
<code>message_challenge</code>, is either a full transaction input witness stack, a full
|
<code>message_challenge</code>, is either a full transaction input witness stack, a full
|
||||||
transaction, or a PSBT packet that can be validated against a Bitcoin Script Interpreter. Such a
|
transaction, or a PSBT packet that can be validated against a Bitcoin Script Interpreter. Such a
|
||||||
"signature" may or may not contain an actual cryptographic (ECDSA or Schnorr) signature, depending
|
"signature" may or may not contain an actual cryptographic (ECDSA or Schnorr) signature, depending
|
||||||
@@ -85,32 +77,32 @@ UTXOs.
|
|||||||
| Simple
|
| Simple
|
||||||
| <code>P2WPKH</code>, <code>P2WSH</code><sup>2</sup>, <code>P2TR</code><sup>2</sup> <br/>
|
| <code>P2WPKH</code>, <code>P2WSH</code><sup>2</sup>, <code>P2TR</code><sup>2</sup> <br/>
|
||||||
| <code>smp</code>
|
| <code>smp</code>
|
||||||
| witness stack, consensus encoded and base64-encoded
|
| witness stack, consensus-encoded and base64-encoded
|
||||||
|-
|
|-
|
||||||
| Full
|
| Full
|
||||||
| <code>all</code>
|
| <code>all</code>
|
||||||
| <code>ful</code>
|
| <code>ful</code>
|
||||||
| full <code>to_sign</code> transaction, consensus and base64-encoded
|
| full <code>to_sign</code> transaction, consensus-encoded and base64-encoded
|
||||||
|-
|
|-
|
||||||
| Full (Proof of Funds)
|
| Full (Proof of Funds)
|
||||||
| <code>all</code>
|
| <code>all</code>
|
||||||
| <code>pof</code>
|
| <code>pof</code>
|
||||||
| full finalized PSBT of the <code>to_sign</code> transaction, consensus and base64-encoded
|
| full finalized PSBT of the <code>to_sign</code> transaction, consensus-encoded and base64-encoded
|
||||||
|}
|
|}
|
||||||
|
|
||||||
<sup>1</sup>: Possible on a technical level but should NOT be used anymore in the context of this
|
<sup>1</sup>: Possible on a technical level but SHOULD NOT be used anymore in the context of this
|
||||||
BIP, see section [[#legacy|Legacy]] below.<br/>
|
BIP, see section [[#legacy|Legacy]] below.<br/>
|
||||||
<sup>2</sup>: Excluding time lock scripts.
|
<sup>2</sup>: Excluding time lock scripts.
|
||||||
|
|
||||||
Signers must prefix the signature with the variant that was used to create the signature.
|
Signers MUST prefix the signature with the variant that was used to create the signature.
|
||||||
To support backward compatibility with implementations of this BIP before it was finalized, a
|
To support backward compatibility with implementations of this BIP before it was finalized, a
|
||||||
verifier might assume the ''simple'' variant in the absence of a prefix.
|
verifier might assume the ''simple'' variant in the absence of a prefix.
|
||||||
|
|
||||||
=== Legacy ===
|
=== Legacy ===
|
||||||
|
|
||||||
New proofs should use the new format for all invoice address formats, including P2PKH.
|
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.
|
The legacy format MAY be used, but MUST be restricted to the legacy P2PKH invoice address format.
|
||||||
|
|
||||||
=== Simple ===
|
=== Simple ===
|
||||||
|
|
||||||
@@ -136,7 +128,7 @@ and then proceed as they would for a full signature.
|
|||||||
|
|
||||||
=== Full ===
|
=== Full ===
|
||||||
|
|
||||||
Full signatures follow an analogous specification to the BIP-325 challenges and solutions used by
|
Full signatures follow an analogous specification to the BIP325 challenges and solutions used by
|
||||||
Signet.
|
Signet.
|
||||||
|
|
||||||
Let there be two virtual transactions <code>to_spend</code> and <code>to_sign</code>.
|
Let there be two virtual transactions <code>to_spend</code> and <code>to_sign</code>.
|
||||||
@@ -153,14 +145,14 @@ The <code>to_spend</code> transaction is:
|
|||||||
vout[0].nValue = 0
|
vout[0].nValue = 0
|
||||||
vout[0].scriptPubKey = message_challenge
|
vout[0].scriptPubKey = message_challenge
|
||||||
|
|
||||||
where <code>message_hash</code> is a BIP340-tagged hash of the message, i.e. sha256_tag(m), where
|
where <code>message_hash</code> is a BIP340-tagged hash of the message, i.e., sha256_tag(m), where
|
||||||
tag = <code>BIP0322-signed-message</code> and <code>m</code> is the message as is without length
|
tag = <code>BIP0322-signed-message</code> and <code>m</code> is the message as-is without length
|
||||||
prefix or null terminator, and <code>message_challenge</code> is the to be proven (public) key
|
prefix or null terminator, and <code>message_challenge</code> is the (public) key script to be
|
||||||
script.
|
proven.
|
||||||
|
|
||||||
The <code>to_sign</code> transaction is:
|
The <code>to_sign</code> transaction is:
|
||||||
|
|
||||||
nVersion = 0 or (FULL format only) as appropriate (e.g. 2, for time locks)
|
nVersion = 0 or (FULL format only) as appropriate (e.g., 2 for time locks)
|
||||||
nLockTime = 0 or (FULL format only) as appropriate (for time locks)
|
nLockTime = 0 or (FULL format only) as appropriate (for time locks)
|
||||||
vin[0].prevout.hash = to_spend.txid
|
vin[0].prevout.hash = to_spend.txid
|
||||||
vin[0].prevout.n = 0
|
vin[0].prevout.n = 0
|
||||||
@@ -175,13 +167,22 @@ A ''full'' signature consists of the variant-prefixed (<code>ful</code>) base64-
|
|||||||
|
|
||||||
=== Full (Proof of Funds) ===
|
=== Full (Proof of Funds) ===
|
||||||
|
|
||||||
|
The [[#full-proof-of-funds|Proof of Funds]] variant extends the basic scheme: in addition to signing
|
||||||
|
a message under a single address's key, the signer proves control over an arbitrary set of UTXOs.
|
||||||
|
This UTXO set is chosen freely by the signer and MAY be associated with the signing address
|
||||||
|
(the <code>message_challenge</code>). For example, it may consist of outputs paid to that address,
|
||||||
|
but any UTXOs the signer wants to show control over are permitted.
|
||||||
|
In any case, however, the UTXO list does not aim to prove completeness (e.g., it does NOT mean:
|
||||||
|
"these are all UTXOs that exist for an address"), nor that they are unspent (e.g., a validator must
|
||||||
|
consult the blockchain to verify that).
|
||||||
|
|
||||||
A signer may construct a proof of funds, demonstrating control of a set of UTXOs, by constructing a
|
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.
|
full signature as above, with the following modifications.
|
||||||
|
|
||||||
<ul>
|
<ul>
|
||||||
<li>
|
<li>
|
||||||
The <code>to_spend</code> transaction is represented as a finalized PSBT instead of a raw
|
The <code>to_spend</code> transaction is represented as a finalized PSBT instead of a raw
|
||||||
transaction (see [[bip-0174.mediawiki#input-finalizer|BIP-0174]] for details on the finalization
|
transaction (see [[bip-0174.mediawiki#input-finalizer|BIP174]] for details on the finalization
|
||||||
process).
|
process).
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
@@ -207,7 +208,7 @@ Unlike an ordinary signature, validators of a proof of funds need access to the
|
|||||||
learn that the claimed inputs exist on the blockchain and remain unspent.
|
learn that the claimed inputs exist on the blockchain and remain unspent.
|
||||||
An offline validator therefore can only attest to the cryptographic validity of the additional
|
An offline validator therefore can only attest to the cryptographic validity of the additional
|
||||||
inputs' witness stack, but not its blockchain state.
|
inputs' witness stack, but not its blockchain state.
|
||||||
An attested list of UTXOs can also never prove that there don't exist more UTXOs for a certain
|
An attested list of UTXOs can also never prove that there do not exist more UTXOs for a certain
|
||||||
address.
|
address.
|
||||||
|
|
||||||
== Detailed Specification ==
|
== Detailed Specification ==
|
||||||
@@ -219,7 +220,7 @@ output with prevout <code>000...000:FFFFFFFF</code> does not exist.
|
|||||||
=== Verification ===
|
=== Verification ===
|
||||||
|
|
||||||
A validator is given as input an address ''A'' (which may be omitted in a proof-of-funds), signature
|
A validator is given as input an address ''A'' (which may be omitted in a proof-of-funds), signature
|
||||||
''s'' and message ''m'', and outputs one of three states
|
''s'' and message ''m'', and outputs one of three states:
|
||||||
|
|
||||||
<ul>
|
<ul>
|
||||||
<li>
|
<li>
|
||||||
@@ -242,14 +243,14 @@ Validation consists of the following steps:
|
|||||||
## Compute the transaction <code>to_spend</code> from ''m'' and ''A''
|
## Compute the transaction <code>to_spend</code> from ''m'' and ''A''
|
||||||
## Decode ''s'' as the transaction <code>to_sign</code>
|
## Decode ''s'' as the transaction <code>to_sign</code>
|
||||||
## If ''s'' was a full transaction or PSBT, confirm all fields are set as specified above; in particular that
|
## If ''s'' was a full transaction or PSBT, confirm all fields are set as specified above; in particular that
|
||||||
##* <code>to_sign</code> has at least one input and its first input spends the output of </code>to_spend</code>
|
##* <code>to_sign</code> has at least one input and its first input spends the output of <code>to_spend</code>
|
||||||
##* <code>to_sign</code> with more than one input has an appropriate Witness UTXO or Non-Witness UTXO for each input
|
##* <code>to_sign</code> with more than one input has an appropriate Witness UTXO or Non-Witness UTXO for each input
|
||||||
##** If (based on the input type) a Non-Witness UTXO is required but not provided, check if the first input with the same transaction ID has a Non-Witness UTXO set and use that; fail validation if no such Non-Witness UTXO can be found
|
##** If (based on the input type) a Non-Witness UTXO is required but not provided, check if the first input with the same transaction ID has a Non-Witness UTXO set and use that; fail validation if no such Non-Witness UTXO can be found
|
||||||
##* <code>to_sign</code> has exactly one output, as specified above
|
##* <code>to_sign</code> has exactly one output, as specified above
|
||||||
## Confirm that the two transactions together satisfy all consensus rules, except for <code>to_spend</code>'s missing input, and except that ''nSequence'' of <code>to_sign</code>'s first input and ''nLockTime'' of <code>to_sign</code> are not checked.
|
## Confirm that the two transactions together satisfy all consensus rules, except for <code>to_spend</code>'s missing input, and except that ''nSequence'' of <code>to_sign</code>'s first input and ''nLockTime'' of <code>to_sign</code> are not checked.
|
||||||
# (Optional) If the validator does not have a full script interpreter, it should check that it understands all scripts being satisfied. If not, it should stop here and output ''inconclusive''.
|
# (Optional) If the validator does not have a full script interpreter, it should check that it understands all scripts being satisfied. If not, it should stop here and output ''inconclusive''.
|
||||||
# Check the '''required rules''':
|
# Check the '''required rules''':
|
||||||
## All signatures must use the <code>SIGHASH_ALL</code> (or <code>SIGHASH_DEFAULT</code> for [[bip-0341.mediawiki|BIP341 P2TR]] inputs) flag.
|
## All signatures MUST use the <code>SIGHASH_ALL</code> flag, unless the output type supports <code>SIGHASH_DEFAULT</code>, which then MAY be used alternatively (e.g., [[bip-0341.mediawiki|BIP341 P2TR]]).
|
||||||
## The use of <code>CODESEPARATOR</code> or <code>FindAndDelete</code> is forbidden.
|
## The use of <code>CODESEPARATOR</code> or <code>FindAndDelete</code> is forbidden.
|
||||||
## <code>LOW_S</code>, <code>STRICTENC</code> and <code>NULLFAIL</code>: valid ECDSA signatures must be strictly DER-encoded and have a low-S value; invalid ECDSA signature must be the empty push
|
## <code>LOW_S</code>, <code>STRICTENC</code> and <code>NULLFAIL</code>: valid ECDSA signatures must be strictly DER-encoded and have a low-S value; invalid ECDSA signature must be the empty push
|
||||||
## <code>MINIMALDATA</code>: all pushes must be minimally encoded
|
## <code>MINIMALDATA</code>: all pushes must be minimally encoded
|
||||||
@@ -261,7 +262,7 @@ Validation consists of the following steps:
|
|||||||
## The use of NOPs reserved for upgrades is forbidden.
|
## The use of NOPs reserved for upgrades is forbidden.
|
||||||
## The use of Segwit versions greater than 1 are forbidden.
|
## The use of Segwit versions greater than 1 are forbidden.
|
||||||
## If any of the above steps failed, the validator should stop and output the ''inconclusive'' state.
|
## If any of the above steps failed, the validator should stop and output the ''inconclusive'' state.
|
||||||
# Let ''T'' by the nLockTime of <code>to_sign</code> and ''S'' be the nSequence of the first input of <code>to_sign</code>. Output the state ''valid at time T and age S''.
|
# Let ''T'' be the nLockTime of <code>to_sign</code> and ''S'' be the nSequence of the first input of <code>to_sign</code>. Output the state ''valid at time T and age S''.
|
||||||
|
|
||||||
=== Signing ===
|
=== Signing ===
|
||||||
|
|
||||||
@@ -338,7 +339,7 @@ request to the user. The new global type is defined as follows:
|
|||||||
|
|
||||||
=== PSBT creator ===
|
=== PSBT creator ===
|
||||||
|
|
||||||
The '''transaction creator''' of a BIP-0322 PSBT must follow these steps:
|
The '''transaction creator''' of a BIP322 PSBT must follow these steps:
|
||||||
|
|
||||||
<ol>
|
<ol>
|
||||||
<li>
|
<li>
|
||||||
@@ -368,12 +369,12 @@ The '''transaction creator''' of a BIP-0322 PSBT must follow these steps:
|
|||||||
partial signature.
|
partial signature.
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
They set the <code>PSBT_GLOBAL_GENERIC_SIGNED_MESSAGE</code> field, using the full UTF-8 encoded
|
They set the <code>PSBT_GLOBAL_GENERIC_SIGNED_MESSAGE</code> field, using the full UTF-8-encoded
|
||||||
message as the <code>valuedata</code>.
|
message as the <code>valuedata</code>.
|
||||||
<ol>
|
<ol>
|
||||||
<li>
|
<li>
|
||||||
There is no specified maximum length of an input's <code>valuedata</code> or a PSBT as a whole in
|
There is no specified maximum length of an input's <code>valuedata</code> or a PSBT as a whole in
|
||||||
[[bip-0174.mediawiki|BIP-0174]], but different signers might impose safety limits. It is
|
[[bip-0174.mediawiki|BIP174]], but different signers might impose safety limits. It is
|
||||||
recommended to use a maximum length of a few kilobytes to maximize compatibility. Very large
|
recommended to use a maximum length of a few kilobytes to maximize compatibility. Very large
|
||||||
messages should be committed to by hash instead.
|
messages should be committed to by hash instead.
|
||||||
</li>
|
</li>
|
||||||
@@ -383,14 +384,14 @@ The '''transaction creator''' of a BIP-0322 PSBT must follow these steps:
|
|||||||
|
|
||||||
=== PSBT signer ===
|
=== PSBT signer ===
|
||||||
|
|
||||||
A '''transaction signer''' of a BIP-0322 PSBT must follow these steps:
|
A '''transaction signer''' of a BIP322 PSBT must follow these steps:
|
||||||
|
|
||||||
<ol>
|
<ol>
|
||||||
<li>
|
<li>
|
||||||
They decode the base64-encoded PSBT as specified in [[bip-0174.mediawiki|BIP-0174]].
|
They decode the base64-encoded PSBT as specified in [[bip-0174.mediawiki|BIP174]].
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
If they detect the following properties (all must be true, otherwise this is NOT a BIP-0322 PSBT
|
If they detect the following properties (all must be true, otherwise this is NOT a BIP322 PSBT
|
||||||
and they should treat it as an ordinary PSBT):
|
and they should treat it as an ordinary PSBT):
|
||||||
<ol>
|
<ol>
|
||||||
<li>
|
<li>
|
||||||
@@ -399,7 +400,7 @@ A '''transaction signer''' of a BIP-0322 PSBT must follow these steps:
|
|||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
The first PSBT input has either a <code>witness_utxo</code> or a <code>non_witness_utxo</code>
|
The first PSBT input has either a <code>witness_utxo</code> or a <code>non_witness_utxo</code>
|
||||||
field set and the <code>scriptPubKey</code> can be extracted, then use as
|
field set and the <code>scriptPubKey</code> can be extracted. Use that as
|
||||||
<code>message_challenge</code> in the next steps.
|
<code>message_challenge</code> in the next steps.
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
@@ -421,7 +422,7 @@ A '''transaction signer''' of a BIP-0322 PSBT must follow these steps:
|
|||||||
signing and the address they are signing for.
|
signing and the address they are signing for.
|
||||||
<ol>
|
<ol>
|
||||||
<li>
|
<li>
|
||||||
Even though the message being signed is a transaction, the user interaction (e.g. the steps and
|
Even though the message being signed is a transaction, the user interaction (e.g., the steps and
|
||||||
messages shown on a hardware signing device's screen) should resemble the steps to sign a legacy
|
messages shown on a hardware signing device's screen) should resemble the steps to sign a legacy
|
||||||
message, not the steps for signing a transaction.
|
message, not the steps for signing a transaction.
|
||||||
</li>
|
</li>
|
||||||
@@ -438,14 +439,14 @@ A '''transaction signer''' of a BIP-0322 PSBT must follow these steps:
|
|||||||
|
|
||||||
=== PSBT finalizer ===
|
=== PSBT finalizer ===
|
||||||
|
|
||||||
A '''transaction finalizer''' of a BIP-0322 PSBT must follow these steps:
|
A '''transaction finalizer''' of a BIP322 PSBT must follow these steps:
|
||||||
|
|
||||||
<ol>
|
<ol>
|
||||||
<li>
|
<li>
|
||||||
They decode the base64-encoded PSBT as specified in [[bip-0174.mediawiki|BIP-0174]].
|
They decode the base64-encoded PSBT as specified in [[bip-0174.mediawiki|BIP174]].
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
They finalize the PSBT as specified in [[bip-0174.mediawiki#input-finalizer|BIP-0174]].
|
They finalize the PSBT as specified in [[bip-0174.mediawiki#input-finalizer|BIP174]].
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
They then encode the signature following the same steps as described in [[#signing|Signing]]
|
They then encode the signature following the same steps as described in [[#signing|Signing]]
|
||||||
@@ -455,7 +456,7 @@ A '''transaction finalizer''' of a BIP-0322 PSBT must follow these steps:
|
|||||||
|
|
||||||
== Compatibility ==
|
== Compatibility ==
|
||||||
|
|
||||||
This specification is backwards compatible with the legacy signmessage/verifymessage specification
|
This specification is backwards-compatible with the legacy signmessage/verifymessage specification
|
||||||
through the special case [[#legacy|as described above]].
|
through the special case [[#legacy|as described above]].
|
||||||
To support backward compatibility with implementations of this BIP before it was finalized, a
|
To support backward compatibility with implementations of this BIP before it was finalized, a
|
||||||
verifier might assume the ''simple' variant in the absence of a prefix.
|
verifier might assume the ''simple' variant in the absence of a prefix.
|
||||||
|
|||||||
Reference in New Issue
Block a user