diff --git a/bip-0322.mediawiki b/bip-0322.mediawiki
index c448740e..e29a32ba 100644
--- a/bip-0322.mediawiki
+++ b/bip-0322.mediawiki
@@ -22,31 +22,23 @@
== Abstract ==
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
-address.
+availability of funds, or for committing to a message as the intended recipient of funds sent to the
+invoice address.
== 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
+extend and generalize the standard by using an approach based on Bitcoin Script. 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 that
resembles a Bitcoin transaction (except that it contains an invalid input, so it cannot be spent on
any real network).
-The [[#full-proof-of-funds|Proof of Funds]] variant allows demonstrating control
-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
-message_challenge).
-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
+Additionally, the current message signature format uses ECDSA signatures that 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.)
+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
sign messages on others' behalf even if it would not sign actual transactions. No message signing
protocol can fix these limitations.
@@ -58,7 +50,7 @@ using this BIP.
== Terminology ==
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
message_challenge, 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
"signature" may or may not contain an actual cryptographic (ECDSA or Schnorr) signature, depending
@@ -85,32 +77,32 @@ UTXOs.
| Simple
| P2WPKH, P2WSH2, P2TR2
| smp
-| witness stack, consensus encoded and base64-encoded
+| witness stack, consensus-encoded and base64-encoded
|-
| Full
| all
| ful
-| full to_sign transaction, consensus and base64-encoded
+| full to_sign transaction, consensus-encoded and base64-encoded
|-
| Full (Proof of Funds)
| all
| pof
-| full finalized PSBT of the to_sign transaction, consensus and base64-encoded
+| full finalized PSBT of the to_sign transaction, consensus-encoded and base64-encoded
|}
-1: Possible on a technical level but should NOT be used anymore in the context of this
+1: Possible on a technical level but SHOULD NOT be used anymore in the context of this
BIP, see section [[#legacy|Legacy]] below.
2: 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
verifier might assume the ''simple'' variant in the absence of a prefix.
=== 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 ===
@@ -136,7 +128,7 @@ and then proceed as they would for a full signature.
=== 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.
Let there be two virtual transactions to_spend and to_sign.
@@ -153,14 +145,14 @@ The to_spend transaction is:
vout[0].nValue = 0
vout[0].scriptPubKey = message_challenge
-where message_hash is a BIP340-tagged hash of the message, i.e. sha256_tag(m), where
-tag = BIP0322-signed-message and m is the message as is without length
-prefix or null terminator, and message_challenge is the to be proven (public) key
-script.
+where message_hash is a BIP340-tagged hash of the message, i.e., sha256_tag(m), where
+tag = BIP0322-signed-message and m is the message as-is without length
+prefix or null terminator, and message_challenge is the (public) key script to be
+proven.
The to_sign 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)
vin[0].prevout.hash = to_spend.txid
vin[0].prevout.n = 0
@@ -175,13 +167,22 @@ A ''full'' signature consists of the variant-prefixed (ful) base64-
=== 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 message_challenge). 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
full signature as above, with the following modifications.
to_spend 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).
000...000:FFFFFFFF does not exist.
=== Verification ===
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:
to_spend from ''m'' and ''A''
## Decode ''s'' as the transaction to_sign
## If ''s'' was a full transaction or PSBT, confirm all fields are set as specified above; in particular that
-##* to_sign has at least one input and its first input spends the output of to_spend
+##* to_sign has at least one input and its first input spends the output of to_spend
##* to_sign 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
##* to_sign has exactly one output, as specified above
## Confirm that the two transactions together satisfy all consensus rules, except for to_spend's missing input, and except that ''nSequence'' of to_sign's first input and ''nLockTime'' of to_sign 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''.
# Check the '''required rules''':
-## All signatures must use the SIGHASH_ALL (or SIGHASH_DEFAULT for [[bip-0341.mediawiki|BIP341 P2TR]] inputs) flag.
+## All signatures MUST use the SIGHASH_ALL flag, unless the output type supports SIGHASH_DEFAULT, which then MAY be used alternatively (e.g., [[bip-0341.mediawiki|BIP341 P2TR]]).
## The use of CODESEPARATOR or FindAndDelete is forbidden.
## LOW_S, STRICTENC and NULLFAIL: valid ECDSA signatures must be strictly DER-encoded and have a low-S value; invalid ECDSA signature must be the empty push
## MINIMALDATA: 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 Segwit versions greater than 1 are forbidden.
## If any of the above steps failed, the validator should stop and output the ''inconclusive'' state.
-# Let ''T'' by the nLockTime of to_sign and ''S'' be the nSequence of the first input of to_sign. Output the state ''valid at time T and age S''.
+# Let ''T'' be the nLockTime of to_sign and ''S'' be the nSequence of the first input of to_sign. Output the state ''valid at time T and age S''.
=== Signing ===
@@ -292,7 +293,7 @@ They then encode their signature, choosing either ''simple'', ''full'' or ''full
to_sign, left nVersion, nSequence and nLockTime at 0, and
''A'' is a "native" Segwit address (P2WPKH, P2WSH, P2TR), then they may base64-encode
- message_signature with smp as prefix.
+ message_signature with smp as prefix.
to_sign, they may base64-encode to_sign with
@@ -338,7 +339,7 @@ request to the user. The new global type is defined as follows:
=== 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:
PSBT_GLOBAL_GENERIC_SIGNED_MESSAGE field, using the full UTF-8 encoded
+ They set the PSBT_GLOBAL_GENERIC_SIGNED_MESSAGE field, using the full UTF-8-encoded
message as the valuedata.
valuedata 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
messages should be committed to by hash instead.
witness_utxo or a non_witness_utxo
- field set and the scriptPubKey can be extracted, then use as
+ field set and the scriptPubKey can be extracted. Use that as
message_challenge in the next steps.